]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/objabi: use a separate bit to mark weak relocation
authorCherry Zhang <cherryyz@google.com>
Sun, 8 Nov 2020 16:50:10 +0000 (11:50 -0500)
committerCherry Zhang <cherryyz@google.com>
Fri, 5 Mar 2021 23:58:34 +0000 (23:58 +0000)
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>
src/cmd/internal/objabi/reloctype.go
src/cmd/internal/objabi/reloctype_string.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/loader/loader.go

index 649f6901944f9876b4a30a6118786f4898766d60..217d8565f27a7677826865958510c5aa87977b57 100644 (file)
@@ -50,11 +50,6 @@ const (
        // R_ADDROFF resolves to a 32-bit offset from the beginning of the section
        // holding the data being relocated to the referenced symbol.
        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_CALL
        R_CALLARM
@@ -256,6 +251,14 @@ const (
        // of a symbol. This isn't a real relocation, it can be placed in anywhere
        // in a symbol and target any symbols.
        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.
index 658a44f8b81bfa4bf3abefc43f4d23f5b4f46fd6..8882d19f883f0bc2b3321db0a500e423289e6a46 100644 (file)
@@ -13,66 +13,65 @@ func _() {
        _ = x[R_ADDRARM64-3]
        _ = x[R_ADDRMIPS-4]
        _ = x[R_ADDROFF-5]
-       _ = x[R_WEAKADDROFF-6]
-       _ = x[R_SIZE-7]
-       _ = x[R_CALL-8]
-       _ = x[R_CALLARM-9]
-       _ = x[R_CALLARM64-10]
-       _ = x[R_CALLIND-11]
-       _ = x[R_CALLPOWER-12]
-       _ = x[R_CALLMIPS-13]
-       _ = x[R_CALLRISCV-14]
-       _ = x[R_CONST-15]
-       _ = x[R_PCREL-16]
-       _ = x[R_TLS_LE-17]
-       _ = x[R_TLS_IE-18]
-       _ = x[R_GOTOFF-19]
-       _ = x[R_PLT0-20]
-       _ = x[R_PLT1-21]
-       _ = x[R_PLT2-22]
-       _ = x[R_USEFIELD-23]
-       _ = x[R_USETYPE-24]
-       _ = x[R_USEIFACE-25]
-       _ = x[R_USEIFACEMETHOD-26]
-       _ = x[R_METHODOFF-27]
-       _ = x[R_POWER_TOC-28]
-       _ = x[R_GOTPCREL-29]
-       _ = x[R_JMPMIPS-30]
-       _ = x[R_DWARFSECREF-31]
-       _ = x[R_DWARFFILEREF-32]
-       _ = x[R_ARM64_TLS_LE-33]
-       _ = x[R_ARM64_TLS_IE-34]
-       _ = x[R_ARM64_GOTPCREL-35]
-       _ = x[R_ARM64_GOT-36]
-       _ = x[R_ARM64_PCREL-37]
-       _ = x[R_ARM64_LDST8-38]
-       _ = x[R_ARM64_LDST16-39]
-       _ = x[R_ARM64_LDST32-40]
-       _ = x[R_ARM64_LDST64-41]
-       _ = x[R_ARM64_LDST128-42]
-       _ = x[R_POWER_TLS_LE-43]
-       _ = x[R_POWER_TLS_IE-44]
-       _ = x[R_POWER_TLS-45]
-       _ = x[R_ADDRPOWER_DS-46]
-       _ = x[R_ADDRPOWER_GOT-47]
-       _ = x[R_ADDRPOWER_PCREL-48]
-       _ = x[R_ADDRPOWER_TOCREL-49]
-       _ = x[R_ADDRPOWER_TOCREL_DS-50]
-       _ = x[R_RISCV_PCREL_ITYPE-51]
-       _ = x[R_RISCV_PCREL_STYPE-52]
-       _ = x[R_RISCV_TLS_IE_ITYPE-53]
-       _ = x[R_RISCV_TLS_IE_STYPE-54]
-       _ = x[R_PCRELDBL-55]
-       _ = x[R_ADDRMIPSU-56]
-       _ = x[R_ADDRMIPSTLS-57]
-       _ = x[R_ADDRCUOFF-58]
-       _ = x[R_WASMIMPORT-59]
-       _ = x[R_XCOFFREF-60]
+       _ = x[R_SIZE-6]
+       _ = x[R_CALL-7]
+       _ = x[R_CALLARM-8]
+       _ = x[R_CALLARM64-9]
+       _ = x[R_CALLIND-10]
+       _ = x[R_CALLPOWER-11]
+       _ = x[R_CALLMIPS-12]
+       _ = x[R_CALLRISCV-13]
+       _ = x[R_CONST-14]
+       _ = x[R_PCREL-15]
+       _ = x[R_TLS_LE-16]
+       _ = x[R_TLS_IE-17]
+       _ = x[R_GOTOFF-18]
+       _ = x[R_PLT0-19]
+       _ = x[R_PLT1-20]
+       _ = x[R_PLT2-21]
+       _ = x[R_USEFIELD-22]
+       _ = x[R_USETYPE-23]
+       _ = x[R_USEIFACE-24]
+       _ = x[R_USEIFACEMETHOD-25]
+       _ = x[R_METHODOFF-26]
+       _ = x[R_POWER_TOC-27]
+       _ = x[R_GOTPCREL-28]
+       _ = x[R_JMPMIPS-29]
+       _ = x[R_DWARFSECREF-30]
+       _ = x[R_DWARFFILEREF-31]
+       _ = x[R_ARM64_TLS_LE-32]
+       _ = x[R_ARM64_TLS_IE-33]
+       _ = x[R_ARM64_GOTPCREL-34]
+       _ = x[R_ARM64_GOT-35]
+       _ = x[R_ARM64_PCREL-36]
+       _ = x[R_ARM64_LDST8-37]
+       _ = x[R_ARM64_LDST16-38]
+       _ = x[R_ARM64_LDST32-39]
+       _ = x[R_ARM64_LDST64-40]
+       _ = x[R_ARM64_LDST128-41]
+       _ = x[R_POWER_TLS_LE-42]
+       _ = x[R_POWER_TLS_IE-43]
+       _ = x[R_POWER_TLS-44]
+       _ = x[R_ADDRPOWER_DS-45]
+       _ = x[R_ADDRPOWER_GOT-46]
+       _ = x[R_ADDRPOWER_PCREL-47]
+       _ = x[R_ADDRPOWER_TOCREL-48]
+       _ = x[R_ADDRPOWER_TOCREL_DS-49]
+       _ = x[R_RISCV_PCREL_ITYPE-50]
+       _ = x[R_RISCV_PCREL_STYPE-51]
+       _ = x[R_RISCV_TLS_IE_ITYPE-52]
+       _ = x[R_RISCV_TLS_IE_STYPE-53]
+       _ = x[R_PCRELDBL-54]
+       _ = x[R_ADDRMIPSU-55]
+       _ = x[R_ADDRMIPSTLS-56]
+       _ = x[R_ADDRCUOFF-57]
+       _ = x[R_WASMIMPORT-58]
+       _ = x[R_XCOFFREF-59]
 }
 
-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 {
        i -= 1
index 92d38bb63e54aa04c441d18a6613273a6a91ce24..a9d17c806ef7fb1b246325c022adaed9d40e7ee1 100644 (file)
@@ -165,6 +165,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                rs := r.Sym()
                rs = ldr.ResolveABIAlias(rs)
                rt := r.Type()
+               weak := r.Weak()
                if off < 0 || off+siz > int32(len(P)) {
                        rname := ""
                        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))
                        }
                }
