]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: pass value being relocated to archreloc
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Mon, 3 Aug 2015 02:08:17 +0000 (14:08 +1200)
committerIan Lance Taylor <iant@golang.org>
Mon, 31 Aug 2015 00:07:59 +0000 (00:07 +0000)
And clean up the mess on arm64 (the mess on arm is too confusing).

See issue #10050

Change-Id: I2ce813fe8646d4e818eb660612a7e4b2bb04de4c
Reviewed-on: https://go-review.googlesource.com/13884
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/internal/obj/arm64/asm7.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/data.go

index ab0f7aebdb608f712ac1a179e0a3488affb007b8..ce0d3c1a2b4a383b958a7e5b2024dc56c1b5ec5b 100644 (file)
@@ -1899,7 +1899,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                rel.Off = int32(ctxt.Pc)
                rel.Siz = 4
                rel.Sym = p.To.Sym
-               rel.Add = int64(o1) | (p.To.Offset>>2)&0x3ffffff
+               rel.Add = p.To.Offset
                rel.Type = obj.R_CALLARM64
 
        case 6: /* b ,O(R); bl ,O(R) */
index 3aebd8a2232efd27cbfae1702463cf54561337ee..5888101531650e0b68a1258f344e6b36fae1c4ec 100644 (file)
@@ -191,17 +191,21 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                        }
                        r.Xsym = rs
 
-                       // the first instruction is always at the lower address, this is endian neutral;
-                       // but note that o0 and o1 should still use the target endian.
-                       o0 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off : r.Off+4])
-                       o1 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off+4 : r.Off+8])
-
                        // Note: ld64 currently has a bug that any non-zero addend for BR26 relocation
                        // will make the linking fail because it thinks the code is not PIC even though
                        // the BR26 relocation should be fully resolved at link time.
                        // That is the reason why the next if block is disabled. When the bug in ld64
                        // is fixed, we can enable this block and also enable duff's device in cmd/7g.
                        if false && ld.HEADTYPE == obj.Hdarwin {
+                               var o0, o1 uint32
+
+                               if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
+                                       o0 = uint32(*val >> 32)
+                                       o1 = uint32(*val)
+                               } else {
+                                       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
                                // can only encode 24-bit of signed addend, but the instructions
@@ -210,13 +214,13 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                                o0 |= (uint32((r.Xadd>>12)&3) << 29) | (uint32((r.Xadd>>12>>2)&0x7ffff) << 5)
                                o1 |= uint32(r.Xadd&0xfff) << 10
                                r.Xadd = 0
-                       }
 
-                       // when laid out, the instruction order must always be o1, o2.
-                       if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
-                               *val = int64(o0)<<32 | int64(o1)
-                       } else {
-                               *val = int64(o1)<<32 | int64(o0)
+                               // when laid out, the instruction order must always be o1, o2.
+                               if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
+                                       *val = int64(o0)<<32 | int64(o1)
+                               } else {
+                                       *val = int64(o1)<<32 | int64(o0)
+                               }
                        }
 
                        return 0
@@ -224,9 +228,7 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                case obj.R_CALLARM64:
                        r.Done = 0
                        r.Xsym = r.Sym
-                       *val = int64(0xfc000000 & uint32(r.Add))
-                       r.Xadd = int64((uint32(r.Add) &^ 0xfc000000) * 4)
-                       r.Add = 0
+                       r.Xadd = r.Add
                        return 0
                }
        }
@@ -246,10 +248,15 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                        ld.Diag("program too large, address relocation distance = %d", t)
                }
 
-               // the first instruction is always at the lower address, this is endian neutral;
-               // but note that o0 and o1 should still use the target endian.
-               o0 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off : r.Off+4])
-               o1 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off+4 : r.Off+8])
+               var o0, o1 uint32
+
+               if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
+                       o0 = uint32(*val >> 32)
+                       o1 = uint32(*val)
+               } else {
+                       o0 = uint32(*val)
+                       o1 = uint32(*val >> 32)
+               }
 
                o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
                o1 |= uint32(t&0xfff) << 10
@@ -263,7 +270,11 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                return 0
 
        case obj.R_CALLARM64:
-               *val = int64((0xfc000000 & uint32(r.Add)) | uint32((ld.Symaddr(r.Sym)+r.Add*4-(s.Value+int64(r.Off)))/4))
+               t := (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
+               if t >= 1<<27 || t < -1<<27 {
+                       ld.Diag("program too large, call relocation distance = %d", t)
+               }
+               *val |= (t >> 2) & 0x03ffffff
                return 0
        }
 
index 55b12e5ececa36f511943f182b170f485235caa7..91a5edd3760a86e3c39d42b9879dd8be0ac15802 100644 (file)
@@ -369,7 +369,18 @@ func relocsym(s *LSym) {
 
                switch r.Type {
                default:
-                       o = 0
+                       switch siz {
+                       default:
+                               Diag("bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
+                       case 1:
+                               o = int64(s.P[off])
+                       case 2:
+                               o = int64(Ctxt.Arch.ByteOrder.Uint16(s.P[off:]))
+                       case 4:
+                               o = int64(Ctxt.Arch.ByteOrder.Uint32(s.P[off:]))
+                       case 8:
+                               o = int64(Ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
+                       }
                        if Thearch.Archreloc(r, s, &o) < 0 {
                                Diag("unknown reloc %d", r.Type)
                        }