github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/debug/macho/macho.go (about)

     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 "github.com/x04/go/src/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  }