]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert ppc64 archreloc over to Loader
authorJeremy Faller <jeremy@golang.org>
Tue, 5 May 2020 16:34:10 +0000 (12:34 -0400)
committerJeremy Faller <jeremy@golang.org>
Fri, 8 May 2020 16:44:55 +0000 (16:44 +0000)
Change-Id: I68945a8284fb3dd9ceb5a9cd774b5b4b91e63ce0
Reviewed-on: https://go-review.googlesource.com/c/go/+/230917
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/ppc64/obj.go

index 7b06972c0a15db3d4d997d041c8fcaf80822dab2..c6270af42f797ed4cb7cc951768f0abc392d4459 100644 (file)
@@ -372,7 +372,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                } else if target.IsWindows() {
                                        // nothing to do
                                } else if target.IsAIX() {
-                                       o = ldr.SymValue(rs) + r.Add()
+                                       o = ldr.SymValue(rs) + rr.Xadd
                                } else {
                                        st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
                                }
@@ -391,8 +391,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                // symbol which isn't in .data. However, as .text has the
                                // same address once loaded, this is possible.
                                if ldr.SymSect(s).Seg == &Segdata {
-                                       panic("not implemented")
-                                       //Xcoffadddynrel(target, ldr, err, s, &r) // XXX
+                                       Xcoffadddynrel2(target, ldr, syms, s, r, ri)
                                }
                        }
 
@@ -543,10 +542,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                        needExtReloc = true
                        rr.Xsym = rs
                        rr.Xadd = r.Add()
-
-                       // This isn't a real relocation so it must not update
-                       // its offset value.
-                       continue
+                       goto addExtReloc
 
                case objabi.R_DWARFFILEREF:
                        // We don't renumber files in dwarf.go:writelines anymore.
@@ -590,6 +586,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                        target.Arch.ByteOrder.PutUint64(P[off:], uint64(o))
                }
 
+       addExtReloc:
                if needExtReloc {
                        extRelocs = append(extRelocs, rr)
                }
