...

Source file src/pkg/debug/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	// Originally at:
     7	// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html (since deleted by Apply)
     8	// Archived copy at:
     9	// https://web.archive.org/web/20090819232456/http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html
    10	// For cloned PDF see:
    11	// https://github.com/aidansteele/osx-abi-macho-file-format-reference
    12	
    13	package macho
    14	
    15	import "strconv"
    16	
    17	// A FileHeader represents a Mach-O file header.
    18	type FileHeader struct {
    19		Magic  uint32
    20		Cpu    Cpu
    21		SubCpu uint32
    22		Type   Type
    23		Ncmd   uint32
    24		Cmdsz  uint32
    25		Flags  uint32
    26	}
    27	
    28	const (
    29		fileHeaderSize32 = 7 * 4
    30		fileHeaderSize64 = 8 * 4
    31	)
    32	
    33	const (
    34		Magic32  uint32 = 0xfeedface
    35		Magic64  uint32 = 0xfeedfacf
    36		MagicFat uint32 = 0xcafebabe
    37	)
    38	
    39	// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
    40	type Type uint32
    41	
    42	const (
    43		TypeObj    Type = 1
    44		TypeExec   Type = 2
    45		TypeDylib  Type = 6
    46		TypeBundle Type = 8
    47	)
    48	
    49	var typeStrings = []intName{
    50		{uint32(TypeObj), "Obj"},
    51		{uint32(TypeExec), "Exec"},
    52		{uint32(TypeDylib), "Dylib"},
    53		{uint32(TypeBundle), "Bundle"},
    54	}
    55	
    56	func (t Type) String() string   { return stringName(uint32(t), typeStrings, false) }
    57	func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) }
    58	
    59	// A Cpu is a Mach-O cpu type.
    60	type Cpu uint32
    61	
    62	const cpuArch64 = 0x01000000
    63	
    64	const (
    65		Cpu386   Cpu = 7
    66		CpuAmd64 Cpu = Cpu386 | cpuArch64
    67		CpuArm   Cpu = 12
    68		CpuArm64 Cpu = CpuArm | cpuArch64
    69		CpuPpc   Cpu = 18
    70		CpuPpc64 Cpu = CpuPpc | cpuArch64
    71	)
    72	
    73	var cpuStrings = []intName{
    74		{uint32(Cpu386), "Cpu386"},
    75		{uint32(CpuAmd64), "CpuAmd64"},
    76		{uint32(CpuArm), "CpuArm"},
    77		{uint32(CpuArm64), "CpuArm64"},
    78		{uint32(CpuPpc), "CpuPpc"},
    79		{uint32(CpuPpc64), "CpuPpc64"},
    80	}
    81	
    82	func (i Cpu) String() string   { return stringName(uint32(i), cpuStrings, false) }
    83	func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
    84	
    85	// A LoadCmd is a Mach-O load command.
    86	type LoadCmd uint32
    87	
    88	const (
    89		LoadCmdSegment    LoadCmd = 0x1
    90		LoadCmdSymtab     LoadCmd = 0x2
    91		LoadCmdThread     LoadCmd = 0x4
    92		LoadCmdUnixThread LoadCmd = 0x5 // thread+stack
    93		LoadCmdDysymtab   LoadCmd = 0xb
    94		LoadCmdDylib      LoadCmd = 0xc // load dylib command
    95		LoadCmdDylinker   LoadCmd = 0xf // id dylinker command (not load dylinker command)
    96		LoadCmdSegment64  LoadCmd = 0x19
    97		LoadCmdRpath      LoadCmd = 0x8000001c
    98	)
    99	
   100	var cmdStrings = []intName{
   101		{uint32(LoadCmdSegment), "LoadCmdSegment"},
   102		{uint32(LoadCmdThread), "LoadCmdThread"},
   103		{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
   104		{uint32(LoadCmdDylib), "LoadCmdDylib"},
   105		{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
   106		{uint32(LoadCmdRpath), "LoadCmdRpath"},
   107	}
   108	
   109	func (i LoadCmd) String() string   { return stringName(uint32(i), cmdStrings, false) }
   110	func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
   111	
   112	type (
   113		// A Segment32 is a 32-bit Mach-O segment load command.
   114		Segment32 struct {
   115			Cmd     LoadCmd
   116			Len     uint32
   117			Name    [16]byte
   118			Addr    uint32
   119			Memsz   uint32
   120			Offset  uint32
   121			Filesz  uint32
   122			Maxprot uint32
   123			Prot    uint32
   124			Nsect   uint32
   125			Flag    uint32
   126		}
   127	
   128		// A Segment64 is a 64-bit Mach-O segment load command.
   129		Segment64 struct {
   130			Cmd     LoadCmd
   131			Len     uint32
   132			Name    [16]byte
   133			Addr    uint64
   134			Memsz   uint64
   135			Offset  uint64
   136			Filesz  uint64
   137			Maxprot uint32
   138			Prot    uint32
   139			Nsect   uint32
   140			Flag    uint32
   141		}
   142	
   143		// A SymtabCmd is a Mach-O symbol table command.
   144		SymtabCmd struct {
   145			Cmd     LoadCmd
   146			Len     uint32
   147			Symoff  uint32
   148			Nsyms   uint32
   149			Stroff  uint32
   150			Strsize uint32
   151		}
   152	
   153		// A DysymtabCmd is a Mach-O dynamic symbol table command.
   154		DysymtabCmd struct {
   155			Cmd            LoadCmd
   156			Len            uint32
   157			Ilocalsym      uint32
   158			Nlocalsym      uint32
   159			Iextdefsym     uint32
   160			Nextdefsym     uint32
   161			Iundefsym      uint32
   162			Nundefsym      uint32
   163			Tocoffset      uint32
   164			Ntoc           uint32
   165			Modtaboff      uint32
   166			Nmodtab        uint32
   167			Extrefsymoff   uint32
   168			Nextrefsyms    uint32
   169			Indirectsymoff uint32
   170			Nindirectsyms  uint32
   171			Extreloff      uint32
   172			Nextrel        uint32
   173			Locreloff      uint32
   174			Nlocrel        uint32
   175		}
   176	
   177		// A DylibCmd is a Mach-O load dynamic library command.
   178		DylibCmd struct {
   179			Cmd            LoadCmd
   180			Len            uint32
   181			Name           uint32
   182			Time           uint32
   183			CurrentVersion uint32
   184			CompatVersion  uint32
   185		}
   186	
   187		// A RpathCmd is a Mach-O rpath command.
   188		RpathCmd struct {
   189			Cmd  LoadCmd
   190			Len  uint32
   191			Path uint32
   192		}
   193	
   194		// A Thread is a Mach-O thread state command.
   195		Thread struct {
   196			Cmd  LoadCmd
   197			Len  uint32
   198			Type uint32
   199			Data []uint32
   200		}
   201	)
   202	
   203	const (
   204		FlagNoUndefs              uint32 = 0x1
   205		FlagIncrLink              uint32 = 0x2
   206		FlagDyldLink              uint32 = 0x4
   207		FlagBindAtLoad            uint32 = 0x8
   208		FlagPrebound              uint32 = 0x10
   209		FlagSplitSegs             uint32 = 0x20
   210		FlagLazyInit              uint32 = 0x40
   211		FlagTwoLevel              uint32 = 0x80
   212		FlagForceFlat             uint32 = 0x100
   213		FlagNoMultiDefs           uint32 = 0x200
   214		FlagNoFixPrebinding       uint32 = 0x400
   215		FlagPrebindable           uint32 = 0x800
   216		FlagAllModsBound          uint32 = 0x1000
   217		FlagSubsectionsViaSymbols uint32 = 0x2000
   218		FlagCanonical             uint32 = 0x4000
   219		FlagWeakDefines           uint32 = 0x8000
   220		FlagBindsToWeak           uint32 = 0x10000
   221		FlagAllowStackExecution   uint32 = 0x20000
   222		FlagRootSafe              uint32 = 0x40000
   223		FlagSetuidSafe            uint32 = 0x80000
   224		FlagNoReexportedDylibs    uint32 = 0x100000
   225		FlagPIE                   uint32 = 0x200000
   226		FlagDeadStrippableDylib   uint32 = 0x400000
   227		FlagHasTLVDescriptors     uint32 = 0x800000
   228		FlagNoHeapExecution       uint32 = 0x1000000
   229		FlagAppExtensionSafe      uint32 = 0x2000000
   230	)
   231	
   232	// A Section32 is a 32-bit Mach-O section header.
   233	type Section32 struct {
   234		Name     [16]byte
   235		Seg      [16]byte
   236		Addr     uint32
   237		Size     uint32
   238		Offset   uint32
   239		Align    uint32
   240		Reloff   uint32
   241		Nreloc   uint32
   242		Flags    uint32
   243		Reserve1 uint32
   244		Reserve2 uint32
   245	}
   246	
   247	// A Section64 is a 64-bit Mach-O section header.
   248	type Section64 struct {
   249		Name     [16]byte
   250		Seg      [16]byte
   251		Addr     uint64
   252		Size     uint64
   253		Offset   uint32
   254		Align    uint32
   255		Reloff   uint32
   256		Nreloc   uint32
   257		Flags    uint32
   258		Reserve1 uint32
   259		Reserve2 uint32
   260		Reserve3 uint32
   261	}
   262	
   263	// An Nlist32 is a Mach-O 32-bit symbol table entry.
   264	type Nlist32 struct {
   265		Name  uint32
   266		Type  uint8
   267		Sect  uint8
   268		Desc  uint16
   269		Value uint32
   270	}
   271	
   272	// An Nlist64 is a Mach-O 64-bit symbol table entry.
   273	type Nlist64 struct {
   274		Name  uint32
   275		Type  uint8
   276		Sect  uint8
   277		Desc  uint16
   278		Value uint64
   279	}
   280	
   281	// Regs386 is the Mach-O 386 register structure.
   282	type Regs386 struct {
   283		AX    uint32
   284		BX    uint32
   285		CX    uint32
   286		DX    uint32
   287		DI    uint32
   288		SI    uint32
   289		BP    uint32
   290		SP    uint32
   291		SS    uint32
   292		FLAGS uint32
   293		IP    uint32
   294		CS    uint32
   295		DS    uint32
   296		ES    uint32
   297		FS    uint32
   298		GS    uint32
   299	}
   300	
   301	// RegsAMD64 is the Mach-O AMD64 register structure.
   302	type RegsAMD64 struct {
   303		AX    uint64
   304		BX    uint64
   305		CX    uint64
   306		DX    uint64
   307		DI    uint64
   308		SI    uint64
   309		BP    uint64
   310		SP    uint64
   311		R8    uint64
   312		R9    uint64
   313		R10   uint64
   314		R11   uint64
   315		R12   uint64
   316		R13   uint64
   317		R14   uint64
   318		R15   uint64
   319		IP    uint64
   320		FLAGS uint64
   321		CS    uint64
   322		FS    uint64
   323		GS    uint64
   324	}
   325	
   326	type intName struct {
   327		i uint32
   328		s string
   329	}
   330	
   331	func stringName(i uint32, names []intName, goSyntax bool) string {
   332		for _, n := range names {
   333			if n.i == i {
   334				if goSyntax {
   335					return "macho." + n.s
   336				}
   337				return n.s
   338			}
   339		}
   340		return strconv.FormatUint(uint64(i), 10)
   341	}
   342	

View as plain text