[llvm-dev] (LLD / lto ) How to avoid GOT code generation

Fāng-ruì Sòng via llvm-dev llvm-dev at lists.llvm.org
Sat Jan 9 22:45:42 PST 2021


On Sat, Jan 9, 2021 at 12:03 PM Moshtaghi, Alireza via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
>
> Hi
>
> I’m generating a special shared object in x86_64 large memory model (-mcmodel=large).
>
> For this object, I pass -z notext to lld to leave the text relocations alone and normally it builds and works with no problem.
>
> But when I add link time optimization, lld generates R_X86_64_GOTOFF64 which stops itself from linking. (Note that when I objdump -r on my elf objects without lto, this relocation is not generated; but for some reason lld decides to treat the non pic lto object as a pic object and generate got/pic code)
>
> How can I tell lld to not generate GOT / PIC code ?
>
>
>
> Here is the example:
>
> When I compile as follows, my shared lib is generated and works fine
>
> clang -mcmodel=large -o sample.o -c sample.c.  # -flto=thin fails
>
> ld.lld -Bshareable -z notext -o out.so sample.o
>
>
>
> but when I compile with -flto=thin, lld errors that R_X86_64_GOTOFF64 can’t be used against foo and foo_call and wants me to compile with -fPIC but I don’t want to use PIC and GOT
>
>
>
> sample.c :
>
> extern int foo;
>
> int* bar = &foo;
>
>
>
> int foo_call (int, int *);
>
>
>
> int foo_call (int a, int *b) {
>
>   return a+ *b;
>
> }
>
>
>
> int dummy (void) {
>
>   int *fooptr = &foo;
>
>   return foo_call (1, fooptr);
>
> }

clang -fpic -flto -mcmodel=large -o sample.o -c sample.c will work.

Your compile mode is -fno-pic (Clang default for Linux), which can
only be linked in -no-pie mode.
-fpie is compatible with -no-pie and -pie.
-fpic is compatible with -no-pie, -pie and -shared (-Bsharable).

-fno-pic + -shared can sometimes work, work in more cases with -z
notext, but still not always.

For this case: the formula for R_X86_64_GOTOFF64 is S+A-GOT where S
represents the symbol value.
Since foo is undefined, the relocation cannot be resolved at link
time. LLD does not produce a dynamic relocation
because R_X86_64_GOTOFF64 is not a generally acceptable dynamic
relocation type by ld.so implementations.


More information about the llvm-dev mailing list