index 838f92af9e7c25ffb085808d47dc577f55d9ae47..75d6bbf05de429e48098619e79c0c1d4e7dc82b4 100644 (file)
@@ -318,7 +318,7 @@ 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()
+       newreloc := ctxt.Is386() || ctxt.IsAMD64() || ctxt.IsARM() || ctxt.IsARM64() || ctxt.IsMIPS() || ctxt.IsMIPS64() || ctxt.IsRISCV64() || ctxt.IsS390X() || ctxt.IsWasm() || ctxt.IsPPC64()
        newasmb2 := ctxt.IsDarwin()
        if newreloc {
                bench.Start("reloc")
index 281747b64d1a74188f0d3d08b0467b54809b0df6..f0ddc408fe5bb9cc50a68f809229d8d36d380d09 100644 (file)
@@ -1122,7 +1122,7 @@ func Xcoffadddynrel2(target *Target, ldr *loader.Loader, syms *ArchSyms, s loade
                sym2: s,
                roff: r.Off(),
        }
-       targ := r.Sym()
+       targ := ldr.ResolveABIAlias(r.Sym())
        var targType sym.SymKind
        if targ != 0 {
                targType = ldr.SymType(targ)
index ab923c324e872ce95e8883db6fad5463a33770b3..22021ee8c44d51dfbb9cef84096bfe172cad42b8 100644 (file)
@@ -416,7 +416,7 @@ func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
        switch r.Type {
        default:
                return false
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_DWARFSECREF:
                v = ld.XCOFF_R_POS
                if r.Siz == 4 {
                        v |= 0x1F << 8
@@ -437,7 +437,6 @@ func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
                emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
        case objabi.R_XCOFFREF:
                emitReloc(ld.XCOFF_R_REF|0x3F<<8, 0)
-
        }
        return true
 
@@ -533,19 +532,19 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
 }
 
 // Return the value of .TOC. for symbol s
-func symtoc(syms *ld.ArchSyms, s *sym.Symbol) int64 {
-       v := s.Version
-       if s.Outer != nil {
-               v = s.Outer.Version
+func symtoc(ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) int64 {
+       v := ldr.SymVersion(s)
+       if out := ldr.OuterSym(s); out != 0 {
+               v = ldr.SymVersion(out)
        }
 
-       toc := syms.DotTOC[v]
-       if toc == nil {
-               ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
+       toc := syms.DotTOC2[v]
+       if toc == 0 {
+               ldr.Errorf(s, "TOC-relative relocation in object without .TOC.")
                return 0
        }
 
-       return toc.Value
+       return ldr.SymValue(toc)
 }
 
 // archreloctoc relocates a TOC relative symbol.
@@ -553,36 +552,35 @@ func symtoc(syms *ld.ArchSyms, s *sym.Symbol) int64 {
 // default load instruction can be changed to an addi instruction and the
 // symbol address can be used directly.
 // This code is for AIX only.
-func archreloctoc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
+func archreloctoc(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc2, s loader.Sym, val int64) int64 {
+       rs := ldr.ResolveABIAlias(r.Sym())
        if target.IsLinux() {
-               ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
+               ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
        }
        var o1, o2 uint32
 
        o1 = uint32(val >> 32)
        o2 = uint32(val)
 
+       if !strings.HasPrefix(ldr.SymName(rs), "TOC.") {
+               ldr.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
+       }
        var t int64
        useAddi := false
-       const prefix = "TOC."
-       var tarSym *sym.Symbol
-       if strings.HasPrefix(r.Sym.Name, prefix) {
-               tarSym = r.Sym.R[0].Sym
-       } else {
-               ld.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
-       }
+       relocs := ldr.Relocs(rs)
+       tarSym := ldr.ResolveABIAlias(relocs.At2(0).Sym())
 
-       if target.IsInternal() && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) {
-               t = ld.Symaddr(tarSym) + r.Add - syms.TOC.Value
+       if target.IsInternal() && tarSym != 0 && ldr.AttrReachable(tarSym) && ldr.SymSect(tarSym).Seg == &ld.Segdata {
+               t = ldr.SymValue(tarSym) + r.Add() - ldr.SymValue(syms.TOC2)
                // change ld to addi in the second instruction
                o2 = (o2 & 0x03FF0000) | 0xE<<26
                useAddi = true
        } else {
-               t = ld.Symaddr(r.Sym) + r.Add - syms.TOC.Value
+               t = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.TOC2)
        }
 
        if t != int64(int32(t)) {
-               ld.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", s.Name, r.Sym, t)
+               ldr.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", ldr.SymName(s), rs, t)
        }
 
        if t&0x8000 != 0 {
@@ -591,13 +589,13 @@ func archreloctoc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Sym
 
        o1 |= uint32((t >> 16) & 0xFFFF)
 
-       switch r.Type {
+       switch r.Type() {
        case objabi.R_ADDRPOWER_TOCREL_DS:
                if useAddi {
                        o2 |= uint32(t) & 0xFFFF
                } else {
                        if t&3 != 0 {
-                               ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
+                               ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
                        }
                        o2 |= uint32(t) & 0xFFFC
                }
@@ -610,9 +608,10 @@ func archreloctoc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Sym
 
 // archrelocaddr relocates a symbol address.
 // This code is for AIX only.
-func archrelocaddr(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
+func archrelocaddr(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc2, s loader.Sym, val int64) int64 {
+       rs := ldr.ResolveABIAlias(r.Sym())
        if target.IsAIX() {
-               ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
+               ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
        }
        var o1, o2 uint32
        if target.IsBigEndian() {
@@ -630,22 +629,22 @@ func archrelocaddr(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Sy
        // instruction (it is an error in this case if the low 2 bits of the address
        // are non-zero).
 
-       t := ld.Symaddr(r.Sym) + r.Add
+       t := ldr.SymAddr(rs) + r.Add()
        if t < 0 || t >= 1<<31 {
-               ld.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", s.Name, ld.Symaddr(r.Sym))
+               ldr.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", ldr.SymName(s), ldr.SymValue(rs))
        }
        if t&0x8000 != 0 {
                t += 0x10000
        }
 
-       switch r.Type {
+       switch r.Type() {
        case objabi.R_ADDRPOWER:
                o1 |= (uint32(t) >> 16) & 0xffff
                o2 |= uint32(t) & 0xffff
        case objabi.R_ADDRPOWER_DS:
                o1 |= (uint32(t) >> 16) & 0xffff
                if t&3 != 0 {
-                       ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
+                       ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
                }
                o2 |= uint32(t) & 0xfffc
        default:
@@ -795,113 +794,114 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta
        tramp.SetData(P)
 }
 
-func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
+func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (relocatedOffset int64, needExtReloc bool, ok bool) {
+       needExternal := false
+       rs := ldr.ResolveABIAlias(r.Sym())
        if target.IsExternal() {
                // On AIX, relocations (except TLS ones) must be also done to the
                // value with the current addresses.
-               switch r.Type {
+               switch r.Type() {
                default:
                        if target.IsAIX() {
-                               return val, false
+                               return val, needExternal, false
                        }
                case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
-                       r.Done = false
                        // check Outer is nil, Type is TLSBSS?
-                       r.Xadd = r.Add
-                       r.Xsym = r.Sym
-                       return val, true
+                       needExternal = true
+                       rr.Xadd = r.Add()
+                       rr.Xsym = rs
+                       return val, needExternal, true
                case objabi.R_ADDRPOWER,
                        objabi.R_ADDRPOWER_DS,
                        objabi.R_ADDRPOWER_TOCREL,
                        objabi.R_ADDRPOWER_TOCREL_DS,
                        objabi.R_ADDRPOWER_GOT,
                        objabi.R_ADDRPOWER_PCREL:
-                       r.Done = false
+                       needExternal = true
 
                        // set up addend for eventual relocation via outer symbol.
-                       rs := ld.ApplyOuterToXAdd(r)
-                       if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
-                               ld.Errorf(s, "missing section for %s", rs.Name)
+                       rs, off := ld.FoldSubSymbolOffset(ldr, rs)
+                       rr.Xadd = r.Add() + off
+                       rst := ldr.SymType(rs)
+                       if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
+                               ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
                        }
-                       r.Xsym = rs
+                       rr.Xsym = rs
 
                        if !target.IsAIX() {
-                               return val, true
+                               return val, needExternal, true
                        }
                case objabi.R_CALLPOWER:
-                       r.Done = false
-                       r.Xsym = r.Sym
-                       r.Xadd = r.Add
+                       needExternal = true
+                       rr.Xsym = rs
+                       rr.Xadd = r.Add()
                        if !target.IsAIX() {
-                               return val, true
+                               return val, needExternal, true
                        }
                }
        }
 
-       switch r.Type {
-       case objabi.R_CONST:
-               return r.Add, true
-       case objabi.R_GOTOFF:
-               return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(syms.GOT), true
+       switch r.Type() {
        case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
-               return archreloctoc(target, syms, r, s, val), true
+               return archreloctoc(ldr, target, syms, r, s, val), needExternal, true
        case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
-               return archrelocaddr(target, syms, r, s, val), true
+               return archrelocaddr(ldr, target, syms, r, s, val), needExternal, true
        case objabi.R_CALLPOWER:
                // Bits 6 through 29 = (S + A - P) >> 2
 
-               t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
+               t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
 
                if t&3 != 0 {
-                       ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
+                       ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
                }
                // If branch offset is too far then create a trampoline.
 
                if int64(int32(t<<6)>>6) != t {
-                       ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
+                       ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
                }
-               return val | int64(uint32(t)&^0xfc000003), true
+               return val | int64(uint32(t)&^0xfc000003), needExternal, true
        case objabi.R_POWER_TOC: // S + A - .TOC.
-               return ld.Symaddr(r.Sym) + r.Add - symtoc(syms, s), true
+               return ldr.SymValue(rs) + r.Add() - symtoc(ldr, syms, s), needExternal, true
 
        case objabi.R_POWER_TLS_LE:
                // The thread pointer points 0x7000 bytes after the start of the
                // thread local storage area as documented in section "3.7.2 TLS
                // Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
                // Specification".
-               v := r.Sym.Value - 0x7000
+               v := ldr.SymValue(rs) - 0x7000
                if target.IsAIX() {
                        // On AIX, the thread pointer points 0x7800 bytes after
                        // the TLS.
                        v -= 0x800
                }
                if int64(int16(v)) != v {
-                       ld.Errorf(s, "TLS offset out of range %d", v)
+                       ldr.Errorf(s, "TLS offset out of range %d", v)
                }
-               return (val &^ 0xffff) | (v & 0xffff), true
+               return (val &^ 0xffff) | (v & 0xffff), needExternal, true
        }
 
-       return val, false
+       return val, needExternal, false
 }
 
-func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
-       switch r.Variant & sym.RV_TYPE_MASK {
+func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, rv sym.RelocVariant, s loader.Sym, t int64) (relocatedOffset int64) {
+       rs := ldr.ResolveABIAlias(r.Sym())
+       switch rv & sym.RV_TYPE_MASK {
        default:
-               ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
+               ldr.Errorf(s, "unexpected relocation variant %d", rv)
                fallthrough
 
        case sym.RV_NONE:
                return t
 
        case sym.RV_POWER_LO:
-               if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
+               if rv&sym.RV_CHECK_OVERFLOW != 0 {
                        // Whether to check for signed or unsigned
                        // overflow depends on the instruction
                        var o1 uint32
                        if target.IsBigEndian() {
-                               o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
+                               o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
                        } else {
-                               o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
+                               o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
                        }
                        switch o1 >> 26 {
                        case 24, // ori
@@ -928,14 +928,14 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
        case sym.RV_POWER_HI:
                t >>= 16
 
-               if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
+               if rv&sym.RV_CHECK_OVERFLOW != 0 {
                        // Whether to check for signed or unsigned
                        // overflow depends on the instruction
                        var o1 uint32
                        if target.IsBigEndian() {
-                               o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
+                               o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
                        } else {
-                               o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
+                               o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
                        }
                        switch o1 >> 26 {
                        case 25, // oris
@@ -957,21 +957,21 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
        case sym.RV_POWER_DS:
                var o1 uint32
                if target.IsBigEndian() {
-                       o1 = uint32(binary.BigEndian.Uint16(s.P[r.Off:]))
+                       o1 = uint32(binary.BigEndian.Uint16(ldr.Data(s)[r.Off():]))
                } else {
-                       o1 = uint32(binary.LittleEndian.Uint16(s.P[r.Off:]))
+                       o1 = uint32(binary.LittleEndian.Uint16(ldr.Data(s)[r.Off():]))
                }
                if t&3 != 0 {
-                       ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
+                       ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
                }
-               if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
+               if (rv&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
                        goto overflow
                }
                return int64(o1)&0x3 | int64(int16(t))
        }
 
 overflow:
-       ld.Errorf(s, "relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
+       ldr.Errorf(s, "relocation for %s+%d is too big: %d", ldr.SymName(rs), r.Off(), t)
        return t
 }
 
index 67002bc71948389da5f43f2da1d82333e0770bcc..16882d4d45a1d3c53e0e244303a221db289762d1 100644 (file)
@@ -49,18 +49,18 @@ func Init() (*sys.Arch, ld.Arch) {
                Dwarfregsp: dwarfRegSP,
                Dwarfreglr: dwarfRegLR,
 
-               Adddynrel2:       adddynrel2,
-               Archinit:         archinit,
-               Archreloc:        archreloc,
-               Archrelocvariant: archrelocvariant,
-               Asmb:             asmb,
-               Asmb2:            asmb2,
-               Elfreloc1:        elfreloc1,
-               Elfsetupplt:      elfsetupplt,
-               Gentext2:         gentext2,
-               Trampoline:       trampoline,
-               Machoreloc1:      machoreloc1,
-               Xcoffreloc1:      xcoffreloc1,
+               Adddynrel2:        adddynrel2,
+               Archinit:          archinit,
+               Archreloc2:        archreloc,
+               Archrelocvariant2: archrelocvariant,
+               Asmb:              asmb,
+               Asmb2:             asmb2,
+               Elfreloc1:         elfreloc1,
+               Elfsetupplt:       elfsetupplt,
+               Gentext2:          gentext2,
+               Trampoline:        trampoline,
+               Machoreloc1:       machoreloc1,
+               Xcoffreloc1:       xcoffreloc1,
 
                // TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
                Linuxdynld: "/lib64/ld64.so.1",