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.
5 // Mach-O header data structures
6 // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
15 // A FileHeader represents a Mach-O file header.
16 type FileHeader struct {
21 NCommands uint32 // number of load commands
22 SizeCommands uint32 // size of all the load commands, not including this header.
26 func (h *FileHeader) Put(b []byte, o binary.ByteOrder) int {
27 o.PutUint32(b[0:], h.Magic)
28 o.PutUint32(b[4:], uint32(h.Cpu))
29 o.PutUint32(b[8:], h.SubCpu)
30 o.PutUint32(b[12:], uint32(h.Type))
31 o.PutUint32(b[16:], h.NCommands)
32 o.PutUint32(b[20:], h.SizeCommands)
33 o.PutUint32(b[24:], uint32(h.Flags))
34 if h.Magic == Magic32 {
37 o.PutUint32(b[28:], 0)
42 fileHeaderSize32 = 7 * 4
43 fileHeaderSize64 = 8 * 4
47 Magic32 uint32 = 0xfeedface
48 Magic64 uint32 = 0xfeedfacf
49 MagicFat uint32 = 0xcafebabe
56 // A HdrType is the Mach-O file type, e.g. an object file, executable, or dynamic library.
59 const ( // SNAKE_CASE to CamelCase translation from C names
68 var typeStrings = []intName{
69 {uint32(MhObject), "Obj"},
70 {uint32(MhExecute), "Exec"},
71 {uint32(MhDylib), "Dylib"},
72 {uint32(MhBundle), "Bundle"},
73 {uint32(MhDsym), "Dsym"},
76 func (t HdrType) String() string { return stringName(uint32(t), typeStrings, false) }
77 func (t HdrType) GoString() string { return stringName(uint32(t), typeStrings, true) }
79 // A Cpu is a Mach-O cpu type.
82 const cpuArch64 = 0x01000000
86 CpuAmd64 Cpu = Cpu386 | cpuArch64
88 CpuArm64 Cpu = CpuArm | cpuArch64
90 CpuPpc64 Cpu = CpuPpc | cpuArch64
93 var cpuStrings = []intName{
94 {uint32(Cpu386), "Cpu386"},
95 {uint32(CpuAmd64), "CpuAmd64"},
96 {uint32(CpuArm), "CpuArm"},
97 {uint32(CpuArm64), "CpuArm64"},
98 {uint32(CpuPpc), "CpuPpc"},
99 {uint32(CpuPpc64), "CpuPpc64"},
102 func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
103 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
105 // A LoadCmd is a Mach-O load command.
108 func (c LoadCmd) Command() LoadCmd { return c }
110 const ( // SNAKE_CASE to CamelCase translation from C names
111 // Note 3 and 8 are obsolete
112 LcSegment LoadCmd = 0x1
113 LcSymtab LoadCmd = 0x2
114 LcThread LoadCmd = 0x4
115 LcUnixthread LoadCmd = 0x5 // thread+stack
116 LcDysymtab LoadCmd = 0xb
117 LcDylib LoadCmd = 0xc // load dylib command
118 LcIdDylib LoadCmd = 0xd // dynamically linked shared lib ident
119 LcLoadDylinker LoadCmd = 0xe // load a dynamic linker
120 LcIdDylinker LoadCmd = 0xf // id dylinker command (not load dylinker command)
121 LcSegment64 LoadCmd = 0x19
122 LcUuid LoadCmd = 0x1b
123 LcCodeSignature LoadCmd = 0x1d
124 LcSegmentSplitInfo LoadCmd = 0x1e
125 LcRpath LoadCmd = 0x8000001c
126 LcEncryptionInfo LoadCmd = 0x21
127 LcDyldInfo LoadCmd = 0x22
128 LcDyldInfoOnly LoadCmd = 0x80000022
129 LcVersionMinMacosx LoadCmd = 0x24
130 LcVersionMinIphoneos LoadCmd = 0x25
131 LcFunctionStarts LoadCmd = 0x26
132 LcDyldEnvironment LoadCmd = 0x27
133 LcMain LoadCmd = 0x80000028 // replacement for UnixThread
134 LcDataInCode LoadCmd = 0x29 // There are non-instructions in text
135 LcSourceVersion LoadCmd = 0x2a // Source version used to build binary
136 LcDylibCodeSignDrs LoadCmd = 0x2b
137 LcEncryptionInfo64 LoadCmd = 0x2c
138 LcVersionMinTvos LoadCmd = 0x2f
139 LcVersionMinWatchos LoadCmd = 0x30
142 var cmdStrings = []intName{
143 {uint32(LcSegment), "LoadCmdSegment"},
144 {uint32(LcThread), "LoadCmdThread"},
145 {uint32(LcUnixthread), "LoadCmdUnixThread"},
146 {uint32(LcDylib), "LoadCmdDylib"},
147 {uint32(LcIdDylib), "LoadCmdIdDylib"},
148 {uint32(LcLoadDylinker), "LoadCmdLoadDylinker"},
149 {uint32(LcIdDylinker), "LoadCmdIdDylinker"},
150 {uint32(LcSegment64), "LoadCmdSegment64"},
151 {uint32(LcUuid), "LoadCmdUuid"},
152 {uint32(LcRpath), "LoadCmdRpath"},
153 {uint32(LcDyldEnvironment), "LoadCmdDyldEnv"},
154 {uint32(LcMain), "LoadCmdMain"},
155 {uint32(LcDataInCode), "LoadCmdDataInCode"},
156 {uint32(LcSourceVersion), "LoadCmdSourceVersion"},
157 {uint32(LcDyldInfo), "LoadCmdDyldInfo"},
158 {uint32(LcDyldInfoOnly), "LoadCmdDyldInfoOnly"},
159 {uint32(LcVersionMinMacosx), "LoadCmdMinOsx"},
160 {uint32(LcFunctionStarts), "LoadCmdFunctionStarts"},
163 func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
164 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
167 // A Segment32 is a 32-bit Mach-O segment load command.
182 // A Segment64 is a 64-bit Mach-O segment load command.
197 // A SymtabCmd is a Mach-O symbol table command.
207 // A DysymtabCmd is a Mach-O dynamic symbol table command.
223 Indirectsymoff uint32
231 // A DylibCmd is a Mach-O load dynamic library command.
237 CurrentVersion uint32
241 // A DylinkerCmd is a Mach-O load dynamic linker or environment command.
248 // A RpathCmd is a Mach-O rpath command.
255 // A Thread is a Mach-O thread state command.
263 // LC_DYLD_INFO, LC_DYLD_INFO_ONLY
267 RebaseOff, RebaseLen uint32 // file offset and length; data contains segment indices
268 BindOff, BindLen uint32 // file offset and length; data contains segment indices
269 WeakBindOff, WeakBindLen uint32 // file offset and length
270 LazyBindOff, LazyBindLen uint32 // file offset and length
271 ExportOff, ExportLen uint32 // file offset and length
274 // LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS
275 LinkEditDataCmd struct {
278 DataOff, DataLen uint32 // file offset and length
281 // LC_ENCRYPTION_INFO, LC_ENCRYPTION_INFO_64
282 EncryptionInfoCmd struct {
285 CryptOff, CryptLen uint32 // file offset and length
295 // TODO Commands below not fully supported yet.
297 EntryPointCmd struct {
300 EntryOff uint64 // file offset
301 StackSize uint64 // if not zero, initial stack size
308 Offset, Filesz uint64 // file offset and length
313 FlagNoUndefs HdrFlags = 0x1
314 FlagIncrLink HdrFlags = 0x2
315 FlagDyldLink HdrFlags = 0x4
316 FlagBindAtLoad HdrFlags = 0x8
317 FlagPrebound HdrFlags = 0x10
318 FlagSplitSegs HdrFlags = 0x20
319 FlagLazyInit HdrFlags = 0x40
320 FlagTwoLevel HdrFlags = 0x80
321 FlagForceFlat HdrFlags = 0x100
322 FlagNoMultiDefs HdrFlags = 0x200
323 FlagNoFixPrebinding HdrFlags = 0x400
324 FlagPrebindable HdrFlags = 0x800
325 FlagAllModsBound HdrFlags = 0x1000
326 FlagSubsectionsViaSymbols HdrFlags = 0x2000
327 FlagCanonical HdrFlags = 0x4000
328 FlagWeakDefines HdrFlags = 0x8000
329 FlagBindsToWeak HdrFlags = 0x10000
330 FlagAllowStackExecution HdrFlags = 0x20000
331 FlagRootSafe HdrFlags = 0x40000
332 FlagSetuidSafe HdrFlags = 0x80000
333 FlagNoReexportedDylibs HdrFlags = 0x100000
334 FlagPIE HdrFlags = 0x200000
335 FlagDeadStrippableDylib HdrFlags = 0x400000
336 FlagHasTLVDescriptors HdrFlags = 0x800000
337 FlagNoHeapExecution HdrFlags = 0x1000000
338 FlagAppExtensionSafe HdrFlags = 0x2000000
341 // A Section32 is a 32-bit Mach-O section header.
342 type Section32 struct {
356 // A Section64 is a 64-bit Mach-O section header.
357 type Section64 struct {
372 // An Nlist32 is a Mach-O 32-bit symbol table entry.
373 type Nlist32 struct {
381 // An Nlist64 is a Mach-O 64-bit symbol table entry.
382 type Nlist64 struct {
390 func (n *Nlist64) Put64(b []byte, o binary.ByteOrder) uint32 {
391 o.PutUint32(b[0:], n.Name)
394 o.PutUint16(b[6:], n.Desc)
395 o.PutUint64(b[8:], n.Value)
399 func (n *Nlist64) Put32(b []byte, o binary.ByteOrder) uint32 {
400 o.PutUint32(b[0:], n.Name)
403 o.PutUint16(b[6:], n.Desc)
404 o.PutUint32(b[8:], uint32(n.Value))
408 // Regs386 is the Mach-O 386 register structure.
409 type Regs386 struct {
428 // RegsAMD64 is the Mach-O AMD64 register structure.
429 type RegsAMD64 struct {
453 type intName struct {
458 func stringName(i uint32, names []intName, goSyntax bool) string {
459 for _, n := range names {
462 return "macho." + n.s
467 return "0x" + strconv.FormatUint(uint64(i), 16)