From 2da520b91f1cce02db2c0c00767565dfcbadd654 Mon Sep 17 00:00:00 2001 From: Andrew LeFevre Date: Wed, 26 Aug 2020 10:32:31 -0400 Subject: [PATCH] removed symbol sorting code, not neccesary and speeds things up a bit --- goobj2/file.go | 151 +++++------------------------------------------- goobj2/write.go | 28 ++++----- 2 files changed, 28 insertions(+), 151 deletions(-) diff --git a/goobj2/file.go b/goobj2/file.go index d964bb8..ccb69f3 100644 --- a/goobj2/file.go +++ b/goobj2/file.go @@ -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 -} diff --git a/goobj2/write.go b/goobj2/write.go index dfd213f..11d1b6d 100644 --- a/goobj2/write.go +++ b/goobj2/write.go @@ -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 }