-               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))
                }
 
@@ -387,18 +388,18 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                break
                        }
                        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 rt == objabi.R_METHODOFF {
-                                       // Set it to a sentinel value. The runtime knows this is not pointing to
-                                       // anything valid.
-                                       o = -1
-                                       break
-                               }
-                               continue
+                               // Set it to a sentinel value. The runtime knows this is not pointing to
+                               // anything valid.
+                               o = -1
+                               break
                        }
                        fallthrough
                case objabi.R_ADDROFF:
+                       if weak && !ldr.AttrReachable(rs) {
+                               continue
+                       }
                        // 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 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
 
        // 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:
                return rr, false
        }
@@ -710,9 +711,8 @@ func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
                if targ == 0 {
                        continue
                }
-               rt := r.Type()
                if !ctxt.loader.AttrReachable(targ) {
-                       if rt == objabi.R_WEAKADDROFF {
+                       if r.Weak() {
                                continue
                        }
                        ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s",
@@ -786,6 +786,10 @@ func dynrelocsym(ctxt *Link, s loader.Sym) {
                if r.IsMarker() {
                        continue // skip marker relocations
                }
+               rSym := r.Sym()
+               if r.Weak() && !ldr.AttrReachable(rSym) {
+                       continue
+               }
                if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
                        // It's expected that some relocations will be done
                        // later by relocsym (R_TLS_LE, R_ADDROFF), so
@@ -794,7 +798,6 @@ func dynrelocsym(ctxt *Link, s loader.Sym) {
                        continue
                }
 
-               rSym := r.Sym()
                if rSym != 0 && ldr.SymType(rSym) == sym.SDYNIMPORT || r.Type() >= objabi.ElfRelocOffset {
                        if rSym != 0 && !ldr.AttrReachable(rSym) {
                                ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s", ldr.SymName(rSym))
index ebde41499e530a99abadae104020f6896bb92123..ed276b5a998b955333ff15b4e2f0e160c7fcbe65 100644 (file)
@@ -128,10 +128,11 @@ func (d *deadcodePass) flood() {
                methods = methods[:0]
                for i := 0; i < relocs.Count(); i++ {
                        r := relocs.At(i)
+                       if r.Weak() {
+                               continue
+                       }
                        t := r.Type()
                        switch t {
-                       case objabi.R_WEAKADDROFF:
-                               continue
                        case objabi.R_METHODOFF:
                                if i+2 >= relocs.Count() {
                                        panic("expect three consecutive R_METHODOFF relocs")
index 6d2e7dcabc4840984f569c1404fa58d3a609a1b0..5df4348a369e62e4d27931869af7fcf801974b08 100644 (file)
@@ -53,7 +53,8 @@ type Reloc struct {
        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) 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)}) }