mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Rename Sym2 -> Sym Reloc2 -> Reloc Aux2 -> Aux Also the Reader methods. Change-Id: I49f29e2d1cb480f5309e01d7a74b5e0897d826fb Reviewed-on: https://go-review.googlesource.com/c/go/+/227900 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
183 lines
4.8 KiB
Go
183 lines
4.8 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package goobj
|
|
|
|
import (
|
|
"cmd/internal/goobj2"
|
|
"cmd/internal/objabi"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// Read object file in new format. For now we still fill
|
|
// the data to the current goobj API.
|
|
func (r *objReader) readNew() {
|
|
start := uint32(r.offset)
|
|
|
|
length := r.limit - r.offset
|
|
objbytes := make([]byte, length)
|
|
r.readFull(objbytes)
|
|
rr := goobj2.NewReaderFromBytes(objbytes, false)
|
|
if rr == nil {
|
|
panic("cannot read object file")
|
|
}
|
|
|
|
// Imports
|
|
r.p.Imports = rr.Autolib()
|
|
|
|
pkglist := rr.Pkglist()
|
|
|
|
abiToVer := func(abi uint16) int64 {
|
|
var vers int64
|
|
if abi == goobj2.SymABIstatic {
|
|
// Static symbol
|
|
vers = r.p.MaxVersion
|
|
}
|
|
return vers
|
|
}
|
|
|
|
resolveSymRef := func(s goobj2.SymRef) SymID {
|
|
var i int
|
|
switch p := s.PkgIdx; p {
|
|
case goobj2.PkgIdxInvalid:
|
|
if s.SymIdx != 0 {
|
|
panic("bad sym ref")
|
|
}
|
|
return SymID{}
|
|
case goobj2.PkgIdxNone:
|
|
i = int(s.SymIdx) + rr.NSym()
|
|
case goobj2.PkgIdxBuiltin:
|
|
name, abi := goobj2.BuiltinName(int(s.SymIdx))
|
|
return SymID{name, int64(abi)}
|
|
case goobj2.PkgIdxSelf:
|
|
i = int(s.SymIdx)
|
|
default:
|
|
pkg := pkglist[p]
|
|
return SymID{fmt.Sprintf("%s.<#%d>", pkg, s.SymIdx), 0}
|
|
}
|
|
sym := rr.Sym(i)
|
|
return SymID{sym.Name(rr), abiToVer(sym.ABI())}
|
|
}
|
|
|
|
// Read things for the current goobj API for now.
|
|
|
|
// Symbols
|
|
pcdataBase := start + rr.PcdataBase()
|
|
n := rr.NSym() + rr.NNonpkgdef() + rr.NNonpkgref()
|
|
ndef := rr.NSym() + rr.NNonpkgdef()
|
|
for i := 0; i < n; i++ {
|
|
osym := rr.Sym(i)
|
|
if osym.Name(rr) == "" {
|
|
continue // not a real symbol
|
|
}
|
|
// In a symbol name in an object file, "". denotes the
|
|
// prefix for the package in which the object file has been found.
|
|
// Expand it.
|
|
name := strings.ReplaceAll(osym.Name(rr), `"".`, r.pkgprefix)
|
|
symID := SymID{Name: name, Version: abiToVer(osym.ABI())}
|
|
r.p.SymRefs = append(r.p.SymRefs, symID)
|
|
|
|
if i >= ndef {
|
|
continue // not a defined symbol from here
|
|
}
|
|
|
|
// Symbol data
|
|
dataOff := rr.DataOff(i)
|
|
siz := int64(rr.DataSize(i))
|
|
|
|
sym := Sym{
|
|
SymID: symID,
|
|
Kind: objabi.SymKind(osym.Type()),
|
|
DupOK: osym.Dupok(),
|
|
Size: int64(osym.Siz()),
|
|
Data: Data{int64(start + dataOff), siz},
|
|
}
|
|
r.p.Syms = append(r.p.Syms, &sym)
|
|
|
|
// Reloc
|
|
relocs := rr.Relocs(i)
|
|
sym.Reloc = make([]Reloc, len(relocs))
|
|
for j := range relocs {
|
|
rel := &relocs[j]
|
|
sym.Reloc[j] = Reloc{
|
|
Offset: int64(rel.Off()),
|
|
Size: int64(rel.Siz()),
|
|
Type: objabi.RelocType(rel.Type()),
|
|
Add: rel.Add(),
|
|
Sym: resolveSymRef(rel.Sym()),
|
|
}
|
|
}
|
|
|
|
// Aux symbol info
|
|
isym := -1
|
|
funcdata := make([]goobj2.SymRef, 0, 4)
|
|
auxs := rr.Auxs(i)
|
|
for j := range auxs {
|
|
a := &auxs[j]
|
|
switch a.Type() {
|
|
case goobj2.AuxGotype:
|
|
sym.Type = resolveSymRef(a.Sym())
|
|
case goobj2.AuxFuncInfo:
|
|
if a.Sym().PkgIdx != goobj2.PkgIdxSelf {
|
|
panic("funcinfo symbol not defined in current package")
|
|
}
|
|
isym = int(a.Sym().SymIdx)
|
|
case goobj2.AuxFuncdata:
|
|
funcdata = append(funcdata, a.Sym())
|
|
case goobj2.AuxDwarfInfo, goobj2.AuxDwarfLoc, goobj2.AuxDwarfRanges, goobj2.AuxDwarfLines:
|
|
// nothing to do
|
|
default:
|
|
panic("unknown aux type")
|
|
}
|
|
}
|
|
|
|
// Symbol Info
|
|
if isym == -1 {
|
|
continue
|
|
}
|
|
b := rr.BytesAt(rr.DataOff(isym), rr.DataSize(isym))
|
|
info := goobj2.FuncInfo{}
|
|
info.Read(b)
|
|
|
|
info.Pcdata = append(info.Pcdata, info.PcdataEnd) // for the ease of knowing where it ends
|
|
f := &Func{
|
|
Args: int64(info.Args),
|
|
Frame: int64(info.Locals),
|
|
NoSplit: osym.NoSplit(),
|
|
Leaf: osym.Leaf(),
|
|
TopFrame: osym.TopFrame(),
|
|
PCSP: Data{int64(pcdataBase + info.Pcsp), int64(info.Pcfile - info.Pcsp)},
|
|
PCFile: Data{int64(pcdataBase + info.Pcfile), int64(info.Pcline - info.Pcfile)},
|
|
PCLine: Data{int64(pcdataBase + info.Pcline), int64(info.Pcinline - info.Pcline)},
|
|
PCInline: Data{int64(pcdataBase + info.Pcinline), int64(info.Pcdata[0] - info.Pcinline)},
|
|
PCData: make([]Data, len(info.Pcdata)-1), // -1 as we appended one above
|
|
FuncData: make([]FuncData, len(info.Funcdataoff)),
|
|
File: make([]string, len(info.File)),
|
|
InlTree: make([]InlinedCall, len(info.InlTree)),
|
|
}
|
|
sym.Func = f
|
|
for k := range f.PCData {
|
|
f.PCData[k] = Data{int64(pcdataBase + info.Pcdata[k]), int64(info.Pcdata[k+1] - info.Pcdata[k])}
|
|
}
|
|
for k := range f.FuncData {
|
|
symID := resolveSymRef(funcdata[k])
|
|
f.FuncData[k] = FuncData{symID, int64(info.Funcdataoff[k])}
|
|
}
|
|
for k := range f.File {
|
|
symID := resolveSymRef(info.File[k])
|
|
f.File[k] = symID.Name
|
|
}
|
|
for k := range f.InlTree {
|
|
inl := &info.InlTree[k]
|
|
f.InlTree[k] = InlinedCall{
|
|
Parent: int64(inl.Parent),
|
|
File: resolveSymRef(inl.File).Name,
|
|
Line: int64(inl.Line),
|
|
Func: resolveSymRef(inl.Func),
|
|
ParentPC: int64(inl.ParentPC),
|
|
}
|
|
}
|
|
}
|
|
}
|