From 1a472026dae372fc92845899dff0371ed6fa56ae Mon Sep 17 00:00:00 2001 From: Gustavo Niemeyer Date: Thu, 27 Jan 2011 14:09:03 -0500 Subject: [PATCH] 6l: Relocate CMOV* instructions The linker avoids a GOT indirection by turning a MOV into a LEA, but with x86-64 GCC has started emitting CMOV* instructions which break the existing logic. This will generate errors such as: unexpected GOT reloc for non-dynamic symbol luaO_nilobject_ The CMOV* instructions may be emitted with normal code like: if (o >= L->top) return cast(TValue *, luaO_nilobject); else return o; Which gets compiled into (relocation offset at 1b): 13: 48 3b 47 10 cmp 0x10(%rdi),%rax 17: 48 0f 43 05 00 00 00 cmovae 0x0(%rip),%rax 1e: 00 This change will allow the indirection through the GOT to avoid the problem in those cases. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4071044 --- src/cmd/6l/asm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 2119395b38..2e401db913 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -206,15 +206,15 @@ adddynrel(Sym *s, Reloc *r) case 256 + R_X86_64_GOTPCREL: if(targ->dynimpname == nil || targ->dynexport) { // have symbol - // turn MOVQ of GOT entry into LEAQ of symbol itself - if(r->off < 2 || s->p[r->off-2] != 0x8b) { - diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ->name); + if(r->off >= 2 && s->p[r->off-2] == 0x8b) { + // turn MOVQ of GOT entry into LEAQ of symbol itself + s->p[r->off-2] = 0x8d; + r->type = D_PCREL; + r->add += 4; return; } - s->p[r->off-2] = 0x8d; - r->type = D_PCREL; - r->add += 4; - return; + // unknown instruction (CMOV* maybe), use GOT + targ->dynimpname = targ->name; } addgotsym(targ); r->type = D_PCREL;