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