From: Austin Clements Date: Tue, 25 Nov 2014 21:00:25 +0000 (-0500) Subject: [dev.cc] 9l: make R_CALLPOWER like ELF's R_PPC64_REL24 X-Git-Tag: go1.5beta1~2688^2~3 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6f755f2f8f4665d44745b4065cd54a90eba0bde9;p=gostls13.git [dev.cc] 9l: make R_CALLPOWER like ELF's R_PPC64_REL24 These accomplished the same thing, but R_CALLPOWER expected the whole instruction to be in the addend (and completely overwrote what was in the text section), while R_PPC64_REL24 overwrites only bits 6 through 24 of whatever was in the text section. Make R_CALLPOWER work like R_PPC64_REL24 to ease the implementation of dynamic linking. LGTM=rsc R=rsc CC=golang-codereviews, minux https://golang.org/cl/177430043 --- diff --git a/src/cmd/9l/asm.c b/src/cmd/9l/asm.c index b8ca777c35..65a36285d8 100644 --- a/src/cmd/9l/asm.c +++ b/src/cmd/9l/asm.c @@ -65,14 +65,6 @@ needlib(char *name) int nelfsym = 1; -// b is the addresses, a is the I-form branch instruction template, peform -// addition so that the instruction jumps to address (offset) b. -static int32 -braddoff(int32 a, int32 b) -{ - return (((uint32)a) & 0xfc000003U) | (0x03fffffcU & (uint32)((a & 0x3fffffcU) + b)); -} - void adddynrela(LSym *rel, LSym *s, Reloc *r) { @@ -160,7 +152,19 @@ archreloc(Reloc *r, LSym *s, vlong *val) *val = ((vlong)o2 << 32) | o1; return 0; case R_CALLPOWER: - *val = braddoff((uint32)r->add, (int32)(symaddr(r->sym) - (s->value + r->off))); + // Bits 6 through 29 = (S + A - P) >> 2 + if(ctxt->arch->endian == BigEndian) + o1 = be32(s->p + r->off); + else + o1 = le32(s->p + r->off); + + t = symaddr(r->sym) + r->add - (s->value + r->off); + if(t & 3) + ctxt->diag("relocation for %s is not aligned: %lld", s->name, t); + if(t << 6 >> 6 != t) + ctxt->diag("relocation for %s is too big: %lld", s->name, t); + + *val = (o1 & 0xfc000003U) | (t & ~0xfc000003U); return 0; } return -1; diff --git a/src/liblink/asm9.c b/src/liblink/asm9.c index 3c125b3b0f..5a379270d1 100644 --- a/src/liblink/asm9.c +++ b/src/liblink/asm9.c @@ -1589,7 +1589,7 @@ asmout(Link *ctxt, Prog *p, Optab *o, int32 *out) ctxt->diag("odd branch target address\n%P", p); v &= ~03; } - rel->add = o1 | (v & 0x03FFFFFC); + rel->add = v; rel->type = R_CALLPOWER; } break;