Commit 328adf9d authored by isharipo's avatar isharipo Committed by Brad Fitzpatrick

cmd/link: fewer allocs in ld.Arch.Archreloc

Archreloc had this signature:

	func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool

The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.

If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:

	func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)

There are 2 benefits:
1. code becomes more readable.
2. less allocations.

For linking "hello world" example from net/http:

	name      old time/op  new time/op  delta
	Linker-4   530ms ± 2%   520ms ± 2%  -1.83%  (p=0.001 n=17+16)

It's top 1 in alloc_objects from memprofile:

	flat   flat%  sum%       cum    cum%
	229379 33.05% 33.05%     229379 33.05%  cmd/link/internal/ld.relocsym
	...

list relocsym:

	229379     229379 (flat, cum) 33.05% of Total
	229379     229379    183:    var o int64

After the patch, ~230k of int64 allocs (~ 1.75mb) removed.

Passes toolshash-check (toolstash cmp).

Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 4201c207
......@@ -532,8 +532,8 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
return true
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
return false
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -568,7 +568,7 @@ func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
}
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
case objabi.R_CALLARM:
......@@ -602,20 +602,17 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
ld.Errorf(s, "direct call too far %d", r.Xadd/4)
}
*val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4))))
return true
return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4)))), true
}
return false
return -1, false
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
// The following three arch specific relocations are only for generation of
// Linux/ARM ELF's PLT entry (3 assembler instruction)
......@@ -623,16 +620,11 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Symaddr(ctxt.Syms.Lookup(".got.plt", 0)) < ld.Symaddr(ctxt.Syms.Lookup(".plt", 0)) {
ld.Errorf(s, ".got.plt should be placed after .plt section.")
}
*val = 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add)) >> 20))
return true
return 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add)) >> 20)), true
case objabi.R_PLT1: // add ip, ip, #0xYY000
*val = 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+4)) >> 12))
return true
return 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+4)) >> 12)), true
case objabi.R_PLT2: // ldr pc, [ip, #0xZZZ]!
*val = 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+8)))
return true
return 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ctxt.Syms.Lookup(".plt", 0))+int64(r.Off))+r.Add+8))), true
case objabi.R_CALLARM: // bl XXXXXX or b YYYYYY
// r.Add is the instruction
// low 24-bit encodes the target address
......@@ -640,12 +632,10 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if t > 0x7fffff || t < -0x800000 {
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
}
*val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t)))
return true
return int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&t))), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -234,19 +234,19 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return true
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
return val, false
case objabi.R_ARM64_GOTPCREL:
var o1, o2 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(*val >> 32)
o2 = uint32(*val)
o1 = uint32(val >> 32)
o2 = uint32(val)
} else {
o1 = uint32(*val)
o2 = uint32(*val >> 32)
o1 = uint32(val)
o2 = uint32(val >> 32)
}
// Any relocation against a function symbol is redirected to
// be against a local symbol instead (see putelfsym in
......@@ -264,9 +264,9 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
r.Type = objabi.R_ADDRARM64
}
if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o1)<<32 | int64(o2)
val = int64(o1)<<32 | int64(o2)
} else {
*val = int64(o2)<<32 | int64(o1)
val = int64(o2)<<32 | int64(o1)
}
fallthrough
case objabi.R_ADDRARM64:
......@@ -294,11 +294,11 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
var o0, o1 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian {
o0 = uint32(*val >> 32)
o1 = uint32(*val)
o0 = uint32(val >> 32)
o1 = uint32(val)
} else {
o0 = uint32(*val)
o1 = uint32(*val >> 32)
o0 = uint32(val)
o1 = uint32(val >> 32)
}
// Mach-O wants the addend to be encoded in the instruction
// Note that although Mach-O supports ARM64_RELOC_ADDEND, it
......@@ -311,30 +311,28 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
// when laid out, the instruction order must always be o1, o2.
if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o0)<<32 | int64(o1)
val = int64(o0)<<32 | int64(o1)
} else {
*val = int64(o1)<<32 | int64(o0)
val = int64(o1)<<32 | int64(o0)
}
}
return true
return val, true
case objabi.R_CALLARM64,
objabi.R_ARM64_TLS_LE,
objabi.R_ARM64_TLS_IE:
r.Done = false
r.Xsym = r.Sym
r.Xadd = r.Add
return true
return val, true
}
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
case objabi.R_ADDRARM64:
t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
if t >= 1<<32 || t < -1<<32 {
......@@ -344,11 +342,11 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
var o0, o1 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian {
o0 = uint32(*val >> 32)
o1 = uint32(*val)
o0 = uint32(val >> 32)
o1 = uint32(val)
} else {
o0 = uint32(*val)
o1 = uint32(*val >> 32)
o0 = uint32(val)
o1 = uint32(val >> 32)
}
o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
......@@ -356,11 +354,9 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
// when laid out, the instruction order must always be o1, o2.
if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o0)<<32 | int64(o1)
} else {
*val = int64(o1)<<32 | int64(o0)
return int64(o0)<<32 | int64(o1), true
}
return true
return int64(o1)<<32 | int64(o0), true
case objabi.R_ARM64_TLS_LE:
r.Done = false
if ctxt.HeadType != objabi.Hlinux {
......@@ -372,18 +368,16 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if v < 0 || v >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", v)
}
*val |= v << 5
return true
return val | (v << 5), true
case objabi.R_CALLARM64:
t := (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
if t >= 1<<27 || t < -1<<27 {
ld.Errorf(s, "program too large, call relocation distance = %d", t)
}
*val |= (t >> 2) & 0x03ffffff
return true
return val | ((t >> 2) & 0x03ffffff), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -198,7 +198,9 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
case 8:
o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
}
if !thearch.Archreloc(ctxt, r, s, &o) {
if offset, ok := thearch.Archreloc(ctxt, r, s, o); ok {
o = offset
} else {
Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
case objabi.R_TLS_LE:
......
......@@ -104,7 +104,7 @@ type Arch struct {
Solarisdynld string
Adddynrel func(*Link, *sym.Symbol, *sym.Reloc) bool
Archinit func(*Link)
Archreloc func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
Archreloc func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
Archrelocvariant func(*Link, *sym.Reloc, *sym.Symbol, int64) int64
Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
Asmb func(*Link)
......
......@@ -82,23 +82,25 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return false
}
func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val *int64, t int64) {
func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val int64, t int64) int64 {
o := arch.ByteOrder.Uint32(s.P[r.Off:])
switch r.Type {
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
*val = int64(o&0xffff0000 | uint32(t)&0xffff)
return int64(o&0xffff0000 | uint32(t)&0xffff)
case objabi.R_ADDRMIPSU:
*val = int64(o&0xffff0000 | uint32((t+(1<<15))>>16)&0xffff)
return int64(o&0xffff0000 | uint32((t+(1<<15))>>16)&0xffff)
case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
*val = int64(o&0xfc000000 | uint32(t>>2)&^0xfc000000)
return int64(o&0xfc000000 | uint32(t>>2)&^0xfc000000)
default:
return val
}
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
return val, false
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
r.Done = false
......@@ -114,28 +116,23 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
applyrel(ctxt.Arch, r, s, val, r.Xadd)
return true
return applyrel(ctxt.Arch, r, s, val, r.Xadd), true
case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS:
r.Done = false
r.Xsym = r.Sym
r.Xadd = r.Add
applyrel(ctxt.Arch, r, s, val, r.Add)
return true
return applyrel(ctxt.Arch, r, s, val, r.Add), true
}
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add
applyrel(ctxt.Arch, r, s, val, t)
return true
return applyrel(ctxt.Arch, r, s, val, t), true
case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
t := ld.Symaddr(r.Sym) + r.Add
......@@ -148,19 +145,17 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
}
applyrel(ctxt.Arch, r, s, val, t)
return true
return applyrel(ctxt.Arch, r, s, val, t), true
case objabi.R_ADDRMIPSTLS:
// thread pointer is at 0x7000 offset from the start of TLS data area
t := ld.Symaddr(r.Sym) + r.Add - 0x7000
if t < -32768 || t >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", t)
}
applyrel(ctxt.Arch, r, s, val, t)
return true
return applyrel(ctxt.Arch, r, s, val, t), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -99,11 +99,11 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return false
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
return val, false
case objabi.R_ADDRMIPS,
objabi.R_ADDRMIPSU:
r.Done = false
......@@ -121,34 +121,30 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
}
r.Xsym = rs
return true
return val, true
case objabi.R_ADDRMIPSTLS,
objabi.R_CALLMIPS,
objabi.R_JMPMIPS:
r.Done = false
r.Xsym = r.Sym
r.Xadd = r.Add
return true
return val, true
}
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
case objabi.R_ADDRMIPS,
objabi.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
if r.Type == objabi.R_ADDRMIPS {
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
} else {
*val = int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff)
return int64(o1&0xffff0000 | uint32(t)&0xffff), true
}
return true
return int64(o1&0xffff0000 | uint32((t+1<<15)>>16)&0xffff), true
case objabi.R_ADDRMIPSTLS:
// thread pointer is at 0x7000 offset from the start of TLS data area
t := ld.Symaddr(r.Sym) + r.Add - 0x7000
......@@ -156,18 +152,16 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
ld.Errorf(s, "TLS offset out of range %d", t)
}
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
return true
return int64(o1&0xffff0000 | uint32(t)&0xffff), true
case objabi.R_CALLMIPS,
objabi.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2
t := ld.Symaddr(r.Sym) + r.Add
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000)
return true
return int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -474,14 +474,14 @@ func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
return toc.Value
}
func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
var o1, o2 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(*val >> 32)
o2 = uint32(*val)
o1 = uint32(val >> 32)
o2 = uint32(val)
} else {
o1 = uint32(*val)
o2 = uint32(*val >> 32)
o1 = uint32(val)
o2 = uint32(val >> 32)
}
// We are spreading a 31-bit address across two instructions, putting the
......@@ -510,15 +510,13 @@ func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool
}
o2 |= uint32(t) & 0xfffc
default:
return false
return -1
}
if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o1)<<32 | int64(o2)
} else {
*val = int64(o2)<<32 | int64(o1)
return int64(o1)<<32 | int64(o2)
}
return true
return int64(o2)<<32 | int64(o1)
}
// resolve direct jump relocation r in s, and add trampoline if necessary
......@@ -623,17 +621,17 @@ func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, o
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
return val, 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 true
return val, true
case objabi.R_ADDRPOWER,
objabi.R_ADDRPOWER_DS,
objabi.R_ADDRPOWER_TOCREL,
......@@ -655,24 +653,22 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
}
r.Xsym = rs
return true
return val, true
case objabi.R_CALLPOWER:
r.Done = false
r.Xsym = r.Sym
r.Xadd = r.Add
return true
return val, true
}
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
return archrelocaddr(ctxt, r, s, val)
return archrelocaddr(ctxt, r, s, val), true
case objabi.R_CALLPOWER:
// Bits 6 through 29 = (S + A - P) >> 2
......@@ -686,12 +682,10 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if int64(int32(t<<6)>>6) != t {
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
}
*val |= int64(uint32(t) &^ 0xfc000003)
return true
return val | int64(uint32(t)&^0xfc000003), true
case objabi.R_POWER_TOC: // S + A - .TOC.
*val = ld.Symaddr(r.Sym) + r.Add - symtoc(ctxt, s)
return ld.Symaddr(r.Sym) + r.Add - symtoc(ctxt, s), true
return 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
......@@ -701,11 +695,10 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if int64(int16(v)) != v {
ld.Errorf(s, "TLS offset out of range %d", v)
}
*val = (*val &^ 0xffff) | (v & 0xffff)
return true
return (val &^ 0xffff) | (v & 0xffff), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -384,21 +384,19 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
return false
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
return false
return val, false
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
......@@ -491,20 +491,18 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
return true
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
if ctxt.LinkMode == ld.LinkExternal {
return false
return val, false
}
switch r.Type {
case objabi.R_CONST:
*val = r.Add
return true
return r.Add, true
case objabi.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
return true
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
}
return false
return val, false
}
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment