cmd/internal/objfile: cache computation of goobj.Arch

Change-Id: I23774cf185e5fa6b89398001cd0655fb0c5bdb46
GitHub-Last-Rev: ca8cae2469
GitHub-Pull-Request: golang/go#40877
Reviewed-on: https://go-review.googlesource.com/c/go/+/249180
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Tao Qingyun 2020-08-19 01:38:43 +00:00 committed by Keith Randall
parent ac875bc923
commit 31da1d993a
2 changed files with 19 additions and 19 deletions

View file

@ -17,6 +17,7 @@ import (
"log" "log"
"os" "os"
"strconv" "strconv"
"strings"
"time" "time"
"unicode/utf8" "unicode/utf8"
) )
@ -83,6 +84,7 @@ func (e *Entry) String() string {
type GoObj struct { type GoObj struct {
TextHeader []byte TextHeader []byte
Arch string
Data Data
} }
@ -404,6 +406,10 @@ func (r *objReader) parseObject(o *GoObj, size int64) error {
} }
} }
o.TextHeader = h o.TextHeader = h
hs := strings.Fields(string(h))
if len(hs) >= 4 {
o.Arch = hs[3]
}
o.Offset = r.offset o.Offset = r.offset
o.Size = size - int64(len(h)) o.Size = size - int64(len(h))

View file

@ -17,13 +17,13 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strings"
) )
type goobjFile struct { type goobjFile struct {
goobj *archive.GoObj goobj *archive.GoObj
r *goobj.Reader r *goobj.Reader
f *os.File f *os.File
arch *sys.Arch
} }
func openGoFile(f *os.File) (*File, error) { func openGoFile(f *os.File) (*File, error) {
@ -45,9 +45,16 @@ L:
return nil, err return nil, err
} }
r := goobj.NewReaderFromBytes(b, false) r := goobj.NewReaderFromBytes(b, false)
var arch *sys.Arch
for _, a := range sys.Archs {
if a.Name == e.Obj.Arch {
arch = a
break
}
}
entries = append(entries, &Entry{ entries = append(entries, &Entry{
name: e.Name, name: e.Name,
raw: &goobjFile{e.Obj, r, f}, raw: &goobjFile{e.Obj, r, f, arch},
}) })
continue continue
case archive.EntryNativeObj: case archive.EntryNativeObj:
@ -223,17 +230,8 @@ func (f *goobjFile) pcln() (textStart uint64, symtab, pclntab []byte, err error)
// Returns "",0,nil if unknown. // Returns "",0,nil if unknown.
// This function implements the Liner interface in preference to pcln() above. // This function implements the Liner interface in preference to pcln() above.
func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) { func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
// TODO: this is really inefficient. Binary search? Memoize last result?
r := f.r r := f.r
var arch *sys.Arch if f.arch == nil {
archname := f.goarch()
for _, a := range sys.Archs {
if a.Name == archname {
arch = a
break
}
}
if arch == nil {
return "", 0, nil return "", 0, nil
} }
pcdataBase := r.PcdataBase() pcdataBase := r.PcdataBase()
@ -264,10 +262,10 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
lengths := info.ReadFuncInfoLengths(b) lengths := info.ReadFuncInfoLengths(b)
off, end := info.ReadPcline(b) off, end := info.ReadPcline(b)
pcline := r.BytesAt(pcdataBase+off, int(end-off)) pcline := r.BytesAt(pcdataBase+off, int(end-off))
line := int(pcValue(pcline, pc-addr, arch)) line := int(pcValue(pcline, pc-addr, f.arch))
off, end = info.ReadPcfile(b) off, end = info.ReadPcfile(b)
pcfile := r.BytesAt(pcdataBase+off, int(end-off)) pcfile := r.BytesAt(pcdataBase+off, int(end-off))
fileID := pcValue(pcfile, pc-addr, arch) fileID := pcValue(pcfile, pc-addr, f.arch)
globalFileID := info.ReadFile(b, lengths.FileOff, uint32(fileID)) globalFileID := info.ReadFile(b, lengths.FileOff, uint32(fileID))
fileName := r.File(int(globalFileID)) fileName := r.File(int(globalFileID))
// Note: we provide only the name in the Func structure. // Note: we provide only the name in the Func structure.
@ -332,11 +330,7 @@ func (f *goobjFile) text() (textStart uint64, text []byte, err error) {
} }
func (f *goobjFile) goarch() string { func (f *goobjFile) goarch() string {
hs := strings.Fields(string(f.goobj.TextHeader)) return f.goobj.Arch
if len(hs) >= 4 {
return hs[3]
}
return ""
} }
func (f *goobjFile) loadAddress() (uint64, error) { func (f *goobjFile) loadAddress() (uint64, error) {