mirror of
https://github.com/golang/go.git
synced 2025-05-18 05:44:35 +00:00
[dev.link] cmd/link: delete old reloc pass
We use the new one everywhere now. Change-Id: Ic9b1314e71e4666500cbf1689bb93839e040682a Reviewed-on: https://go-review.googlesource.com/c/go/+/232982 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
fdb9249d82
commit
85298173f6
@ -560,13 +560,13 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
|
||||
return true
|
||||
}
|
||||
|
||||
func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
|
||||
return val, false
|
||||
func archreloc(*ld.Target, *loader.Loader, *ld.ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool) {
|
||||
return -1, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
log.Fatalf("unexpected relocation variant")
|
||||
return t
|
||||
return -1
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
|
@ -523,7 +523,7 @@ func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym,
|
||||
tramp.AddReloc(r)
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
rs := r.Sym()
|
||||
rs = ldr.ResolveABIAlias(rs)
|
||||
if target.IsExternal() {
|
||||
@ -577,9 +577,9 @@ func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r load
|
||||
return val, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
log.Fatalf("unexpected relocation variant")
|
||||
return t
|
||||
return -1
|
||||
}
|
||||
|
||||
func addpltreloc2(ldr *loader.Loader, plt *loader.SymbolBuilder, got *loader.SymbolBuilder, s loader.Sym, typ objabi.RelocType) {
|
||||
|
@ -48,7 +48,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel2: adddynrel2,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Trampoline: trampoline,
|
||||
Asmb: asmb,
|
||||
|
@ -442,7 +442,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
|
||||
return true
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (int64, bool, bool) {
|
||||
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (int64, bool, bool) {
|
||||
const extRelocNeeded = true
|
||||
const extRelocNotNeeded = false
|
||||
const isOk = true
|
||||
@ -679,7 +679,7 @@ func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r load
|
||||
return val, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
log.Fatalf("unexpected relocation variant")
|
||||
return -1
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel2: adddynrel2,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
|
@ -272,14 +272,14 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
||||
}
|
||||
var rp *loader.ExtReloc
|
||||
if target.IsExternal() {
|
||||
// Don't pass &rr directly to Archreloc2, which will escape rr
|
||||
// Don't pass &rr directly to Archreloc, which will escape rr
|
||||
// even if this case is not taken. Instead, as Archreloc2 will
|
||||
// likely return true, we speculatively add rr to extRelocs
|
||||
// and use that space to pass to Archreloc2.
|
||||
// and use that space to pass to Archreloc.
|
||||
extRelocs = append(extRelocs, rr)
|
||||
rp = &extRelocs[len(extRelocs)-1]
|
||||
}
|
||||
out, needExtReloc1, ok := thearch.Archreloc2(target, ldr, syms, r, rp, s, o)
|
||||
out, needExtReloc1, ok := thearch.Archreloc(target, ldr, syms, r, rp, s, o)
|
||||
if target.IsExternal() && !needExtReloc1 {
|
||||
// Speculation failed. Undo the append.
|
||||
extRelocs = extRelocs[:len(extRelocs)-1]
|
||||
@ -557,7 +557,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
||||
|
||||
if target.IsPPC64() || target.IsS390X() {
|
||||
if rv != sym.RV_NONE {
|
||||
o = thearch.Archrelocvariant2(target, ldr, r, rv, s, o)
|
||||
o = thearch.Archrelocvariant(target, ldr, r, rv, s, o)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,8 @@
|
||||
package ld
|
||||
|
||||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Temporary dumping around for sym.Symbol version of helper
|
||||
@ -19,21 +14,6 @@ import (
|
||||
// FIXME: get rid of this file when dodata() is completely
|
||||
// converted.
|
||||
|
||||
func Addstring(s *sym.Symbol, str string) int64 {
|
||||
if s.Type == 0 {
|
||||
s.Type = sym.SNOPTRDATA
|
||||
}
|
||||
s.Attr |= sym.AttrReachable
|
||||
r := s.Size
|
||||
if s.Name == ".shstrtab" {
|
||||
elfsetstring(s, str, int(r))
|
||||
}
|
||||
s.P = append(s.P, str...)
|
||||
s.P = append(s.P, 0)
|
||||
s.Size = int64(len(s.P))
|
||||
return r
|
||||
}
|
||||
|
||||
// symalign returns the required alignment for the given symbol s.
|
||||
func symalign(s *sym.Symbol) int32 {
|
||||
min := int32(thearch.Minalign)
|
||||
@ -54,451 +34,3 @@ func symalign(s *sym.Symbol) int32 {
|
||||
s.Align = align
|
||||
return align
|
||||
}
|
||||
|
||||
func relocsym2(target *Target, ldr *loader.Loader, err *ErrorReporter, syms *ArchSyms, s *sym.Symbol) {
|
||||
if len(s.R) == 0 {
|
||||
return
|
||||
}
|
||||
for ri := int32(0); ri < int32(len(s.R)); ri++ {
|
||||
r := &s.R[ri]
|
||||
if r.Done {
|
||||
// Relocation already processed by an earlier phase.
|
||||
continue
|
||||
}
|
||||
r.Done = true
|
||||
off := r.Off
|
||||
siz := int32(r.Siz)
|
||||
if off < 0 || off+siz > int32(len(s.P)) {
|
||||
rname := ""
|
||||
if r.Sym != nil {
|
||||
rname = r.Sym.Name
|
||||
}
|
||||
Errorf(s, "invalid relocation %s: %d+%d not in [%d,%d)", rname, off, siz, 0, len(s.P))
|
||||
continue
|
||||
}
|
||||
|
||||
if r.Sym != nil && ((r.Sym.Type == sym.Sxxx && !r.Sym.Attr.VisibilityHidden()) || r.Sym.Type == sym.SXREF) {
|
||||
// When putting the runtime but not main into a shared library
|
||||
// these symbols are undefined and that's OK.
|
||||
if target.IsShared() || target.IsPlugin() {
|
||||
if r.Sym.Name == "main.main" || (!target.IsPlugin() && r.Sym.Name == "main..inittask") {
|
||||
r.Sym.Type = sym.SDYNIMPORT
|
||||
} else if strings.HasPrefix(r.Sym.Name, "go.info.") {
|
||||
// Skip go.info symbols. They are only needed to communicate
|
||||
// DWARF info between the compiler and linker.
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
err.errorUnresolved2(s, r)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if r.Type >= objabi.ElfRelocOffset {
|
||||
continue
|
||||
}
|
||||
if r.Siz == 0 { // informational relocation - no work to do
|
||||
continue
|
||||
}
|
||||
|
||||
// We need to be able to reference dynimport symbols when linking against
|
||||
// shared libraries, and Solaris, Darwin and AIX need it always
|
||||
if !target.IsSolaris() && !target.IsDarwin() && !target.IsAIX() && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !target.IsDynlinkingGo() && !r.Sym.Attr.SubSymbol() {
|
||||
if !(target.IsPPC64() && target.IsExternal() && r.Sym.Name == ".TOC.") {
|
||||
Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(target.Arch, r.Type))
|
||||
}
|
||||
}
|
||||
if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
|
||||
Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name)
|
||||
}
|
||||
|
||||
if target.IsExternal() {
|
||||
r.InitExt()
|
||||
}
|
||||
|
||||
// TODO(mundaym): remove this special case - see issue 14218.
|
||||
if target.IsS390X() {
|
||||
switch r.Type {
|
||||
case objabi.R_PCRELDBL:
|
||||
r.InitExt()
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_390_DBL
|
||||
case objabi.R_CALL:
|
||||
r.InitExt()
|
||||
r.Variant = sym.RV_390_DBL
|
||||
}
|
||||
}
|
||||
|
||||
var o int64
|
||||
switch r.Type {
|
||||
default:
|
||||
switch siz {
|
||||
default:
|
||||
Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
|
||||
case 1:
|
||||
o = int64(s.P[off])
|
||||
case 2:
|
||||
o = int64(target.Arch.ByteOrder.Uint16(s.P[off:]))
|
||||
case 4:
|
||||
o = int64(target.Arch.ByteOrder.Uint32(s.P[off:]))
|
||||
case 8:
|
||||
o = int64(target.Arch.ByteOrder.Uint64(s.P[off:]))
|
||||
}
|
||||
if offset, ok := thearch.Archreloc(target, syms, r, s, o); ok {
|
||||
o = offset
|
||||
} else {
|
||||
Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(target.Arch, r.Type))
|
||||
}
|
||||
case objabi.R_TLS_LE:
|
||||
if target.IsExternal() && target.IsElf() {
|
||||
r.Done = false
|
||||
if r.Sym == nil {
|
||||
r.Sym = syms.Tlsg
|
||||
}
|
||||
r.Xsym = r.Sym
|
||||
r.Xadd = r.Add
|
||||
o = 0
|
||||
if !target.IsAMD64() {
|
||||
o = r.Add
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if target.IsElf() && target.IsARM() {
|
||||
// On ELF ARM, the thread pointer is 8 bytes before
|
||||
// the start of the thread-local data block, so add 8
|
||||
// to the actual TLS offset (r->sym->value).
|
||||
// This 8 seems to be a fundamental constant of
|
||||
// ELF on ARM (or maybe Glibc on ARM); it is not
|
||||
// related to the fact that our own TLS storage happens
|
||||
// to take up 8 bytes.
|
||||
o = 8 + r.Sym.Value
|
||||
} else if target.IsElf() || target.IsPlan9() || target.IsDarwin() {
|
||||
o = int64(syms.Tlsoffset) + r.Add
|
||||
} else if target.IsWindows() {
|
||||
o = r.Add
|
||||
} else {
|
||||
log.Fatalf("unexpected R_TLS_LE relocation for %v", target.HeadType)
|
||||
}
|
||||
case objabi.R_TLS_IE:
|
||||
if target.IsExternal() && target.IsElf() {
|
||||
r.Done = false
|
||||
if r.Sym == nil {
|
||||
r.Sym = syms.Tlsg
|
||||
}
|
||||
r.Xsym = r.Sym
|
||||
r.Xadd = r.Add
|
||||
o = 0
|
||||
if !target.IsAMD64() {
|
||||
o = r.Add
|
||||
}
|
||||
break
|
||||
}
|
||||
if target.IsPIE() && target.IsElf() {
|
||||
// We are linking the final executable, so we
|
||||
// can optimize any TLS IE relocation to LE.
|
||||
if thearch.TLSIEtoLE == nil {
|
||||
log.Fatalf("internal linking of TLS IE not supported on %v", target.Arch.Family)
|
||||
}
|
||||
thearch.TLSIEtoLE(s.P, int(off), int(r.Siz))
|
||||
o = int64(syms.Tlsoffset)
|
||||
// TODO: o += r.Add when !target.IsAmd64()?
|
||||
// Why do we treat r.Add differently on AMD64?
|
||||
// Is the external linker using Xadd at all?
|
||||
} else {
|
||||
log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
|
||||
}
|
||||
case objabi.R_ADDR:
|
||||
if target.IsExternal() && r.Sym.Type != sym.SCONST {
|
||||
r.Done = false
|
||||
|
||||
// set up addend for eventual relocation via outer symbol.
|
||||
rs := ApplyOuterToXAdd(r)
|
||||
if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
|
||||
Errorf(s, "missing section for relocation target %s", rs.Name)
|
||||
}
|
||||
r.Xsym = rs
|
||||
|
||||
o = r.Xadd
|
||||
if target.IsElf() {
|
||||
if target.IsAMD64() {
|
||||
o = 0
|
||||
}
|
||||
} else if target.IsDarwin() {
|
||||
if rs.Type != sym.SHOSTOBJ {
|
||||
o += Symaddr(rs)
|
||||
}
|
||||
} else if target.IsWindows() {
|
||||
// nothing to do
|
||||
} else if target.IsAIX() {
|
||||
o = Symaddr(r.Sym) + r.Add
|
||||
} else {
|
||||
Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, target.HeadType)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// On AIX, a second relocation must be done by the loader,
|
||||
// as section addresses can change once loaded.
|
||||
// The "default" symbol address is still needed by the loader so
|
||||
// the current relocation can't be skipped.
|
||||
if target.IsAIX() && r.Sym.Type != sym.SDYNIMPORT {
|
||||
// It's not possible to make a loader relocation in a
|
||||
// symbol which is not inside .data section.
|
||||
// FIXME: It should be forbidden to have R_ADDR from a
|
||||
// symbol which isn't in .data. However, as .text has the
|
||||
// same address once loaded, this is possible.
|
||||
if s.Sect.Seg == &Segdata {
|
||||
Xcoffadddynrel(target, ldr, s, r)
|
||||
}
|
||||
}
|
||||
|
||||
o = Symaddr(r.Sym) + r.Add
|
||||
|
||||
// On amd64, 4-byte offsets will be sign-extended, so it is impossible to
|
||||
// access more than 2GB of static data; fail at link time is better than
|
||||
// fail at runtime. See https://golang.org/issue/7980.
|
||||
// Instead of special casing only amd64, we treat this as an error on all
|
||||
// 64-bit architectures so as to be future-proof.
|
||||
if int32(o) < 0 && target.Arch.PtrSize > 4 && siz == 4 {
|
||||
Errorf(s, "non-pc-relative relocation address for %s is too big: %#x (%#x + %#x)", r.Sym.Name, uint64(o), Symaddr(r.Sym), r.Add)
|
||||
errorexit()
|
||||
}
|
||||
case objabi.R_DWARFSECREF:
|
||||
if r.Sym.Sect == nil {
|
||||
Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
|
||||
}
|
||||
|
||||
if target.IsExternal() {
|
||||
r.Done = false
|
||||
|
||||
// On most platforms, the external linker needs to adjust DWARF references
|
||||
// as it combines DWARF sections. However, on Darwin, dsymutil does the
|
||||
// DWARF linking, and it understands how to follow section offsets.
|
||||
// Leaving in the relocation records confuses it (see
|
||||
// https://golang.org/issue/22068) so drop them for Darwin.
|
||||
if target.IsDarwin() {
|
||||
r.Done = true
|
||||
}
|
||||
|
||||
// PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
|
||||
// for R_DWARFSECREF relocations, while R_ADDR is replaced with
|
||||
// IMAGE_REL_I386_DIR32, IMAGE_REL_AMD64_ADDR64 and IMAGE_REL_AMD64_ADDR32.
|
||||
// Do not replace R_DWARFSECREF with R_ADDR for windows -
|
||||
// let PE code emit correct relocations.
|
||||
if !target.IsWindows() {
|
||||
r.Type = objabi.R_ADDR
|
||||
}
|
||||
|
||||
r.Xsym = r.Sym.Sect.Sym
|
||||
r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
|
||||
|
||||
o = r.Xadd
|
||||
if target.IsElf() && target.IsAMD64() {
|
||||
o = 0
|
||||
}
|
||||
break
|
||||
}
|
||||
o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
|
||||
case objabi.R_WEAKADDROFF:
|
||||
if !r.Sym.Attr.Reachable() {
|
||||
continue
|
||||
}
|
||||
fallthrough
|
||||
case objabi.R_ADDROFF:
|
||||
// The method offset tables using this relocation expect the offset to be relative
|
||||
// to the start of the first text section, even if there are multiple.
|
||||
if r.Sym.Sect.Name == ".text" {
|
||||
o = Symaddr(r.Sym) - int64(Segtext.Sections[0].Vaddr) + r.Add
|
||||
} else {
|
||||
o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
|
||||
}
|
||||
|
||||
case objabi.R_ADDRCUOFF:
|
||||
// debug_range and debug_loc elements use this relocation type to get an
|
||||
// offset from the start of the compile unit.
|
||||
u := ldr.SymUnit(loader.Sym(r.Sym.SymIdx))
|
||||
o = Symaddr(r.Sym) + r.Add - Symaddr(ldr.Syms[u.Textp2[0]])
|
||||
|
||||
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
|
||||
case objabi.R_GOTPCREL:
|
||||
if target.IsDynlinkingGo() && target.IsDarwin() && r.Sym != nil && r.Sym.Type != sym.SCONST {
|
||||
r.Done = false
|
||||
r.Xadd = r.Add
|
||||
r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
|
||||
r.Xsym = r.Sym
|
||||
|
||||
o = r.Xadd
|
||||
o += int64(r.Siz)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case objabi.R_CALL, objabi.R_PCREL:
|
||||
if target.IsExternal() && r.Sym != nil && r.Sym.Type == sym.SUNDEFEXT {
|
||||
// pass through to the external linker.
|
||||
r.Done = false
|
||||
r.Xadd = 0
|
||||
if target.IsElf() {
|
||||
r.Xadd -= int64(r.Siz)
|
||||
}
|
||||
r.Xsym = r.Sym
|
||||
o = 0
|
||||
break
|
||||
}
|
||||
if target.IsExternal() && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
|
||||
r.Done = false
|
||||
|
||||
// set up addend for eventual relocation via outer symbol.
|
||||
rs := ApplyOuterToXAdd(r)
|
||||
r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
|
||||
if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
|
||||
Errorf(s, "missing section for relocation target %s", rs.Name)
|
||||
}
|
||||
r.Xsym = rs
|
||||
|
||||
o = r.Xadd
|
||||
if target.IsElf() {
|
||||
if target.IsAMD64() {
|
||||
o = 0
|
||||
}
|
||||
} else if target.IsDarwin() {
|
||||
if r.Type == objabi.R_CALL {
|
||||
if target.IsExternal() && rs.Type == sym.SDYNIMPORT {
|
||||
if target.IsAMD64() {
|
||||
// AMD64 dynamic relocations are relative to the end of the relocation.
|
||||
o += int64(r.Siz)
|
||||
}
|
||||
} else {
|
||||
if rs.Type != sym.SHOSTOBJ {
|
||||
o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
|
||||
}
|
||||
o -= int64(r.Off) // relative to section offset, not symbol
|
||||
}
|
||||
} else {
|
||||
o += int64(r.Siz)
|
||||
}
|
||||
} else if target.IsWindows() && target.IsAMD64() { // only amd64 needs PCREL
|
||||
// PE/COFF's PC32 relocation uses the address after the relocated
|
||||
// bytes as the base. Compensate by skewing the addend.
|
||||
o += int64(r.Siz)
|
||||
} else {
|
||||
Errorf(s, "unhandled pcrel relocation to %s on %v", rs.Name, target.HeadType)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
o = 0
|
||||
if r.Sym != nil {
|
||||
o += Symaddr(r.Sym)
|
||||
}
|
||||
|
||||
o += r.Add - (s.Value + int64(r.Off) + int64(r.Siz))
|
||||
case objabi.R_SIZE:
|
||||
o = r.Sym.Size + r.Add
|
||||
|
||||
case objabi.R_XCOFFREF:
|
||||
if !target.IsAIX() {
|
||||
Errorf(s, "find XCOFF R_REF on non-XCOFF files")
|
||||
}
|
||||
if !target.IsExternal() {
|
||||
Errorf(s, "find XCOFF R_REF with internal linking")
|
||||
}
|
||||
r.Xsym = r.Sym
|
||||
r.Xadd = r.Add
|
||||
r.Done = false
|
||||
|
||||
// This isn't a real relocation so it must not update
|
||||
// its offset value.
|
||||
continue
|
||||
|
||||
case objabi.R_DWARFFILEREF:
|
||||
// The final file index is saved in r.Add in dwarf.go:writelines.
|
||||
o = r.Add
|
||||
}
|
||||
|
||||
if target.IsPPC64() || target.IsS390X() {
|
||||
r.InitExt()
|
||||
if r.Variant != sym.RV_NONE {
|
||||
o = thearch.Archrelocvariant(target, syms, r, s, o)
|
||||
}
|
||||
}
|
||||
|
||||
if false {
|
||||
nam := "<nil>"
|
||||
var addr int64
|
||||
if r.Sym != nil {
|
||||
nam = r.Sym.Name
|
||||
addr = Symaddr(r.Sym)
|
||||
}
|
||||
xnam := "<nil>"
|
||||
if r.Xsym != nil {
|
||||
xnam = r.Xsym.Name
|
||||
}
|
||||
fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x (xsym: %s +%#x) [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, addr, r.Add, xnam, r.Xadd, r.Type, sym.RelocName(target.Arch, r.Type), r.Variant, o)
|
||||
}
|
||||
switch siz {
|
||||
default:
|
||||
Errorf(s, "bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
|
||||
fallthrough
|
||||
|
||||
// TODO(rsc): Remove.
|
||||
case 1:
|
||||
s.P[off] = byte(int8(o))
|
||||
case 2:
|
||||
if o != int64(int16(o)) {
|
||||
Errorf(s, "relocation address for %s is too big: %#x", r.Sym.Name, o)
|
||||
}
|
||||
i16 := int16(o)
|
||||
target.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16))
|
||||
case 4:
|
||||
if r.Type == objabi.R_PCREL || r.Type == objabi.R_CALL {
|
||||
if o != int64(int32(o)) {
|
||||
Errorf(s, "pc-relative relocation address for %s is too big: %#x", r.Sym.Name, o)
|
||||
}
|
||||
} else {
|
||||
if o != int64(int32(o)) && o != int64(uint32(o)) {
|
||||
Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", r.Sym.Name, uint64(o))
|
||||
}
|
||||
}
|
||||
|
||||
fl := int32(o)
|
||||
target.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
|
||||
case 8:
|
||||
target.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctxt *Link) reloc2() {
|
||||
var wg sync.WaitGroup
|
||||
target := &ctxt.Target
|
||||
ldr := ctxt.loader
|
||||
reporter := &ctxt.ErrorReporter
|
||||
syms := &ctxt.ArchSyms
|
||||
wg.Add(3)
|
||||
go func() {
|
||||
if !ctxt.IsWasm() { // On Wasm, text relocations are applied in Asmb2.
|
||||
for _, s := range ctxt.Textp {
|
||||
relocsym2(target, ldr, reporter, syms, s)
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
for _, s := range ctxt.datap {
|
||||
relocsym2(target, ldr, reporter, syms, s)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
for _, si := range dwarfp {
|
||||
for _, s := range si.syms {
|
||||
relocsym2(target, ldr, reporter, syms, s)
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
@ -244,9 +244,7 @@ type Arch struct {
|
||||
// same spot in sym.P), a boolean indicating if the external relocations'
|
||||
// been used, and a boolean indicating success/failure (a failing value
|
||||
// indicates a fatal error).
|
||||
Archreloc func(target *Target, syms *ArchSyms, rel *sym.Reloc, sym *sym.Symbol,
|
||||
offset int64) (relocatedOffset int64, success bool)
|
||||
Archreloc2 func(*Target, *loader.Loader, *ArchSyms, loader.Reloc2, *loader.ExtReloc,
|
||||
Archreloc func(*Target, *loader.Loader, *ArchSyms, loader.Reloc2, *loader.ExtReloc,
|
||||
loader.Sym, int64) (relocatedOffset int64, needExtReloc bool, ok bool)
|
||||
// Archrelocvariant is a second arch-specific hook used for
|
||||
// relocation processing; it handles relocations where r.Type is
|
||||
@ -256,9 +254,7 @@ type Arch struct {
|
||||
// relocation applies, and "off" is the contents of the
|
||||
// to-be-relocated data item (from sym.P). Return is an updated
|
||||
// offset value.
|
||||
Archrelocvariant func(target *Target, syms *ArchSyms, rel *sym.Reloc, sym *sym.Symbol,
|
||||
offset int64) (relocatedOffset int64)
|
||||
Archrelocvariant2 func(target *Target, ldr *loader.Loader, rel loader.Reloc2,
|
||||
Archrelocvariant func(target *Target, ldr *loader.Loader, rel loader.Reloc2,
|
||||
rv sym.RelocVariant, sym loader.Sym, offset int64) (relocatedOffset int64)
|
||||
|
||||
// Generate a trampoline for a call from s to rs if necessary. ri is
|
||||
|
@ -318,11 +318,9 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
bench.Start("Asmb")
|
||||
ctxt.loader.InitOutData()
|
||||
thearch.Asmb(ctxt, ctxt.loader)
|
||||
newreloc := ctxt.Is386() || ctxt.IsAMD64() || ctxt.IsARM() || ctxt.IsARM64() || ctxt.IsMIPS() || ctxt.IsMIPS64() || ctxt.IsRISCV64() || ctxt.IsS390X() || ctxt.IsWasm() || ctxt.IsPPC64()
|
||||
newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows()
|
||||
if newreloc {
|
||||
bench.Start("reloc")
|
||||
ctxt.reloc()
|
||||
newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows()
|
||||
if !newasmb2 {
|
||||
bench.Start("loadlibfull")
|
||||
// We don't need relocations at this point.
|
||||
@ -333,12 +331,6 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
needExtReloc := ctxt.IsExternal() && !(ctxt.IsAMD64() && ctxt.IsELF)
|
||||
ctxt.loadlibfull(symGroupType, needReloc, needExtReloc) // XXX do it here for now
|
||||
}
|
||||
} else {
|
||||
bench.Start("loadlibfull")
|
||||
ctxt.loadlibfull(symGroupType, true, false) // XXX do it here for now
|
||||
bench.Start("reloc")
|
||||
ctxt.reloc2()
|
||||
}
|
||||
bench.Start("Asmb2")
|
||||
thearch.Asmb2(ctxt)
|
||||
|
||||
|
@ -98,7 +98,7 @@ func applyrel(arch *sys.Arch, ldr *loader.Loader, rt objabi.RelocType, off int32
|
||||
}
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
rs := r.Sym()
|
||||
rs = ldr.ResolveABIAlias(rs)
|
||||
if target.IsExternal() {
|
||||
@ -155,7 +155,7 @@ func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r load
|
||||
return val, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
return -1
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel: adddynrel,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
|
@ -101,7 +101,7 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
|
||||
return false
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
rs := r.Sym()
|
||||
rs = ldr.ResolveABIAlias(rs)
|
||||
if target.IsExternal() {
|
||||
@ -160,7 +160,7 @@ func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r load
|
||||
return val, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
return -1
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Dwarfreglr: dwarfRegLR,
|
||||
Adddynrel: adddynrel,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
|
@ -51,8 +51,8 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel2: adddynrel2,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc,
|
||||
Archrelocvariant2: archrelocvariant,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
|
@ -42,7 +42,7 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
|
||||
return false
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
rs := r.Sym()
|
||||
rs = ldr.ResolveABIAlias(rs)
|
||||
switch r.Type() {
|
||||
@ -95,7 +95,7 @@ func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r load
|
||||
return val, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
log.Fatalf("archrelocvariant")
|
||||
return -1
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel: adddynrel,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
|
@ -367,11 +367,11 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
|
||||
return false
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (o int64, needExtReloc bool, ok bool) {
|
||||
return val, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant2(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, rv sym.RelocVariant, s loader.Sym, t int64) int64 {
|
||||
func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, rv sym.RelocVariant, s loader.Sym, t int64) int64 {
|
||||
switch rv & sym.RV_TYPE_MASK {
|
||||
default:
|
||||
ldr.Errorf(s, "unexpected relocation variant %d", rv)
|
||||
|
@ -48,8 +48,8 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel2: adddynrel2,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archrelocvariant2: archrelocvariant2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
|
@ -436,13 +436,13 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
|
||||
return true
|
||||
}
|
||||
|
||||
func archreloc2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, sym loader.Sym, val int64) (int64, bool, bool) {
|
||||
return val, false, false
|
||||
func archreloc(*ld.Target, *loader.Loader, *ld.ArchSyms, loader.Reloc2, *loader.ExtReloc, loader.Sym, int64) (int64, bool, bool) {
|
||||
return -1, false, false
|
||||
}
|
||||
|
||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||
func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc2, sym.RelocVariant, loader.Sym, int64) int64 {
|
||||
log.Fatalf("unexpected relocation variant")
|
||||
return t
|
||||
return -1
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
|
@ -48,7 +48,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
|
||||
Adddynrel2: adddynrel2,
|
||||
Archinit: archinit,
|
||||
Archreloc2: archreloc2,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
|
Loading…
x
Reference in New Issue
Block a user