diff options
| author | David Crawshaw <crawshaw@golang.org> | 2016-11-13 21:20:58 -0500 |
|---|---|---|
| committer | David Crawshaw <crawshaw@golang.org> | 2016-11-16 18:37:03 +0000 |
| commit | 7ee793652307269c9fdee2c0cb222509371a6e36 (patch) | |
| tree | 8d41c474f6dcfe4a93ff598b6934f42afa289845 /src/cmd | |
| parent | b75b9e1d65989753d0ee14ccc6007729e49e2e51 (diff) | |
| download | go-7ee793652307269c9fdee2c0cb222509371a6e36.tar.xz | |
cmd/link: handle R_GOTPCREL separately on darwin
To generate the correct section offset the shared code path for
R_CALL, R_PCREL, and R_GOTPCREL on darwin when externally linking
walks up the symbol heirarchy adding the differences. This is fine,
except in the case where we are generating a GOT lookup, because
the topmost symbol is left in r.Xsym instead of the symbol we are
looking up. So all funcsym GOT lookups were looking up the outer
"go.func.*" symbol.
Fix this by separating out the R_GOTPCREL code path.
For #17828 (and may fix it).
Change-Id: I2c9f4d135e77c17270aa064d8c876dc6d485d659
Reviewed-on: https://go-review.googlesource.com/33211
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/link/internal/ld/data.go | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 7dff9baaea..de043305d0 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -599,7 +599,19 @@ func relocsym(ctxt *Link, s *Symbol) { } // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. - case obj.R_CALL, obj.R_GOTPCREL, obj.R_PCREL: + case obj.R_GOTPCREL: + if ctxt.DynlinkingGo() && Headtype == obj.Hdarwin && r.Sym != nil && r.Sym.Type != obj.SCONST { + r.Done = 0 + r.Xadd = r.Add + r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk + r.Xsym = r.Sym + + o = r.Xadd + o += int64(r.Siz) + break + } + fallthrough + case obj.R_CALL, obj.R_PCREL: if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != obj.SCONST && (r.Sym.Sect != s.Sect || r.Type == obj.R_GOTPCREL) { r.Done = 0 |
