| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Mach-O header data structures |
| // http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html |
| |
| package macho |
| |
| import "strconv" |
| |
| // A FileHeader represents a Mach-O file header. |
| type FileHeader struct { |
| Magic uint32; |
| Cpu Cpu; |
| SubCpu uint32; |
| Type Type; |
| Ncmd uint32; |
| Cmdsz uint32; |
| Flags uint32; |
| } |
| |
| const ( |
| fileHeaderSize32 = 7 * 4; |
| fileHeaderSize64 = 8 * 4; |
| ) |
| |
| const ( |
| Magic32 uint32 = 0xfeedface; |
| Magic64 uint32 = 0xfeedfacf; |
| ) |
| |
| // A Type is a Mach-O file type, either an object or an executable. |
| type Type uint32 |
| |
| const ( |
| TypeObj Type = 1; |
| TypeExec Type = 2; |
| ) |
| |
| // A Cpu is a Mach-O cpu type. |
| type Cpu uint32 |
| |
| const ( |
| Cpu386 Cpu = 7; |
| CpuAmd64 Cpu = Cpu386 + 1<<24; |
| ) |
| |
| var cpuStrings = []intName{ |
| intName{uint32(Cpu386), "Cpu386"}, |
| intName{uint32(CpuAmd64), "CpuAmd64"}, |
| } |
| |
| func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) } |
| func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) } |
| |
| // A LoadCmd is a Mach-O load command. |
| type LoadCmd uint32 |
| |
| const ( |
| LoadCmdSegment LoadCmd = 1; |
| LoadCmdSegment64 LoadCmd = 25; |
| LoadCmdThread LoadCmd = 4; |
| LoadCmdUnixThread LoadCmd = 5; // thread+stack |
| ) |
| |
| var cmdStrings = []intName{ |
| intName{uint32(LoadCmdSegment), "LoadCmdSegment"}, |
| intName{uint32(LoadCmdSegment64), "LoadCmdSegment64"}, |
| intName{uint32(LoadCmdThread), "LoadCmdThread"}, |
| intName{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"}, |
| } |
| |
| func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) } |
| func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) } |
| |
| // A Segment64 is a 64-bit Mach-O segment load command. |
| type Segment64 struct { |
| Cmd LoadCmd; |
| Len uint32; |
| Name [16]byte; |
| Addr uint64; |
| Memsz uint64; |
| Offset uint64; |
| Filesz uint64; |
| Maxprot uint32; |
| Prot uint32; |
| Nsect uint32; |
| Flag uint32; |
| } |
| |
| // A Segment32 is a 32-bit Mach-O segment load command. |
| type Segment32 struct { |
| Cmd LoadCmd; |
| Len uint32; |
| Name [16]byte; |
| Addr uint32; |
| Memsz uint32; |
| Offset uint32; |
| Filesz uint32; |
| Maxprot uint32; |
| Prot uint32; |
| Nsect uint32; |
| Flag uint32; |
| } |
| |
| // A Section32 is a 32-bit Mach-O section header. |
| type Section32 struct { |
| Name [16]byte; |
| Seg [16]byte; |
| Addr uint32; |
| Size uint32; |
| Offset uint32; |
| Align uint32; |
| Reloff uint32; |
| Nreloc uint32; |
| Flags uint32; |
| Reserve1 uint32; |
| Reserve2 uint32; |
| } |
| |
| // A Section32 is a 64-bit Mach-O section header. |
| type Section64 struct { |
| Name [16]byte; |
| Seg [16]byte; |
| Addr uint64; |
| Size uint64; |
| Offset uint32; |
| Align uint32; |
| Reloff uint32; |
| Nreloc uint32; |
| Flags uint32; |
| Reserve1 uint32; |
| Reserve2 uint32; |
| Reserve3 uint32; |
| } |
| |
| // A Thread is a Mach-O thread state command. |
| type Thread struct { |
| Cmd LoadCmd; |
| Len uint32; |
| Type uint32; |
| Data []uint32; |
| } |
| |
| // Regs386 is the Mach-O 386 register structure. |
| type Regs386 struct { |
| AX uint32; |
| BX uint32; |
| CX uint32; |
| DX uint32; |
| DI uint32; |
| SI uint32; |
| BP uint32; |
| SP uint32; |
| SS uint32; |
| FLAGS uint32; |
| IP uint32; |
| CS uint32; |
| DS uint32; |
| ES uint32; |
| FS uint32; |
| GS uint32; |
| } |
| |
| // RegsAMD64 is the Mach-O AMD64 register structure. |
| type RegsAMD64 struct { |
| AX uint64; |
| BX uint64; |
| CX uint64; |
| DX uint64; |
| DI uint64; |
| SI uint64; |
| BP uint64; |
| SP uint64; |
| R8 uint64; |
| R9 uint64; |
| R10 uint64; |
| R11 uint64; |
| R12 uint64; |
| R13 uint64; |
| R14 uint64; |
| R15 uint64; |
| IP uint64; |
| FLAGS uint64; |
| CS uint64; |
| FS uint64; |
| GS uint64; |
| } |
| |
| type intName struct { |
| i uint32; |
| s string; |
| } |
| |
| func stringName(i uint32, names []intName, goSyntax bool) string { |
| for _, n := range names { |
| if n.i == i { |
| if goSyntax { |
| return "macho." + n.s |
| } |
| return n.s; |
| } |
| } |
| return strconv.Uitoa64(uint64(i)); |
| } |
| |
| func flagName(i uint32, names []intName, goSyntax bool) string { |
| s := ""; |
| for _, n := range names { |
| if n.i&i == n.i { |
| if len(s) > 0 { |
| s += "+" |
| } |
| if goSyntax { |
| s += "macho." |
| } |
| s += n.s; |
| i -= n.i; |
| } |
| } |
| if len(s) == 0 { |
| return "0x" + strconv.Uitob64(uint64(i), 16) |
| } |
| if i != 0 { |
| s += "+0x" + strconv.Uitob64(uint64(i), 16) |
| } |
| return s; |
| } |