[llvm-dev] [LLD] Incorrect comparision of pointers to function defined in DSO

Simon Atanasyan via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 8 07:55:51 PST 2016


It looks like I have found a bug in LLD. Suppose DSO defines a global
variable 'data' and initializes it by the address of function
'set_data' defined in the same DSO. If an executable file (linked by
LLD) gets address of the '&set_data' function and compares it with a
value stored in the 'data' variable it gets different result. If the
executable is linked by BFD or Gold linker it gets the same result.

Right now I do not have a time to investigate this problem further. I
will plan to do that later. But maybe the reason of this problem is
obvious to somebody?

The reproduction script:

% cat so.c
void set_data(void *v) {}
void *data = &set_data;

% cat main.c
int printf(const char *, ...);

extern void *data;
void set_data(void *v);

int main(void)
  printf("%p = %p\n", &set_data, data);

% clang -fPIC -shared so.c -o libdump.so
% clang -c main.c

% clang main.o -Wl,-rpath -Wl,. -L. -ldump
% ./a.out
0x400600 = 0x400600  # The same addresses

% lld -flavor gnu --sysroot=/ --build-id --no-add-needed --eh-frame-hdr \
    -m elf_x86_64 --hash-style=both \
    -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
    /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o \
    /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o \
    -L. -L/usr/lib/gcc/x86_64-linux-gnu/4.7 \
    -L/usr/lib/x86_64-linux-gnu \
    -L/usr/lib -L/lib/x86_64-linux-gnu -L/lib \
    -L/usr/lib/x86_64-linux-gnu -L/usr/lib \
    main.o -rpath . -ldump -lgcc --as-needed -lgcc_s --no-as-needed \
    -lc -lgcc --as-needed -lgcc_s --no-as-needed \
    /usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o \
% ./a.out
0x11250 = 0x7f02915bd6b0 # garbage in 'data'

Simon Atanasyan

More information about the llvm-dev mailing list