]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use versioned .TOC. symbols on AIX
authorCherry Zhang <cherryyz@google.com>
Fri, 13 Mar 2020 21:02:31 +0000 (17:02 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 16 Mar 2020 13:50:40 +0000 (13:50 +0000)
I thought that only non-static symbols need TOC, but apparently
this is not true. We need to use versioned .TOC. symbols.

Partially fix AIX build. There is still another problem, but this
gets us a bit farther in make.bash.

Change-Id: I40ba4a4dd27da0fc6ab26e4a54ff76bd2930aef1
Reviewed-on: https://go-review.googlesource.com/c/go/+/223379
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/sym/symbols.go

index d7d52a579b1676ac6fef6d18c0237fc754496106..c7cbbddcbaa2e649c303b655cec2ea5f3c9cd0ea 100644 (file)
@@ -101,7 +101,8 @@ type LookupFn func(name string, version int) *sym.Symbol
 // we keep a subset for relocation application.
 type ArchSyms struct {
        TOC    *sym.Symbol
-       DotTOC *sym.Symbol
+       DotTOC []*sym.Symbol // for each version
+
        GOT    *sym.Symbol
        PLT    *sym.Symbol
        GOTPLT *sym.Symbol
@@ -117,8 +118,6 @@ type ArchSyms struct {
 // setArchSyms sets up the ArchSyms structure, and must be called before
 // relocations are applied.
 func (ctxt *Link) setArchSyms() {
-       ctxt.TOC = ctxt.Syms.Lookup("TOC", 0)
-       ctxt.DotTOC = ctxt.Syms.Lookup(".TOC.", 0)
        ctxt.GOT = ctxt.Syms.Lookup(".got", 0)
        ctxt.PLT = ctxt.Syms.Lookup(".plt", 0)
        ctxt.GOTPLT = ctxt.Syms.Lookup(".got.plt", 0)
@@ -126,6 +125,17 @@ func (ctxt *Link) setArchSyms() {
        ctxt.Dynamic = ctxt.Syms.Lookup(".dynamic", 0)
        ctxt.DynSym = ctxt.Syms.Lookup(".dynsym", 0)
        ctxt.DynStr = ctxt.Syms.Lookup(".dynstr", 0)
+
+       if ctxt.IsAIX() {
+               ctxt.TOC = ctxt.Syms.Lookup("TOC", 0)
+               ctxt.DotTOC = make([]*sym.Symbol, ctxt.Syms.MaxVersion()+1)
+               for i := 0; i <= ctxt.Syms.MaxVersion(); i++ {
+                       if i >= 2 && i < sym.SymVerStatic { // these versions are not used currently
+                               continue
+                       }
+                       ctxt.DotTOC[i] = ctxt.Syms.Lookup(".TOC.", i)
+               }
+       }
 }
 
 type Arch struct {
index d0993e32678b4ff1dbc4f677a91893fb306ece58..d3ebafc6036a554587d588addaa27e989247aa8d 100644 (file)
@@ -513,6 +513,22 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
        return false
 }
 
+// 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
+       }
+
+       toc := syms.DotTOC[v]
+       if toc == nil {
+               ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
+               return 0
+       }
+
+       return toc.Value
+}
+
 // archreloctoc relocates a TOC relative symbol.
 // If the symbol pointed by this TOC relative symbol is in .data or .bss, the
 // default load instruction can be changed to an addi instruction and the
@@ -825,7 +841,7 @@ func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol
                }
                return val | int64(uint32(t)&^0xfc000003), true
        case objabi.R_POWER_TOC: // S + A - .TOC.
-               return ld.Symaddr(r.Sym) + r.Add - syms.DotTOC.Value, true
+               return ld.Symaddr(r.Sym) + r.Add - symtoc(syms, s), true
 
        case objabi.R_POWER_TLS_LE:
                // The thread pointer points 0x7000 bytes after the start of the
index e64779da9cb5355011e6679a1b27abe32ce7a60d..10e4ac5f543bdc931a61dcd643736832c5143e4e 100644 (file)
@@ -62,3 +62,8 @@ func (syms *Symbols) IncVersion() int {
        syms.versions++
        return syms.versions - 1
 }
+
+// returns the maximum version number
+func (syms *Symbols) MaxVersion() int {
+       return syms.versions
+}