+++ /dev/null
-// 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 (
- "encoding/binary"
- "strconv"
-)
-
-// A FileHeader represents a Mach-O file header.
-type FileHeader struct {
- Magic uint32
- Cpu Cpu
- SubCpu uint32
- Type HdrType
- NCommands uint32 // number of load commands
- SizeCommands uint32 // size of all the load commands, not including this header.
- Flags HdrFlags
-}
-
-func (h *FileHeader) Put(b []byte, o binary.ByteOrder) int {
- o.PutUint32(b[0:], h.Magic)
- o.PutUint32(b[4:], uint32(h.Cpu))
- o.PutUint32(b[8:], h.SubCpu)
- o.PutUint32(b[12:], uint32(h.Type))
- o.PutUint32(b[16:], h.NCommands)
- o.PutUint32(b[20:], h.SizeCommands)
- o.PutUint32(b[24:], uint32(h.Flags))
- if h.Magic == Magic32 {
- return 28
- }
- o.PutUint32(b[28:], 0)
- return 32
-}
-
-const (
- fileHeaderSize32 = 7 * 4
- fileHeaderSize64 = 8 * 4
-)
-
-const (
- Magic32 uint32 = 0xfeedface
- Magic64 uint32 = 0xfeedfacf
- MagicFat uint32 = 0xcafebabe
-)
-
-type HdrFlags uint32
-type SegFlags uint32
-type SecFlags uint32
-
-// A HdrType is the Mach-O file type, e.g. an object file, executable, or dynamic library.
-type HdrType uint32
-
-const ( // SNAKE_CASE to CamelCase translation from C names
- MhObject HdrType = 1
- MhExecute HdrType = 2
- MhCore HdrType = 4
- MhDylib HdrType = 6
- MhBundle HdrType = 8
- MhDsym HdrType = 0xa
-)
-
-var typeStrings = []intName{
- {uint32(MhObject), "Obj"},
- {uint32(MhExecute), "Exec"},
- {uint32(MhDylib), "Dylib"},
- {uint32(MhBundle), "Bundle"},
- {uint32(MhDsym), "Dsym"},
-}
-
-func (t HdrType) String() string { return stringName(uint32(t), typeStrings, false) }
-func (t HdrType) GoString() string { return stringName(uint32(t), typeStrings, true) }
-
-// A Cpu is a Mach-O cpu type.
-type Cpu uint32
-
-const cpuArch64 = 0x01000000
-
-const (
- Cpu386 Cpu = 7
- CpuAmd64 Cpu = Cpu386 | cpuArch64
- CpuArm Cpu = 12
- CpuArm64 Cpu = CpuArm | cpuArch64
- CpuPpc Cpu = 18
- CpuPpc64 Cpu = CpuPpc | cpuArch64
-)
-
-var cpuStrings = []intName{
- {uint32(Cpu386), "Cpu386"},
- {uint32(CpuAmd64), "CpuAmd64"},
- {uint32(CpuArm), "CpuArm"},
- {uint32(CpuArm64), "CpuArm64"},
- {uint32(CpuPpc), "CpuPpc"},
- {uint32(CpuPpc64), "CpuPpc64"},
-}
-
-func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
-func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
-
-// A LoadCmd is a Mach-O load command.
-type LoadCmd uint32
-
-func (c LoadCmd) Command() LoadCmd { return c }
-
-const ( // SNAKE_CASE to CamelCase translation from C names
- // Note 3 and 8 are obsolete
- LcSegment LoadCmd = 0x1
- LcSymtab LoadCmd = 0x2
- LcThread LoadCmd = 0x4
- LcUnixthread LoadCmd = 0x5 // thread+stack
- LcDysymtab LoadCmd = 0xb
- LcDylib LoadCmd = 0xc // load dylib command
- LcIdDylib LoadCmd = 0xd // dynamically linked shared lib ident
- LcLoadDylinker LoadCmd = 0xe // load a dynamic linker
- LcIdDylinker LoadCmd = 0xf // id dylinker command (not load dylinker command)
- LcSegment64 LoadCmd = 0x19
- LcUuid LoadCmd = 0x1b
- LcCodeSignature LoadCmd = 0x1d
- LcSegmentSplitInfo LoadCmd = 0x1e
- LcRpath LoadCmd = 0x8000001c
- LcEncryptionInfo LoadCmd = 0x21
- LcDyldInfo LoadCmd = 0x22
- LcDyldInfoOnly LoadCmd = 0x80000022
- LcVersionMinMacosx LoadCmd = 0x24
- LcVersionMinIphoneos LoadCmd = 0x25
- LcFunctionStarts LoadCmd = 0x26
- LcDyldEnvironment LoadCmd = 0x27
- LcMain LoadCmd = 0x80000028 // replacement for UnixThread
- LcDataInCode LoadCmd = 0x29 // There are non-instructions in text
- LcSourceVersion LoadCmd = 0x2a // Source version used to build binary
- LcDylibCodeSignDrs LoadCmd = 0x2b
- LcEncryptionInfo64 LoadCmd = 0x2c
- LcVersionMinTvos LoadCmd = 0x2f
- LcVersionMinWatchos LoadCmd = 0x30
-)
-
-var cmdStrings = []intName{
- {uint32(LcSegment), "LoadCmdSegment"},
- {uint32(LcThread), "LoadCmdThread"},
- {uint32(LcUnixthread), "LoadCmdUnixThread"},
- {uint32(LcDylib), "LoadCmdDylib"},
- {uint32(LcIdDylib), "LoadCmdIdDylib"},
- {uint32(LcLoadDylinker), "LoadCmdLoadDylinker"},
- {uint32(LcIdDylinker), "LoadCmdIdDylinker"},
- {uint32(LcSegment64), "LoadCmdSegment64"},
- {uint32(LcUuid), "LoadCmdUuid"},
- {uint32(LcRpath), "LoadCmdRpath"},
- {uint32(LcDyldEnvironment), "LoadCmdDyldEnv"},
- {uint32(LcMain), "LoadCmdMain"},
- {uint32(LcDataInCode), "LoadCmdDataInCode"},
- {uint32(LcSourceVersion), "LoadCmdSourceVersion"},
- {uint32(LcDyldInfo), "LoadCmdDyldInfo"},
- {uint32(LcDyldInfoOnly), "LoadCmdDyldInfoOnly"},
- {uint32(LcVersionMinMacosx), "LoadCmdMinOsx"},
- {uint32(LcFunctionStarts), "LoadCmdFunctionStarts"},
-}
-
-func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
-func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
-
-type (
- // A Segment32 is a 32-bit Mach-O segment load command.
- Segment32 struct {
- LoadCmd
- Len uint32
- Name [16]byte
- Addr uint32
- Memsz uint32
- Offset uint32
- Filesz uint32
- Maxprot uint32
- Prot uint32
- Nsect uint32
- Flag SegFlags
- }
-
- // A Segment64 is a 64-bit Mach-O segment load command.
- Segment64 struct {
- LoadCmd
- Len uint32
- Name [16]byte
- Addr uint64
- Memsz uint64
- Offset uint64
- Filesz uint64
- Maxprot uint32
- Prot uint32
- Nsect uint32
- Flag SegFlags
- }
-
- // A SymtabCmd is a Mach-O symbol table command.
- SymtabCmd struct {
- LoadCmd
- Len uint32
- Symoff uint32
- Nsyms uint32
- Stroff uint32
- Strsize uint32
- }
-
- // A DysymtabCmd is a Mach-O dynamic symbol table command.
- DysymtabCmd struct {
- LoadCmd
- Len uint32
- Ilocalsym uint32
- Nlocalsym uint32
- Iextdefsym uint32
- Nextdefsym uint32
- Iundefsym uint32
- Nundefsym uint32
- Tocoffset uint32
- Ntoc uint32
- Modtaboff uint32
- Nmodtab uint32
- Extrefsymoff uint32
- Nextrefsyms uint32
- Indirectsymoff uint32
- Nindirectsyms uint32
- Extreloff uint32
- Nextrel uint32
- Locreloff uint32
- Nlocrel uint32
- }
-
- // A DylibCmd is a Mach-O load dynamic library command.
- DylibCmd struct {
- LoadCmd
- Len uint32
- Name uint32
- Time uint32
- CurrentVersion uint32
- CompatVersion uint32
- }
-
- // A DylinkerCmd is a Mach-O load dynamic linker or environment command.
- DylinkerCmd struct {
- LoadCmd
- Len uint32
- Name uint32
- }
-
- // A RpathCmd is a Mach-O rpath command.
- RpathCmd struct {
- LoadCmd
- Len uint32
- Path uint32
- }
-
- // A Thread is a Mach-O thread state command.
- Thread struct {
- LoadCmd
- Len uint32
- Type uint32
- Data []uint32
- }
-
- // LC_DYLD_INFO, LC_DYLD_INFO_ONLY
- DyldInfoCmd struct {
- LoadCmd
- Len uint32
- RebaseOff, RebaseLen uint32 // file offset and length; data contains segment indices
- BindOff, BindLen uint32 // file offset and length; data contains segment indices
- WeakBindOff, WeakBindLen uint32 // file offset and length
- LazyBindOff, LazyBindLen uint32 // file offset and length
- ExportOff, ExportLen uint32 // file offset and length
- }
-
- // LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS
- LinkEditDataCmd struct {
- LoadCmd
- Len uint32
- DataOff, DataLen uint32 // file offset and length
- }
-
- // LC_ENCRYPTION_INFO, LC_ENCRYPTION_INFO_64
- EncryptionInfoCmd struct {
- LoadCmd
- Len uint32
- CryptOff, CryptLen uint32 // file offset and length
- CryptId uint32
- }
-
- UuidCmd struct {
- LoadCmd
- Len uint32
- Id [16]byte
- }
-
- // TODO Commands below not fully supported yet.
-
- EntryPointCmd struct {
- LoadCmd
- Len uint32
- EntryOff uint64 // file offset
- StackSize uint64 // if not zero, initial stack size
- }
-
- NoteCmd struct {
- LoadCmd
- Len uint32
- Name [16]byte
- Offset, Filesz uint64 // file offset and length
- }
-)
-
-const (
- FlagNoUndefs HdrFlags = 0x1
- FlagIncrLink HdrFlags = 0x2
- FlagDyldLink HdrFlags = 0x4
- FlagBindAtLoad HdrFlags = 0x8
- FlagPrebound HdrFlags = 0x10
- FlagSplitSegs HdrFlags = 0x20
- FlagLazyInit HdrFlags = 0x40
- FlagTwoLevel HdrFlags = 0x80
- FlagForceFlat HdrFlags = 0x100
- FlagNoMultiDefs HdrFlags = 0x200
- FlagNoFixPrebinding HdrFlags = 0x400
- FlagPrebindable HdrFlags = 0x800
- FlagAllModsBound HdrFlags = 0x1000
- FlagSubsectionsViaSymbols HdrFlags = 0x2000
- FlagCanonical HdrFlags = 0x4000
- FlagWeakDefines HdrFlags = 0x8000
- FlagBindsToWeak HdrFlags = 0x10000
- FlagAllowStackExecution HdrFlags = 0x20000
- FlagRootSafe HdrFlags = 0x40000
- FlagSetuidSafe HdrFlags = 0x80000
- FlagNoReexportedDylibs HdrFlags = 0x100000
- FlagPIE HdrFlags = 0x200000
- FlagDeadStrippableDylib HdrFlags = 0x400000
- FlagHasTLVDescriptors HdrFlags = 0x800000
- FlagNoHeapExecution HdrFlags = 0x1000000
- FlagAppExtensionSafe HdrFlags = 0x2000000
-)
-
-// A Section32 is a 32-bit Mach-O section header.
-type Section32 struct {
- Name [16]byte
- Seg [16]byte
- Addr uint32
- Size uint32
- Offset uint32
- Align uint32
- Reloff uint32
- Nreloc uint32
- Flags SecFlags
- Reserve1 uint32
- Reserve2 uint32
-}
-
-// A Section64 is a 64-bit Mach-O section header.
-type Section64 struct {
- Name [16]byte
- Seg [16]byte
- Addr uint64
- Size uint64
- Offset uint32
- Align uint32
- Reloff uint32
- Nreloc uint32
- Flags SecFlags
- Reserve1 uint32
- Reserve2 uint32
- Reserve3 uint32
-}
-
-// An Nlist32 is a Mach-O 32-bit symbol table entry.
-type Nlist32 struct {
- Name uint32
- Type uint8
- Sect uint8
- Desc uint16
- Value uint32
-}
-
-// An Nlist64 is a Mach-O 64-bit symbol table entry.
-type Nlist64 struct {
- Name uint32
- Type uint8
- Sect uint8
- Desc uint16
- Value uint64
-}
-
-func (n *Nlist64) Put64(b []byte, o binary.ByteOrder) uint32 {
- o.PutUint32(b[0:], n.Name)
- b[4] = byte(n.Type)
- b[5] = byte(n.Sect)
- o.PutUint16(b[6:], n.Desc)
- o.PutUint64(b[8:], n.Value)
- return 8 + 8
-}
-
-func (n *Nlist64) Put32(b []byte, o binary.ByteOrder) uint32 {
- o.PutUint32(b[0:], n.Name)
- b[4] = byte(n.Type)
- b[5] = byte(n.Sect)
- o.PutUint16(b[6:], n.Desc)
- o.PutUint32(b[8:], uint32(n.Value))
- return 8 + 4
-}
-
-// 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 {
- i uint32
- s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
- for _, n := range names {
- if n.i == i {
- if goSyntax {
- return "macho." + n.s
- }
- return n.s
- }
- }
- return "0x" + strconv.FormatUint(uint64(i), 16)
-}