removed symbol sorting code, not neccesary and speeds things up a bit

This commit is contained in:
Andrew LeFevre
2020-08-26 10:32:31 -04:00
parent d63df83dee
commit 2da520b91f
2 changed files with 28 additions and 151 deletions
+16 -135
View File
@@ -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
View File
@@ -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
}