[PATCH] D140279: Adds support for GOT relocations to i386/ELF backend
Lang Hames via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 9 20:48:07 PST 2023
lhames added inline comments.
================
Comment at: llvm/test/ExecutionEngine/JITLink/i386/ELF_external_to_absolute_conversion.s:27-31
+ addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax
+ movl $0, -4(%ebp)
+ movl a at GOTOFF(%eax), %eax
+ addl $4, %esp
+ popl %ebp
----------------
jain98 wrote:
> lhames wrote:
> > This sequence is trying to access the non-existent GOT-entry, which is why it crashes at runtime.
> >
> > I think the assembly can be reduced to the i386 equivalent of the x86-64 sequence:
> > ```
> > .text
> > .globl main
> > .p2align 4, 0x90
> > .type main, at function
> > main:
> > .L0$pb:
> > movl $_GLOBAL_OFFSET_TABLE_-.L0$pb, %eax
> > movl $foo at GOTOFF, %eax
> > xorl %eax, %eax
> > retl
> > .size main, .-main
> > ```
> > The '$' symbol at the start of the expression means that we're treating the result of the expression as an immediate, not an address to be loaded from. The immediate values that we move into `%eax` will be zeros, but since `%eax` isn't used anyway we can disregard that.
> > This sequence is trying to access the non-existent GOT-entry, which is why it crashes at runtime.
>
> I didn't quite get that. I //think//, you're referring to this instruction -
> ```
> movl a at GOTOFF(%eax), %eax
> ```
> I thought this instruction was using `a`'s offset from the GOT symbol - not accessing any GOT entry? Could you point to the specific instruction that you were referring to in your comment?
>
> I do think I understand why the seg fault might be happening though. Essentially `a at GOTOFF(%eax)` ends up being `a at GOTOFF(0x00000000)`? Which is likely out of the JITLink process' memory. If that is indeed the case, I have another question. The assembly that I used from the test was actually generated by Clang. Is it just that Clang uses a different linker that can actually handle the code that it's producing without seg-faulting?
> I thought this instruction was using a's offset from the GOT symbol - not accessing any GOT entry? Could you point to the specific instruction that you were referring to in your comment?
Oh you're right -- `GOTOFF` references the symbol, not the GOT entry for the symbol. Sorry for the confusion!
In that case you're absolutely right -- this should work even if there's no GOT synthesized. It looks like the problem is that the `R_386_GOTPC` relocation has an addend embedded in it, but it's not being included in the Edge construction:
```
ELF_external_to_absolute_conversion.i386.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 50 push %eax
4: e8 00 00 00 00 call 9 <main+0x9>
9: 58 pop %eax
a: 81 c0 03 00 00 00 add $0x3,%eax. <-- 0x00000003 addend embedded here at fixup location.
10: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
17: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
1d: 83 c4 04 add $0x4,%esp
20: 5d pop %ebp
21: c3 ret
```
Edge from debugging output:
```
0xb7ab600c (block + 0x0000000c), addend = +0x00000000, kind = Delta32, target = _GLOBAL_OFFSET_TABLE_
```
You just need to read that addend out when constructing the edge. E.g. here's the MachO_x86_64 backend doing something similar: https://github.com/llvm/llvm-project/blob/5a58b19f9c93f3ac51bcde318508131ae78aa10c/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp#L342
The missing addend is causing the variable reference to point to the page _before_ the data section, which is usually outside allocated memory -- that's triggering the crash, not the missing GOT.
Once you fix that I think your original test case should just work -- sorry for the bad advice above!
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D140279/new/
https://reviews.llvm.org/D140279
More information about the llvm-commits
mailing list