]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/9l: fix bogus C conversion
authorRuss Cox <rsc@golang.org>
Sun, 1 Mar 2015 18:32:49 +0000 (13:32 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 2 Mar 2015 00:14:48 +0000 (00:14 +0000)
Looks like c2go and gcc disagree about the exact meaning of the
usual arithmetic conversions, in a way that broke 9l's archreloc.
Fix it.

It's very hard for me to see why the original C code did not say
what c2go interpreted it to say, but apparently it did not.
This is why Go has explicit numerical conversions.

Change-Id: I75bd73afd1fa4ce9a53c887e1bd7d1e26ff43ae4
Reviewed-on: https://go-review.googlesource.com/6405
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/9l/asm.go
src/cmd/internal/ld/data.go

index eab0ef2af1d6eed4646a93c90babf05be97e840f..3197f5170b561277789fa2b18d83eaec278232d8 100644 (file)
@@ -379,26 +379,25 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
                return 0
 
-               // r->add is two ppc64 instructions holding an immediate 32-bit constant.
-       // We want to add r->sym's address to that constant.
-       // The encoding of the immediate x<<16 + y,
-       // where x is the low 16 bits of the first instruction and y is the low 16
-       // bits of the second. Both x and y are signed (int16, not uint16).
        case ld.R_ADDRPOWER:
+               // r->add is two ppc64 instructions holding an immediate 32-bit constant.
+               // We want to add r->sym's address to that constant.
+               // The encoding of the immediate x<<16 + y,
+               // where x is the low 16 bits of the first instruction and y is the low 16
+               // bits of the second. Both x and y are signed (int16, not uint16).
                o1 = uint32(r.Add >> 32)
-
                o2 = uint32(r.Add)
                t = ld.Symaddr(r.Sym)
                if t < 0 {
                        ld.Ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(r.Sym))
                }
 
-               t += ((int64(o1) & 0xffff) << 16) + (int64(int32(o2)) << 16 >> 16)
+               t += int64((o1&0xffff)<<16 + uint32(int32(o2)<<16>>16))
                if t&0x8000 != 0 {
                        t += 0x10000
                }
-               o1 = uint32(int64(o1&0xffff0000) | (t>>16)&0xffff)
-               o2 = uint32(int64(o2&0xffff0000) | t&0xffff)
+               o1 = o1&0xffff0000 | (uint32(t)>>16)&0xffff
+               o2 = o2&0xffff0000 | uint32(t)&0xffff
 
                // when laid out, the instruction order must always be o1, o2.
                if ld.Ctxt.Arch.Endian == ld.BigEndian {
@@ -408,8 +407,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                }
                return 0
 
-               // Bits 6 through 29 = (S + A - P) >> 2
        case ld.R_CALLPOWER:
+               // Bits 6 through 29 = (S + A - P) >> 2
                if ld.Ctxt.Arch.Endian == ld.BigEndian {
                        o1 = ld.Be32(s.P[r.Off:])
                } else {
@@ -426,7 +425,7 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
                        ld.Ctxt.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
                }
 
-               *val = int64(o1)&0xfc000003 | t&^0xfc000003
+               *val = int64(o1&0xfc000003 | uint32(t)&^0xfc000003)
                return 0
 
        case ld.R_POWER_TOC: // S + A - .TOC.
index ff2d09f4ae6890d8c24f6d1c1bf388fc7317fa7e..381030dd421306d71dafeca134ead0007b1eb447 100644 (file)
@@ -479,7 +479,7 @@ func relocsym(s *LSym) {
                        // Instead of special casing only amd64, we treat this as an error on all
                        // 64-bit architectures so as to be future-proof.
                        if int32(o) < 0 && Thearch.Ptrsize > 4 && siz == 4 {
-                               Diag("non-pc-relative relocation address is too big: %#x", uint64(o))
+                               Diag("non-pc-relative relocation address is too big: %#x (%#x + %#x)", uint64(o), Symaddr(r.Sym), r.Add)
                                Errorexit()
                        }
 
@@ -546,7 +546,13 @@ func relocsym(s *LSym) {
                        o = Thearch.Archrelocvariant(r, s, o)
                }
 
-               //print("relocate %s %#llux (%#llux+%#llux, size %d) => %s %#llux +%#llx [%llx]\n", s->name, (uvlong)(s->value+off), (uvlong)s->value, (uvlong)r->off, r->siz, r->sym ? r->sym->name : "<nil>", (uvlong)symaddr(r->sym), (vlong)r->add, (vlong)o);
+               if false {
+                       nam := "<nil>"
+                       if r.Sym != nil {
+                               nam = r.Sym.Name
+                       }
+                       fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, r.Variant, o)
+               }
                switch siz {
                default:
                        Ctxt.Cursym = s