[llvm] [X86] Don't convert local function foo in the same section to foo(%rip) when the offset is near INT32_MIN (PR #98438)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 11 18:52:45 PDT 2024
MaskRay wrote:
> But that's only _one_ of the kinds of errors you can get from such code.
The other kind of errors are prevented by other code, e.g. `isOffsetSuitableForCodeModel` has `return Offset < 16 * 1024 * 1024`.
> We'll also emit a PC32 relocation -- with the user-specified addend included -- for symbols that are _NOT_ in the same section. It won't be an assembler error, then, but will turn into a linker error. A binary can easily be larger than 256MB, in which case this breaks again.
```
define internal void @foo() {
ret void
}
define i64 @main() {
ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -1879048192)
}
define i64 @bar() {
ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 1879048192)
}
```
When `foo` and `main` are in different sections, MC will emit a relocation.
There won't be a linker error, even if `--emit-relocs` is used.
(When ld --emit-relocs converts `.text.foo - 0x70000004 to .text + addend`, the `addend` will be larger than -0x70000004.)
```
% readelf -Wr r.o
Relocation section '.rela.text.main' at offset 0xd0 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000003 0000000200000002 R_X86_64_PC32 0000000000000000 .text.foo - 70000004
```
---
Even when `foo` and `bar` are in the same section, we will not fold the large displacement (0x70000000) into leaq
due to `return Offset < 16 * 1024 * 1024` in `isOffsetSuitableForCodeModel`.
```asm
movl $1879048192, %eax # imm = 0x70000000
leaq foo(%rax), %rax
retq
```
> I really don't think magic numbers are the right answer here. We either need to formalize this sort of code as invalid, or else modify codegen to not use a 32-bit-limited fixup/relocation for code like this.
The magic number is about the input section section size, instead of the output section size.
If the leaq optimization of a function symbol with a negative offset like -0x70000000 isn't that useful, I could also drop it completely.
https://github.com/llvm/llvm-project/pull/98438
More information about the llvm-commits
mailing list