Commit 1a472026 authored by Gustavo Niemeyer's avatar Gustavo Niemeyer Committed by Russ Cox

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
parent a3120f67
...@@ -206,15 +206,15 @@ adddynrel(Sym *s, Reloc *r) ...@@ -206,15 +206,15 @@ adddynrel(Sym *s, Reloc *r)
case 256 + R_X86_64_GOTPCREL: case 256 + R_X86_64_GOTPCREL:
if(targ->dynimpname == nil || targ->dynexport) { if(targ->dynimpname == nil || targ->dynexport) {
// have symbol // have symbol
// turn MOVQ of GOT entry into LEAQ of symbol itself if(r->off >= 2 && s->p[r->off-2] == 0x8b) {
if(r->off < 2 || s->p[r->off-2] != 0x8b) { // turn MOVQ of GOT entry into LEAQ of symbol itself
diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ->name); s->p[r->off-2] = 0x8d;
r->type = D_PCREL;
r->add += 4;
return; return;
} }
s->p[r->off-2] = 0x8d; // unknown instruction (CMOV* maybe), use GOT
r->type = D_PCREL; targ->dynimpname = targ->name;
r->add += 4;
return;
} }
addgotsym(targ); addgotsym(targ);
r->type = D_PCREL; r->type = D_PCREL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment