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