llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.04k stars 11.98k forks source link

Missing relocations when linking i686 with -fpie #29294

Closed llvmbot closed 8 years ago

llvmbot commented 8 years ago
Bugzilla Link 28924
Resolution FIXED
Resolved on Aug 31, 2016 18:24
Version unspecified
OS All
Reporter LLVM Bugzilla Contributor
CC @rui314

Extended Description

Compiling for i686-unknown-linux-gnu with -fpie, it looks like lld is missing some relocations, or applying them incorrectly, causing the use of external global variables to fail. I boiled a bug down to this, but am not sure if I can go further, as this is starting to go well outside my expertise.

This is using LLVM r278216, Clang r278213, LLD r278205.

Thanks for investigating!

-------8<-------

$ cat header.h extern int (*global_function)();

static inline int do_global_call() { return global_function(); } $ cat unit1.c

include "header.h"

include

int (*global_function)();

int global_implementation() { return 1234; }

void cu2_call();

int main() { global_function = global_implementation; printf("Global call value: %d\n", do_global_call()); cu2_call(); } $ cat unit2.c

include "header.h"

include

void cu2_call() { printf("Compilation unit 2 global call value: %d\n", do_global_call()); } $ i686-unknown-linux-gnu-clang -Wall -fpie unit1.c -c -o unit1.o $ i686-unknown-linux-gnu-clang -Wall -fpie unit2.c -c -o unit2.o $ i686-unknown-linux-gnu-clang -fpie -fuse-ld=lld -Wl,--allow-multiple-definition unit1.o unit2.o -o testbin.lld duplicate symbol: __x86.get_pc_thunk.bx in /usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu/crti.o and /usr/lib/i386-linux-gnu/libc_nonshared.a(elf-init.oS) $ i686-unknown-linux-gnu-clang -fpie unit1.o unit2.o -o testbin.gld $ ./testbin.lld Global call value: 1234 [1] 21726 segmentation fault ./testbin.lld $ ./testbin.gld Global call value: 1234 Compilation unit 2 global call value: 1234

-------8<------

$ readelf -r testbin.lld

Relocation section '.rel.plt' at offset 0x36c contains 2 entries: Offset Info Type Sym.Value Sym. Name 00013014 00000307 R_386_JUMP_SLOT 000112c0 __libc_start_main 00013018 00000207 R_386_JUMP_SLOT 00000000 printf

$ readelf -r testbin.gld

Relocation section '.rel.dyn' at offset 0x278 contains 1 entries: Offset Info Type Sym.Value Sym. Name 08049784 00000206 R_386_GLOB_DAT 00000000 __gmon_start__

Relocation section '.rel.plt' at offset 0x280 contains 3 entries: Offset Info Type Sym.Value Sym. Name 08049794 00000107 R_386_JUMP_SLOT 00000000 printf 08049798 00000207 R_386_JUMP_SLOT 00000000 gmon_start__ 0804979c 00000307 R_386_JUMP_SLOT 00000000 libc_start_main

llvmbot commented 8 years ago

r280310.

llvmbot commented 8 years ago

The linkonce section (that we don't support) is from glibc. I reported https://sourceware.org/bugzilla/show_bug.cgi?id=20543 to see if they can move to using comdats.

rui314 commented 8 years ago

Thanks. I could reproduce the issue. I was building 64-bit executable instead of 32-bit.

llvmbot commented 8 years ago

Requested repro.cpio, created with LLD_REPRODUCE

llvmbot commented 8 years ago

I cannot reproduce the issue locally. Please makes sure that you are using SVN HEAD. If you are able to reproduce the issue on HEAD, please build the final executable with

i686-unknown-linux-gnu-clang -fpie -fuse-ld=lld -Wl,--allow-multiple-definition unit1.o unit2.o -o testbin.lld -reproduce=repro.cpio

and share repro.cpio with us. That archive file contains all input files so that we can run the same command with the same inputs.

Hi Rui,

I'm pretty sure I'm using SVN head: i686-unknown-linux-gnu-clang -v shows "clang version 4.0.0 (trunk 278216)", and ld.lld -v shows "LLD 4.0 (http://llvm.org/svn/llvm-project/lld/trunk 278216)". The last changed revisions are in my original post.

I've tried to build the final executable with -reproduce=repro.cpio, but it seems my clang doesn't have that option, and my ldd didn't as well. But I did find the LLD_REPRODUCE environment variable in the source and will attach the generated file. Please let me know if this is OK.

Thanks, Sjors

rui314 commented 8 years ago

I cannot reproduce the issue locally. Please makes sure that you are using SVN HEAD. If you are able to reproduce the issue on HEAD, please build the final executable with

i686-unknown-linux-gnu-clang -fpie -fuse-ld=lld -Wl,--allow-multiple-definition unit1.o unit2.o -o testbin.lld -reproduce=repro.cpio

and share repro.cpio with us. That archive file contains all input files so that we can run the same command with the same inputs.