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 // A Cpu is a Mach-O cpu type.
     45 type Cpu uint32
     46 
     47 const cpuArch64 = 0x01000000
     48 
     49 const (
     50 	Cpu386   Cpu = 7
     51 	CpuAmd64 Cpu = Cpu386 | cpuArch64
     52 	CpuArm   Cpu = 12
     53 	CpuPpc   Cpu = 18
     54 	CpuPpc64 Cpu = CpuPpc | cpuArch64
     55 )
     56 
     57 var cpuStrings = []intName{
     58 	{uint32(Cpu386), "Cpu386"},
     59 	{uint32(CpuAmd64), "CpuAmd64"},
     60 	{uint32(CpuArm), "CpuArm"},
     61 	{uint32(CpuPpc), "CpuPpc"},
     62 	{uint32(CpuPpc64), "CpuPpc64"},
     63 }
     64 
     65 func (i Cpu) String() string   { return stringName(uint32(i), cpuStrings, false) }
     66 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
     67 
     68 // A LoadCmd is a Mach-O load command.
     69 type LoadCmd uint32
     70 
     71 const (
     72 	LoadCmdSegment    LoadCmd = 1
     73 	LoadCmdSymtab     LoadCmd = 2
     74 	LoadCmdThread     LoadCmd = 4
     75 	LoadCmdUnixThread LoadCmd = 5 // thread+stack
     76 	LoadCmdDysymtab   LoadCmd = 11
     77 	LoadCmdDylib      LoadCmd = 12
     78 	LoadCmdDylinker   LoadCmd = 15
     79 	LoadCmdSegment64  LoadCmd = 25
     80 )
     81 
     82 var cmdStrings = []intName{
     83 	{uint32(LoadCmdSegment), "LoadCmdSegment"},
     84 	{uint32(LoadCmdThread), "LoadCmdThread"},
     85 	{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
     86 	{uint32(LoadCmdDylib), "LoadCmdDylib"},
     87 	{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
     88 }
     89 
     90 func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) }
     91 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
     92 
     93 // A Segment64 is a 64-bit Mach-O segment load command.
     94 type Segment64 struct {
     95 	Cmd     LoadCmd
     96 	Len     uint32
     97 	Name    [16]byte
     98 	Addr    uint64
     99 	Memsz   uint64
    100 	Offset  uint64
    101 	Filesz  uint64
    102 	Maxprot uint32
    103 	Prot    uint32
    104 	Nsect   uint32
    105 	Flag    uint32
    106 }
    107 
    108 // A Segment32 is a 32-bit Mach-O segment load command.
    109 type Segment32 struct {
    110 	Cmd     LoadCmd
    111 	Len     uint32
    112 	Name    [16]byte
    113 	Addr    uint32
    114 	Memsz   uint32
    115 	Offset  uint32
    116 	Filesz  uint32
    117 	Maxprot uint32
    118 	Prot    uint32
    119 	Nsect   uint32
    120 	Flag    uint32
    121 }
    122 
    123 // A DylibCmd is a Mach-O load dynamic library command.
    124 type DylibCmd struct {
    125 	Cmd            LoadCmd
    126 	Len            uint32
    127 	Name           uint32
    128 	Time           uint32
    129 	CurrentVersion uint32
    130 	CompatVersion  uint32
    131 }
    132 
    133 // A Section32 is a 32-bit Mach-O section header.
    134 type Section32 struct {
    135 	Name     [16]byte
    136 	Seg      [16]byte
    137 	Addr     uint32
    138 	Size     uint32
    139 	Offset   uint32
    140 	Align    uint32
    141 	Reloff   uint32
    142 	Nreloc   uint32
    143 	Flags    uint32
    144 	Reserve1 uint32
    145 	Reserve2 uint32
    146 }
    147 
    148 // A Section32 is a 64-bit Mach-O section header.
    149 type Section64 struct {
    150 	Name     [16]byte
    151 	Seg      [16]byte
    152 	Addr     uint64
    153 	Size     uint64
    154 	Offset   uint32
    155 	Align    uint32
    156 	Reloff   uint32
    157 	Nreloc   uint32
    158 	Flags    uint32
    159 	Reserve1 uint32
    160 	Reserve2 uint32
    161 	Reserve3 uint32
    162 }
    163 
    164 // A SymtabCmd is a Mach-O symbol table command.
    165 type SymtabCmd struct {
    166 	Cmd     LoadCmd
    167 	Len     uint32
    168 	Symoff  uint32
    169 	Nsyms   uint32
    170 	Stroff  uint32
    171 	Strsize uint32
    172 }
    173 
    174 // A DysymtabCmd is a Mach-O dynamic symbol table command.
    175 type DysymtabCmd struct {
    176 	Cmd            LoadCmd
    177 	Len            uint32
    178 	Ilocalsym      uint32
    179 	Nlocalsym      uint32
    180 	Iextdefsym     uint32
    181 	Nextdefsym     uint32
    182 	Iundefsym      uint32
    183 	Nundefsym      uint32
    184 	Tocoffset      uint32
    185 	Ntoc           uint32
    186 	Modtaboff      uint32
    187 	Nmodtab        uint32
    188 	Extrefsymoff   uint32
    189 	Nextrefsyms    uint32
    190 	Indirectsymoff uint32
    191 	Nindirectsyms  uint32
    192 	Extreloff      uint32
    193 	Nextrel        uint32
    194 	Locreloff      uint32
    195 	Nlocrel        uint32
    196 }
    197 
    198 // An Nlist32 is a Mach-O 32-bit symbol table entry.
    199 type Nlist32 struct {
    200 	Name  uint32
    201 	Type  uint8
    202 	Sect  uint8
    203 	Desc  uint16
    204 	Value uint32
    205 }
    206 
    207 // An Nlist64 is a Mach-O 64-bit symbol table entry.
    208 type Nlist64 struct {
    209 	Name  uint32
    210 	Type  uint8
    211 	Sect  uint8
    212 	Desc  uint16
    213 	Value uint64
    214 }
    215 
    216 // A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
    217 type Symbol struct {
    218 	Name  string
    219 	Type  uint8
    220 	Sect  uint8
    221 	Desc  uint16
    222 	Value uint64
    223 }
    224 
    225 // A Thread is a Mach-O thread state command.
    226 type Thread struct {
    227 	Cmd  LoadCmd
    228 	Len  uint32
    229 	Type uint32
    230 	Data []uint32
    231 }
    232 
    233 // Regs386 is the Mach-O 386 register structure.
    234 type Regs386 struct {
    235 	AX    uint32
    236 	BX    uint32
    237 	CX    uint32
    238 	DX    uint32
    239 	DI    uint32
    240 	SI    uint32
    241 	BP    uint32
    242 	SP    uint32
    243 	SS    uint32
    244 	FLAGS uint32
    245 	IP    uint32
    246 	CS    uint32
    247 	DS    uint32
    248 	ES    uint32
    249 	FS    uint32
    250 	GS    uint32
    251 }
    252 
    253 // RegsAMD64 is the Mach-O AMD64 register structure.
    254 type RegsAMD64 struct {
    255 	AX    uint64
    256 	BX    uint64
    257 	CX    uint64
    258 	DX    uint64
    259 	DI    uint64
    260 	SI    uint64
    261 	BP    uint64
    262 	SP    uint64
    263 	R8    uint64
    264 	R9    uint64
    265 	R10   uint64
    266 	R11   uint64
    267 	R12   uint64
    268 	R13   uint64
    269 	R14   uint64
    270 	R15   uint64
    271 	IP    uint64
    272 	FLAGS uint64
    273 	CS    uint64
    274 	FS    uint64
    275 	GS    uint64
    276 }
    277 
    278 type intName struct {
    279 	i uint32
    280 	s string
    281 }
    282 
    283 func stringName(i uint32, names []intName, goSyntax bool) string {
    284 	for _, n := range names {
    285 		if n.i == i {
    286 			if goSyntax {
    287 				return "macho." + n.s
    288 			}
    289 			return n.s
    290 		}
    291 	}
    292 	return strconv.FormatUint(uint64(i), 10)
    293 }
    294 
    295 func flagName(i uint32, names []intName, goSyntax bool) string {
    296 	s := ""
    297 	for _, n := range names {
    298 		if n.i&i == n.i {
    299 			if len(s) > 0 {
    300 				s += "+"
    301 			}
    302 			if goSyntax {
    303 				s += "macho."
    304 			}
    305 			s += n.s
    306 			i -= n.i
    307 		}
    308 	}
    309 	if len(s) == 0 {
    310 		return "0x" + strconv.FormatUint(uint64(i), 16)
    311 	}
    312 	if i != 0 {
    313 		s += "+0x" + strconv.FormatUint(uint64(i), 16)
    314 	}
    315 	return s
    316 }
    317