Home | History | Annotate | Download | only in macho
      1 // Copyright 2009 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Mach-O header data structures
      6 // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
      7 
      8 package macho
      9 
     10 import "strconv"
     11 
     12 // A FileHeader represents a Mach-O file header.
     13 type FileHeader struct {
     14 	Magic  uint32
     15 	Cpu    Cpu
     16 	SubCpu uint32
     17 	Type   Type
     18 	Ncmd   uint32
     19 	Cmdsz  uint32
     20 	Flags  uint32
     21 }
     22 
     23 const (
     24 	fileHeaderSize32 = 7 * 4
     25 	fileHeaderSize64 = 8 * 4
     26 )
     27 
     28 const (
     29 	Magic32  uint32 = 0xfeedface
     30 	Magic64  uint32 = 0xfeedfacf
     31 	MagicFat uint32 = 0xcafebabe
     32 )
     33 
     34 // A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
     35 type Type uint32
     36 
     37 const (
     38 	TypeObj    Type = 1
     39 	TypeExec   Type = 2
     40 	TypeDylib  Type = 6
     41 	TypeBundle Type = 8
     42 )
     43 
     44 var typeStrings = []intName{
     45 	{uint32(TypeObj), "Obj"},
     46 	{uint32(TypeExec), "Exec"},
     47 	{uint32(TypeDylib), "Dylib"},
     48 	{uint32(TypeBundle), "Bundle"},
     49 }
     50 
     51 func (t Type) String() string   { return stringName(uint32(t), typeStrings, false) }
     52 func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) }
     53 
     54 // A Cpu is a Mach-O cpu type.
     55 type Cpu uint32
     56 
     57 const cpuArch64 = 0x01000000
     58 
     59 const (
     60 	Cpu386   Cpu = 7
     61 	CpuAmd64 Cpu = Cpu386 | cpuArch64
     62 	CpuArm   Cpu = 12
     63 	CpuPpc   Cpu = 18
     64 	CpuPpc64 Cpu = CpuPpc | cpuArch64
     65 )
     66 
     67 var cpuStrings = []intName{
     68 	{uint32(Cpu386), "Cpu386"},
     69 	{uint32(CpuAmd64), "CpuAmd64"},
     70 	{uint32(CpuArm), "CpuArm"},
     71 	{uint32(CpuPpc), "CpuPpc"},
     72 	{uint32(CpuPpc64), "CpuPpc64"},
     73 }
     74 
     75 func (i Cpu) String() string   { return stringName(uint32(i), cpuStrings, false) }
     76 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
     77 
     78 // A LoadCmd is a Mach-O load command.
     79 type LoadCmd uint32
     80 
     81 const (
     82 	LoadCmdSegment    LoadCmd = 0x1
     83 	LoadCmdSymtab     LoadCmd = 0x2
     84 	LoadCmdThread     LoadCmd = 0x4
     85 	LoadCmdUnixThread LoadCmd = 0x5 // thread+stack
     86 	LoadCmdDysymtab   LoadCmd = 0xb
     87 	LoadCmdDylib      LoadCmd = 0xc // load dylib command
     88 	LoadCmdDylinker   LoadCmd = 0xf // id dylinker command (not load dylinker command)
     89 	LoadCmdSegment64  LoadCmd = 0x19
     90 	LoadCmdRpath      LoadCmd = 0x8000001c
     91 )
     92 
     93 var cmdStrings = []intName{
     94 	{uint32(LoadCmdSegment), "LoadCmdSegment"},
     95 	{uint32(LoadCmdThread), "LoadCmdThread"},
     96 	{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
     97 	{uint32(LoadCmdDylib), "LoadCmdDylib"},
     98 	{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
     99 	{uint32(LoadCmdRpath), "LoadCmdRpath"},
    100 }
    101 
    102 func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) }
    103 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
    104 
    105 type (
    106 	// A Segment32 is a 32-bit Mach-O segment load command.
    107 	Segment32 struct {
    108 		Cmd     LoadCmd
    109 		Len     uint32
    110 		Name    [16]byte
    111 		Addr    uint32
    112 		Memsz   uint32
    113 		Offset  uint32
    114 		Filesz  uint32
    115 		Maxprot uint32
    116 		Prot    uint32
    117 		Nsect   uint32
    118 		Flag    uint32
    119 	}
    120 
    121 	// A Segment64 is a 64-bit Mach-O segment load command.
    122 	Segment64 struct {
    123 		Cmd     LoadCmd
    124 		Len     uint32
    125 		Name    [16]byte
    126 		Addr    uint64
    127 		Memsz   uint64
    128 		Offset  uint64
    129 		Filesz  uint64
    130 		Maxprot uint32
    131 		Prot    uint32
    132 		Nsect   uint32
    133 		Flag    uint32
    134 	}
    135 
    136 	// A SymtabCmd is a Mach-O symbol table command.
    137 	SymtabCmd struct {
    138 		Cmd     LoadCmd
    139 		Len     uint32
    140 		Symoff  uint32
    141 		Nsyms   uint32
    142 		Stroff  uint32
    143 		Strsize uint32
    144 	}
    145 
    146 	// A DysymtabCmd is a Mach-O dynamic symbol table command.
    147 	DysymtabCmd struct {
    148 		Cmd            LoadCmd
    149 		Len            uint32
    150 		Ilocalsym      uint32
    151 		Nlocalsym      uint32
    152 		Iextdefsym     uint32
    153 		Nextdefsym     uint32
    154 		Iundefsym      uint32
    155 		Nundefsym      uint32
    156 		Tocoffset      uint32
    157 		Ntoc           uint32
    158 		Modtaboff      uint32
    159 		Nmodtab        uint32
    160 		Extrefsymoff   uint32
    161 		Nextrefsyms    uint32
    162 		Indirectsymoff uint32
    163 		Nindirectsyms  uint32
    164 		Extreloff      uint32
    165 		Nextrel        uint32
    166 		Locreloff      uint32
    167 		Nlocrel        uint32
    168 	}
    169 
    170 	// A DylibCmd is a Mach-O load dynamic library command.
    171 	DylibCmd struct {
    172 		Cmd            LoadCmd
    173 		Len            uint32
    174 		Name           uint32
    175 		Time           uint32
    176 		CurrentVersion uint32
    177 		CompatVersion  uint32
    178 	}
    179 
    180 	// A RpathCmd is a Mach-O rpath command.
    181 	RpathCmd struct {
    182 		Cmd  LoadCmd
    183 		Len  uint32
    184 		Path uint32
    185 	}
    186 
    187 	// A Thread is a Mach-O thread state command.
    188 	Thread struct {
    189 		Cmd  LoadCmd
    190 		Len  uint32
    191 		Type uint32
    192 		Data []uint32
    193 	}
    194 )
    195 
    196 const (
    197 	FlagNoUndefs              uint32 = 0x1
    198 	FlagIncrLink              uint32 = 0x2
    199 	FlagDyldLink              uint32 = 0x4
    200 	FlagBindAtLoad            uint32 = 0x8
    201 	FlagPrebound              uint32 = 0x10
    202 	FlagSplitSegs             uint32 = 0x20
    203 	FlagLazyInit              uint32 = 0x40
    204 	FlagTwoLevel              uint32 = 0x80
    205 	FlagForceFlat             uint32 = 0x100
    206 	FlagNoMultiDefs           uint32 = 0x200
    207 	FlagNoFixPrebinding       uint32 = 0x400
    208 	FlagPrebindable           uint32 = 0x800
    209 	FlagAllModsBound          uint32 = 0x1000
    210 	FlagSubsectionsViaSymbols uint32 = 0x2000
    211 	FlagCanonical             uint32 = 0x4000
    212 	FlagWeakDefines           uint32 = 0x8000
    213 	FlagBindsToWeak           uint32 = 0x10000
    214 	FlagAllowStackExecution   uint32 = 0x20000
    215 	FlagRootSafe              uint32 = 0x40000
    216 	FlagSetuidSafe            uint32 = 0x80000
    217 	FlagNoReexportedDylibs    uint32 = 0x100000
    218 	FlagPIE                   uint32 = 0x200000
    219 	FlagDeadStrippableDylib   uint32 = 0x400000
    220 	FlagHasTLVDescriptors     uint32 = 0x800000
    221 	FlagNoHeapExecution       uint32 = 0x1000000
    222 	FlagAppExtensionSafe      uint32 = 0x2000000
    223 )
    224 
    225 // A Section32 is a 32-bit Mach-O section header.
    226 type Section32 struct {
    227 	Name     [16]byte
    228 	Seg      [16]byte
    229 	Addr     uint32
    230 	Size     uint32
    231 	Offset   uint32
    232 	Align    uint32
    233 	Reloff   uint32
    234 	Nreloc   uint32
    235 	Flags    uint32
    236 	Reserve1 uint32
    237 	Reserve2 uint32
    238 }
    239 
    240 // A Section64 is a 64-bit Mach-O section header.
    241 type Section64 struct {
    242 	Name     [16]byte
    243 	Seg      [16]byte
    244 	Addr     uint64
    245 	Size     uint64
    246 	Offset   uint32
    247 	Align    uint32
    248 	Reloff   uint32
    249 	Nreloc   uint32
    250 	Flags    uint32
    251 	Reserve1 uint32
    252 	Reserve2 uint32
    253 	Reserve3 uint32
    254 }
    255 
    256 // An Nlist32 is a Mach-O 32-bit symbol table entry.
    257 type Nlist32 struct {
    258 	Name  uint32
    259 	Type  uint8
    260 	Sect  uint8
    261 	Desc  uint16
    262 	Value uint32
    263 }
    264 
    265 // An Nlist64 is a Mach-O 64-bit symbol table entry.
    266 type Nlist64 struct {
    267 	Name  uint32
    268 	Type  uint8
    269 	Sect  uint8
    270 	Desc  uint16
    271 	Value uint64
    272 }
    273 
    274 // Regs386 is the Mach-O 386 register structure.
    275 type Regs386 struct {
    276 	AX    uint32
    277 	BX    uint32
    278 	CX    uint32
    279 	DX    uint32
    280 	DI    uint32
    281 	SI    uint32
    282 	BP    uint32
    283 	SP    uint32
    284 	SS    uint32
    285 	FLAGS uint32
    286 	IP    uint32
    287 	CS    uint32
    288 	DS    uint32
    289 	ES    uint32
    290 	FS    uint32
    291 	GS    uint32
    292 }
    293 
    294 // RegsAMD64 is the Mach-O AMD64 register structure.
    295 type RegsAMD64 struct {
    296 	AX    uint64
    297 	BX    uint64
    298 	CX    uint64
    299 	DX    uint64
    300 	DI    uint64
    301 	SI    uint64
    302 	BP    uint64
    303 	SP    uint64
    304 	R8    uint64
    305 	R9    uint64
    306 	R10   uint64
    307 	R11   uint64
    308 	R12   uint64
    309 	R13   uint64
    310 	R14   uint64
    311 	R15   uint64
    312 	IP    uint64
    313 	FLAGS uint64
    314 	CS    uint64
    315 	FS    uint64
    316 	GS    uint64
    317 }
    318 
    319 type intName struct {
    320 	i uint32
    321 	s string
    322 }
    323 
    324 func stringName(i uint32, names []intName, goSyntax bool) string {
    325 	for _, n := range names {
    326 		if n.i == i {
    327 			if goSyntax {
    328 				return "macho." + n.s
    329 			}
    330 			return n.s
    331 		}
    332 	}
    333 	return strconv.FormatUint(uint64(i), 10)
    334 }
    335