mirror of
https://github.com/golang/go
synced 2024-10-05 12:21:22 -06:00
231 lines
4.1 KiB
Go
231 lines
4.1 KiB
Go
|
// 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
|
||
|
}
|