[PATCH] D35944: [ELF] Disable relocation validation when targeting weak undefined symbols

ben via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 2 09:24:36 PDT 2017


bd1976llvm added a comment.

> Rafael via mailing list:



> 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

Hi Rafael,

The behaviour for weak references is different across different platforms.

For example on arm and power you can write.

void f1() __attribute__((weak));
void main() {f1();}

Which can be expected to work correctly. However, this may fault on x86_64.

> I think that is a bug in llvm on x86_64. I will take a quick look.

That does look like a bug. However, in general the codegen should not account for the possibility that the reference is unresolved - because we want to generate identical code as for strong references for the case that the weak reference is resolved. i.e:

"void f1() __attribute__((weak)); void f2() {f1();}" and "void f1(); void f2() {f1();}"

should codegen identically.

Another way to see what the right behaviour should be here is to draw a comparison with the lld feature "--unresolved-symbols=ignore-all".

If I link this example:

void f1(); void main() {f1();}

At a high address, e.g. "lld main.o -Ttext=0xbadbadbad" - I get an undefined symbol error.  If I link the same example with: "lld main.o -Ttext=0xbadbadbad --unresolved-symbols=ignore-all" the link should succeed. It would clearly be a bug here to warn about an overflowing relocation - the same logic should apply to weak references.


https://reviews.llvm.org/D35944





More information about the llvm-commits mailing list