mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: create symbol updated lazily in amd64 adddynrel
Tweak the code in the amd64 version of adddynrel to avoid creating a symbol updated for the symbol being processed until it's clear we need to alter its relocations. This should help performance for the PIE+internal linking scenario. Reviewed-on: https://go-review.googlesource.com/c/go/+/229866 Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Change-Id: Id25adfd81a5bbd2dde0f80a83b976397ba6abfb5 Reviewed-on: https://go-review.googlesource.com/c/go/+/230026 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
027055240f
commit
42cca1a7fe
2 changed files with 11 additions and 6 deletions
|
|
@ -85,7 +85,6 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
targType = ldr.SymType(targ)
|
targType = ldr.SymType(targ)
|
||||||
}
|
}
|
||||||
|
|
||||||
su := ldr.MakeSymbolUpdater(s)
|
|
||||||
switch r.Type() {
|
switch r.Type() {
|
||||||
default:
|
default:
|
||||||
if r.Type() >= objabi.ElfRelocOffset {
|
if r.Type() >= objabi.ElfRelocOffset {
|
||||||
|
|
@ -103,6 +102,7 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
if (targType == 0 || targType == sym.SXREF) && !ldr.AttrVisibilityHidden(targ) {
|
if (targType == 0 || targType == sym.SXREF) && !ldr.AttrVisibilityHidden(targ) {
|
||||||
ldr.Errorf(s, "unknown symbol %s in pcrel", ldr.SymName(targ))
|
ldr.Errorf(s, "unknown symbol %s in pcrel", ldr.SymName(targ))
|
||||||
}
|
}
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||||
su.SetRelocAdd(rIdx, r.Add()+4)
|
su.SetRelocAdd(rIdx, r.Add()+4)
|
||||||
return true
|
return true
|
||||||
|
|
@ -114,11 +114,13 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
if targType == 0 || targType == sym.SXREF {
|
if targType == 0 || targType == sym.SXREF {
|
||||||
ldr.Errorf(s, "unknown symbol %s in pcrel", ldr.SymName(targ))
|
ldr.Errorf(s, "unknown symbol %s in pcrel", ldr.SymName(targ))
|
||||||
}
|
}
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||||
su.SetRelocAdd(rIdx, r.Add()+8)
|
su.SetRelocAdd(rIdx, r.Add()+8)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PLT32):
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_PLT32):
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||||
su.SetRelocAdd(rIdx, r.Add()+4)
|
su.SetRelocAdd(rIdx, r.Add()+4)
|
||||||
if targType == sym.SDYNIMPORT {
|
if targType == sym.SDYNIMPORT {
|
||||||
|
|
@ -132,11 +134,11 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCREL),
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCREL),
|
||||||
objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCRELX),
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_GOTPCRELX),
|
||||||
objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_REX_GOTPCRELX):
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_X86_64_REX_GOTPCRELX):
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
if targType != sym.SDYNIMPORT {
|
if targType != sym.SDYNIMPORT {
|
||||||
// have symbol
|
// have symbol
|
||||||
sData := ldr.Data(s)
|
sData := ldr.Data(s)
|
||||||
if r.Off() >= 2 && sData[r.Off()-2] == 0x8b {
|
if r.Off() >= 2 && sData[r.Off()-2] == 0x8b {
|
||||||
su := ldr.MakeSymbolUpdater(s)
|
|
||||||
su.MakeWritable()
|
su.MakeWritable()
|
||||||
// turn MOVQ of GOT entry into LEAQ of symbol itself
|
// turn MOVQ of GOT entry into LEAQ of symbol itself
|
||||||
writeableData := su.Data()
|
writeableData := su.Data()
|
||||||
|
|
@ -160,6 +162,7 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
if targType == sym.SDYNIMPORT {
|
if targType == sym.SDYNIMPORT {
|
||||||
ldr.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", ldr.SymName(targ))
|
ldr.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", ldr.SymName(targ))
|
||||||
}
|
}
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_ADDR)
|
su.SetRelocType(rIdx, objabi.R_ADDR)
|
||||||
if target.IsPIE() && target.IsInternal() {
|
if target.IsPIE() && target.IsInternal() {
|
||||||
// For internal linking PIE, this R_ADDR relocation cannot
|
// For internal linking PIE, this R_ADDR relocation cannot
|
||||||
|
|
@ -174,6 +177,7 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0,
|
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0,
|
||||||
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0:
|
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0:
|
||||||
// TODO: What is the difference between all these?
|
// TODO: What is the difference between all these?
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_ADDR)
|
su.SetRelocType(rIdx, objabi.R_ADDR)
|
||||||
|
|
||||||
if targType == sym.SDYNIMPORT {
|
if targType == sym.SDYNIMPORT {
|
||||||
|
|
@ -184,6 +188,7 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
|
case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
|
||||||
if targType == sym.SDYNIMPORT {
|
if targType == sym.SDYNIMPORT {
|
||||||
addpltsym2(target, ldr, syms, targ)
|
addpltsym2(target, ldr, syms, targ)
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocSym(rIdx, syms.PLT2)
|
su.SetRelocSym(rIdx, syms.PLT2)
|
||||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||||
su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
|
su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
|
||||||
|
|
@ -196,6 +201,7 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_1*2 + 1,
|
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_1*2 + 1,
|
||||||
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_2*2 + 1,
|
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_2*2 + 1,
|
||||||
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
|
objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||||
|
|
||||||
if targType == sym.SDYNIMPORT {
|
if targType == sym.SDYNIMPORT {
|
||||||
|
|
@ -227,6 +233,7 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
ldr.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", ldr.SymName(targ))
|
ldr.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", ldr.SymName(targ))
|
||||||
}
|
}
|
||||||
addgotsym2(target, ldr, syms, targ)
|
addgotsym2(target, ldr, syms, targ)
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||||
su.SetRelocSym(rIdx, syms.GOT2)
|
su.SetRelocSym(rIdx, syms.GOT2)
|
||||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
|
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
|
||||||
|
|
@ -251,12 +258,14 @@ func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s load
|
||||||
// Internal linking, for both ELF and Mach-O.
|
// Internal linking, for both ELF and Mach-O.
|
||||||
// Build a PLT entry and change the relocation target to that entry.
|
// Build a PLT entry and change the relocation target to that entry.
|
||||||
addpltsym2(target, ldr, syms, targ)
|
addpltsym2(target, ldr, syms, targ)
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
su.SetRelocSym(rIdx, syms.PLT2)
|
su.SetRelocSym(rIdx, syms.PLT2)
|
||||||
su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
|
su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case objabi.R_ADDR:
|
case objabi.R_ADDR:
|
||||||
if ldr.SymType(s) == sym.STEXT && target.IsElf() {
|
if ldr.SymType(s) == sym.STEXT && target.IsElf() {
|
||||||
|
su := ldr.MakeSymbolUpdater(s)
|
||||||
if target.IsSolaris() {
|
if target.IsSolaris() {
|
||||||
addpltsym2(target, ldr, syms, targ)
|
addpltsym2(target, ldr, syms, targ)
|
||||||
su.SetRelocSym(rIdx, syms.PLT2)
|
su.SetRelocSym(rIdx, syms.PLT2)
|
||||||
|
|
|
||||||
|
|
@ -684,10 +684,6 @@ func dynrelocsym2(ctxt *Link, s loader.Sym) {
|
||||||
relocs := ldr.Relocs(s)
|
relocs := ldr.Relocs(s)
|
||||||
for ri := 0; ri < relocs.Count(); ri++ {
|
for ri := 0; ri < relocs.Count(); ri++ {
|
||||||
r := relocs.At2(ri)
|
r := relocs.At2(ri)
|
||||||
// FIXME: the call to Adddynrel2 below is going to wind up
|
|
||||||
// eagerly promoting the symbol to external, which is not great--
|
|
||||||
// it would improve things for internal/PIE if we could
|
|
||||||
// create the symbol updater lazily.
|
|
||||||
if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
|
if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
|
||||||
// It's expected that some relocations will be done
|
// It's expected that some relocations will be done
|
||||||
// later by relocsym (R_TLS_LE, R_ADDROFF), so
|
// later by relocsym (R_TLS_LE, R_ADDROFF), so
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue