2009-09-18 12:49:22 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// Mach-O header data structures
|
|
|
|
// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
|
|
|
|
|
|
|
|
package macho
|
|
|
|
|
|
|
|
import "strconv"
|
|
|
|
|
|
|
|
// A FileHeader represents a Mach-O file header.
|
|
|
|
type FileHeader struct {
|
|
|
|
Magic uint32;
|
|
|
|
Cpu Cpu;
|
|
|
|
SubCpu uint32;
|
|
|
|
Type Type;
|
|
|
|
Ncmd uint32;
|
|
|
|
Cmdsz uint32;
|
|
|
|
Flags uint32;
|
|
|
|
}
|
2009-10-06 15:55:06 -06:00
|
|
|
|
2009-09-18 12:49:22 -06:00
|
|
|
const (
|
2009-10-06 15:55:06 -06:00
|
|
|
fileHeaderSize32 = 7*4;
|
|
|
|
fileHeaderSize64 = 8*4;
|
2009-09-18 12:49:22 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2009-10-06 15:55:06 -06:00
|
|
|
Magic32 uint32 = 0xfeedface;
|
|
|
|
Magic64 uint32 = 0xfeedfacf;
|
2009-09-18 12:49:22 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// A Type is a Mach-O file type, either an object or an executable.
|
|
|
|
type Type uint32
|
2009-10-06 15:55:06 -06:00
|
|
|
|
2009-09-18 12:49:22 -06:00
|
|
|
const (
|
2009-10-06 15:55:06 -06:00
|
|
|
TypeObj Type = 1;
|
|
|
|
TypeExec Type = 2;
|
2009-09-18 12:49:22 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// A Cpu is a Mach-O cpu type.
|
|
|
|
type Cpu uint32
|
2009-10-06 15:55:06 -06:00
|
|
|
|
2009-09-18 12:49:22 -06:00
|
|
|
const (
|
2009-10-06 15:55:06 -06:00
|
|
|
Cpu386 Cpu = 7;
|
|
|
|
CpuAmd64 Cpu = Cpu386 + 1<<24;
|
2009-09-18 12:49:22 -06:00
|
|
|
)
|
|
|
|
|
2009-10-06 15:55:06 -06:00
|
|
|
var cpuStrings = []intName{
|
|
|
|
intName{uint32(Cpu386), "Cpu386"},
|
|
|
|
intName{uint32(CpuAmd64), "CpuAmd64"},
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
2009-10-06 15:55:06 -06:00
|
|
|
|
2009-11-06 15:24:38 -07:00
|
|
|
func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
|
|
|
|
func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
|
2009-09-18 12:49:22 -06:00
|
|
|
|
|
|
|
// A LoadCmd is a Mach-O load command.
|
2009-10-06 15:55:06 -06:00
|
|
|
type LoadCmd uint32
|
|
|
|
|
2009-09-18 12:49:22 -06:00
|
|
|
const (
|
2009-10-06 15:55:06 -06:00
|
|
|
LoadCmdSegment LoadCmd = 1;
|
|
|
|
LoadCmdSegment64 LoadCmd = 25;
|
|
|
|
LoadCmdThread LoadCmd = 4;
|
|
|
|
LoadCmdUnixThread LoadCmd = 5; // thread+stack
|
2009-09-18 12:49:22 -06:00
|
|
|
)
|
2009-10-06 15:55:06 -06:00
|
|
|
|
|
|
|
var cmdStrings = []intName{
|
|
|
|
intName{uint32(LoadCmdSegment), "LoadCmdSegment"},
|
|
|
|
intName{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
|
|
|
|
intName{uint32(LoadCmdThread), "LoadCmdThread"},
|
|
|
|
intName{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
2009-10-06 15:55:06 -06:00
|
|
|
|
2009-11-06 15:24:38 -07:00
|
|
|
func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
|
|
|
|
func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
|
2009-09-18 12:49:22 -06:00
|
|
|
|
|
|
|
// A Segment64 is a 64-bit Mach-O segment load command.
|
|
|
|
type Segment64 struct {
|
|
|
|
Cmd LoadCmd;
|
|
|
|
Len uint32;
|
|
|
|
Name [16]byte;
|
|
|
|
Addr uint64;
|
|
|
|
Memsz uint64;
|
|
|
|
Offset uint64;
|
|
|
|
Filesz uint64;
|
|
|
|
Maxprot uint32;
|
|
|
|
Prot uint32;
|
|
|
|
Nsect uint32;
|
|
|
|
Flag uint32;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A Segment32 is a 32-bit Mach-O segment load command.
|
|
|
|
type Segment32 struct {
|
|
|
|
Cmd LoadCmd;
|
|
|
|
Len uint32;
|
|
|
|
Name [16]byte;
|
|
|
|
Addr uint32;
|
|
|
|
Memsz uint32;
|
|
|
|
Offset uint32;
|
|
|
|
Filesz uint32;
|
|
|
|
Maxprot uint32;
|
|
|
|
Prot uint32;
|
|
|
|
Nsect uint32;
|
|
|
|
Flag uint32;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A Section32 is a 32-bit Mach-O section header.
|
|
|
|
type Section32 struct {
|
2009-10-06 15:55:06 -06:00
|
|
|
Name [16]byte;
|
2009-09-18 12:49:22 -06:00
|
|
|
Seg [16]byte;
|
2009-10-06 15:55:06 -06:00
|
|
|
Addr uint32;
|
|
|
|
Size uint32;
|
|
|
|
Offset uint32;
|
|
|
|
Align uint32;
|
|
|
|
Reloff uint32;
|
|
|
|
Nreloc uint32;
|
|
|
|
Flags uint32;
|
2009-09-18 12:49:22 -06:00
|
|
|
Reserve1 uint32;
|
|
|
|
Reserve2 uint32;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A Section32 is a 64-bit Mach-O section header.
|
|
|
|
type Section64 struct {
|
2009-10-06 15:55:06 -06:00
|
|
|
Name [16]byte;
|
2009-09-18 12:49:22 -06:00
|
|
|
Seg [16]byte;
|
2009-10-06 15:55:06 -06:00
|
|
|
Addr uint64;
|
|
|
|
Size uint64;
|
|
|
|
Offset uint32;
|
|
|
|
Align uint32;
|
|
|
|
Reloff uint32;
|
|
|
|
Nreloc uint32;
|
|
|
|
Flags uint32;
|
2009-09-18 12:49:22 -06:00
|
|
|
Reserve1 uint32;
|
|
|
|
Reserve2 uint32;
|
|
|
|
Reserve3 uint32;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A Thread is a Mach-O thread state command.
|
|
|
|
type Thread struct {
|
|
|
|
Cmd LoadCmd;
|
|
|
|
Len uint32;
|
|
|
|
Type uint32;
|
|
|
|
Data []uint32;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Regs386 is the Mach-O 386 register structure.
|
|
|
|
type Regs386 struct {
|
|
|
|
AX uint32;
|
|
|
|
BX uint32;
|
|
|
|
CX uint32;
|
|
|
|
DX uint32;
|
|
|
|
DI uint32;
|
|
|
|
SI uint32;
|
|
|
|
BP uint32;
|
|
|
|
SP uint32;
|
|
|
|
SS uint32;
|
|
|
|
FLAGS uint32;
|
|
|
|
IP uint32;
|
|
|
|
CS uint32;
|
|
|
|
DS uint32;
|
|
|
|
ES uint32;
|
|
|
|
FS uint32;
|
|
|
|
GS uint32;
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegsAMD64 is the Mach-O AMD64 register structure.
|
|
|
|
type RegsAMD64 struct {
|
|
|
|
AX uint64;
|
|
|
|
BX uint64;
|
|
|
|
CX uint64;
|
|
|
|
DX uint64;
|
|
|
|
DI uint64;
|
|
|
|
SI uint64;
|
|
|
|
BP uint64;
|
|
|
|
SP uint64;
|
|
|
|
R8 uint64;
|
|
|
|
R9 uint64;
|
|
|
|
R10 uint64;
|
|
|
|
R11 uint64;
|
|
|
|
R12 uint64;
|
|
|
|
R13 uint64;
|
|
|
|
R14 uint64;
|
|
|
|
R15 uint64;
|
|
|
|
IP uint64;
|
|
|
|
FLAGS uint64;
|
|
|
|
CS uint64;
|
|
|
|
FS uint64;
|
|
|
|
GS uint64;
|
|
|
|
}
|
|
|
|
|
|
|
|
type intName struct {
|
2009-10-06 15:55:06 -06:00
|
|
|
i uint32;
|
|
|
|
s string;
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func stringName(i uint32, names []intName, goSyntax bool) string {
|
|
|
|
for _, n := range names {
|
|
|
|
if n.i == i {
|
|
|
|
if goSyntax {
|
2009-10-06 15:55:06 -06:00
|
|
|
return "macho." + n.s;
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
2009-10-06 15:55:06 -06:00
|
|
|
return n.s;
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
|
|
|
}
|
2009-10-06 15:55:06 -06:00
|
|
|
return strconv.Uitoa64(uint64(i));
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func flagName(i uint32, names []intName, goSyntax bool) string {
|
|
|
|
s := "";
|
|
|
|
for _, n := range names {
|
|
|
|
if n.i & i == n.i {
|
|
|
|
if len(s) > 0 {
|
|
|
|
s += "+";
|
|
|
|
}
|
|
|
|
if goSyntax {
|
|
|
|
s += "macho.";
|
|
|
|
}
|
|
|
|
s += n.s;
|
|
|
|
i -= n.i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(s) == 0 {
|
2009-10-06 15:55:06 -06:00
|
|
|
return "0x" + strconv.Uitob64(uint64(i), 16);
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
|
|
|
if i != 0 {
|
2009-10-06 15:55:06 -06:00
|
|
|
s += "+0x" + strconv.Uitob64(uint64(i), 16);
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|
2009-10-06 15:55:06 -06:00
|
|
|
return s;
|
2009-09-18 12:49:22 -06:00
|
|
|
}
|