mirror of
https://github.com/golang/go
synced 2024-11-25 02:07:58 -07:00
debug/elf, debug/macho: add ImportedLibraries, ImportedSymbols
R=r, iant CC=golang-dev https://golang.org/cl/3470044
This commit is contained in:
parent
f16c280fe5
commit
37499ebcfd
@ -1356,9 +1356,12 @@ type Sym32 struct {
|
|||||||
|
|
||||||
const Sym32Size = 16
|
const Sym32Size = 16
|
||||||
|
|
||||||
func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
|
func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
|
||||||
func ST_TYPE(bind SymBind, typ SymType) uint8 { return uint8(bind)<<4 | uint8(typ)&0xf }
|
func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
|
||||||
func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
|
func ST_INFO(bind SymBind, typ SymType) uint8 {
|
||||||
|
return uint8(bind)<<4 | uint8(typ)&0xf
|
||||||
|
}
|
||||||
|
func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ELF64
|
* ELF64
|
||||||
|
@ -75,6 +75,15 @@ func (s *Section) Data() ([]byte, os.Error) {
|
|||||||
return dat[0:n], err
|
return dat[0:n], err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stringTable reads and returns the string table given by the
|
||||||
|
// specified link value.
|
||||||
|
func (f *File) stringTable(link uint32) ([]byte, os.Error) {
|
||||||
|
if link <= 0 || link >= uint32(len(f.Sections)) {
|
||||||
|
return nil, os.ErrorString("section has invalid string table link")
|
||||||
|
}
|
||||||
|
return f.Sections[link].Data()
|
||||||
|
}
|
||||||
|
|
||||||
// Open returns a new ReadSeeker reading the ELF section.
|
// Open returns a new ReadSeeker reading the ELF section.
|
||||||
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
|
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
|
||||||
|
|
||||||
@ -108,9 +117,9 @@ func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-
|
|||||||
|
|
||||||
// A Symbol represents an entry in an ELF symbol table section.
|
// A Symbol represents an entry in an ELF symbol table section.
|
||||||
type Symbol struct {
|
type Symbol struct {
|
||||||
Name uint32
|
Name string
|
||||||
Info, Other byte
|
Info, Other byte
|
||||||
Section uint32
|
Section SectionIndex
|
||||||
Value, Size uint64
|
Value, Size uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +169,17 @@ func (f *File) Close() os.Error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SectionByType returns the first section in f with the
|
||||||
|
// given type, or nil if there is no such section.
|
||||||
|
func (f *File) SectionByType(typ SectionType) *Section {
|
||||||
|
for _, s := range f.Sections {
|
||||||
|
if s.Type == typ {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewFile creates a new File for accessing an ELF binary in an underlying reader.
|
// NewFile creates a new File for accessing an ELF binary in an underlying reader.
|
||||||
// The ELF binary is expected to start at position 0 in the ReaderAt.
|
// The ELF binary is expected to start at position 0 in the ReaderAt.
|
||||||
func NewFile(r io.ReaderAt) (*File, os.Error) {
|
func NewFile(r io.ReaderAt) (*File, os.Error) {
|
||||||
@ -293,9 +313,8 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load section header string table.
|
// Load section header string table.
|
||||||
s := f.Sections[shstrndx]
|
shstrtab, err := f.Sections[shstrndx].Data()
|
||||||
shstrtab := make([]byte, s.Size)
|
if err != nil {
|
||||||
if _, err := r.ReadAt(shstrtab, int64(s.Offset)); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for i, s := range f.Sections {
|
for i, s := range f.Sections {
|
||||||
@ -309,25 +328,65 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) getSymbols() ([]Symbol, os.Error) {
|
// getSymbols returns a slice of Symbols from parsing the symbol table
|
||||||
|
// with the given type.
|
||||||
|
func (f *File) getSymbols(typ SectionType) ([]Symbol, os.Error) {
|
||||||
switch f.Class {
|
switch f.Class {
|
||||||
case ELFCLASS64:
|
case ELFCLASS64:
|
||||||
return f.getSymbols64()
|
return f.getSymbols64(typ)
|
||||||
|
|
||||||
|
case ELFCLASS32:
|
||||||
|
return f.getSymbols32(typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, os.ErrorString("not implemented")
|
return nil, os.ErrorString("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSymbols returns a slice of Symbols from parsing the symbol table.
|
func (f *File) getSymbols32(typ SectionType) ([]Symbol, os.Error) {
|
||||||
func (f *File) getSymbols64() ([]Symbol, os.Error) {
|
symtabSection := f.SectionByType(typ)
|
||||||
var symtabSection *Section
|
if symtabSection == nil {
|
||||||
for _, section := range f.Sections {
|
return nil, os.ErrorString("no symbol section")
|
||||||
if section.Type == SHT_SYMTAB {
|
|
||||||
symtabSection = section
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, err := symtabSection.Data()
|
||||||
|
if err != nil {
|
||||||
|
return nil, os.ErrorString("cannot load symbol section")
|
||||||
|
}
|
||||||
|
symtab := bytes.NewBuffer(data)
|
||||||
|
if symtab.Len()%Sym32Size != 0 {
|
||||||
|
return nil, os.ErrorString("length of symbol section is not a multiple of SymSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
strdata, err := f.stringTable(symtabSection.Link)
|
||||||
|
if err != nil {
|
||||||
|
return nil, os.ErrorString("cannot load string table section")
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first entry is all zeros.
|
||||||
|
var skip [Sym32Size]byte
|
||||||
|
symtab.Read(skip[0:])
|
||||||
|
|
||||||
|
symbols := make([]Symbol, symtab.Len()/Sym32Size)
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
var sym Sym32
|
||||||
|
for symtab.Len() > 0 {
|
||||||
|
binary.Read(symtab, f.ByteOrder, &sym)
|
||||||
|
str, _ := getString(strdata, int(sym.Name))
|
||||||
|
symbols[i].Name = str
|
||||||
|
symbols[i].Info = sym.Info
|
||||||
|
symbols[i].Other = sym.Other
|
||||||
|
symbols[i].Section = SectionIndex(sym.Shndx)
|
||||||
|
symbols[i].Value = uint64(sym.Value)
|
||||||
|
symbols[i].Size = uint64(sym.Size)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbols, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) getSymbols64(typ SectionType) ([]Symbol, os.Error) {
|
||||||
|
symtabSection := f.SectionByType(typ)
|
||||||
if symtabSection == nil {
|
if symtabSection == nil {
|
||||||
return nil, os.ErrorString("no symbol section")
|
return nil, os.ErrorString("no symbol section")
|
||||||
}
|
}
|
||||||
@ -341,6 +400,11 @@ func (f *File) getSymbols64() ([]Symbol, os.Error) {
|
|||||||
return nil, os.ErrorString("length of symbol section is not a multiple of Sym64Size")
|
return nil, os.ErrorString("length of symbol section is not a multiple of Sym64Size")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strdata, err := f.stringTable(symtabSection.Link)
|
||||||
|
if err != nil {
|
||||||
|
return nil, os.ErrorString("cannot load string table section")
|
||||||
|
}
|
||||||
|
|
||||||
// The first entry is all zeros.
|
// The first entry is all zeros.
|
||||||
var skip [Sym64Size]byte
|
var skip [Sym64Size]byte
|
||||||
symtab.Read(skip[0:])
|
symtab.Read(skip[0:])
|
||||||
@ -351,10 +415,11 @@ func (f *File) getSymbols64() ([]Symbol, os.Error) {
|
|||||||
var sym Sym64
|
var sym Sym64
|
||||||
for symtab.Len() > 0 {
|
for symtab.Len() > 0 {
|
||||||
binary.Read(symtab, f.ByteOrder, &sym)
|
binary.Read(symtab, f.ByteOrder, &sym)
|
||||||
symbols[i].Name = sym.Name
|
str, _ := getString(strdata, int(sym.Name))
|
||||||
|
symbols[i].Name = str
|
||||||
symbols[i].Info = sym.Info
|
symbols[i].Info = sym.Info
|
||||||
symbols[i].Other = sym.Other
|
symbols[i].Other = sym.Other
|
||||||
symbols[i].Section = uint32(sym.Shndx)
|
symbols[i].Section = SectionIndex(sym.Shndx)
|
||||||
symbols[i].Value = sym.Value
|
symbols[i].Value = sym.Value
|
||||||
symbols[i].Size = sym.Size
|
symbols[i].Size = sym.Size
|
||||||
i++
|
i++
|
||||||
@ -403,7 +468,7 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) os.Error {
|
|||||||
return os.ErrorString("length of relocation section is not a multiple of Sym64Size")
|
return os.ErrorString("length of relocation section is not a multiple of Sym64Size")
|
||||||
}
|
}
|
||||||
|
|
||||||
symbols, err := f.getSymbols()
|
symbols, err := f.getSymbols(SHT_SYMTAB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -478,3 +543,63 @@ func (f *File) DWARF() (*dwarf.Data, os.Error) {
|
|||||||
abbrev, info, str := dat[0], dat[1], dat[2]
|
abbrev, info, str := dat[0], dat[1], dat[2]
|
||||||
return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
|
return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImportedSymbols returns the names of all symbols
|
||||||
|
// referred to by the binary f that are expected to be
|
||||||
|
// satisfied by other libraries at dynamic load time.
|
||||||
|
// It does not return weak symbols.
|
||||||
|
func (f *File) ImportedSymbols() ([]string, os.Error) {
|
||||||
|
sym, err := f.getSymbols(SHT_DYNSYM)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var all []string
|
||||||
|
for _, s := range sym {
|
||||||
|
if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
|
||||||
|
all = append(all, s.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImportedLibraries returns the names of all libraries
|
||||||
|
// referred to by the binary f that are expected to be
|
||||||
|
// linked with the binary at dynamic link time.
|
||||||
|
func (f *File) ImportedLibraries() ([]string, os.Error) {
|
||||||
|
ds := f.SectionByType(SHT_DYNAMIC)
|
||||||
|
if ds == nil {
|
||||||
|
// not dynamic, so no libraries
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
d, err := ds.Data()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
str, err := f.stringTable(ds.Link)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var all []string
|
||||||
|
for len(d) > 0 {
|
||||||
|
var tag DynTag
|
||||||
|
var value uint64
|
||||||
|
switch f.Class {
|
||||||
|
case ELFCLASS32:
|
||||||
|
tag = DynTag(f.ByteOrder.Uint32(d[0:4]))
|
||||||
|
value = uint64(f.ByteOrder.Uint32(d[4:8]))
|
||||||
|
d = d[8:]
|
||||||
|
case ELFCLASS64:
|
||||||
|
tag = DynTag(f.ByteOrder.Uint64(d[0:8]))
|
||||||
|
value = f.ByteOrder.Uint64(d[8:16])
|
||||||
|
d = d[16:]
|
||||||
|
}
|
||||||
|
if tag == DT_NEEDED {
|
||||||
|
s, ok := getString(str, int(value))
|
||||||
|
if ok {
|
||||||
|
all = append(all, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
@ -24,6 +24,9 @@ type File struct {
|
|||||||
Loads []Load
|
Loads []Load
|
||||||
Sections []*Section
|
Sections []*Section
|
||||||
|
|
||||||
|
Symtab *Symtab
|
||||||
|
Dysymtab *Dysymtab
|
||||||
|
|
||||||
closer io.Closer
|
closer io.Closer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +115,28 @@ func (s *Section) Data() ([]byte, os.Error) {
|
|||||||
// Open returns a new ReadSeeker reading the Mach-O section.
|
// Open returns a new ReadSeeker reading the Mach-O section.
|
||||||
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
|
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
|
||||||
|
|
||||||
|
// A Dylib represents a Mach-O load dynamic library command.
|
||||||
|
type Dylib struct {
|
||||||
|
LoadBytes
|
||||||
|
Name string
|
||||||
|
Time uint32
|
||||||
|
CurrentVersion uint32
|
||||||
|
CompatVersion uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Symtab represents a Mach-O symbol table command.
|
||||||
|
type Symtab struct {
|
||||||
|
LoadBytes
|
||||||
|
SymtabCmd
|
||||||
|
Syms []Symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Dysymtab represents a Mach-O dynamic symbol table command.
|
||||||
|
type Dysymtab struct {
|
||||||
|
LoadBytes
|
||||||
|
DysymtabCmd
|
||||||
|
IndirectSyms []uint32 // indices into Symtab.Syms
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mach-O reader
|
* Mach-O reader
|
||||||
@ -217,6 +242,71 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
|
|||||||
default:
|
default:
|
||||||
f.Loads[i] = LoadBytes(cmddat)
|
f.Loads[i] = LoadBytes(cmddat)
|
||||||
|
|
||||||
|
case LoadCmdDylib:
|
||||||
|
var hdr DylibCmd
|
||||||
|
b := bytes.NewBuffer(cmddat)
|
||||||
|
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l := new(Dylib)
|
||||||
|
if hdr.Name >= uint32(len(cmddat)) {
|
||||||
|
return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name}
|
||||||
|
}
|
||||||
|
l.Name = cstring(cmddat[hdr.Name:])
|
||||||
|
l.Time = hdr.Time
|
||||||
|
l.CurrentVersion = hdr.CurrentVersion
|
||||||
|
l.CompatVersion = hdr.CompatVersion
|
||||||
|
l.LoadBytes = LoadBytes(cmddat)
|
||||||
|
f.Loads[i] = l
|
||||||
|
|
||||||
|
case LoadCmdSymtab:
|
||||||
|
var hdr SymtabCmd
|
||||||
|
b := bytes.NewBuffer(cmddat)
|
||||||
|
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
strtab := make([]byte, hdr.Strsize)
|
||||||
|
if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var symsz int
|
||||||
|
if f.Magic == Magic64 {
|
||||||
|
symsz = 16
|
||||||
|
} else {
|
||||||
|
symsz = 12
|
||||||
|
}
|
||||||
|
symdat := make([]byte, int(hdr.Nsyms)*symsz)
|
||||||
|
if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f.Loads[i] = st
|
||||||
|
f.Symtab = st
|
||||||
|
|
||||||
|
case LoadCmdDysymtab:
|
||||||
|
var hdr DysymtabCmd
|
||||||
|
b := bytes.NewBuffer(cmddat)
|
||||||
|
if err := binary.Read(b, bo, &hdr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dat := make([]byte, hdr.Nindirectsyms*4)
|
||||||
|
if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
x := make([]uint32, hdr.Nindirectsyms)
|
||||||
|
if err := binary.Read(bytes.NewBuffer(dat), bo, x); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st := new(Dysymtab)
|
||||||
|
st.LoadBytes = LoadBytes(cmddat)
|
||||||
|
st.DysymtabCmd = hdr
|
||||||
|
st.IndirectSyms = x
|
||||||
|
f.Loads[i] = st
|
||||||
|
f.Dysymtab = st
|
||||||
|
|
||||||
case LoadCmdSegment:
|
case LoadCmdSegment:
|
||||||
var seg32 Segment32
|
var seg32 Segment32
|
||||||
b := bytes.NewBuffer(cmddat)
|
b := bytes.NewBuffer(cmddat)
|
||||||
@ -301,6 +391,43 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, os.Error) {
|
||||||
|
bo := f.ByteOrder
|
||||||
|
symtab := make([]Symbol, hdr.Nsyms)
|
||||||
|
b := bytes.NewBuffer(symdat)
|
||||||
|
for i := range symtab {
|
||||||
|
var n Nlist64
|
||||||
|
if f.Magic == Magic64 {
|
||||||
|
if err := binary.Read(b, bo, &n); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var n32 Nlist32
|
||||||
|
if err := binary.Read(b, bo, &n32); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
n.Name = n32.Name
|
||||||
|
n.Type = n32.Type
|
||||||
|
n.Sect = n32.Sect
|
||||||
|
n.Desc = n32.Desc
|
||||||
|
n.Value = uint64(n32.Value)
|
||||||
|
}
|
||||||
|
sym := &symtab[i]
|
||||||
|
if n.Name >= uint32(len(strtab)) {
|
||||||
|
return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
|
||||||
|
}
|
||||||
|
sym.Name = cstring(strtab[n.Name:])
|
||||||
|
sym.Type = n.Type
|
||||||
|
sym.Sect = n.Sect
|
||||||
|
sym.Desc = n.Desc
|
||||||
|
sym.Value = n.Value
|
||||||
|
}
|
||||||
|
st := new(Symtab)
|
||||||
|
st.LoadBytes = LoadBytes(cmddat)
|
||||||
|
st.Syms = symtab
|
||||||
|
return st, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f *File) pushSection(sh *Section, r io.ReaderAt) {
|
func (f *File) pushSection(sh *Section, r io.ReaderAt) {
|
||||||
f.Sections = append(f.Sections, sh)
|
f.Sections = append(f.Sections, sh)
|
||||||
sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
|
sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
|
||||||
@ -358,3 +485,33 @@ func (f *File) DWARF() (*dwarf.Data, os.Error) {
|
|||||||
abbrev, info, str := dat[0], dat[1], dat[2]
|
abbrev, info, str := dat[0], dat[1], dat[2]
|
||||||
return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
|
return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImportedSymbols returns the names of all symbols
|
||||||
|
// referred to by the binary f that are expected to be
|
||||||
|
// satisfied by other libraries at dynamic load time.
|
||||||
|
func (f *File) ImportedSymbols() ([]string, os.Error) {
|
||||||
|
if f.Dysymtab == nil || f.Symtab == nil {
|
||||||
|
return nil, &FormatError{0, "missing symbol table", nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
st := f.Symtab
|
||||||
|
dt := f.Dysymtab
|
||||||
|
var all []string
|
||||||
|
for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
|
||||||
|
all = append(all, s.Name)
|
||||||
|
}
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImportedLibraries returns the paths of all libraries
|
||||||
|
// referred to by the binary f that are expected to be
|
||||||
|
// linked with the binary at dynamic link time.
|
||||||
|
func (f *File) ImportedLibraries() ([]string, os.Error) {
|
||||||
|
var all []string
|
||||||
|
for _, l := range f.Loads {
|
||||||
|
if lib, ok := l.(*Dylib); ok {
|
||||||
|
all = append(all, lib.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
@ -59,16 +59,21 @@ type LoadCmd uint32
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
LoadCmdSegment LoadCmd = 1
|
LoadCmdSegment LoadCmd = 1
|
||||||
LoadCmdSegment64 LoadCmd = 25
|
LoadCmdSymtab LoadCmd = 2
|
||||||
LoadCmdThread LoadCmd = 4
|
LoadCmdThread LoadCmd = 4
|
||||||
LoadCmdUnixThread LoadCmd = 5 // thread+stack
|
LoadCmdUnixThread LoadCmd = 5 // thread+stack
|
||||||
|
LoadCmdDysymtab LoadCmd = 11
|
||||||
|
LoadCmdDylib LoadCmd = 12
|
||||||
|
LoadCmdDylinker LoadCmd = 15
|
||||||
|
LoadCmdSegment64 LoadCmd = 25
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdStrings = []intName{
|
var cmdStrings = []intName{
|
||||||
{uint32(LoadCmdSegment), "LoadCmdSegment"},
|
{uint32(LoadCmdSegment), "LoadCmdSegment"},
|
||||||
{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
|
|
||||||
{uint32(LoadCmdThread), "LoadCmdThread"},
|
{uint32(LoadCmdThread), "LoadCmdThread"},
|
||||||
{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
|
{uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
|
||||||
|
{uint32(LoadCmdDylib), "LoadCmdDylib"},
|
||||||
|
{uint32(LoadCmdSegment64), "LoadCmdSegment64"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
|
func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
|
||||||
@ -104,6 +109,16 @@ type Segment32 struct {
|
|||||||
Flag uint32
|
Flag uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A DylibCmd is a Mach-O load dynamic library command.
|
||||||
|
type DylibCmd struct {
|
||||||
|
Cmd LoadCmd
|
||||||
|
Len uint32
|
||||||
|
Name uint32
|
||||||
|
Time uint32
|
||||||
|
CurrentVersion uint32
|
||||||
|
CompatVersion uint32
|
||||||
|
}
|
||||||
|
|
||||||
// A Section32 is a 32-bit Mach-O section header.
|
// A Section32 is a 32-bit Mach-O section header.
|
||||||
type Section32 struct {
|
type Section32 struct {
|
||||||
Name [16]byte
|
Name [16]byte
|
||||||
@ -135,6 +150,67 @@ type Section64 struct {
|
|||||||
Reserve3 uint32
|
Reserve3 uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A SymtabCmd is a Mach-O symbol table command.
|
||||||
|
type SymtabCmd struct {
|
||||||
|
Cmd LoadCmd
|
||||||
|
Len uint32
|
||||||
|
Symoff uint32
|
||||||
|
Nsyms uint32
|
||||||
|
Stroff uint32
|
||||||
|
Strsize uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// A DysymtabCmd is a Mach-O dynamic symbol table command.
|
||||||
|
type DysymtabCmd struct {
|
||||||
|
Cmd LoadCmd
|
||||||
|
Len uint32
|
||||||
|
Ilocalsym uint32
|
||||||
|
Nlocalsym uint32
|
||||||
|
Iextdefsym uint32
|
||||||
|
Nextdefsym uint32
|
||||||
|
Iundefsym uint32
|
||||||
|
Nundefsym uint32
|
||||||
|
Tocoffset uint32
|
||||||
|
Ntoc uint32
|
||||||
|
Modtaboff uint32
|
||||||
|
Nmodtab uint32
|
||||||
|
Extrefsymoff uint32
|
||||||
|
Nextrefsyms uint32
|
||||||
|
Indirectsymoff uint32
|
||||||
|
Nindirectsyms uint32
|
||||||
|
Extreloff uint32
|
||||||
|
Nextrel uint32
|
||||||
|
Locreloff uint32
|
||||||
|
Nlocrel uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Nlist32 is a Mach-O 32-bit symbol table entry.
|
||||||
|
type Nlist32 struct {
|
||||||
|
Name uint32
|
||||||
|
Type uint8
|
||||||
|
Sect uint8
|
||||||
|
Desc uint16
|
||||||
|
Value uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Nlist64 is a Mach-O 64-bit symbol table entry.
|
||||||
|
type Nlist64 struct {
|
||||||
|
Name uint32
|
||||||
|
Type uint8
|
||||||
|
Sect uint8
|
||||||
|
Desc uint16
|
||||||
|
Value uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
|
||||||
|
type Symbol struct {
|
||||||
|
Name string
|
||||||
|
Type uint8
|
||||||
|
Sect uint8
|
||||||
|
Desc uint16
|
||||||
|
Value uint64
|
||||||
|
}
|
||||||
|
|
||||||
// A Thread is a Mach-O thread state command.
|
// A Thread is a Mach-O thread state command.
|
||||||
type Thread struct {
|
type Thread struct {
|
||||||
Cmd LoadCmd
|
Cmd LoadCmd
|
||||||
|
Loading…
Reference in New Issue
Block a user