mirror of
https://github.com/golang/go
synced 2024-11-18 09:54:57 -07:00
[dev.link] cmd/link: delete sym.Symbol and sym.Reloc
This deletes all sym.Symbol and sym.Reloc references. This is certainly not complete, and there are more cleanups to do. But I feel this makes a good first round. Change-Id: I7621d016957f7ef114be5f0606fcb3ad6aee71c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/234097 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
parent
4e03dac77c
commit
b97212d1f1
@ -70,14 +70,6 @@ func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
|||||||
o(0xc3)
|
o(0xc3)
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeWritable makes a readonly symbol writable if we do opcode rewriting.
|
|
||||||
func makeWritable(s *sym.Symbol) {
|
|
||||||
if s.Attr.ReadOnly() {
|
|
||||||
s.Attr.Set(sym.AttrReadOnly, false)
|
|
||||||
s.P = append([]byte(nil), s.P...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
|
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc2, rIdx int) bool {
|
||||||
targ := r.Sym()
|
targ := r.Sym()
|
||||||
var targType sym.SymKind
|
var targType sym.SymKind
|
||||||
|
@ -133,19 +133,6 @@ func FoldSubSymbolOffset(ldr *loader.Loader, s loader.Sym) (loader.Sym, int64) {
|
|||||||
return s, off
|
return s, off
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyOuterToXAdd takes a relocation and updates the relocation's
|
|
||||||
// XAdd field to take into account the target syms's outer symbol (if
|
|
||||||
// applicable).
|
|
||||||
func ApplyOuterToXAdd(r *sym.Reloc) *sym.Symbol {
|
|
||||||
rs := r.Sym
|
|
||||||
r.Xadd = r.Add
|
|
||||||
if rs.Outer != nil {
|
|
||||||
r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
|
|
||||||
rs = rs.Outer
|
|
||||||
}
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
// relocsym resolve relocations in "s", updating the symbol's content
|
// relocsym resolve relocations in "s", updating the symbol's content
|
||||||
// in "P".
|
// in "P".
|
||||||
// The main loop walks through the list of relocations attached to "s"
|
// The main loop walks through the list of relocations attached to "s"
|
||||||
@ -1359,8 +1346,6 @@ type dodataState struct {
|
|||||||
// Link context
|
// Link context
|
||||||
ctxt *Link
|
ctxt *Link
|
||||||
// Data symbols bucketed by type.
|
// Data symbols bucketed by type.
|
||||||
data [sym.SXREF][]*sym.Symbol
|
|
||||||
// Data symbols bucketed by type.
|
|
||||||
data2 [sym.SXREF][]loader.Sym
|
data2 [sym.SXREF][]loader.Sym
|
||||||
// Max alignment for each flavor of data symbol.
|
// Max alignment for each flavor of data symbol.
|
||||||
dataMaxAlign [sym.SXREF]int32
|
dataMaxAlign [sym.SXREF]int32
|
||||||
@ -1740,7 +1725,7 @@ func (state *dodataState) allocateDataSections2(ctxt *Link) {
|
|||||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), sect)
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), sect)
|
||||||
|
|
||||||
// Coverage instrumentation counters for libfuzzer.
|
// Coverage instrumentation counters for libfuzzer.
|
||||||
if len(state.data[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
|
if len(state.data2[sym.SLIBFUZZER_EXTRA_COUNTER]) > 0 {
|
||||||
state.allocateNamedSectionAndAssignSyms2(&Segdata, "__libfuzzer_extra_counters", sym.SLIBFUZZER_EXTRA_COUNTER, sym.Sxxx, 06)
|
state.allocateNamedSectionAndAssignSyms2(&Segdata, "__libfuzzer_extra_counters", sym.SLIBFUZZER_EXTRA_COUNTER, sym.Sxxx, 06)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,28 +24,6 @@ func isDwarf64(ctxt *Link) bool {
|
|||||||
return ctxt.HeadType == objabi.Haix
|
return ctxt.HeadType == objabi.Haix
|
||||||
}
|
}
|
||||||
|
|
||||||
// dwarfSecInfo2 is a replica of the dwarfSecInfo struct but with
|
|
||||||
// *sym.Symbol content instead of loader.Sym content.
|
|
||||||
type dwarfSecInfo2 struct {
|
|
||||||
syms []*sym.Symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dsi *dwarfSecInfo2) secSym() *sym.Symbol {
|
|
||||||
if len(dsi.syms) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return dsi.syms[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dsi *dwarfSecInfo2) subSyms() []*sym.Symbol {
|
|
||||||
if len(dsi.syms) == 0 {
|
|
||||||
return []*sym.Symbol{}
|
|
||||||
}
|
|
||||||
return dsi.syms[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
var dwarfp []dwarfSecInfo2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Elf.
|
* Elf.
|
||||||
*/
|
*/
|
||||||
|
@ -15,12 +15,6 @@ type unresolvedSymKey struct {
|
|||||||
to loader.Sym // Unresolved symbol referenced by "from"
|
to loader.Sym // Unresolved symbol referenced by "from"
|
||||||
}
|
}
|
||||||
|
|
||||||
type unresolvedSymKey2 struct {
|
|
||||||
from *sym.Symbol // Symbol that referenced unresolved "to"
|
|
||||||
to *sym.Symbol // Unresolved symbol referenced by "from"
|
|
||||||
}
|
|
||||||
|
|
||||||
type lookupFn func(name string, version int) *sym.Symbol
|
|
||||||
type symNameFn func(s loader.Sym) string
|
type symNameFn func(s loader.Sym) string
|
||||||
|
|
||||||
// ErrorReporter is used to make error reporting thread safe.
|
// ErrorReporter is used to make error reporting thread safe.
|
||||||
@ -28,9 +22,7 @@ type ErrorReporter struct {
|
|||||||
loader.ErrorReporter
|
loader.ErrorReporter
|
||||||
unresOnce sync.Once
|
unresOnce sync.Once
|
||||||
unresSyms map[unresolvedSymKey]bool
|
unresSyms map[unresolvedSymKey]bool
|
||||||
unresSyms2 map[unresolvedSymKey2]bool
|
|
||||||
unresMutex sync.Mutex
|
unresMutex sync.Mutex
|
||||||
lookup lookupFn
|
|
||||||
SymName symNameFn
|
SymName symNameFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,40 +63,3 @@ func (reporter *ErrorReporter) errorUnresolved(ldr *loader.Loader, s, rs loader.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// errorUnresolved2 prints unresolved symbol error for r.Sym that is referenced from s.
|
|
||||||
func (reporter *ErrorReporter) errorUnresolved2(s *sym.Symbol, r *sym.Reloc) {
|
|
||||||
reporter.unresOnce.Do(func() { reporter.unresSyms2 = make(map[unresolvedSymKey2]bool) })
|
|
||||||
|
|
||||||
k := unresolvedSymKey2{from: s, to: r.Sym}
|
|
||||||
reporter.unresMutex.Lock()
|
|
||||||
defer reporter.unresMutex.Unlock()
|
|
||||||
if !reporter.unresSyms2[k] {
|
|
||||||
reporter.unresSyms2[k] = true
|
|
||||||
|
|
||||||
// Try to find symbol under another ABI.
|
|
||||||
var reqABI, haveABI obj.ABI
|
|
||||||
haveABI = ^obj.ABI(0)
|
|
||||||
reqABI, ok := sym.VersionToABI(int(r.Sym.Version))
|
|
||||||
if ok {
|
|
||||||
for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
|
|
||||||
v := sym.ABIToVersion(abi)
|
|
||||||
if v == -1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if rs := reporter.lookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx && rs.Type != sym.SXREF {
|
|
||||||
haveABI = abi
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Give a special error message for main symbol (see #24809).
|
|
||||||
if r.Sym.Name == "main.main" {
|
|
||||||
Errorf(s, "function main is undeclared in the main package")
|
|
||||||
} else if haveABI != ^obj.ABI(0) {
|
|
||||||
Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", r.Sym.Name, reqABI, haveABI)
|
|
||||||
} else {
|
|
||||||
Errorf(s, "relocation target %s not defined", r.Sym.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -27,17 +27,6 @@ func expandpkg(t0 string, pkg string) string {
|
|||||||
return strings.Replace(t0, `"".`, pkg+".", -1)
|
return strings.Replace(t0, `"".`, pkg+".", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveABIAlias(s *sym.Symbol) *sym.Symbol {
|
|
||||||
if s.Type != sym.SABIALIAS {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
target := s.R[0].Sym
|
|
||||||
if target.Type == sym.SABIALIAS {
|
|
||||||
panic(fmt.Sprintf("ABI alias %s references another ABI alias %s", s, target))
|
|
||||||
}
|
|
||||||
return target
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// generate debugging section in binary.
|
// generate debugging section in binary.
|
||||||
// once the dust settles, try to move some code to
|
// once the dust settles, try to move some code to
|
||||||
|
@ -94,38 +94,10 @@ import (
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
type LookupFn func(name string, version int) *sym.Symbol
|
|
||||||
|
|
||||||
// ArchSyms holds a number of architecture specific symbols used during
|
// ArchSyms holds a number of architecture specific symbols used during
|
||||||
// relocation. Rather than allowing them universal access to all symbols,
|
// relocation. Rather than allowing them universal access to all symbols,
|
||||||
// we keep a subset for relocation application.
|
// we keep a subset for relocation application.
|
||||||
type ArchSyms struct {
|
type ArchSyms struct {
|
||||||
TOC *sym.Symbol
|
|
||||||
DotTOC []*sym.Symbol // for each version
|
|
||||||
|
|
||||||
GOT *sym.Symbol
|
|
||||||
PLT *sym.Symbol
|
|
||||||
GOTPLT *sym.Symbol
|
|
||||||
|
|
||||||
Tlsg *sym.Symbol
|
|
||||||
Tlsoffset int
|
|
||||||
|
|
||||||
Dynamic *sym.Symbol
|
|
||||||
DynSym *sym.Symbol
|
|
||||||
DynStr *sym.Symbol
|
|
||||||
|
|
||||||
// Elf specific
|
|
||||||
Rel *sym.Symbol
|
|
||||||
Rela *sym.Symbol
|
|
||||||
RelPLT *sym.Symbol
|
|
||||||
RelaPLT *sym.Symbol
|
|
||||||
|
|
||||||
// Darwin symbols
|
|
||||||
LinkEditGOT *sym.Symbol
|
|
||||||
LinkEditPLT *sym.Symbol
|
|
||||||
|
|
||||||
// ----- loader.Sym equivalents -----
|
|
||||||
|
|
||||||
Rel2 loader.Sym
|
Rel2 loader.Sym
|
||||||
Rela2 loader.Sym
|
Rela2 loader.Sym
|
||||||
RelPLT2 loader.Sym
|
RelPLT2 loader.Sym
|
||||||
@ -141,7 +113,8 @@ type ArchSyms struct {
|
|||||||
PLT2 loader.Sym
|
PLT2 loader.Sym
|
||||||
GOTPLT2 loader.Sym
|
GOTPLT2 loader.Sym
|
||||||
|
|
||||||
Tlsg2 loader.Sym
|
Tlsg2 loader.Sym
|
||||||
|
Tlsoffset int
|
||||||
|
|
||||||
Dynamic2 loader.Sym
|
Dynamic2 loader.Sym
|
||||||
DynSym2 loader.Sym
|
DynSym2 loader.Sym
|
||||||
@ -151,43 +124,30 @@ type ArchSyms struct {
|
|||||||
const BeforeLoadlibFull = 1
|
const BeforeLoadlibFull = 1
|
||||||
const AfterLoadlibFull = 2
|
const AfterLoadlibFull = 2
|
||||||
|
|
||||||
// mkArchSym is a helper for setArchSyms, invoked once before loadlibfull
|
// mkArchSym is a helper for setArchSyms, to set up a special symbol.
|
||||||
// and once after. On the first call it creates a loader.Sym with the
|
func (ctxt *Link) mkArchSym(name string, ver int, ls *loader.Sym) {
|
||||||
// specified name, and on the second call a corresponding sym.Symbol.
|
*ls = ctxt.loader.LookupOrCreateSym(name, ver)
|
||||||
func (ctxt *Link) mkArchSym(which int, name string, ver int, ls *loader.Sym, ss **sym.Symbol) {
|
|
||||||
if which == BeforeLoadlibFull {
|
|
||||||
*ls = ctxt.loader.LookupOrCreateSym(name, ver)
|
|
||||||
} else {
|
|
||||||
*ss = ctxt.loader.Syms[*ls]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkArchVecSym is similar to setArchSyms, but operates on elements within
|
// mkArchVecSym is similar to setArchSyms, but operates on elements within
|
||||||
// a slice, where each element corresponds to some symbol version.
|
// a slice, where each element corresponds to some symbol version.
|
||||||
func (ctxt *Link) mkArchSymVec(which int, name string, ver int, ls []loader.Sym, ss []*sym.Symbol) {
|
func (ctxt *Link) mkArchSymVec(name string, ver int, ls []loader.Sym) {
|
||||||
if which == BeforeLoadlibFull {
|
ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver)
|
||||||
ls[ver] = ctxt.loader.LookupOrCreateSym(name, ver)
|
|
||||||
} else if ls[ver] != 0 {
|
|
||||||
ss[ver] = ctxt.loader.Syms[ls[ver]]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setArchSyms sets up the ArchSyms structure, and must be called before
|
// setArchSyms sets up the ArchSyms structure, and must be called before
|
||||||
// relocations are applied. This function is invoked twice, once prior
|
// relocations are applied. This function is invoked twice, once prior
|
||||||
// to loadlibfull(), and once after the work of loadlibfull is complete.
|
// to loadlibfull(), and once after the work of loadlibfull is complete.
|
||||||
func (ctxt *Link) setArchSyms(which int) {
|
func (ctxt *Link) setArchSyms() {
|
||||||
if which != BeforeLoadlibFull && which != AfterLoadlibFull {
|
ctxt.mkArchSym(".got", 0, &ctxt.GOT2)
|
||||||
panic("internal error")
|
ctxt.mkArchSym(".plt", 0, &ctxt.PLT2)
|
||||||
}
|
ctxt.mkArchSym(".got.plt", 0, &ctxt.GOTPLT2)
|
||||||
ctxt.mkArchSym(which, ".got", 0, &ctxt.GOT2, &ctxt.GOT)
|
ctxt.mkArchSym(".dynamic", 0, &ctxt.Dynamic2)
|
||||||
ctxt.mkArchSym(which, ".plt", 0, &ctxt.PLT2, &ctxt.PLT)
|
ctxt.mkArchSym(".dynsym", 0, &ctxt.DynSym2)
|
||||||
ctxt.mkArchSym(which, ".got.plt", 0, &ctxt.GOTPLT2, &ctxt.GOTPLT)
|
ctxt.mkArchSym(".dynstr", 0, &ctxt.DynStr2)
|
||||||
ctxt.mkArchSym(which, ".dynamic", 0, &ctxt.Dynamic2, &ctxt.Dynamic)
|
|
||||||
ctxt.mkArchSym(which, ".dynsym", 0, &ctxt.DynSym2, &ctxt.DynSym)
|
|
||||||
ctxt.mkArchSym(which, ".dynstr", 0, &ctxt.DynStr2, &ctxt.DynStr)
|
|
||||||
|
|
||||||
if ctxt.IsPPC64() {
|
if ctxt.IsPPC64() {
|
||||||
ctxt.mkArchSym(which, "TOC", 0, &ctxt.TOC2, &ctxt.TOC)
|
ctxt.mkArchSym("TOC", 0, &ctxt.TOC2)
|
||||||
|
|
||||||
// NB: note the +2 below for DotTOC2 compared to the +1 for
|
// NB: note the +2 below for DotTOC2 compared to the +1 for
|
||||||
// DocTOC. This is because loadlibfull() creates an additional
|
// DocTOC. This is because loadlibfull() creates an additional
|
||||||
@ -195,27 +155,23 @@ func (ctxt *Link) setArchSyms(which int) {
|
|||||||
// *sym.Symbol symbols. Symbols that are assigned this final
|
// *sym.Symbol symbols. Symbols that are assigned this final
|
||||||
// version are not going to have TOC references, so it should
|
// version are not going to have TOC references, so it should
|
||||||
// be ok for them to inherit an invalid .TOC. symbol.
|
// be ok for them to inherit an invalid .TOC. symbol.
|
||||||
if which == BeforeLoadlibFull {
|
ctxt.DotTOC2 = make([]loader.Sym, ctxt.Syms.MaxVersion()+2)
|
||||||
ctxt.DotTOC2 = make([]loader.Sym, ctxt.Syms.MaxVersion()+2)
|
|
||||||
} else {
|
|
||||||
ctxt.DotTOC = make([]*sym.Symbol, ctxt.Syms.MaxVersion()+1)
|
|
||||||
}
|
|
||||||
for i := 0; i <= ctxt.Syms.MaxVersion(); i++ {
|
for i := 0; i <= ctxt.Syms.MaxVersion(); i++ {
|
||||||
if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
|
if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ctxt.mkArchSymVec(which, ".TOC.", i, ctxt.DotTOC2, ctxt.DotTOC)
|
ctxt.mkArchSymVec(".TOC.", i, ctxt.DotTOC2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ctxt.IsElf() {
|
if ctxt.IsElf() {
|
||||||
ctxt.mkArchSym(which, ".rel", 0, &ctxt.Rel2, &ctxt.Rel)
|
ctxt.mkArchSym(".rel", 0, &ctxt.Rel2)
|
||||||
ctxt.mkArchSym(which, ".rela", 0, &ctxt.Rela2, &ctxt.Rela)
|
ctxt.mkArchSym(".rela", 0, &ctxt.Rela2)
|
||||||
ctxt.mkArchSym(which, ".rel.plt", 0, &ctxt.RelPLT2, &ctxt.RelPLT)
|
ctxt.mkArchSym(".rel.plt", 0, &ctxt.RelPLT2)
|
||||||
ctxt.mkArchSym(which, ".rela.plt", 0, &ctxt.RelaPLT2, &ctxt.RelaPLT)
|
ctxt.mkArchSym(".rela.plt", 0, &ctxt.RelaPLT2)
|
||||||
}
|
}
|
||||||
if ctxt.IsDarwin() {
|
if ctxt.IsDarwin() {
|
||||||
ctxt.mkArchSym(which, ".linkedit.got", 0, &ctxt.LinkEditGOT2, &ctxt.LinkEditGOT)
|
ctxt.mkArchSym(".linkedit.got", 0, &ctxt.LinkEditGOT2)
|
||||||
ctxt.mkArchSym(which, ".linkedit.plt", 0, &ctxt.LinkEditPLT2, &ctxt.LinkEditPLT)
|
ctxt.mkArchSym(".linkedit.plt", 0, &ctxt.LinkEditPLT2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +273,6 @@ func (ctxt *Link) CanUsePlugins() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dynexp []*sym.Symbol
|
|
||||||
dynlib []string
|
dynlib []string
|
||||||
ldflag []string
|
ldflag []string
|
||||||
havedynamic int
|
havedynamic int
|
||||||
@ -636,15 +591,6 @@ func (ctxt *Link) loadlib() {
|
|||||||
strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
|
strictDupMsgCount = ctxt.loader.NStrictDupMsgs()
|
||||||
}
|
}
|
||||||
|
|
||||||
// genSymsForDynexp constructs a *sym.Symbol version of ctxt.dynexp,
|
|
||||||
// writing to the global variable 'dynexp'.
|
|
||||||
func genSymsForDynexp(ctxt *Link) {
|
|
||||||
dynexp = make([]*sym.Symbol, len(ctxt.dynexp2))
|
|
||||||
for i, s := range ctxt.dynexp2 {
|
|
||||||
dynexp[i] = ctxt.loader.Syms[s]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setupdynexp constructs ctxt.dynexp, a list of loader.Sym.
|
// setupdynexp constructs ctxt.dynexp, a list of loader.Sym.
|
||||||
func setupdynexp(ctxt *Link) {
|
func setupdynexp(ctxt *Link) {
|
||||||
dynexpMap := ctxt.cgo_export_dynamic
|
dynexpMap := ctxt.cgo_export_dynamic
|
||||||
@ -2493,164 +2439,6 @@ const (
|
|||||||
DeletedAutoSym = 'x'
|
DeletedAutoSym = 'x'
|
||||||
)
|
)
|
||||||
|
|
||||||
func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64)) {
|
|
||||||
// These symbols won't show up in the first loop below because we
|
|
||||||
// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
|
|
||||||
s := ctxt.Syms.Lookup("runtime.text", 0)
|
|
||||||
if s.Type == sym.STEXT {
|
|
||||||
// We've already included this symbol in ctxt.Textp
|
|
||||||
// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
|
|
||||||
// on AIX with external linker.
|
|
||||||
// See data.go:/textaddress
|
|
||||||
if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
|
|
||||||
put(ctxt, s, s.Name, TextSym, s.Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
|
||||||
|
|
||||||
// Generate base addresses for all text sections if there are multiple
|
|
||||||
for _, sect := range Segtext.Sections {
|
|
||||||
if n == 0 {
|
|
||||||
n++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if sect.Name != ".text" || (ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
|
|
||||||
// On AIX, runtime.text.X are symbols already in the symtab.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
s = ctxt.Syms.ROLookup(fmt.Sprintf("runtime.text.%d", n), 0)
|
|
||||||
if s == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if s.Type == sym.STEXT {
|
|
||||||
put(ctxt, s, s.Name, TextSym, s.Value)
|
|
||||||
}
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup("runtime.etext", 0)
|
|
||||||
if s.Type == sym.STEXT {
|
|
||||||
// We've already included this symbol in ctxt.Textp
|
|
||||||
// if ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin or
|
|
||||||
// on AIX with external linker.
|
|
||||||
// See data.go:/textaddress
|
|
||||||
if !(ctxt.DynlinkingGo() && ctxt.HeadType == objabi.Hdarwin) && !(ctxt.HeadType == objabi.Haix && ctxt.LinkMode == LinkExternal) {
|
|
||||||
put(ctxt, s, s.Name, TextSym, s.Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldBeInSymbolTable := func(s *sym.Symbol) bool {
|
|
||||||
if s.Attr.NotInSymbolTable() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if ctxt.HeadType == objabi.Haix && s.Name == ".go.buildinfo" {
|
|
||||||
// On AIX, .go.buildinfo must be in the symbol table as
|
|
||||||
// it has relocations.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (s.Name == "" || s.Name[0] == '.') && !s.IsFileLocal() && s.Name != ".rathole" && s.Name != ".TOC." {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range ctxt.loader.Syms {
|
|
||||||
if s == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !shouldBeInSymbolTable(s) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch s.Type {
|
|
||||||
case sym.SCONST,
|
|
||||||
sym.SRODATA,
|
|
||||||
sym.SSYMTAB,
|
|
||||||
sym.SPCLNTAB,
|
|
||||||
sym.SINITARR,
|
|
||||||
sym.SDATA,
|
|
||||||
sym.SNOPTRDATA,
|
|
||||||
sym.SELFROSECT,
|
|
||||||
sym.SMACHOGOT,
|
|
||||||
sym.STYPE,
|
|
||||||
sym.SSTRING,
|
|
||||||
sym.SGOSTRING,
|
|
||||||
sym.SGOFUNC,
|
|
||||||
sym.SGCBITS,
|
|
||||||
sym.STYPERELRO,
|
|
||||||
sym.SSTRINGRELRO,
|
|
||||||
sym.SGOSTRINGRELRO,
|
|
||||||
sym.SGOFUNCRELRO,
|
|
||||||
sym.SGCBITSRELRO,
|
|
||||||
sym.SRODATARELRO,
|
|
||||||
sym.STYPELINK,
|
|
||||||
sym.SITABLINK,
|
|
||||||
sym.SWINDOWS:
|
|
||||||
if !s.Attr.Reachable() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
put(ctxt, s, s.Name, DataSym, Symaddr(s))
|
|
||||||
|
|
||||||
case sym.SBSS, sym.SNOPTRBSS, sym.SLIBFUZZER_EXTRA_COUNTER:
|
|
||||||
if !s.Attr.Reachable() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(s.P) > 0 {
|
|
||||||
Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(s.P), s.Type, s.Attr.Special())
|
|
||||||
}
|
|
||||||
put(ctxt, s, s.Name, BSSSym, Symaddr(s))
|
|
||||||
|
|
||||||
case sym.SUNDEFEXT:
|
|
||||||
if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF {
|
|
||||||
put(ctxt, s, s.Name, UndefinedSym, s.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
case sym.SHOSTOBJ:
|
|
||||||
if !s.Attr.Reachable() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
|
|
||||||
put(ctxt, s, s.Name, UndefinedSym, s.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
case sym.SDYNIMPORT:
|
|
||||||
if !s.Attr.Reachable() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
put(ctxt, s, s.Extname(), UndefinedSym, 0)
|
|
||||||
|
|
||||||
case sym.STLSBSS:
|
|
||||||
if ctxt.LinkMode == LinkExternal {
|
|
||||||
put(ctxt, s, s.Name, TLSSym, Symaddr(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range ctxt.Textp {
|
|
||||||
put(ctxt, s, s.Name, TextSym, s.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctxt.Debugvlog != 0 || *flagN {
|
|
||||||
ctxt.Logf("symsize = %d\n", uint32(Symsize))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Symaddr(s *sym.Symbol) int64 {
|
|
||||||
if !s.Attr.Reachable() {
|
|
||||||
Errorf(s, "unreachable symbol in symaddr")
|
|
||||||
}
|
|
||||||
return s.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
|
|
||||||
s := ctxt.Syms.Lookup(p, 0)
|
|
||||||
s.Type = t
|
|
||||||
s.Value = v
|
|
||||||
s.Attr |= sym.AttrReachable
|
|
||||||
s.Attr |= sym.AttrSpecial
|
|
||||||
s.Attr |= sym.AttrLocal
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctxt *Link) xdefine2(p string, t sym.SymKind, v int64) {
|
func (ctxt *Link) xdefine2(p string, t sym.SymKind, v int64) {
|
||||||
ldr := ctxt.loader
|
ldr := ctxt.loader
|
||||||
s := ldr.CreateSymForUpdate(p, 0)
|
s := ldr.CreateSymForUpdate(p, 0)
|
||||||
@ -2765,111 +2553,6 @@ func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library
|
|||||||
*order = append(*order, lib)
|
*order = append(*order, lib)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addToTextp populates the context Textp slice.
|
|
||||||
func addToTextp(ctxt *Link) {
|
|
||||||
// Set up ctxt.Textp, based on ctxt.Textp2.
|
|
||||||
textp := make([]*sym.Symbol, 0, len(ctxt.Textp2))
|
|
||||||
haveshlibs := len(ctxt.Shlibs) > 0
|
|
||||||
for _, tsym := range ctxt.Textp2 {
|
|
||||||
sp := ctxt.loader.Syms[tsym]
|
|
||||||
if sp == nil || !ctxt.loader.AttrReachable(tsym) {
|
|
||||||
panic("should never happen")
|
|
||||||
}
|
|
||||||
if haveshlibs && sp.Type == sym.SDYNIMPORT {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
textp = append(textp, sp)
|
|
||||||
}
|
|
||||||
ctxt.Textp = textp
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctxt *Link) loadlibfull(symGroupType []sym.SymKind, needReloc, needExtReloc bool) {
|
|
||||||
|
|
||||||
// Load full symbol contents, resolve indexed references.
|
|
||||||
ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms, needReloc, needExtReloc)
|
|
||||||
|
|
||||||
// Convert ctxt.Moduledata2 to ctxt.Moduledata, etc
|
|
||||||
if ctxt.Moduledata2 != 0 {
|
|
||||||
ctxt.Moduledata = ctxt.loader.Syms[ctxt.Moduledata2]
|
|
||||||
ctxt.Tlsg = ctxt.loader.Syms[ctxt.Tlsg2]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pull the symbols out.
|
|
||||||
ctxt.loader.ExtractSymbols(ctxt.Syms)
|
|
||||||
ctxt.lookup = ctxt.Syms.ROLookup
|
|
||||||
|
|
||||||
// Recreate dynexp using *sym.Symbol instead of loader.Sym
|
|
||||||
genSymsForDynexp(ctxt)
|
|
||||||
|
|
||||||
// Drop the cgodata reference.
|
|
||||||
ctxt.cgodata = nil
|
|
||||||
|
|
||||||
addToTextp(ctxt)
|
|
||||||
|
|
||||||
// Set special global symbols.
|
|
||||||
ctxt.setArchSyms(AfterLoadlibFull)
|
|
||||||
|
|
||||||
// Populate dwarfp from dwarfp2. If we see a symbol index
|
|
||||||
// whose loader.Syms entry is nil, something went wrong.
|
|
||||||
for _, si := range dwarfp2 {
|
|
||||||
syms := make([]*sym.Symbol, 0, len(si.syms))
|
|
||||||
for _, symIdx := range si.syms {
|
|
||||||
s := ctxt.loader.Syms[symIdx]
|
|
||||||
if s == nil {
|
|
||||||
panic(fmt.Sprintf("nil sym for dwarfp2 element %d", symIdx))
|
|
||||||
}
|
|
||||||
s.Attr |= sym.AttrLocal
|
|
||||||
syms = append(syms, s)
|
|
||||||
}
|
|
||||||
dwarfp = append(dwarfp, dwarfSecInfo2{syms: syms})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate datap from datap2
|
|
||||||
ctxt.datap = make([]*sym.Symbol, len(ctxt.datap2))
|
|
||||||
for i, symIdx := range ctxt.datap2 {
|
|
||||||
s := ctxt.loader.Syms[symIdx]
|
|
||||||
if s == nil {
|
|
||||||
panic(fmt.Sprintf("nil sym for datap2 element %d", symIdx))
|
|
||||||
}
|
|
||||||
ctxt.datap[i] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the sym.Section 'Sym' fields based on their 'Sym2'
|
|
||||||
// fields.
|
|
||||||
allSegments := []*sym.Segment{&Segtext, &Segrodata, &Segrelrodata, &Segdata, &Segdwarf}
|
|
||||||
for _, seg := range allSegments {
|
|
||||||
for _, sect := range seg.Sections {
|
|
||||||
if sect.Sym2 != 0 {
|
|
||||||
s := ctxt.loader.Syms[sect.Sym2]
|
|
||||||
if s == nil {
|
|
||||||
panic(fmt.Sprintf("nil sym for sect %s sym %d", sect.Name, sect.Sym2))
|
|
||||||
}
|
|
||||||
sect.Sym = s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For now, overwrite symbol type with its "group" type, as dodata
|
|
||||||
// expected. Once we converted dodata, this will probably not be
|
|
||||||
// needed.
|
|
||||||
for i, t := range symGroupType {
|
|
||||||
if t != sym.Sxxx {
|
|
||||||
s := ctxt.loader.Syms[i]
|
|
||||||
if s == nil {
|
|
||||||
continue // in dwarfcompress we drop compressed DWARF symbols
|
|
||||||
}
|
|
||||||
s.Type = t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
symGroupType = nil
|
|
||||||
|
|
||||||
if ctxt.Debugvlog > 1 {
|
|
||||||
// loadlibfull is likely a good place to dump.
|
|
||||||
// Only dump under -v=2 and above.
|
|
||||||
ctxt.dumpsyms()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ElfSymForReloc2(ctxt *Link, s loader.Sym) int32 {
|
func ElfSymForReloc2(ctxt *Link, s loader.Sym) int32 {
|
||||||
// If putelfsym created a local version of this symbol, use that in all
|
// If putelfsym created a local version of this symbol, use that in all
|
||||||
// relocations.
|
// relocations.
|
||||||
@ -2880,22 +2563,3 @@ func ElfSymForReloc2(ctxt *Link, s loader.Sym) int32 {
|
|||||||
return ctxt.loader.SymElfSym(s)
|
return ctxt.loader.SymElfSym(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func symSub(ctxt *Link, s *sym.Symbol) *sym.Symbol {
|
|
||||||
if lsub := ctxt.loader.SubSym(loader.Sym(s.SymIdx)); lsub != 0 {
|
|
||||||
return ctxt.loader.Syms[lsub]
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctxt *Link) dumpsyms() {
|
|
||||||
for _, s := range ctxt.loader.Syms {
|
|
||||||
if s == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Printf("%s %s reachable=%v onlist=%v outer=%v sub=%v\n", s, s.Type, s.Attr.Reachable(), s.Attr.OnList(), s.Outer, symSub(ctxt, s))
|
|
||||||
for i := range s.R {
|
|
||||||
fmt.Println("\t", s.R[i].Type, s.R[i].Sym)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -70,10 +70,8 @@ type Link struct {
|
|||||||
Library []*sym.Library
|
Library []*sym.Library
|
||||||
LibraryByPkg map[string]*sym.Library
|
LibraryByPkg map[string]*sym.Library
|
||||||
Shlibs []Shlib
|
Shlibs []Shlib
|
||||||
Textp []*sym.Symbol
|
|
||||||
Textp2 []loader.Sym
|
Textp2 []loader.Sym
|
||||||
NumFilesyms int
|
NumFilesyms int
|
||||||
Moduledata *sym.Symbol
|
|
||||||
Moduledata2 loader.Sym
|
Moduledata2 loader.Sym
|
||||||
|
|
||||||
PackageFile map[string]string
|
PackageFile map[string]string
|
||||||
@ -90,7 +88,6 @@ type Link struct {
|
|||||||
cgo_export_static map[string]bool
|
cgo_export_static map[string]bool
|
||||||
cgo_export_dynamic map[string]bool
|
cgo_export_dynamic map[string]bool
|
||||||
|
|
||||||
datap []*sym.Symbol
|
|
||||||
datap2 []loader.Sym
|
datap2 []loader.Sym
|
||||||
dynexp2 []loader.Sym
|
dynexp2 []loader.Sym
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ func Main(arch *sys.Arch, theArch Arch) {
|
|||||||
ctxt.textbuildid()
|
ctxt.textbuildid()
|
||||||
bench.Start("addexport")
|
bench.Start("addexport")
|
||||||
setupdynexp(ctxt)
|
setupdynexp(ctxt)
|
||||||
ctxt.setArchSyms(BeforeLoadlibFull)
|
ctxt.setArchSyms()
|
||||||
ctxt.addexport()
|
ctxt.addexport()
|
||||||
bench.Start("Gentext")
|
bench.Start("Gentext")
|
||||||
thearch.Gentext2(ctxt, ctxt.loader) // trampolines, call stubs, etc.
|
thearch.Gentext2(ctxt, ctxt.loader) // trampolines, call stubs, etc.
|
||||||
|
@ -6,7 +6,6 @@ package ld
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/link/internal/loader"
|
"cmd/link/internal/loader"
|
||||||
"cmd/link/internal/sym"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -57,10 +56,10 @@ func afterErrorAction() {
|
|||||||
//
|
//
|
||||||
// Logging an error means that on exit cmd/link will delete any
|
// Logging an error means that on exit cmd/link will delete any
|
||||||
// output file and return a non-zero error code.
|
// output file and return a non-zero error code.
|
||||||
func Errorf(s *sym.Symbol, format string, args ...interface{}) {
|
//
|
||||||
if s != nil {
|
// TODO: remove. Use ctxt.Errof instead.
|
||||||
format = s.Name + ": " + format
|
// All remaining calls use nil as first arg.
|
||||||
}
|
func Errorf(dummy *int, format string, args ...interface{}) {
|
||||||
format += "\n"
|
format += "\n"
|
||||||
fmt.Fprintf(os.Stderr, format, args...)
|
fmt.Fprintf(os.Stderr, format, args...)
|
||||||
afterErrorAction()
|
afterErrorAction()
|
||||||
@ -113,10 +112,3 @@ func contains(s []string, v string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// implements sort.Interface, for sorting symbols by name.
|
|
||||||
type byName []*sym.Symbol
|
|
||||||
|
|
||||||
func (s byName) Len() int { return len(s) }
|
|
||||||
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
func (s byName) Less(i, j int) bool { return s[i].Name < s[j].Name }
|
|
||||||
|
@ -202,13 +202,6 @@ func growBitmap(reqLen int, b Bitmap) Bitmap {
|
|||||||
// extending the external symbol index space range. The host object
|
// extending the external symbol index space range. The host object
|
||||||
// loader stores symbol payloads in loader.payloads using SymbolBuilder.
|
// loader stores symbol payloads in loader.payloads using SymbolBuilder.
|
||||||
//
|
//
|
||||||
// - For now, in loader.LoadFull we convert all symbols (Go + external)
|
|
||||||
// to sym.Symbols.
|
|
||||||
//
|
|
||||||
// - At some point (when the wayfront is pushed through all of the
|
|
||||||
// linker), all external symbols will be payload-based, and we can
|
|
||||||
// get rid of the loader.Syms array.
|
|
||||||
//
|
|
||||||
// - Each symbol gets a unique global index. For duplicated and
|
// - Each symbol gets a unique global index. For duplicated and
|
||||||
// overwriting/overwritten symbols, the second (or later) appearance
|
// overwriting/overwritten symbols, the second (or later) appearance
|
||||||
// of the symbol gets the same global index as the first appearance.
|
// of the symbol gets the same global index as the first appearance.
|
||||||
@ -240,9 +233,6 @@ type Loader struct {
|
|||||||
|
|
||||||
objByPkg map[string]*oReader // map package path to its Go object reader
|
objByPkg map[string]*oReader // map package path to its Go object reader
|
||||||
|
|
||||||
Syms []*sym.Symbol // indexed symbols. XXX we still make sym.Symbol for now.
|
|
||||||
symBatch []sym.Symbol // batch of symbols.
|
|
||||||
|
|
||||||
anonVersion int // most recently assigned ext static sym pseudo-version
|
anonVersion int // most recently assigned ext static sym pseudo-version
|
||||||
|
|
||||||
// Bitmaps and other side structures used to store data used to store
|
// Bitmaps and other side structures used to store data used to store
|
||||||
@ -292,9 +282,6 @@ type Loader struct {
|
|||||||
// the symbol that triggered the marking of symbol K as live.
|
// the symbol that triggered the marking of symbol K as live.
|
||||||
Reachparent []Sym
|
Reachparent []Sym
|
||||||
|
|
||||||
relocBatch []sym.Reloc // for bulk allocation of relocations
|
|
||||||
relocExtBatch []sym.RelocExt // for bulk allocation of relocations
|
|
||||||
|
|
||||||
flags uint32
|
flags uint32
|
||||||
|
|
||||||
strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
|
strictDupMsgs int // number of strict-dup warning/errors, when FlagStrictDups is enabled
|
||||||
@ -302,8 +289,6 @@ type Loader struct {
|
|||||||
elfsetstring elfsetstringFunc
|
elfsetstring elfsetstringFunc
|
||||||
|
|
||||||
errorReporter *ErrorReporter
|
errorReporter *ErrorReporter
|
||||||
|
|
||||||
SymLookup func(name string, ver int) *sym.Symbol
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -562,17 +547,6 @@ func (ms *extSymPayload) Grow(siz int64) {
|
|||||||
ms.data = ms.data[:siz]
|
ms.data = ms.data[:siz]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure Syms slice has enough space.
|
|
||||||
func (l *Loader) growSyms(i int) {
|
|
||||||
n := len(l.Syms)
|
|
||||||
if n > i {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
l.Syms = append(l.Syms, make([]*sym.Symbol, i+1-n)...)
|
|
||||||
l.growValues(int(i) + 1)
|
|
||||||
l.growAttrBitmaps(int(i) + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a local index to a global index.
|
// Convert a local index to a global index.
|
||||||
func (l *Loader) toGlobal(r *oReader, i uint32) Sym {
|
func (l *Loader) toGlobal(r *oReader, i uint32) Sym {
|
||||||
return r.syms[i]
|
return r.syms[i]
|
||||||
@ -2078,163 +2052,6 @@ func (l *Loader) preprocess(arch *sys.Arch, s Sym, name string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load full contents.
|
|
||||||
func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc, needExtReloc bool) {
|
|
||||||
// create all Symbols first.
|
|
||||||
l.growSyms(l.NSym())
|
|
||||||
l.growSects(l.NSym())
|
|
||||||
|
|
||||||
if needReloc && len(l.extRelocs) != 0 {
|
|
||||||
// If needReloc is true, we are going to convert the loader's
|
|
||||||
// "internal" relocations to sym.Relocs. In this case, external
|
|
||||||
// relocations shouldn't be used.
|
|
||||||
panic("phase error")
|
|
||||||
}
|
|
||||||
|
|
||||||
nr := 0 // total number of sym.Reloc's we'll need
|
|
||||||
for _, o := range l.objs[goObjStart:] {
|
|
||||||
nr += loadObjSyms(l, syms, o.r, needReloc, needExtReloc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a first pass through the external symbols, making
|
|
||||||
// sure that each external symbol has a non-nil entry in
|
|
||||||
// l.Syms (note that relocations and symbol content will
|
|
||||||
// be copied in a later loop).
|
|
||||||
toConvert := make([]Sym, 0, len(l.payloads))
|
|
||||||
for _, i := range l.extReader.syms {
|
|
||||||
if !l.attrReachable.Has(i) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pp := l.getPayload(i)
|
|
||||||
if needReloc {
|
|
||||||
nr += len(pp.relocs)
|
|
||||||
}
|
|
||||||
if needExtReloc && int(i) < len(l.extRelocs) {
|
|
||||||
nr += len(l.extRelocs[i])
|
|
||||||
}
|
|
||||||
// create and install the sym.Symbol here so that l.Syms will
|
|
||||||
// be fully populated when we do relocation processing and
|
|
||||||
// outer/sub processing below. Note that once we do this,
|
|
||||||
// we'll need to get at the payload for a symbol with direct
|
|
||||||
// reference to l.payloads[] as opposed to calling l.getPayload().
|
|
||||||
s := l.allocSym(pp.name, 0)
|
|
||||||
l.installSym(i, s)
|
|
||||||
toConvert = append(toConvert, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate a single large slab of relocations for all live symbols
|
|
||||||
if nr != 0 {
|
|
||||||
l.relocBatch = make([]sym.Reloc, nr)
|
|
||||||
if needExtReloc {
|
|
||||||
l.relocExtBatch = make([]sym.RelocExt, nr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert payload-based external symbols into sym.Symbol-based
|
|
||||||
for _, i := range toConvert {
|
|
||||||
|
|
||||||
// Copy kind/size/value etc.
|
|
||||||
pp := l.payloads[l.extIndex(i)]
|
|
||||||
s := l.Syms[i]
|
|
||||||
s.Version = int16(pp.ver)
|
|
||||||
s.Type = pp.kind
|
|
||||||
s.Size = pp.size
|
|
||||||
|
|
||||||
// Copy relocations
|
|
||||||
if needReloc {
|
|
||||||
batch := l.relocBatch
|
|
||||||
s.R = batch[:len(pp.relocs):len(pp.relocs)]
|
|
||||||
l.relocBatch = batch[len(pp.relocs):]
|
|
||||||
relocs := l.Relocs(i)
|
|
||||||
l.convertRelocations(i, &relocs, s, false)
|
|
||||||
}
|
|
||||||
if needExtReloc {
|
|
||||||
l.convertExtRelocs(s, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy data
|
|
||||||
s.P = pp.data
|
|
||||||
|
|
||||||
// Transfer over attributes.
|
|
||||||
l.migrateAttributes(i, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// load contents of defined symbols
|
|
||||||
for _, o := range l.objs[goObjStart:] {
|
|
||||||
loadObjFull(l, o.r, needReloc, needExtReloc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sanity check: we should have consumed all batched allocations.
|
|
||||||
if len(l.relocBatch) != 0 || len(l.relocExtBatch) != 0 {
|
|
||||||
panic("batch allocation mismatch")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: resolution of ABI aliases is now also handled in
|
|
||||||
// loader.convertRelocations, so once the host object loaders move
|
|
||||||
// completely to loader.Sym, we can remove the code below.
|
|
||||||
|
|
||||||
// Resolve ABI aliases for external symbols. This is only
|
|
||||||
// needed for internal cgo linking.
|
|
||||||
if needReloc {
|
|
||||||
for _, i := range l.extReader.syms {
|
|
||||||
if s := l.Syms[i]; s != nil && s.Attr.Reachable() {
|
|
||||||
for ri := range s.R {
|
|
||||||
r := &s.R[ri]
|
|
||||||
if r.Sym != nil && r.Sym.Type == sym.SABIALIAS {
|
|
||||||
r.Sym = r.Sym.R[0].Sym
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free some memory.
|
|
||||||
// At this point we still need basic index mapping, and some fields of
|
|
||||||
// external symbol payloads, but not much else.
|
|
||||||
l.values = nil
|
|
||||||
l.symSects = nil
|
|
||||||
l.outdata = nil
|
|
||||||
l.itablink = nil
|
|
||||||
l.attrOnList = nil
|
|
||||||
l.attrLocal = nil
|
|
||||||
l.attrNotInSymbolTable = nil
|
|
||||||
l.attrVisibilityHidden = nil
|
|
||||||
l.attrDuplicateOK = nil
|
|
||||||
l.attrShared = nil
|
|
||||||
l.attrExternal = nil
|
|
||||||
l.attrReadOnly = nil
|
|
||||||
l.attrTopFrame = nil
|
|
||||||
l.attrSpecial = nil
|
|
||||||
l.attrCgoExportDynamic = nil
|
|
||||||
l.attrCgoExportStatic = nil
|
|
||||||
l.outer = nil
|
|
||||||
l.align = nil
|
|
||||||
l.dynimplib = nil
|
|
||||||
l.dynimpvers = nil
|
|
||||||
l.localentry = nil
|
|
||||||
l.extname = nil
|
|
||||||
l.elfType = nil
|
|
||||||
l.plt = nil
|
|
||||||
l.got = nil
|
|
||||||
l.dynid = nil
|
|
||||||
if needExtReloc { // converted to sym.Relocs, drop loader references
|
|
||||||
l.relocVariant = nil
|
|
||||||
l.extRelocs = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop fields that are no longer needed.
|
|
||||||
for _, i := range l.extReader.syms {
|
|
||||||
pp := l.getPayload(i)
|
|
||||||
pp.name = ""
|
|
||||||
pp.auxs = nil
|
|
||||||
pp.data = nil
|
|
||||||
if needExtReloc {
|
|
||||||
pp.relocs = nil
|
|
||||||
pp.reltypes = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolveABIAlias given a symbol returns the ABI alias target of that
|
// ResolveABIAlias given a symbol returns the ABI alias target of that
|
||||||
// symbol. If the sym in question is not an alias, the sym itself is
|
// symbol. If the sym in question is not an alias, the sym itself is
|
||||||
// returned.
|
// returned.
|
||||||
@ -2253,88 +2070,6 @@ func (l *Loader) ResolveABIAlias(s Sym) Sym {
|
|||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractSymbols grabs the symbols out of the loader for work that hasn't been
|
|
||||||
// ported to the new symbol type.
|
|
||||||
func (l *Loader) ExtractSymbols(syms *sym.Symbols) {
|
|
||||||
// Add symbols to the ctxt.Syms lookup table. This explicitly skips things
|
|
||||||
// created via loader.Create (marked with versions less than zero), since
|
|
||||||
// if we tried to add these we'd wind up with collisions. We do, however,
|
|
||||||
// add these symbols to the list of global symbols so that other future
|
|
||||||
// steps (like pclntab generation) can find these symbols if neceassary.
|
|
||||||
// Along the way, update the version from the negative anon version to
|
|
||||||
// something larger than sym.SymVerStatic (needed so that
|
|
||||||
// sym.symbol.IsFileLocal() works properly).
|
|
||||||
anonVerReplacement := syms.IncVersion()
|
|
||||||
for _, s := range l.Syms {
|
|
||||||
if s == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if s.Version < 0 {
|
|
||||||
s.Version = int16(anonVerReplacement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide lookup functions for sym.Symbols.
|
|
||||||
l.SymLookup = func(name string, ver int) *sym.Symbol {
|
|
||||||
i := l.LookupOrCreateSym(name, ver)
|
|
||||||
if s := l.Syms[i]; s != nil {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
s := l.allocSym(name, ver)
|
|
||||||
l.installSym(i, s)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
syms.Lookup = l.SymLookup
|
|
||||||
syms.ROLookup = func(name string, ver int) *sym.Symbol {
|
|
||||||
i := l.Lookup(name, ver)
|
|
||||||
return l.Syms[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocSym allocates a new symbol backing.
|
|
||||||
func (l *Loader) allocSym(name string, version int) *sym.Symbol {
|
|
||||||
batch := l.symBatch
|
|
||||||
if len(batch) == 0 {
|
|
||||||
batch = make([]sym.Symbol, 1000)
|
|
||||||
}
|
|
||||||
s := &batch[0]
|
|
||||||
l.symBatch = batch[1:]
|
|
||||||
|
|
||||||
s.Dynid = -1
|
|
||||||
s.Name = name
|
|
||||||
s.Version = int16(version)
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// installSym sets the underlying sym.Symbol for the specified sym index.
|
|
||||||
func (l *Loader) installSym(i Sym, s *sym.Symbol) {
|
|
||||||
if s == nil {
|
|
||||||
panic("installSym nil symbol")
|
|
||||||
}
|
|
||||||
if l.Syms[i] != nil {
|
|
||||||
panic("sym already present in installSym")
|
|
||||||
}
|
|
||||||
l.Syms[i] = s
|
|
||||||
s.SymIdx = sym.LoaderSym(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
// addNewSym adds a new sym.Symbol to the i-th index in the list of symbols.
|
|
||||||
func (l *Loader) addNewSym(i Sym, name string, ver int, unit *sym.CompilationUnit, t sym.SymKind) *sym.Symbol {
|
|
||||||
s := l.allocSym(name, ver)
|
|
||||||
if s.Type != 0 && s.Type != sym.SXREF {
|
|
||||||
fmt.Println("symbol already processed:", unit.Lib, i, s)
|
|
||||||
panic("symbol already processed")
|
|
||||||
}
|
|
||||||
if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) {
|
|
||||||
t = s.Type
|
|
||||||
}
|
|
||||||
s.Type = t
|
|
||||||
l.growSyms(int(i))
|
|
||||||
l.installSym(i, s)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// TopLevelSym tests a symbol (by name and kind) to determine whether
|
// TopLevelSym tests a symbol (by name and kind) to determine whether
|
||||||
// the symbol first class sym (participating in the link) or is an
|
// the symbol first class sym (participating in the link) or is an
|
||||||
// anonymous aux or sub-symbol containing some sub-part or payload of
|
// anonymous aux or sub-symbol containing some sub-part or payload of
|
||||||
@ -2359,49 +2094,6 @@ func topLevelSym(sname string, skind sym.SymKind) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadObjSyms creates sym.Symbol objects for the live Syms in the
|
|
||||||
// object corresponding to object reader "r". Return value is the
|
|
||||||
// number of sym.Reloc entries required for all the new symbols.
|
|
||||||
func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader, needReloc, needExtReloc bool) int {
|
|
||||||
nr := 0
|
|
||||||
for i, n := uint32(0), uint32(r.NSym()+r.NNonpkgdef()); i < n; i++ {
|
|
||||||
gi := r.syms[i]
|
|
||||||
if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
|
|
||||||
continue // come from a different object
|
|
||||||
}
|
|
||||||
osym := r.Sym(i)
|
|
||||||
name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1)
|
|
||||||
t := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type())]
|
|
||||||
|
|
||||||
// Skip non-dwarf anonymous symbols (e.g. funcdata),
|
|
||||||
// since they will never be turned into sym.Symbols.
|
|
||||||
if !topLevelSym(name, t) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ver := abiToVer(osym.ABI(), r.version)
|
|
||||||
if t == sym.SXREF {
|
|
||||||
log.Fatalf("bad sxref")
|
|
||||||
}
|
|
||||||
if t == 0 {
|
|
||||||
log.Fatalf("missing type for %s in %s", name, r.unit.Lib)
|
|
||||||
}
|
|
||||||
if !l.attrReachable.Has(gi) && name != "runtime.addmoduledata" && name != "runtime.lastmoduledatap" {
|
|
||||||
// No need to load unreachable symbols.
|
|
||||||
// XXX reference to runtime.addmoduledata may be generated later by the linker in plugin mode.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
l.addNewSym(gi, name, ver, r.unit, t)
|
|
||||||
if needReloc {
|
|
||||||
nr += r.NReloc(i)
|
|
||||||
}
|
|
||||||
if needExtReloc && int(gi) < len(l.extRelocs) {
|
|
||||||
nr += len(l.extRelocs[gi])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nr
|
|
||||||
}
|
|
||||||
|
|
||||||
// cloneToExternal takes the existing object file symbol (symIdx)
|
// cloneToExternal takes the existing object file symbol (symIdx)
|
||||||
// and creates a new external symbol payload that is a clone with
|
// and creates a new external symbol payload that is a clone with
|
||||||
// respect to name, version, type, relocations, etc. The idea here
|
// respect to name, version, type, relocations, etc. The idea here
|
||||||
@ -2505,72 +2197,6 @@ func (l *Loader) CopyAttributes(src Sym, dst Sym) {
|
|||||||
l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
|
l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
|
||||||
}
|
}
|
||||||
|
|
||||||
// migrateAttributes copies over all of the attributes of symbol 'src' to
|
|
||||||
// sym.Symbol 'dst'.
|
|
||||||
func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
|
|
||||||
dst.Value = l.SymValue(src)
|
|
||||||
dst.Align = l.SymAlign(src)
|
|
||||||
dst.Sect = l.SymSect(src)
|
|
||||||
|
|
||||||
dst.Attr.Set(sym.AttrReachable, l.AttrReachable(src))
|
|
||||||
dst.Attr.Set(sym.AttrOnList, l.AttrOnList(src))
|
|
||||||
dst.Attr.Set(sym.AttrLocal, l.AttrLocal(src))
|
|
||||||
dst.Attr.Set(sym.AttrNotInSymbolTable, l.AttrNotInSymbolTable(src))
|
|
||||||
dst.Attr.Set(sym.AttrNoSplit, l.IsNoSplit(src))
|
|
||||||
dst.Attr.Set(sym.AttrVisibilityHidden, l.AttrVisibilityHidden(src))
|
|
||||||
dst.Attr.Set(sym.AttrDuplicateOK, l.AttrDuplicateOK(src))
|
|
||||||
dst.Attr.Set(sym.AttrShared, l.AttrShared(src))
|
|
||||||
dst.Attr.Set(sym.AttrExternal, l.AttrExternal(src))
|
|
||||||
dst.Attr.Set(sym.AttrTopFrame, l.AttrTopFrame(src))
|
|
||||||
dst.Attr.Set(sym.AttrSpecial, l.AttrSpecial(src))
|
|
||||||
dst.Attr.Set(sym.AttrCgoExportDynamic, l.AttrCgoExportDynamic(src))
|
|
||||||
dst.Attr.Set(sym.AttrCgoExportStatic, l.AttrCgoExportStatic(src))
|
|
||||||
dst.Attr.Set(sym.AttrReadOnly, l.AttrReadOnly(src))
|
|
||||||
|
|
||||||
// Convert outer relationship
|
|
||||||
if outer, ok := l.outer[src]; ok {
|
|
||||||
dst.Outer = l.Syms[outer]
|
|
||||||
// relocsym's foldSubSymbolOffset requires that we only
|
|
||||||
// have a single level of containment-- enforce here.
|
|
||||||
if l.outer[outer] != 0 {
|
|
||||||
panic("multiply nested outer syms")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sub-symbol attribute. See the comment on the AttrSubSymbol
|
|
||||||
// method for more on this, there is some tricky stuff here.
|
|
||||||
dst.Attr.Set(sym.AttrSubSymbol, l.outer[src] != 0 && l.sub[l.outer[src]] != 0)
|
|
||||||
|
|
||||||
// Copy over dynimplib, dynimpvers, extname.
|
|
||||||
if name, ok := l.extname[src]; ok {
|
|
||||||
dst.SetExtname(name)
|
|
||||||
}
|
|
||||||
if l.SymDynimplib(src) != "" {
|
|
||||||
dst.SetDynimplib(l.SymDynimplib(src))
|
|
||||||
}
|
|
||||||
if l.SymDynimpvers(src) != "" {
|
|
||||||
dst.SetDynimpvers(l.SymDynimpvers(src))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy ELF type if set.
|
|
||||||
if et, ok := l.elfType[src]; ok {
|
|
||||||
dst.SetElfType(et)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy pe objects values if set.
|
|
||||||
if plt, ok := l.plt[src]; ok {
|
|
||||||
dst.SetPlt(plt)
|
|
||||||
}
|
|
||||||
if got, ok := l.got[src]; ok {
|
|
||||||
dst.SetGot(got)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy dynid
|
|
||||||
if dynid, ok := l.dynid[src]; ok {
|
|
||||||
dst.Dynid = dynid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateExtSym creates a new external symbol with the specified name
|
// CreateExtSym creates a new external symbol with the specified name
|
||||||
// without adding it to any lookup tables, returning a Sym index for it.
|
// without adding it to any lookup tables, returning a Sym index for it.
|
||||||
func (l *Loader) CreateExtSym(name string, ver int) Sym {
|
func (l *Loader) CreateExtSym(name string, ver int) Sym {
|
||||||
@ -2581,8 +2207,7 @@ func (l *Loader) CreateExtSym(name string, ver int) Sym {
|
|||||||
// without adding it to any lookup tables, returning a Sym index for it.
|
// without adding it to any lookup tables, returning a Sym index for it.
|
||||||
func (l *Loader) CreateStaticSym(name string) Sym {
|
func (l *Loader) CreateStaticSym(name string) Sym {
|
||||||
// Assign a new unique negative version -- this is to mark the
|
// Assign a new unique negative version -- this is to mark the
|
||||||
// symbol so that it can be skipped when ExtractSymbols is adding
|
// symbol so that it is not included in the name lookup table.
|
||||||
// ext syms to the sym.Symbols hash.
|
|
||||||
l.anonVersion--
|
l.anonVersion--
|
||||||
return l.newExtSym(name, l.anonVersion)
|
return l.newExtSym(name, l.anonVersion)
|
||||||
}
|
}
|
||||||
@ -2594,144 +2219,6 @@ func (l *Loader) FreeSym(i Sym) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadObjFull(l *Loader, r *oReader, needReloc, needExtReloc bool) {
|
|
||||||
for i, n := uint32(0), uint32(r.NSym()+r.NNonpkgdef()); i < n; i++ {
|
|
||||||
// A symbol may be a dup or overwritten. In this case, its
|
|
||||||
// content will actually be provided by a different object
|
|
||||||
// (to which its global index points). Skip those symbols.
|
|
||||||
gi := l.toGlobal(r, i)
|
|
||||||
if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s := l.Syms[gi]
|
|
||||||
if s == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
l.migrateAttributes(gi, s)
|
|
||||||
// Be careful not to overwrite attributes set by the linker.
|
|
||||||
// Don't use the attributes from the object file.
|
|
||||||
|
|
||||||
osym := r.Sym(i)
|
|
||||||
size := osym.Siz()
|
|
||||||
|
|
||||||
// Symbol data
|
|
||||||
s.P = l.OutData(gi)
|
|
||||||
|
|
||||||
// Relocs
|
|
||||||
if needReloc {
|
|
||||||
relocs := l.relocs(r, i)
|
|
||||||
batch := l.relocBatch
|
|
||||||
s.R = batch[:relocs.Count():relocs.Count()]
|
|
||||||
l.relocBatch = batch[relocs.Count():]
|
|
||||||
l.convertRelocations(gi, &relocs, s, false)
|
|
||||||
}
|
|
||||||
if needExtReloc {
|
|
||||||
l.convertExtRelocs(s, gi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aux symbol info
|
|
||||||
auxs := r.Auxs(i)
|
|
||||||
for j := range auxs {
|
|
||||||
a := &auxs[j]
|
|
||||||
switch a.Type() {
|
|
||||||
case goobj2.AuxFuncInfo, goobj2.AuxFuncdata, goobj2.AuxGotype:
|
|
||||||
// already handled
|
|
||||||
case goobj2.AuxDwarfInfo, goobj2.AuxDwarfLoc, goobj2.AuxDwarfRanges, goobj2.AuxDwarfLines:
|
|
||||||
// ignored for now
|
|
||||||
default:
|
|
||||||
panic("unknown aux type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.Size < int64(size) {
|
|
||||||
s.Size = int64(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertRelocations takes a vector of loader.Reloc relocations and
|
|
||||||
// translates them into an equivalent set of sym.Reloc relocations on
|
|
||||||
// the symbol "dst", performing fixups along the way for ABI aliases,
|
|
||||||
// etc. It is assumed that the caller has pre-allocated the dst symbol
|
|
||||||
// relocations slice. If 'strict' is set, then this method will
|
|
||||||
// panic if it finds a relocation targeting a nil symbol.
|
|
||||||
func (l *Loader) convertRelocations(symIdx Sym, src *Relocs, dst *sym.Symbol, strict bool) {
|
|
||||||
for j := range dst.R {
|
|
||||||
r := src.At2(j)
|
|
||||||
rs := r.Sym()
|
|
||||||
sz := r.Siz()
|
|
||||||
rt := r.Type()
|
|
||||||
if rt == objabi.R_METHODOFF {
|
|
||||||
if l.attrReachable.Has(rs) {
|
|
||||||
rt = objabi.R_ADDROFF
|
|
||||||
} else {
|
|
||||||
sz = 0
|
|
||||||
rs = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if rt == objabi.R_WEAKADDROFF && !l.attrReachable.Has(rs) {
|
|
||||||
rs = 0
|
|
||||||
sz = 0
|
|
||||||
}
|
|
||||||
if rs != 0 && l.Syms[rs] != nil && l.Syms[rs].Type == sym.SABIALIAS {
|
|
||||||
rsrelocs := l.Relocs(rs)
|
|
||||||
rs = rsrelocs.At2(0).Sym()
|
|
||||||
}
|
|
||||||
if strict && rs != 0 && l.Syms[rs] == nil && rt != objabi.R_USETYPE {
|
|
||||||
panic("nil reloc target in convertRelocations")
|
|
||||||
}
|
|
||||||
dst.R[j] = sym.Reloc{
|
|
||||||
Off: r.Off(),
|
|
||||||
Siz: sz,
|
|
||||||
Type: rt,
|
|
||||||
Add: r.Add(),
|
|
||||||
Sym: l.Syms[rs],
|
|
||||||
}
|
|
||||||
if rv := l.RelocVariant(symIdx, j); rv != 0 {
|
|
||||||
dst.R[j].InitExt()
|
|
||||||
dst.R[j].Variant = rv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert external relocations to sym.Relocs on symbol dst.
|
|
||||||
func (l *Loader) convertExtRelocs(dst *sym.Symbol, src Sym) {
|
|
||||||
if int(src) >= len(l.extRelocs) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
extRelocs := l.extRelocs[src]
|
|
||||||
if len(extRelocs) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(dst.R) != 0 {
|
|
||||||
panic("bad")
|
|
||||||
}
|
|
||||||
|
|
||||||
n := len(extRelocs)
|
|
||||||
batch := l.relocBatch
|
|
||||||
dst.R = batch[:n:n]
|
|
||||||
l.relocBatch = batch[n:]
|
|
||||||
relocs := l.Relocs(src)
|
|
||||||
for i := range dst.R {
|
|
||||||
er := &extRelocs[i]
|
|
||||||
sr := relocs.At2(er.Idx)
|
|
||||||
r := &dst.R[i]
|
|
||||||
r.RelocExt = &l.relocExtBatch[0]
|
|
||||||
l.relocExtBatch = l.relocExtBatch[1:]
|
|
||||||
r.Off = sr.Off()
|
|
||||||
r.Siz = sr.Siz()
|
|
||||||
r.Type = sr.Type()
|
|
||||||
r.Sym = l.Syms[l.ResolveABIAlias(sr.Sym())]
|
|
||||||
r.Add = sr.Add()
|
|
||||||
r.Xsym = l.Syms[er.Xsym]
|
|
||||||
r.Xadd = er.Xadd
|
|
||||||
if rv := l.RelocVariant(src, er.Idx); rv != 0 {
|
|
||||||
r.Variant = rv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// relocId is essentially a <S,R> tuple identifying the Rth
|
// relocId is essentially a <S,R> tuple identifying the Rth
|
||||||
// relocation of symbol S.
|
// relocation of symbol S.
|
||||||
type relocId struct {
|
type relocId struct {
|
||||||
@ -2941,15 +2428,7 @@ func (l *Loader) Dump() {
|
|||||||
if l.IsExternal(i) {
|
if l.IsExternal(i) {
|
||||||
pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
|
pi = fmt.Sprintf("<ext %d>", l.extIndex(i))
|
||||||
}
|
}
|
||||||
var s *sym.Symbol
|
fmt.Println(i, l.SymName(i), l.SymType(i), pi)
|
||||||
if int(i) < len(l.Syms) {
|
|
||||||
s = l.Syms[i]
|
|
||||||
}
|
|
||||||
if s != nil {
|
|
||||||
fmt.Println(i, s, s.Type, pi)
|
|
||||||
} else {
|
|
||||||
fmt.Println(i, l.SymName(i), "<not loaded>", pi)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fmt.Println("symsByName")
|
fmt.Println("symsByName")
|
||||||
for name, i := range l.symsByName[0] {
|
for name, i := range l.symsByName[0] {
|
||||||
|
@ -72,7 +72,9 @@ func TestAddMaterializedSymbol(t *testing.T) {
|
|||||||
// Suppose we create some more symbols, which triggers a grow.
|
// Suppose we create some more symbols, which triggers a grow.
|
||||||
// Make sure the symbol builder's payload pointer is valid,
|
// Make sure the symbol builder's payload pointer is valid,
|
||||||
// even across a grow.
|
// even across a grow.
|
||||||
ldr.growSyms(9999)
|
for i := 0; i < 9999; i++ {
|
||||||
|
ldr.CreateStaticSym("dummy")
|
||||||
|
}
|
||||||
|
|
||||||
// Check get/set symbol type
|
// Check get/set symbol type
|
||||||
es3typ := sb3.Type()
|
es3typ := sb3.Type()
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,9 +25,6 @@ type SymbolBuilder struct {
|
|||||||
func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
|
func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
|
||||||
// for now assume that any new sym is intended to be static
|
// for now assume that any new sym is intended to be static
|
||||||
symIdx := l.CreateStaticSym(name)
|
symIdx := l.CreateStaticSym(name)
|
||||||
if l.Syms[symIdx] != nil {
|
|
||||||
panic("can't build if sym.Symbol already present")
|
|
||||||
}
|
|
||||||
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
||||||
sb.extSymPayload = l.getPayload(symIdx)
|
sb.extSymPayload = l.getPayload(symIdx)
|
||||||
return sb
|
return sb
|
||||||
@ -47,14 +43,6 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) *SymbolBuilder {
|
|||||||
// Create a clone with the same name/version/kind etc.
|
// Create a clone with the same name/version/kind etc.
|
||||||
l.cloneToExternal(symIdx)
|
l.cloneToExternal(symIdx)
|
||||||
}
|
}
|
||||||
// Now that we're doing phase 2 DWARF generation using the loader
|
|
||||||
// but before the wavefront has reached dodata(), we can't have this
|
|
||||||
// assertion here. Commented out for now.
|
|
||||||
if false {
|
|
||||||
if l.Syms[symIdx] != nil {
|
|
||||||
panic(fmt.Sprintf("can't build if sym.Symbol %q already present", l.RawSymName(symIdx)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct updater and return.
|
// Construct updater and return.
|
||||||
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
||||||
|
@ -16,13 +16,8 @@ type LoaderSym int
|
|||||||
type CompilationUnit struct {
|
type CompilationUnit struct {
|
||||||
Pkg string // The package name, eg ("fmt", or "runtime")
|
Pkg string // The package name, eg ("fmt", or "runtime")
|
||||||
Lib *Library // Our library
|
Lib *Library // Our library
|
||||||
Consts *Symbol // Package constants DIEs
|
|
||||||
PCs []dwarf.Range // PC ranges, relative to Textp[0]
|
PCs []dwarf.Range // PC ranges, relative to Textp[0]
|
||||||
DWInfo *dwarf.DWDie // CU root DIE
|
DWInfo *dwarf.DWDie // CU root DIE
|
||||||
FuncDIEs []*Symbol // Function DIE subtrees
|
|
||||||
AbsFnDIEs []*Symbol // Abstract function DIE subtrees
|
|
||||||
RangeSyms []*Symbol // Symbols for debug_range
|
|
||||||
Textp []*Symbol // Text symbols in this CU
|
|
||||||
DWARFFileTable []string // The file table used to generate the .debug_lines
|
DWARFFileTable []string // The file table used to generate the .debug_lines
|
||||||
|
|
||||||
Consts2 LoaderSym // Package constants DIEs (loader)
|
Consts2 LoaderSym // Package constants DIEs (loader)
|
||||||
|
@ -10,41 +10,6 @@ import (
|
|||||||
"debug/elf"
|
"debug/elf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reloc is a relocation.
|
|
||||||
//
|
|
||||||
// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
|
|
||||||
// A Reloc is stored in a slice on the Symbol it rewrites.
|
|
||||||
//
|
|
||||||
// Relocations are generated by the compiler as the type
|
|
||||||
// cmd/internal/obj.Reloc, which is encoded into the object file wire
|
|
||||||
// format and decoded by the linker into this type. A separate type is
|
|
||||||
// used to hold linker-specific state about the relocation.
|
|
||||||
//
|
|
||||||
// Some relocations are created by cmd/link.
|
|
||||||
type Reloc struct {
|
|
||||||
Off int32 // offset to rewrite
|
|
||||||
Siz uint8 // number of bytes to rewrite, 1, 2, or 4
|
|
||||||
Done bool // set to true when relocation is complete
|
|
||||||
Type objabi.RelocType // the relocation type
|
|
||||||
Add int64 // addend
|
|
||||||
Sym *Symbol // symbol the relocation addresses
|
|
||||||
*RelocExt // extra fields (see below), may be nil, call InitExt before use
|
|
||||||
}
|
|
||||||
|
|
||||||
// relocExt contains extra fields in Reloc that are used only in
|
|
||||||
// certain cases.
|
|
||||||
type RelocExt struct {
|
|
||||||
Xadd int64 // addend passed to external linker
|
|
||||||
Xsym *Symbol // symbol passed to external linker
|
|
||||||
Variant RelocVariant // variation on Type, currently used only on PPC64 and S390X
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reloc) InitExt() {
|
|
||||||
if r.RelocExt == nil {
|
|
||||||
r.RelocExt = new(RelocExt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RelocVariant is a linker-internal variation on a relocation.
|
// RelocVariant is a linker-internal variation on a relocation.
|
||||||
type RelocVariant uint8
|
type RelocVariant uint8
|
||||||
|
|
||||||
@ -107,22 +72,3 @@ func RelocName(arch *sys.Arch, r objabi.RelocType) string {
|
|||||||
|
|
||||||
return r.String()
|
return r.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RelocByOff implements sort.Interface for sorting relocations by offset.
|
|
||||||
type RelocByOff []Reloc
|
|
||||||
|
|
||||||
func (x RelocByOff) Len() int { return len(x) }
|
|
||||||
|
|
||||||
func (x RelocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
|
||||||
|
|
||||||
func (x RelocByOff) Less(i, j int) bool {
|
|
||||||
a := &x[i]
|
|
||||||
b := &x[j]
|
|
||||||
if a.Off < b.Off {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if a.Off > b.Off {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@ -55,7 +55,6 @@ type Section struct {
|
|||||||
Elfsect interface{} // an *ld.ElfShdr
|
Elfsect interface{} // an *ld.ElfShdr
|
||||||
Reloff uint64
|
Reloff uint64
|
||||||
Rellen uint64
|
Rellen uint64
|
||||||
Sym *Symbol // symbol for the section, if any
|
|
||||||
Sym2 LoaderSym // symbol for the section, if any
|
Sym2 LoaderSym // symbol for the section, if any
|
||||||
Index uint16 // each section has a unique index, used internally
|
Index uint16 // each section has a unique index, used internally
|
||||||
}
|
}
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2018 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 sym
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Assert that the size of important structures do not change unexpectedly.
|
|
||||||
|
|
||||||
func TestSizeof(t *testing.T) {
|
|
||||||
const nbit = unsafe.Sizeof(uintptr(0)) * 8
|
|
||||||
const _64bit = nbit == 64
|
|
||||||
|
|
||||||
var tests = []struct {
|
|
||||||
val interface{} // type as a value
|
|
||||||
_32bit uintptr // size on 32bit platforms
|
|
||||||
_64bit uintptr // size on 64bit platforms
|
|
||||||
}{
|
|
||||||
{Symbol{}, 80, 128},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
want := tt._32bit
|
|
||||||
if _64bit {
|
|
||||||
want = tt._64bit
|
|
||||||
}
|
|
||||||
got := reflect.TypeOf(tt.val).Size()
|
|
||||||
if want != got {
|
|
||||||
t.Errorf("%d bit unsafe.Sizeof(%T) = %d, want %d", nbit, tt.val, got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,46 +6,8 @@ package sym
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/objabi"
|
|
||||||
"cmd/internal/sys"
|
|
||||||
"debug/elf"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Symbol is an entry in the symbol table.
|
|
||||||
type Symbol struct {
|
|
||||||
Name string
|
|
||||||
Type SymKind
|
|
||||||
Version int16
|
|
||||||
Attr Attribute
|
|
||||||
Dynid int32
|
|
||||||
Align int32
|
|
||||||
Value int64
|
|
||||||
Size int64
|
|
||||||
Outer *Symbol
|
|
||||||
SymIdx LoaderSym
|
|
||||||
auxinfo *AuxSymbol
|
|
||||||
Sect *Section
|
|
||||||
// P contains the raw symbol data.
|
|
||||||
P []byte
|
|
||||||
R []Reloc
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuxSymbol contains less-frequently used sym.Symbol fields.
|
|
||||||
type AuxSymbol struct {
|
|
||||||
extname string
|
|
||||||
dynimplib string
|
|
||||||
dynimpvers string
|
|
||||||
localentry uint8
|
|
||||||
plt int32
|
|
||||||
got int32
|
|
||||||
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
|
|
||||||
// is not set for symbols defined by the packages being linked or by symbols
|
|
||||||
// read by ldelf (and so is left as elf.STT_NOTYPE).
|
|
||||||
elftype elf.SymType
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SymVerABI0 = 0
|
SymVerABI0 = 0
|
||||||
SymVerABIInternal = 1
|
SymVerABIInternal = 1
|
||||||
@ -72,363 +34,6 @@ func VersionToABI(v int) (obj.ABI, bool) {
|
|||||||
return ^obj.ABI(0), false
|
return ^obj.ABI(0), false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Symbol) String() string {
|
|
||||||
if s.Version == 0 {
|
|
||||||
return s.Name
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s<%d>", s.Name, s.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) IsFileLocal() bool {
|
|
||||||
return s.Version >= SymVerStatic
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Len() int64 {
|
|
||||||
return s.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Length(dwarfContext interface{}) int64 {
|
|
||||||
return s.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Grow(siz int64) {
|
|
||||||
if int64(int(siz)) != siz {
|
|
||||||
log.Fatalf("symgrow size %d too long", siz)
|
|
||||||
}
|
|
||||||
if int64(len(s.P)) >= siz {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cap(s.P) < int(siz) {
|
|
||||||
p := make([]byte, 2*(siz+1))
|
|
||||||
s.P = append(p[:0], s.P...)
|
|
||||||
}
|
|
||||||
s.P = s.P[:siz]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddBytes(bytes []byte) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
s.P = append(s.P, bytes...)
|
|
||||||
s.Size = int64(len(s.P))
|
|
||||||
|
|
||||||
return s.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddUint8(v uint8) int64 {
|
|
||||||
off := s.Size
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
s.Size++
|
|
||||||
s.P = append(s.P, v)
|
|
||||||
|
|
||||||
return off
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
|
|
||||||
return s.AddUintXX(arch, uint64(v), 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
|
|
||||||
return s.AddUintXX(arch, uint64(v), 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
|
|
||||||
return s.AddUintXX(arch, v, 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
|
|
||||||
return s.AddUintXX(arch, v, arch.PtrSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
|
|
||||||
return s.setUintXX(arch, r, uint64(v), 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetUint16(arch *sys.Arch, r int64, v uint16) int64 {
|
|
||||||
return s.setUintXX(arch, r, uint64(v), 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
|
|
||||||
return s.setUintXX(arch, r, uint64(v), 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
|
|
||||||
return s.setUintXX(arch, r, v, int64(arch.PtrSize))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
i := s.Size
|
|
||||||
s.Size += int64(arch.PtrSize)
|
|
||||||
s.Grow(s.Size)
|
|
||||||
r := s.AddRel()
|
|
||||||
r.Sym = t
|
|
||||||
r.Off = int32(i)
|
|
||||||
r.Siz = uint8(arch.PtrSize)
|
|
||||||
r.Type = typ
|
|
||||||
r.Add = add
|
|
||||||
return i + int64(r.Siz)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
|
|
||||||
return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
|
|
||||||
return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
i := s.Size
|
|
||||||
s.Size += 4
|
|
||||||
s.Grow(s.Size)
|
|
||||||
r := s.AddRel()
|
|
||||||
r.Sym = t
|
|
||||||
r.Off = int32(i)
|
|
||||||
r.Add = add
|
|
||||||
r.Type = objabi.R_PCREL
|
|
||||||
r.Siz = 4
|
|
||||||
if arch.Family == sys.S390X || arch.Family == sys.PPC64 {
|
|
||||||
r.InitExt()
|
|
||||||
}
|
|
||||||
if arch.Family == sys.S390X {
|
|
||||||
r.Variant = RV_390_DBL
|
|
||||||
}
|
|
||||||
return i + int64(r.Siz)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
|
|
||||||
return s.AddAddrPlus(arch, t, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
if off+int64(arch.PtrSize) > s.Size {
|
|
||||||
s.Size = off + int64(arch.PtrSize)
|
|
||||||
s.Grow(s.Size)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := s.AddRel()
|
|
||||||
r.Sym = t
|
|
||||||
r.Off = int32(off)
|
|
||||||
r.Siz = uint8(arch.PtrSize)
|
|
||||||
r.Type = objabi.R_ADDR
|
|
||||||
r.Add = add
|
|
||||||
return off + int64(r.Siz)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
|
|
||||||
return s.SetAddrPlus(arch, off, t, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
i := s.Size
|
|
||||||
s.Size += int64(arch.PtrSize)
|
|
||||||
s.Grow(s.Size)
|
|
||||||
r := s.AddRel()
|
|
||||||
r.Sym = t
|
|
||||||
r.Off = int32(i)
|
|
||||||
r.Siz = uint8(arch.PtrSize)
|
|
||||||
r.Type = objabi.R_SIZE
|
|
||||||
return i + int64(r.Siz)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
i := s.Size
|
|
||||||
s.Size += 4
|
|
||||||
s.Grow(s.Size)
|
|
||||||
r := s.AddRel()
|
|
||||||
r.Sym = t
|
|
||||||
r.Off = int32(i)
|
|
||||||
r.Siz = 4
|
|
||||||
r.Type = objabi.R_ADDR
|
|
||||||
r.Add = add
|
|
||||||
return i + int64(r.Siz)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddRel() *Reloc {
|
|
||||||
s.R = append(s.R, Reloc{})
|
|
||||||
return &s.R[len(s.R)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
|
|
||||||
off := s.Size
|
|
||||||
s.setUintXX(arch, off, v, int64(wid))
|
|
||||||
return off
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
|
|
||||||
if s.Type == 0 {
|
|
||||||
s.Type = SDATA
|
|
||||||
}
|
|
||||||
s.Attr |= AttrReachable
|
|
||||||
if s.Size < off+wid {
|
|
||||||
s.Size = off + wid
|
|
||||||
s.Grow(s.Size)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch wid {
|
|
||||||
case 1:
|
|
||||||
s.P[off] = uint8(v)
|
|
||||||
case 2:
|
|
||||||
arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
|
|
||||||
case 4:
|
|
||||||
arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
|
|
||||||
case 8:
|
|
||||||
arch.ByteOrder.PutUint64(s.P[off:], v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return off + wid
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) makeAuxInfo() {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Extname() string {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return s.Name
|
|
||||||
}
|
|
||||||
return s.auxinfo.extname
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetExtname(n string) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
if s.Name == n {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.extname = n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Dynimplib() string {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return s.auxinfo.dynimplib
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Dynimpvers() string {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return s.auxinfo.dynimpvers
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetDynimplib(lib string) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.dynimplib = lib
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetDynimpvers(vers string) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.dynimpvers = vers
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) ResetDyninfo() {
|
|
||||||
if s.auxinfo != nil {
|
|
||||||
s.auxinfo.dynimplib = ""
|
|
||||||
s.auxinfo.dynimpvers = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Localentry() uint8 {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return s.auxinfo.localentry
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetLocalentry(val uint8) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
if val != 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.localentry = val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Plt() int32 {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return s.auxinfo.plt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetPlt(val int32) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
if val == -1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.plt = val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) Got() int32 {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return s.auxinfo.got
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetGot(val int32) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
if val == -1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.got = val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) ElfType() elf.SymType {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
return elf.STT_NOTYPE
|
|
||||||
}
|
|
||||||
return s.auxinfo.elftype
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Symbol) SetElfType(val elf.SymType) {
|
|
||||||
if s.auxinfo == nil {
|
|
||||||
if val == elf.STT_NOTYPE {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.makeAuxInfo()
|
|
||||||
}
|
|
||||||
s.auxinfo.elftype = val
|
|
||||||
}
|
|
||||||
|
|
||||||
type Pcdata struct {
|
type Pcdata struct {
|
||||||
P []byte
|
P []byte
|
||||||
}
|
}
|
||||||
|
@ -33,16 +33,6 @@ package sym
|
|||||||
type Symbols struct {
|
type Symbols struct {
|
||||||
// Symbol lookup based on name and indexed by version.
|
// Symbol lookup based on name and indexed by version.
|
||||||
versions int
|
versions int
|
||||||
|
|
||||||
// Provided by the loader
|
|
||||||
|
|
||||||
// Look up the symbol with the given name and version, creating the
|
|
||||||
// symbol if it is not found.
|
|
||||||
Lookup func(name string, v int) *Symbol
|
|
||||||
|
|
||||||
// Look up the symbol with the given name and version, returning nil
|
|
||||||
// if it is not found.
|
|
||||||
ROLookup func(name string, v int) *Symbol
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSymbols() *Symbols {
|
func NewSymbols() *Symbols {
|
||||||
|
Loading…
Reference in New Issue
Block a user