mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: batch allocations when converting external relocations
Change-Id: Iad81cb159e46f694a03d58892ca7dfde3ee3095a Reviewed-on: https://go-review.googlesource.com/c/go/+/231219 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
f875f8fe76
commit
83db26ac4a
2 changed files with 43 additions and 12 deletions
|
|
@ -284,7 +284,8 @@ 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
|
relocBatch []sym.Reloc // for bulk allocation of relocations
|
||||||
|
relocExtBatch []sym.RelocExt // for bulk allocation of relocations
|
||||||
|
|
||||||
flags uint32
|
flags uint32
|
||||||
|
|
||||||
|
|
@ -2037,9 +2038,16 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) {
|
||||||
l.growSyms(l.NSym())
|
l.growSyms(l.NSym())
|
||||||
l.growSects(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
|
nr := 0 // total number of sym.Reloc's we'll need
|
||||||
for _, o := range l.objs[1:] {
|
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
|
// Make a first pass through the external symbols, making
|
||||||
|
|
@ -2052,7 +2060,12 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pp := l.getPayload(i)
|
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
|
// create and install the sym.Symbol here so that l.Syms will
|
||||||
// be fully populated when we do relocation processing and
|
// be fully populated when we do relocation processing and
|
||||||
// outer/sub processing below. Note that once we do this,
|
// outer/sub processing below. Note that once we do this,
|
||||||
|
|
@ -2064,8 +2077,11 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate a single large slab of relocations for all live symbols
|
// allocate a single large slab of relocations for all live symbols
|
||||||
if needReloc {
|
if nr != 0 {
|
||||||
l.relocBatch = make([]sym.Reloc, nr)
|
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
|
// convert payload-based external symbols into sym.Symbol-based
|
||||||
|
|
@ -2101,6 +2117,11 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols, needReloc bool) {
|
||||||
loadObjFull(l, o.r, needReloc)
|
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
|
// Note: resolution of ABI aliases is now also handled in
|
||||||
// loader.convertRelocations, so once the host object loaders move
|
// loader.convertRelocations, so once the host object loaders move
|
||||||
// completely to loader.Sym, we can remove the code below.
|
// completely to loader.Sym, we can remove the code below.
|
||||||
|
|
@ -2417,7 +2438,7 @@ func topLevelSym(sname string, skind sym.SymKind) bool {
|
||||||
// loadObjSyms creates sym.Symbol objects for the live Syms in the
|
// loadObjSyms creates sym.Symbol objects for the live Syms in the
|
||||||
// object corresponding to object reader "r". Return value is the
|
// object corresponding to object reader "r". Return value is the
|
||||||
// number of sym.Reloc entries required for all the new symbols.
|
// 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
|
nr := 0
|
||||||
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
|
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
|
||||||
gi := r.syms[i]
|
gi := r.syms[i]
|
||||||
|
|
@ -2447,7 +2468,12 @@ func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
l.addNewSym(gi, name, ver, r.unit, t)
|
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
|
return nr
|
||||||
}
|
}
|
||||||
|
|
@ -2764,13 +2790,18 @@ func (l *Loader) convertExtRelocs(dst *sym.Symbol, src Sym) {
|
||||||
if len(dst.R) != 0 {
|
if len(dst.R) != 0 {
|
||||||
panic("bad")
|
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)
|
relocs := l.Relocs(src)
|
||||||
for i := range dst.R {
|
for i := range dst.R {
|
||||||
er := &extRelocs[i]
|
er := &extRelocs[i]
|
||||||
sr := relocs.At2(er.Idx)
|
sr := relocs.At2(er.Idx)
|
||||||
r := &dst.R[i]
|
r := &dst.R[i]
|
||||||
r.InitExt()
|
r.RelocExt = &l.relocExtBatch[0]
|
||||||
|
l.relocExtBatch = l.relocExtBatch[1:]
|
||||||
r.Off = sr.Off()
|
r.Off = sr.Off()
|
||||||
r.Siz = sr.Siz()
|
r.Siz = sr.Siz()
|
||||||
r.Type = sr.Type()
|
r.Type = sr.Type()
|
||||||
|
|
|
||||||
|
|
@ -28,20 +28,20 @@ type Reloc struct {
|
||||||
Type objabi.RelocType // the relocation type
|
Type objabi.RelocType // the relocation type
|
||||||
Add int64 // addend
|
Add int64 // addend
|
||||||
Sym *Symbol // symbol the relocation addresses
|
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
|
// relocExt contains extra fields in Reloc that are used only in
|
||||||
// certain cases.
|
// certain cases.
|
||||||
type relocExt struct {
|
type RelocExt struct {
|
||||||
Xadd int64 // addend passed to external linker
|
Xadd int64 // addend passed to external linker
|
||||||
Xsym *Symbol // symbol passed to external linker
|
Xsym *Symbol // symbol passed to external linker
|
||||||
Variant RelocVariant // variation on Type, currently used only on PPC64 and S390X
|
Variant RelocVariant // variation on Type, currently used only on PPC64 and S390X
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reloc) InitExt() {
|
func (r *Reloc) InitExt() {
|
||||||
if r.relocExt == nil {
|
if r.RelocExt == nil {
|
||||||
r.relocExt = new(relocExt)
|
r.RelocExt = new(RelocExt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue