mirror of
https://github.com/golang/go
synced 2024-11-26 17:16:54 -07:00
cmd/internal/objabi: use a separate bit to mark weak relocation
Instead of using two relocation types R_XXX and R_WEAKXXX, use a separate bit, R_WEAK, to mark weak relocations. This makes it easier to add more weak relocation types. Change-Id: Iec4195c2aefa65f59e464c83018246e17cd08173 Reviewed-on: https://go-review.googlesource.com/c/go/+/268478 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
009bfeae86
commit
414fa8c35e
@ -50,11 +50,6 @@ const (
|
|||||||
// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
|
// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
|
||||||
// holding the data being relocated to the referenced symbol.
|
// holding the data being relocated to the referenced symbol.
|
||||||
R_ADDROFF
|
R_ADDROFF
|
||||||
// R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation.
|
|
||||||
// A weak relocation does not make the symbol it refers to reachable,
|
|
||||||
// and is only honored by the linker if the symbol is in some other way
|
|
||||||
// reachable.
|
|
||||||
R_WEAKADDROFF
|
|
||||||
R_SIZE
|
R_SIZE
|
||||||
R_CALL
|
R_CALL
|
||||||
R_CALLARM
|
R_CALLARM
|
||||||
@ -256,6 +251,14 @@ const (
|
|||||||
// of a symbol. This isn't a real relocation, it can be placed in anywhere
|
// of a symbol. This isn't a real relocation, it can be placed in anywhere
|
||||||
// in a symbol and target any symbols.
|
// in a symbol and target any symbols.
|
||||||
R_XCOFFREF
|
R_XCOFFREF
|
||||||
|
|
||||||
|
// R_WEAK marks the relocation as a weak reference.
|
||||||
|
// A weak relocation does not make the symbol it refers to reachable,
|
||||||
|
// and is only honored by the linker if the symbol is in some other way
|
||||||
|
// reachable.
|
||||||
|
R_WEAK = -1 << 15
|
||||||
|
|
||||||
|
R_WEAKADDROFF = R_WEAK | R_ADDROFF
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsDirectCall reports whether r is a relocation for a direct call.
|
// IsDirectCall reports whether r is a relocation for a direct call.
|
||||||
|
@ -13,66 +13,65 @@ func _() {
|
|||||||
_ = x[R_ADDRARM64-3]
|
_ = x[R_ADDRARM64-3]
|
||||||
_ = x[R_ADDRMIPS-4]
|
_ = x[R_ADDRMIPS-4]
|
||||||
_ = x[R_ADDROFF-5]
|
_ = x[R_ADDROFF-5]
|
||||||
_ = x[R_WEAKADDROFF-6]
|
_ = x[R_SIZE-6]
|
||||||
_ = x[R_SIZE-7]
|
_ = x[R_CALL-7]
|
||||||
_ = x[R_CALL-8]
|
_ = x[R_CALLARM-8]
|
||||||
_ = x[R_CALLARM-9]
|
_ = x[R_CALLARM64-9]
|
||||||
_ = x[R_CALLARM64-10]
|
_ = x[R_CALLIND-10]
|
||||||
_ = x[R_CALLIND-11]
|
_ = x[R_CALLPOWER-11]
|
||||||
_ = x[R_CALLPOWER-12]
|
_ = x[R_CALLMIPS-12]
|
||||||
_ = x[R_CALLMIPS-13]
|
_ = x[R_CALLRISCV-13]
|
||||||
_ = x[R_CALLRISCV-14]
|
_ = x[R_CONST-14]
|
||||||
_ = x[R_CONST-15]
|
_ = x[R_PCREL-15]
|
||||||
_ = x[R_PCREL-16]
|
_ = x[R_TLS_LE-16]
|
||||||
_ = x[R_TLS_LE-17]
|
_ = x[R_TLS_IE-17]
|
||||||
_ = x[R_TLS_IE-18]
|
_ = x[R_GOTOFF-18]
|
||||||
_ = x[R_GOTOFF-19]
|
_ = x[R_PLT0-19]
|
||||||
_ = x[R_PLT0-20]
|
_ = x[R_PLT1-20]
|
||||||
_ = x[R_PLT1-21]
|
_ = x[R_PLT2-21]
|
||||||
_ = x[R_PLT2-22]
|
_ = x[R_USEFIELD-22]
|
||||||
_ = x[R_USEFIELD-23]
|
_ = x[R_USETYPE-23]
|
||||||
_ = x[R_USETYPE-24]
|
_ = x[R_USEIFACE-24]
|
||||||
_ = x[R_USEIFACE-25]
|
_ = x[R_USEIFACEMETHOD-25]
|
||||||
_ = x[R_USEIFACEMETHOD-26]
|
_ = x[R_METHODOFF-26]
|
||||||
_ = x[R_METHODOFF-27]
|
_ = x[R_POWER_TOC-27]
|
||||||
_ = x[R_POWER_TOC-28]
|
_ = x[R_GOTPCREL-28]
|
||||||
_ = x[R_GOTPCREL-29]
|
_ = x[R_JMPMIPS-29]
|
||||||
_ = x[R_JMPMIPS-30]
|
_ = x[R_DWARFSECREF-30]
|
||||||
_ = x[R_DWARFSECREF-31]
|
_ = x[R_DWARFFILEREF-31]
|
||||||
_ = x[R_DWARFFILEREF-32]
|
_ = x[R_ARM64_TLS_LE-32]
|
||||||
_ = x[R_ARM64_TLS_LE-33]
|
_ = x[R_ARM64_TLS_IE-33]
|
||||||
_ = x[R_ARM64_TLS_IE-34]
|
_ = x[R_ARM64_GOTPCREL-34]
|
||||||
_ = x[R_ARM64_GOTPCREL-35]
|
_ = x[R_ARM64_GOT-35]
|
||||||
_ = x[R_ARM64_GOT-36]
|
_ = x[R_ARM64_PCREL-36]
|
||||||
_ = x[R_ARM64_PCREL-37]
|
_ = x[R_ARM64_LDST8-37]
|
||||||
_ = x[R_ARM64_LDST8-38]
|
_ = x[R_ARM64_LDST16-38]
|
||||||
_ = x[R_ARM64_LDST16-39]
|
_ = x[R_ARM64_LDST32-39]
|
||||||
_ = x[R_ARM64_LDST32-40]
|
_ = x[R_ARM64_LDST64-40]
|
||||||
_ = x[R_ARM64_LDST64-41]
|
_ = x[R_ARM64_LDST128-41]
|
||||||
_ = x[R_ARM64_LDST128-42]
|
_ = x[R_POWER_TLS_LE-42]
|
||||||
_ = x[R_POWER_TLS_LE-43]
|
_ = x[R_POWER_TLS_IE-43]
|
||||||
_ = x[R_POWER_TLS_IE-44]
|
_ = x[R_POWER_TLS-44]
|
||||||
_ = x[R_POWER_TLS-45]
|
_ = x[R_ADDRPOWER_DS-45]
|
||||||
_ = x[R_ADDRPOWER_DS-46]
|
_ = x[R_ADDRPOWER_GOT-46]
|
||||||
_ = x[R_ADDRPOWER_GOT-47]
|
_ = x[R_ADDRPOWER_PCREL-47]
|
||||||
_ = x[R_ADDRPOWER_PCREL-48]
|
_ = x[R_ADDRPOWER_TOCREL-48]
|
||||||
_ = x[R_ADDRPOWER_TOCREL-49]
|
_ = x[R_ADDRPOWER_TOCREL_DS-49]
|
||||||
_ = x[R_ADDRPOWER_TOCREL_DS-50]
|
_ = x[R_RISCV_PCREL_ITYPE-50]
|
||||||
_ = x[R_RISCV_PCREL_ITYPE-51]
|
_ = x[R_RISCV_PCREL_STYPE-51]
|
||||||
_ = x[R_RISCV_PCREL_STYPE-52]
|
_ = x[R_RISCV_TLS_IE_ITYPE-52]
|
||||||
_ = x[R_RISCV_TLS_IE_ITYPE-53]
|
_ = x[R_RISCV_TLS_IE_STYPE-53]
|
||||||
_ = x[R_RISCV_TLS_IE_STYPE-54]
|
_ = x[R_PCRELDBL-54]
|
||||||
_ = x[R_PCRELDBL-55]
|
_ = x[R_ADDRMIPSU-55]
|
||||||
_ = x[R_ADDRMIPSU-56]
|
_ = x[R_ADDRMIPSTLS-56]
|
||||||
_ = x[R_ADDRMIPSTLS-57]
|
_ = x[R_ADDRCUOFF-57]
|
||||||
_ = x[R_ADDRCUOFF-58]
|
_ = x[R_WASMIMPORT-58]
|
||||||
_ = x[R_WASMIMPORT-59]
|
_ = x[R_XCOFFREF-59]
|
||||||
_ = x[R_XCOFFREF-60]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
|
const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
|
||||||
|
|
||||||
var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709}
|
var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 120, 127, 134, 142, 150, 158, 164, 170, 176, 186, 195, 205, 221, 232, 243, 253, 262, 275, 289, 303, 317, 333, 344, 357, 370, 384, 398, 412, 427, 441, 455, 466, 480, 495, 512, 530, 551, 570, 589, 609, 629, 639, 650, 663, 674, 686, 696}
|
||||||
|
|
||||||
func (i RelocType) String() string {
|
func (i RelocType) String() string {
|
||||||
i -= 1
|
i -= 1
|
||||||
|
@ -165,6 +165,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
rs := r.Sym()
|
rs := r.Sym()
|
||||||
rs = ldr.ResolveABIAlias(rs)
|
rs = ldr.ResolveABIAlias(rs)
|
||||||
rt := r.Type()
|
rt := r.Type()
|
||||||
|
weak := r.Weak()
|
||||||
if off < 0 || off+siz > int32(len(P)) {
|
if off < 0 || off+siz > int32(len(P)) {
|
||||||
rname := ""
|
rname := ""
|
||||||
if rs != 0 {
|
if rs != 0 {
|
||||||
@ -211,7 +212,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt))
|
st.err.Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", ldr.SymName(rs), rst, rst, rt, sym.RelocName(target.Arch, rt))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if rs != 0 && rst != sym.STLSBSS && rt != objabi.R_WEAKADDROFF && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) {
|
if rs != 0 && rst != sym.STLSBSS && !weak && rt != objabi.R_METHODOFF && !ldr.AttrReachable(rs) {
|
||||||
st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
|
st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,18 +388,18 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr)
|
o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr)
|
||||||
case objabi.R_WEAKADDROFF, objabi.R_METHODOFF:
|
case objabi.R_METHODOFF:
|
||||||
if !ldr.AttrReachable(rs) {
|
if !ldr.AttrReachable(rs) {
|
||||||
if rt == objabi.R_METHODOFF {
|
// Set it to a sentinel value. The runtime knows this is not pointing to
|
||||||
// Set it to a sentinel value. The runtime knows this is not pointing to
|
// anything valid.
|
||||||
// anything valid.
|
o = -1
|
||||||
o = -1
|
break
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case objabi.R_ADDROFF:
|
case objabi.R_ADDROFF:
|
||||||
|
if weak && !ldr.AttrReachable(rs) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// The method offset tables using this relocation expect the offset to be relative
|
// 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.
|
// to the start of the first text section, even if there are multiple.
|
||||||
if ldr.SymSect(rs).Name == ".text" {
|
if ldr.SymSect(rs).Name == ".text" {
|
||||||
@ -635,7 +636,7 @@ func extreloc(ctxt *Link, ldr *loader.Loader, s loader.Sym, r loader.Reloc) (loa
|
|||||||
return ExtrelocSimple(ldr, r), true
|
return ExtrelocSimple(ldr, r), true
|
||||||
|
|
||||||
// These reloc types don't need external relocations.
|
// These reloc types don't need external relocations.
|
||||||
case objabi.R_ADDROFF, objabi.R_WEAKADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF,
|
case objabi.R_ADDROFF, objabi.R_METHODOFF, objabi.R_ADDRCUOFF,
|
||||||
objabi.R_SIZE, objabi.R_CONST, objabi.R_GOTOFF:
|
objabi.R_SIZE, objabi.R_CONST, objabi.R_GOTOFF:
|
||||||
return rr, false
|
return rr, false
|
||||||
}
|
}
|
||||||
@ -710,9 +711,8 @@ func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
|
|||||||
if targ == 0 {
|
if targ == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
rt := r.Type()
|
|
||||||
if !ctxt.loader.AttrReachable(targ) {
|
if !ctxt.loader.AttrReachable(targ) {
|
||||||
if rt == objabi.R_WEAKADDROFF {
|
if r.Weak() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s",
|
ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s",
|
||||||
@ -786,6 +786,10 @@ func dynrelocsym(ctxt *Link, s loader.Sym) {
|
|||||||
if r.IsMarker() {
|
if r.IsMarker() {
|
||||||
continue // skip marker relocations
|
continue // skip marker relocations
|
||||||
}
|
}
|
||||||
|
rSym := r.Sym()
|
||||||
|
if r.Weak() && !ldr.AttrReachable(rSym) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
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
|
||||||
@ -794,7 +798,6 @@ func dynrelocsym(ctxt *Link, s loader.Sym) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
rSym := r.Sym()
|
|
||||||
if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset {
|
if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset {
|
||||||
if rSym != 0 && !ldr.AttrReachable(rSym) {
|
if rSym != 0 && !ldr.AttrReachable(rSym) {
|
||||||
ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
|
ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
|
||||||
|
@ -128,10 +128,11 @@ func (d *deadcodePass) flood() {
|
|||||||
methods = methods[:0]
|
methods = methods[:0]
|
||||||
for i := 0; i < relocs.Count(); i++ {
|
for i := 0; i < relocs.Count(); i++ {
|
||||||
r := relocs.At(i)
|
r := relocs.At(i)
|
||||||
|
if r.Weak() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
t := r.Type()
|
t := r.Type()
|
||||||
switch t {
|
switch t {
|
||||||
case objabi.R_WEAKADDROFF:
|
|
||||||
continue
|
|
||||||
case objabi.R_METHODOFF:
|
case objabi.R_METHODOFF:
|
||||||
if i+2 >= relocs.Count() {
|
if i+2 >= relocs.Count() {
|
||||||
panic("expect three consecutive R_METHODOFF relocs")
|
panic("expect three consecutive R_METHODOFF relocs")
|
||||||
|
@ -53,7 +53,8 @@ type Reloc struct {
|
|||||||
l *Loader
|
l *Loader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) }
|
func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) &^ objabi.R_WEAK }
|
||||||
|
func (rel Reloc) Weak() bool { return objabi.RelocType(rel.Reloc.Type())&objabi.R_WEAK != 0 }
|
||||||
func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
|
func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
|
||||||
func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
|
func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
|
||||||
func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
|
func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
|
||||||
|
Loading…
Reference in New Issue
Block a user