summaryrefslogtreecommitdiffstats
path: root/src/debug/macho/macho.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/macho/macho.go')
-rw-r--r--src/debug/macho/macho.go341
1 files changed, 341 insertions, 0 deletions
diff --git a/src/debug/macho/macho.go b/src/debug/macho/macho.go
new file mode 100644
index 0000000..9fa9f95
--- /dev/null
+++ b/src/debug/macho/macho.go
@@ -0,0 +1,341 @@
+// 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
+// Originally at:
+// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html (since deleted by Apple)
+// Archived copy at:
+// https://web.archive.org/web/20090819232456/http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html
+// For cloned PDF see:
+// https://github.com/aidansteele/osx-abi-macho-file-format-reference
+
+package macho
+
+import "strconv"
+
+// A FileHeader represents a Mach-O file header.
+type FileHeader struct {
+ Magic uint32
+ Cpu Cpu
+ SubCpu uint32
+ Type Type
+ Ncmd uint32
+ Cmdsz uint32
+ Flags uint32
+}
+
+const (
+ fileHeaderSize32 = 7 * 4
+ fileHeaderSize64 = 8 * 4
+)
+
+const (
+ Magic32 uint32 = 0xfeedface
+ Magic64 uint32 = 0xfeedfacf
+ MagicFat uint32 = 0xcafebabe
+)
+
+// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
+type Type uint32
+
+const (
+ TypeObj Type = 1
+ TypeExec Type = 2
+ TypeDylib Type = 6
+ TypeBundle Type = 8
+)
+
+var typeStrings = []intName{
+ {uint32(TypeObj), "Obj"},
+ {uint32(TypeExec), "Exec"},
+ {uint32(TypeDylib), "Dylib"},
+ {uint32(TypeBundle), "Bundle"},
+}
+
+func (t Type) String() string { return stringName(uint32(t), typeStrings, false) }
+func (t Type) 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
+
+const (
+ LoadCmdSegment LoadCmd = 0x1
+ LoadCmdSymtab LoadCmd = 0x2
+ LoadCmdThread LoadCmd = 0x4
+ LoadCmdUnixThread LoadCmd = 0x5 // thread+stack
+ LoadCmdDysymtab LoadCmd = 0xb
+ LoadCmdDylib LoadCmd = 0xc // load dylib command
+ LoadCmdDylinker LoadCmd = 0xf // id dylinker command (not load dylinker command)
+ LoadCmdSegment64 LoadCmd = 0x19
+ LoadCmdRpath LoadCmd = 0x8000001c
+)
+
+var cmdStrings = []intName{
+ {uint32(LoadCmdSegment), "LoadCmdSegment"},
+ {uint32(LoadCmdThread), "LoadCmdThread"},
+ {uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
+ {uint32(LoadCmdDylib), "LoadCmdDylib"},
+ {uint32(LoadCmdSegment64), "LoadCmdSegment64"},
+ {uint32(LoadCmdRpath), "LoadCmdRpath"},
+}
+
+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 {
+ Cmd LoadCmd
+ Len uint32
+ Name [16]byte
+ Addr uint32
+ Memsz uint32
+ Offset uint32
+ Filesz uint32
+ Maxprot uint32
+ Prot uint32
+ Nsect uint32
+ Flag uint32
+ }
+
+ // A Segment64 is a 64-bit Mach-O segment load command.
+ Segment64 struct {
+ Cmd LoadCmd
+ Len uint32
+ Name [16]byte
+ Addr uint64
+ Memsz uint64
+ Offset uint64
+ Filesz uint64
+ Maxprot uint32
+ Prot uint32
+ Nsect uint32
+ Flag uint32
+ }
+
+ // A SymtabCmd is a Mach-O symbol table command.
+ SymtabCmd struct {
+ Cmd LoadCmd
+ Len uint32
+ Symoff uint32
+ Nsyms uint32
+ Stroff uint32
+ Strsize uint32
+ }
+
+ // A DysymtabCmd is a Mach-O dynamic symbol table command.
+ DysymtabCmd struct {
+ Cmd 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 {
+ Cmd LoadCmd
+ Len uint32
+ Name uint32
+ Time uint32
+ CurrentVersion uint32
+ CompatVersion uint32
+ }
+
+ // A RpathCmd is a Mach-O rpath command.
+ RpathCmd struct {
+ Cmd LoadCmd
+ Len uint32
+ Path uint32
+ }
+
+ // A Thread is a Mach-O thread state command.
+ Thread struct {
+ Cmd LoadCmd
+ Len uint32
+ Type uint32
+ Data []uint32
+ }
+)
+
+const (
+ FlagNoUndefs uint32 = 0x1
+ FlagIncrLink uint32 = 0x2
+ FlagDyldLink uint32 = 0x4
+ FlagBindAtLoad uint32 = 0x8
+ FlagPrebound uint32 = 0x10
+ FlagSplitSegs uint32 = 0x20
+ FlagLazyInit uint32 = 0x40
+ FlagTwoLevel uint32 = 0x80
+ FlagForceFlat uint32 = 0x100
+ FlagNoMultiDefs uint32 = 0x200
+ FlagNoFixPrebinding uint32 = 0x400
+ FlagPrebindable uint32 = 0x800
+ FlagAllModsBound uint32 = 0x1000
+ FlagSubsectionsViaSymbols uint32 = 0x2000
+ FlagCanonical uint32 = 0x4000
+ FlagWeakDefines uint32 = 0x8000
+ FlagBindsToWeak uint32 = 0x10000
+ FlagAllowStackExecution uint32 = 0x20000
+ FlagRootSafe uint32 = 0x40000
+ FlagSetuidSafe uint32 = 0x80000
+ FlagNoReexportedDylibs uint32 = 0x100000
+ FlagPIE uint32 = 0x200000
+ FlagDeadStrippableDylib uint32 = 0x400000
+ FlagHasTLVDescriptors uint32 = 0x800000
+ FlagNoHeapExecution uint32 = 0x1000000
+ FlagAppExtensionSafe uint32 = 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 uint32
+ 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 uint32
+ 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
+}
+
+// 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 strconv.FormatUint(uint64(i), 10)
+}