src/pkg/debug/macho/macho.go - The Go Programming Language

Golang

Source file src/pkg/debug/macho/macho.go

     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	}