]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/link/internal/ld/data.go
[dev.fuzz] all: merge master (65f0d24) into dev.fuzz
[gostls13.git] / src / cmd / link / internal / ld / data.go
index 12ece3e233b0cceaaad67fdee1b95d310c1baded..1898ee020cbd24b40bc19069028fe59c6306e752 100644 (file)
@@ -436,6 +436,11 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                        if weak && !ldr.AttrReachable(rs) {
                                continue
                        }
+                       if ldr.SymSect(rs) == nil {
+                               st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(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" {
@@ -1705,21 +1710,9 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
        }
        ldr := ctxt.loader
 
-       // .got (and .toc on ppc64)
+       // .got
        if len(state.data[sym.SELFGOT]) > 0 {
-               sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
-               if ctxt.IsPPC64() {
-                       for _, s := range state.data[sym.SELFGOT] {
-                               // Resolve .TOC. symbol for this object file (ppc64)
-
-                               toc := ldr.Lookup(".TOC.", int(ldr.SymVersion(s)))
-                               if toc != 0 {
-                                       ldr.SetSymSect(toc, sect)
-                                       ldr.AddInteriorSym(s, toc)
-                                       ldr.SetSymValue(toc, 0x8000)
-                               }
-                       }
-               }
+               state.allocateNamedSectionAndAssignSyms(&Segdata, ".got", sym.SELFGOT, sym.SDATA, 06)
        }
 
        /* pointer-free data */
@@ -2693,6 +2686,24 @@ func (ctxt *Link) address() []*sym.Segment {
                ldr.SetSymSect(ldr.Lookup("_end", 0), ldr.SymSect(end))
        }
 
+       if ctxt.IsPPC64() && ctxt.IsElf() {
+               // Resolve .TOC. symbols for all objects. Only one TOC region is supported. If a
+               // GOT section is present, compute it as suggested by the ELFv2 ABI. Otherwise,
+               // choose a similar offset from the start of the data segment.
+               tocAddr := int64(Segdata.Vaddr) + 0x8000
+               if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 {
+                       tocAddr = gotAddr + 0x8000
+               }
+               for i, _ := range ctxt.DotTOC {
+                       if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently
+                               continue
+                       }
+                       if toc := ldr.Lookup(".TOC.", i); toc != 0 {
+                               ldr.SetSymValue(toc, tocAddr)
+                       }
+               }
+       }
+
        return order
 }