]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fewer allocs in ld.Arch.Archreloc
authorisharipo <iskander.sharipov@intel.com>
Thu, 17 May 2018 16:50:29 +0000 (19:50 +0300)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 20 Aug 2018 22:10:31 +0000 (22:10 +0000)
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: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/mips/asm.go
src/cmd/link/internal/mips64/asm.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/s390x/asm.go
src/cmd/link/internal/x86/asm.go

index af274444f36aed1bb89c1f052c71d9d55b933af5..692edf1524ad722cef0e87a7a4c75d676535fd67 100644 (file)
@@ -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 {
index f0a510f1f07fcb6c85e678fd8839254c6997dca8..5e4ddea88e1fa77f8986d8460490e85331a570f0 100644 (file)
@@ -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 {
index 5b3b9e588049bfa603e134b29b1b44418b143e97..770590fd356a01c371220fce901afb60e7bce94a 100644 (file)
@@ -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 {
index 0ae93f101855504d0a8ebf226e760ce2dc717fba..d71b8b6ac7b615b1b1c1075b1e45e816078fca9a 100644 (file)
@@ -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:
index 220aab310f06d8d615ca5df62863d79b52491621..9f8945775370d5577c32b33c28e33634f9bae498 100644 (file)
@@ -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)
index 306d53f571579c985c5baefc3670e2e14513ddef..8409e43afcbcf6a959fdf4a09cb3a4edbd9bb510 100644 (file)
@@ -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 {
index 295a0aafaed71b48ac5b35ae685819ca7b535369..51eba596dc796f1a99b02fc884694f3d57585bc7 100644 (file)
@@ -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 {
index 11fdf1fb0501e371652c82909de4ab6fb9809052..825366c567a7a1b4eebefaf437bd3f7b246b4199 100644 (file)
@@ -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 {
index 634ba98dd3b44e04ce62ebbc0138e67cee0bf25b..215200721cdb7ccf5f2257cd5708bd664c7f3e11 100644 (file)
@@ -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 {
index 3150aac6cfe3661931a08d9e9d680c757e7314e3..4b45aff6537cc0c201c196ded831888524281a49 100644 (file)
@@ -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 {