// the symbol that triggered the marking of symbol K as live.
Reachparent []Sym
- relocBatch []sym.Reloc // for bulk allocation of relocations
+ relocBatch []sym.Reloc // for bulk allocation of relocations
+ relocExtBatch []sym.RelocExt // for bulk allocation of relocations
flags uint32
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[1:] {
- nr += loadObjSyms(l, syms, o.r)
+ nr += loadObjSyms(l, syms, o.r, needReloc)
}
// Make a first pass through the external symbols, making
continue
}
pp := l.getPayload(i)
- nr += len(pp.relocs)
+ if needReloc {
+ nr += len(pp.relocs)
+ }
+ if 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,
}
// allocate a single large slab of relocations for all live symbols
- if needReloc {
+ if nr != 0 {
l.relocBatch = make([]sym.Reloc, nr)
+ if len(l.extRelocs) != 0 {
+ l.relocExtBatch = make([]sym.RelocExt, nr)
+ }
}
// convert payload-based external symbols into sym.Symbol-based
loadObjFull(l, o.r, needReloc)
}
+ // 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.
// 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) int {
+func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader, needReloc bool) int {
nr := 0
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
gi := r.syms[i]
}
l.addNewSym(gi, name, ver, r.unit, t)
- nr += r.NReloc(i)
+ if needReloc {
+ nr += r.NReloc(i)
+ }
+ if int(gi) < len(l.extRelocs) {
+ nr += len(l.extRelocs[gi])
+ }
}
return nr
}
if len(dst.R) != 0 {
panic("bad")
}
- dst.R = make([]sym.Reloc, len(extRelocs))
+
+ 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.InitExt()
+ r.RelocExt = &l.relocExtBatch[0]
+ l.relocExtBatch = l.relocExtBatch[1:]
r.Off = sr.Off()
r.Siz = sr.Siz()
r.Type = sr.Type()
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 // 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 {
+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)
+ if r.RelocExt == nil {
+ r.RelocExt = new(RelocExt)
}
}