GoPLS Viewer

Home|gopls/cmd/splitdwarf/internal/macho/macho.go
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
8package macho
9
10import (
11    "encoding/binary"
12    "strconv"
13)
14
15// A FileHeader represents a Mach-O file header.
16type FileHeader struct {
17    Magic        uint32
18    Cpu          Cpu
19    SubCpu       uint32
20    Type         HdrType
21    NCommands    uint32 // number of load commands
22    SizeCommands uint32 // size of all the load commands, not including this header.
23    Flags        HdrFlags
24}
25
26func (h *FileHeaderPut(b []byteo binary.ByteOrderint {
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 {
35        return 28
36    }
37    o.PutUint32(b[28:], 0)
38    return 32
39}
40
41const (
42    fileHeaderSize32 = 7 * 4
43    fileHeaderSize64 = 8 * 4
44)
45
46const (
47    Magic32  uint32 = 0xfeedface
48    Magic64  uint32 = 0xfeedfacf
49    MagicFat uint32 = 0xcafebabe
50)
51
52type HdrFlags uint32
53type SegFlags uint32
54type SecFlags uint32
55
56// A HdrType is the Mach-O file type, e.g. an object file, executable, or dynamic library.
57type HdrType uint32
58
59const ( // SNAKE_CASE to CamelCase translation from C names
60    MhObject  HdrType = 1
61    MhExecute HdrType = 2
62    MhCore    HdrType = 4
63    MhDylib   HdrType = 6
64    MhBundle  HdrType = 8
65    MhDsym    HdrType = 0xa
66)
67
68var typeStrings = []intName{
69    {uint32(MhObject), "Obj"},
70    {uint32(MhExecute), "Exec"},
71    {uint32(MhDylib), "Dylib"},
72    {uint32(MhBundle), "Bundle"},
73    {uint32(MhDsym), "Dsym"},
74}
75
76func (t HdrTypeString() string   { return stringName(uint32(t), typeStringsfalse) }
77func (t HdrTypeGoString() string { return stringName(uint32(t), typeStringstrue) }
78
79// A Cpu is a Mach-O cpu type.
80type Cpu uint32
81
82const cpuArch64 = 0x01000000
83
84const (
85    Cpu386   Cpu = 7
86    CpuAmd64 Cpu = Cpu386 | cpuArch64
87    CpuArm   Cpu = 12
88    CpuArm64 Cpu = CpuArm | cpuArch64
89    CpuPpc   Cpu = 18
90    CpuPpc64 Cpu = CpuPpc | cpuArch64
91)
92
93var 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"},
100}
101
102func (i CpuString() string   { return stringName(uint32(i), cpuStringsfalse) }
103func (i CpuGoString() string { return stringName(uint32(i), cpuStringstrue) }
104
105// A LoadCmd is a Mach-O load command.
106type LoadCmd uint32
107
108func (c LoadCmdCommand() LoadCmd { return c }
109
110const ( // 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
140)
141
142var 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"},
161}
162
163func (i LoadCmdString() string   { return stringName(uint32(i), cmdStringsfalse) }
164func (i LoadCmdGoString() string { return stringName(uint32(i), cmdStringstrue) }
165
166type (
167    // A Segment32 is a 32-bit Mach-O segment load command.
168    Segment32 struct {
169        LoadCmd
170        Len     uint32
171        Name    [16]byte
172        Addr    uint32
173        Memsz   uint32
174        Offset  uint32
175        Filesz  uint32
176        Maxprot uint32
177        Prot    uint32
178        Nsect   uint32
179        Flag    SegFlags
180    }
181
182    // A Segment64 is a 64-bit Mach-O segment load command.
183    Segment64 struct {
184        LoadCmd
185        Len     uint32
186        Name    [16]byte
187        Addr    uint64
188        Memsz   uint64
189        Offset  uint64
190        Filesz  uint64
191        Maxprot uint32
192        Prot    uint32
193        Nsect   uint32
194        Flag    SegFlags
195    }
196
197    // A SymtabCmd is a Mach-O symbol table command.
198    SymtabCmd struct {
199        LoadCmd
200        Len     uint32
201        Symoff  uint32
202        Nsyms   uint32
203        Stroff  uint32
204        Strsize uint32
205    }
206
207    // A DysymtabCmd is a Mach-O dynamic symbol table command.
208    DysymtabCmd struct {
209        LoadCmd
210        Len            uint32
211        Ilocalsym      uint32
212        Nlocalsym      uint32
213        Iextdefsym     uint32
214        Nextdefsym     uint32
215        Iundefsym      uint32
216        Nundefsym      uint32
217        Tocoffset      uint32
218        Ntoc           uint32
219        Modtaboff      uint32
220        Nmodtab        uint32
221        Extrefsymoff   uint32
222        Nextrefsyms    uint32
223        Indirectsymoff uint32
224        Nindirectsyms  uint32
225        Extreloff      uint32
226        Nextrel        uint32
227        Locreloff      uint32
228        Nlocrel        uint32
229    }
230
231    // A DylibCmd is a Mach-O load dynamic library command.
232    DylibCmd struct {
233        LoadCmd
234        Len            uint32
235        Name           uint32
236        Time           uint32
237        CurrentVersion uint32
238        CompatVersion  uint32
239    }
240
241    // A DylinkerCmd is a Mach-O load dynamic linker or environment command.
242    DylinkerCmd struct {
243        LoadCmd
244        Len  uint32
245        Name uint32
246    }
247
248    // A RpathCmd is a Mach-O rpath command.
249    RpathCmd struct {
250        LoadCmd
251        Len  uint32
252        Path uint32
253    }
254
255    // A Thread is a Mach-O thread state command.
256    Thread struct {
257        LoadCmd
258        Len  uint32
259        Type uint32
260        Data []uint32
261    }
262
263    // LC_DYLD_INFO, LC_DYLD_INFO_ONLY
264    DyldInfoCmd struct {
265        LoadCmd
266        Len                      uint32
267        RebaseOffRebaseLen     uint32 // file offset and length; data contains segment indices
268        BindOffBindLen         uint32 // file offset and length; data contains segment indices
269        WeakBindOffWeakBindLen uint32 // file offset and length
270        LazyBindOffLazyBindLen uint32 // file offset and length
271        ExportOffExportLen     uint32 // file offset and length
272    }
273
274    // LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS
275    LinkEditDataCmd struct {
276        LoadCmd
277        Len              uint32
278        DataOffDataLen uint32 // file offset and length
279    }
280
281    // LC_ENCRYPTION_INFO, LC_ENCRYPTION_INFO_64
282    EncryptionInfoCmd struct {
283        LoadCmd
284        Len                uint32
285        CryptOffCryptLen uint32 // file offset and length
286        CryptId            uint32
287    }
288
289    UuidCmd struct {
290        LoadCmd
291        Len uint32
292        Id  [16]byte
293    }
294
295    // TODO Commands below not fully supported yet.
296
297    EntryPointCmd struct {
298        LoadCmd
299        Len       uint32
300        EntryOff  uint64 // file offset
301        StackSize uint64 // if not zero, initial stack size
302    }
303
304    NoteCmd struct {
305        LoadCmd
306        Len            uint32
307        Name           [16]byte
308        OffsetFilesz uint64 // file offset and length
309    }
310)
311
312const (
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
339)
340
341// A Section32 is a 32-bit Mach-O section header.
342type Section32 struct {
343    Name     [16]byte
344    Seg      [16]byte
345    Addr     uint32
346    Size     uint32
347    Offset   uint32
348    Align    uint32
349    Reloff   uint32
350    Nreloc   uint32
351    Flags    SecFlags
352    Reserve1 uint32
353    Reserve2 uint32
354}
355
356// A Section64 is a 64-bit Mach-O section header.
357type Section64 struct {
358    Name     [16]byte
359    Seg      [16]byte
360    Addr     uint64
361    Size     uint64
362    Offset   uint32
363    Align    uint32
364    Reloff   uint32
365    Nreloc   uint32
366    Flags    SecFlags
367    Reserve1 uint32
368    Reserve2 uint32
369    Reserve3 uint32
370}
371
372// An Nlist32 is a Mach-O 32-bit symbol table entry.
373type Nlist32 struct {
374    Name  uint32
375    Type  uint8
376    Sect  uint8
377    Desc  uint16
378    Value uint32
379}
380
381// An Nlist64 is a Mach-O 64-bit symbol table entry.
382type Nlist64 struct {
383    Name  uint32
384    Type  uint8
385    Sect  uint8
386    Desc  uint16
387    Value uint64
388}
389
390func (n *Nlist64Put64(b []byteo binary.ByteOrderuint32 {
391    o.PutUint32(b[0:], n.Name)
392    b[4] = byte(n.Type)
393    b[5] = byte(n.Sect)
394    o.PutUint16(b[6:], n.Desc)
395    o.PutUint64(b[8:], n.Value)
396    return 8 + 8
397}
398
399func (n *Nlist64Put32(b []byteo binary.ByteOrderuint32 {
400    o.PutUint32(b[0:], n.Name)
401    b[4] = byte(n.Type)
402    b[5] = byte(n.Sect)
403    o.PutUint16(b[6:], n.Desc)
404    o.PutUint32(b[8:], uint32(n.Value))
405    return 8 + 4
406}
407
408// Regs386 is the Mach-O 386 register structure.
409type Regs386 struct {
410    AX    uint32
411    BX    uint32
412    CX    uint32
413    DX    uint32
414    DI    uint32
415    SI    uint32
416    BP    uint32
417    SP    uint32
418    SS    uint32
419    FLAGS uint32
420    IP    uint32
421    CS    uint32
422    DS    uint32
423    ES    uint32
424    FS    uint32
425    GS    uint32
426}
427
428// RegsAMD64 is the Mach-O AMD64 register structure.
429type RegsAMD64 struct {
430    AX    uint64
431    BX    uint64
432    CX    uint64
433    DX    uint64
434    DI    uint64
435    SI    uint64
436    BP    uint64
437    SP    uint64
438    R8    uint64
439    R9    uint64
440    R10   uint64
441    R11   uint64
442    R12   uint64
443    R13   uint64
444    R14   uint64
445    R15   uint64
446    IP    uint64
447    FLAGS uint64
448    CS    uint64
449    FS    uint64
450    GS    uint64
451}
452
453type intName struct {
454    i uint32
455    s string
456}
457
458func stringName(i uint32names []intNamegoSyntax boolstring {
459    for _n := range names {
460        if n.i == i {
461            if goSyntax {
462                return "macho." + n.s
463            }
464            return n.s
465        }
466    }
467    return "0x" + strconv.FormatUint(uint64(i), 16)
468}
469
MembersX
Cpu.GoString
Segment32.Len
Segment32.Nsect
Thread.Data
FlagPIE
Nlist64.Sect
LcIdDylib
DyldInfoCmd.ExportOff
FlagNoReexportedDylibs
FlagDeadStrippableDylib
Nlist64.Name
strconv
MhObject
HdrType.String
Cpu
LcDyldInfoOnly
RpathCmd.Len
Section64.Name
FileHeader.Put.o
LcVersionMinIphoneos
DyldInfoCmd.LazyBindOff
Section32.Nreloc
RegsAMD64.IP
Section64.Reloff
RegsAMD64.R15
LoadCmd.String
LoadCmd.GoString
DylibCmd.Name
Nlist64
LoadCmd.Command.c
EntryPointCmd.EntryOff
FlagPrebindable
RegsAMD64.R14
DylibCmd
EncryptionInfoCmd.CryptId
Section64.Nreloc
Nlist32.Name
CpuPpc
DylinkerCmd
Thread.Type
RegsAMD64.BP
LcSegmentSplitInfo
Segment32.Addr
Segment64.Flag
UuidCmd.Len
Regs386.GS
UuidCmd
FlagDyldLink
Nlist32.Value
Section32.Size
Segment32.Maxprot
DyldInfoCmd.RebaseOff
Nlist64.Type
Regs386.SP
Regs386.DS
RegsAMD64.R9
DysymtabCmd.Nlocalsym
EntryPointCmd.Len
NoteCmd.Len
FlagNoHeapExecution
RegsAMD64.CX
DyldInfoCmd.LazyBindLen
FlagAllowStackExecution
Segment64.Name
DysymtabCmd.Nmodtab
Nlist64.Put64.b
Regs386.FS
Segment64.Memsz
SymtabCmd.Nsyms
EncryptionInfoCmd.CryptOff
FlagIncrLink
Regs386.SI
Cpu.String
SymtabCmd.Stroff
DylibCmd.CompatVersion
UuidCmd.Id
Section32.Reloff
Nlist64.Put32.b
Regs386.DI
HdrFlags
HdrType
LcCodeSignature
LoadCmd.String.i
SymtabCmd.Strsize
FlagNoUndefs
stringName.RangeStmt_11441.n
stringName.goSyntax
FileHeader.Type
LcSegment
DysymtabCmd.Iextdefsym
DyldInfoCmd.BindOff
Section32.Seg
Section64.Addr
stringName.i
Magic32
Segment32.Filesz
FlagAllModsBound
LcDysymtab
LcVersionMinMacosx
DysymtabCmd.Nextrel
NoteCmd.Name
Section32.Addr
FileHeader
FileHeader.Cpu
FileHeader.Put.h
DysymtabCmd.Len
RegsAMD64.FLAGS
LcDylibCodeSignDrs
RegsAMD64.GS
intName.s
Magic64
Segment32.Offset
DysymtabCmd.Iundefsym
DysymtabCmd.Nlocrel
LinkEditDataCmd
FlagPrebound
FlagWeakDefines
MhExecute
FlagSetuidSafe
LcDyldInfo
Segment64.Nsect
DysymtabCmd.Ilocalsym
Section32.Flags
FileHeader.SizeCommands
CpuArm
DyldInfoCmd.WeakBindOff
LoadCmd.Command
LcVersionMinWatchos
DylibCmd.CurrentVersion
LcSymtab
Regs386.CX
RegsAMD64
DyldInfoCmd.Len
FlagHasTLVDescriptors
Regs386
DysymtabCmd.Locreloff
RpathCmd.Path
NoteCmd.Offset
FlagNoFixPrebinding
Section64.Reserve1
MhDylib
cpuArch64
Nlist32
RegsAMD64.R12
LcThread
DysymtabCmd.Extrefsymoff
Regs386.BP
DylibCmd.Len
DyldInfoCmd.WeakBindLen
Regs386.BX
DysymtabCmd.Modtaboff
Nlist64.Put64.o
RegsAMD64.R8
LcFunctionStarts
Segment64.Prot
DylinkerCmd.Name
Section32.Reserve1
Regs386.SS
Regs386.IP
LcLoadDylinker
Section32.Offset
Section64.Size
Section64.Reserve3
DyldInfoCmd.RebaseLen
EncryptionInfoCmd.Len
LcUuid
Section64.Reserve2
Regs386.CS
RegsAMD64.R10
RegsAMD64.FS
HdrType.GoString
CpuAmd64
Segment64.Filesz
DysymtabCmd.Extreloff
LinkEditDataCmd.DataOff
Section32.Reserve2
RegsAMD64.CS
stringName.names
DylibCmd.Time
FlagForceFlat
FlagNoMultiDefs
Regs386.FLAGS
RegsAMD64.DI
RpathCmd
Thread
DyldInfoCmd
DyldInfoCmd.ExportLen
FlagBindAtLoad
RegsAMD64.R11
DylinkerCmd.Len
Section64.Flags
RegsAMD64.AX
intName.i
SecFlags
LoadCmd
FlagLazyInit
FlagRootSafe
RegsAMD64.BX
intName
LcDyldEnvironment
LcVersionMinTvos
Thread.Len
EncryptionInfoCmd
SymtabCmd.Symoff
DysymtabCmd.Nextrefsyms
Nlist64.Put64.n
DysymtabCmd.Ntoc
Section64
RegsAMD64.SI
Nlist32.Desc
FileHeader.Put
SegFlags
Segment64
SymtabCmd
EncryptionInfoCmd.CryptLen
Nlist32.Type
Nlist32.Sect
RegsAMD64.R13
Section64.Seg
MhCore
Segment32.Name
Segment32.Flag
Segment64.Addr
DysymtabCmd
DysymtabCmd.Indirectsymoff
FlagAppExtensionSafe
LcIdDylinker
LcEncryptionInfo64
Segment32
EntryPointCmd.StackSize
CpuArm64
CpuPpc64
Segment32.Memsz
DysymtabCmd.Nextdefsym
Nlist64.Put32.o
Regs386.DX
LcUnixthread
LoadCmd.GoString.i
Segment32.Prot
DysymtabCmd.Nundefsym
RegsAMD64.SP
FlagBindsToWeak
FileHeader.Magic
FileHeader.SubCpu
FileHeader.Flags
Segment64.Len
Segment64.Maxprot
LinkEditDataCmd.DataLen
FlagTwoLevel
stringName
FileHeader.Put.b
MagicFat
Cpu386
LcEncryptionInfo
DysymtabCmd.Nindirectsyms
Nlist64.Put64
Nlist64.Put32.n
Segment64.Offset
Section32.Align
Section64.Align
Regs386.ES
LcSegment64
LcSourceVersion
LinkEditDataCmd.Len
NoteCmd.Filesz
Cpu.String.i
RegsAMD64.DX
Nlist64.Put32
MhDsym
Cpu.GoString.i
LcRpath
LcMain
LcDataInCode
FlagSplitSegs
Nlist64.Value
HdrType.GoString.t
DysymtabCmd.Tocoffset
Section32
Section32.Name
FileHeader.NCommands
LcDylib
DyldInfoCmd.BindLen
EntryPointCmd
FlagCanonical
Nlist64.Desc
MhBundle
HdrType.String.t
SymtabCmd.Len
NoteCmd
FlagSubsectionsViaSymbols
Section64.Offset
Regs386.AX
Members
X