[PATCH] D35944: [ELF] Disable relocation validation when targeting weak undefined symbols
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 1 16:27:56 PDT 2017
ben via Phabricator <reviews at reviews.llvm.org> writes:
> bd1976llvm added a comment.
>
> Hi Rui,
>
>> Is that a real scenario?
>
> This absolutely is a real example. In fact that is the canonical code sequence for using weak symbols.
>
>> I mean, if function foo is defined in the same compilation unit as main, it is resolved locally, and if function foo is not defined in the same compilation unit as main, then the compiler emits a call instruction that can jump to any address (because the compiler doesn't know where foo will be after linking), no?
>
> I'm afraid not (I am skipping some platform specific details here) but in general the compiler will codegen so that the "if (foo)" test uses an absolute relocation but it is free to use any valid code sequence for the call to foo. For example, when using the small code model on the x86_64 platform the compiler would be expected to use codegen that requires a 32 bit relative relocation for the call. For power-pc the call would be expected to require a 24 bit relative relocation etc...
But isn't it invalid to ask for small code model and use high addresses?
Clang's behavior is inconsistent among architectures. For example, given
--------------------------------------
extern int foo1 __attribute__((weak));
int *bar1() { return &foo1; }
extern int foo2;
int *bar2() { return &foo2; }
--------------------------------------
And the command line
clang -target aarch64-pc-linux -S -Os test.c -fPIE -mpie-copy-relocations
We get
adrp x0, :got:foo1
ldr x0, [x0, :got_lo12:foo1]
...
adrp x0, foo2
add x0, x0, :lo12:foo2
but for x86_64 clang fails to take into consideration the fact that 0
might be out of range:
leaq foo1(%rip), %rax
retq
leaq foo2(%rip), %rax
retq
I think that is a bug in llvm on x86_64. I will take a quick look.
Cheers,
Rafael
More information about the llvm-commits
mailing list