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