mirror of
https://github.com/Binject/debug
synced 2026-06-08 10:28:33 +00:00
removed symbol sorting code, not neccesary and speeds things up a bit
This commit is contained in:
+16
-135
@@ -18,7 +18,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -39,8 +38,6 @@ type Package struct {
|
||||
|
||||
os string
|
||||
arch string
|
||||
|
||||
//symMap map[int]*Sym
|
||||
}
|
||||
|
||||
func (p Package) OS() string {
|
||||
@@ -62,14 +59,17 @@ type ArchiveMember struct {
|
||||
NonPkgSymRefs []*Sym
|
||||
SymRefs []SymRef
|
||||
|
||||
textSyms textSyms
|
||||
initSym specialSym
|
||||
textSyms []*Sym
|
||||
|
||||
symMap map[int]*Sym
|
||||
|
||||
isCompilerObj bool
|
||||
}
|
||||
|
||||
func (a ArchiveMember) IsCompilerObj() bool {
|
||||
return a.isCompilerObj
|
||||
}
|
||||
|
||||
type ArchiveHeader struct {
|
||||
Name string
|
||||
Date string
|
||||
@@ -82,17 +82,16 @@ type ArchiveHeader struct {
|
||||
|
||||
// A Sym is a named symbol in an object file.
|
||||
type Sym struct {
|
||||
Name string
|
||||
ABI uint16
|
||||
Kind objabi.SymKind // kind of symbol
|
||||
Flag uint8
|
||||
Size uint32 // size of corresponding data
|
||||
Align uint32
|
||||
Type *SymRef // symbol for Go type information
|
||||
Data []byte // memory image of symbol
|
||||
Reloc []Reloc // relocations to apply to Data
|
||||
Func *Func // additional data for functions
|
||||
symRef goobj2.SymRef
|
||||
Name string
|
||||
ABI uint16
|
||||
Kind objabi.SymKind // kind of symbol
|
||||
Flag uint8
|
||||
Size uint32 // size of corresponding data
|
||||
Align uint32
|
||||
Type *SymRef // symbol for Go type information
|
||||
Data []byte // memory image of symbol
|
||||
Reloc []Reloc // relocations to apply to Data
|
||||
Func *Func // additional data for functions
|
||||
}
|
||||
|
||||
type SymRef struct {
|
||||
@@ -158,29 +157,6 @@ type InlinedCall struct {
|
||||
ParentPC int32
|
||||
}
|
||||
|
||||
type textSyms []specialSym
|
||||
|
||||
func (t textSyms) Len() int {
|
||||
return len(t)
|
||||
}
|
||||
|
||||
func (t textSyms) Less(i, j int) bool {
|
||||
return t[i].strOff < t[j].strOff
|
||||
}
|
||||
|
||||
func (t textSyms) Swap(i, j int) {
|
||||
var temp specialSym
|
||||
|
||||
temp = t[i]
|
||||
t[i] = t[j]
|
||||
t[j] = temp
|
||||
}
|
||||
|
||||
type specialSym struct {
|
||||
strOff uint32
|
||||
sym *Sym
|
||||
}
|
||||
|
||||
type ImportCfg map[string]ExportInfo
|
||||
|
||||
type ExportInfo struct {
|
||||
@@ -591,10 +567,6 @@ func (r *objReader) parseObject(prefix []byte, importMap ImportCfg, returnReader
|
||||
r.p.os = hs[2]
|
||||
r.p.arch = hs[3]
|
||||
}
|
||||
var isAsmObj bool
|
||||
if len(hs) == 6 {
|
||||
isAsmObj = true
|
||||
}
|
||||
|
||||
p, err := r.peek(8)
|
||||
if err != nil {
|
||||
@@ -694,7 +666,7 @@ func (r *objReader) parseObject(prefix []byte, importMap ImportCfg, returnReader
|
||||
}
|
||||
|
||||
if sym.Kind == objabi.STEXT {
|
||||
am.textSyms = append(am.textSyms, specialSym{sym: sym})
|
||||
am.textSyms = append(am.textSyms, sym)
|
||||
}
|
||||
|
||||
// Symbol data
|
||||
@@ -818,15 +790,8 @@ func (r *objReader) parseObject(prefix []byte, importMap ImportCfg, returnReader
|
||||
// Symbol definitions
|
||||
nsymDefs := rr.NSym()
|
||||
am.SymDefs = make([]*Sym, nsymDefs)
|
||||
realInitSymName := initSymName
|
||||
if r.p.ImportPath != "" {
|
||||
realInitSymName = strings.Replace(initSymName, `""`, r.p.ImportPath, 1)
|
||||
}
|
||||
for i := 0; i < nsymDefs; i++ {
|
||||
parseSym(i, i, am.SymDefs)
|
||||
if am.SymDefs[i].Name == realInitSymName {
|
||||
am.initSym = specialSym{sym: am.SymDefs[i]}
|
||||
}
|
||||
}
|
||||
|
||||
// Non-pkg symbol definitions
|
||||
@@ -847,12 +812,6 @@ func (r *objReader) parseObject(prefix []byte, importMap ImportCfg, returnReader
|
||||
|
||||
// Symbol references were already parsed above
|
||||
|
||||
// Sort text symbols
|
||||
if err := r.configureSpecialSyms(objbytes, &am, isAsmObj); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
sort.Sort(am.textSyms)
|
||||
|
||||
// Resolve missing inlined function names
|
||||
if len(inlFuncsToResolve) == 0 {
|
||||
return nil, &am, h, nil
|
||||
@@ -897,81 +856,3 @@ func getArchivePath(pkg string, importMap ImportCfg) (string, error) {
|
||||
|
||||
return strings.TrimSpace(string(path)), nil
|
||||
}
|
||||
|
||||
func (r *objReader) configureSpecialSyms(objBytes []byte, am *ArchiveMember, isAsmObj bool) error {
|
||||
stringTable := objBytes[objHeaderLen:am.ObjHeader.Offsets[goobj2.BlkAutolib]]
|
||||
|
||||
pkgName := `""`
|
||||
if r.p.ImportPath != "" {
|
||||
pkgName = r.p.ImportPath
|
||||
}
|
||||
prefixes := []string{"go.info.", "go.string.", "type.", "runtime.", "gclocals·", "go.itablink.", "go.itab.", "go.interface.", "go.constinfo.", "gofile..", "go.builtin.", "internal/", "go.cuinfo.packagename.", pkgName + "."} // TODO: only add last element if obj is ASM obj
|
||||
for _, pkg := range am.Packages {
|
||||
prefixes = append(prefixes, pkg+".")
|
||||
}
|
||||
if isAsmObj {
|
||||
prefixes = append(prefixes, `"".`)
|
||||
}
|
||||
|
||||
strTableOff := func(symName string) int {
|
||||
start := 0
|
||||
for {
|
||||
off := bytes.Index(stringTable[start:], []byte(symName))
|
||||
if off == -1 {
|
||||
return -1
|
||||
}
|
||||
|
||||
// check to make sure the string we found isn't actually
|
||||
// a substring of another symbol's name
|
||||
newStart := start + off + len(symName)
|
||||
if !isEndOfStr(stringTable[newStart:], prefixes) {
|
||||
start = newStart
|
||||
continue
|
||||
}
|
||||
|
||||
return off + start
|
||||
}
|
||||
}
|
||||
|
||||
// sort the symbols in the TEXT region by when their name appears in the
|
||||
// string table.
|
||||
// TODO: find better way to order/sort text syms
|
||||
for i, textSym := range am.textSyms {
|
||||
off := strTableOff(textSym.sym.Name)
|
||||
if off == -1 {
|
||||
return fmt.Errorf("symbol not found in string table: %s", textSym.sym.Name)
|
||||
}
|
||||
|
||||
am.textSyms[i].strOff = uint32(off) + objHeaderLen
|
||||
if isAsmObj {
|
||||
prefixes = append(prefixes, textSym.sym.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// find the offset in the string table of the init symbol.
|
||||
// TODO: find better way to know when to write init symbol
|
||||
if am.initSym.sym != nil {
|
||||
off := strTableOff(am.initSym.sym.Name)
|
||||
if off == -1 {
|
||||
return fmt.Errorf("symbol not found in string table: %s", am.initSym.sym.Name)
|
||||
}
|
||||
am.initSym.strOff = uint32(off) + objHeaderLen
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: detect if inside string
|
||||
func isEndOfStr(stringTable []byte, prefixes []string) bool {
|
||||
if stringTable[0] == 46 { // '.'
|
||||
return false
|
||||
}
|
||||
|
||||
for _, prefix := range prefixes {
|
||||
if string(stringTable[:len(prefix)]) == prefix {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
+12
-16
@@ -159,19 +159,16 @@ func WriteObjFile2(pkg *Package, objPath string) error {
|
||||
// Pcdata
|
||||
ctxt.ObjHeader.Offsets[goobj2.BlkPcdata] = w.Offset()
|
||||
for _, ts := range ctxt.textSyms {
|
||||
w.Bytes(ts.sym.Func.PCSP)
|
||||
w.Bytes(ts.sym.Func.PCFile)
|
||||
w.Bytes(ts.sym.Func.PCLine)
|
||||
w.Bytes(ts.sym.Func.PCInline)
|
||||
for i := range ts.sym.Func.PCData {
|
||||
w.Bytes(ts.sym.Func.PCData[i])
|
||||
w.Bytes(ts.Func.PCSP)
|
||||
w.Bytes(ts.Func.PCFile)
|
||||
w.Bytes(ts.Func.PCLine)
|
||||
w.Bytes(ts.Func.PCInline)
|
||||
for i := range ts.Func.PCData {
|
||||
w.Bytes(ts.Func.PCData[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks used only by tools (objdump, nm).
|
||||
|
||||
// Referenced symbol names from other packages
|
||||
// TODO: will be different due to strings in different order
|
||||
ctxt.ObjHeader.Offsets[goobj2.BlkRefName] = w.Offset()
|
||||
for _, ref := range ctxt.SymRefs {
|
||||
var o goobj2.RefName
|
||||
@@ -186,8 +183,10 @@ func WriteObjFile2(pkg *Package, objPath string) error {
|
||||
// If the object size is odd, make it even by adding an
|
||||
// extra null byte as padding
|
||||
size := int64(objEnd) + (start - curObjStartOff)
|
||||
end := start + int64(w.Offset())
|
||||
if size%2 != 0 {
|
||||
b.WriteByte(0x00)
|
||||
end++
|
||||
}
|
||||
|
||||
// Fix size field of the last archive header
|
||||
@@ -195,7 +194,6 @@ func WriteObjFile2(pkg *Package, objPath string) error {
|
||||
b.WriteString(fmt.Sprintf("%-10d", size))
|
||||
|
||||
// Fix up block offsets in the object header
|
||||
end := start + int64(w.Offset())
|
||||
b.MustSeek(start, 0)
|
||||
ctxt.ObjHeader.Write(w.Writer)
|
||||
b.MustSeek(end, 0)
|
||||
@@ -251,15 +249,14 @@ func (w *writer) StringTable() {
|
||||
|
||||
// Symbols of type STEXT (that have functions) are written first
|
||||
for _, ts := range w.ctxt.textSyms {
|
||||
writeSymStrings(ts.sym)
|
||||
writeSymStrings(ts)
|
||||
}
|
||||
|
||||
// TODO: optimize by not writing symbols twice
|
||||
syms := [][]*Sym{w.ctxt.NonPkgSymDefs, w.ctxt.SymDefs, w.ctxt.NonPkgSymRefs}
|
||||
for _, list := range syms {
|
||||
for _, s := range list {
|
||||
if w.ctxt.initSym.sym != nil && w.Offset() == w.ctxt.initSym.strOff {
|
||||
writeSymStrings(w.ctxt.initSym.sym)
|
||||
if s.Kind == objabi.STEXT {
|
||||
continue
|
||||
}
|
||||
|
||||
writeSymStrings(s)
|
||||
@@ -362,8 +359,7 @@ func nAuxSym(s *Sym) int {
|
||||
func genFuncInfoSyms(ctxt *ArchiveMember) {
|
||||
var pcdataoff uint32
|
||||
var b bytes.Buffer
|
||||
for _, textSym := range ctxt.textSyms {
|
||||
s := textSym.sym
|
||||
for _, s := range ctxt.textSyms {
|
||||
if s.Func == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user