...

Source file src/debug/macho/macho.go

Documentation: debug/macho

		 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 Apple)
		 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