Fāng-ruì Sòng via llvm-dev
2021-Jan-10 06:45 UTC
[llvm-dev] (LLD / lto ) How to avoid GOT code generation
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.
Fāng-ruì Sòng via llvm-dev
2021-Jan-10 06:51 UTC
[llvm-dev] (LLD / lto ) How to avoid GOT code generation
On Sat, Jan 9, 2021 at 10:45 PM Fāng-ruì Sòng <maskray at google.com> wrote:> > 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.I'd say R_X86_64_GOTOFF64 is a direct access relocation type, not a GOT indirection relocation type. A GOT indirection relocation type should compute to a place in GOT (e.g. G+A, G+GOT+A-P), but R_X86_64_GOTOFF64 (S+A-GOT) is different. "GOT" refers to the address of _GLOBAL_OFFSET_TABLE_. The large code model needs the GOT base ("GOT" in x86-64 psABI: "Represents the address of the global offset table") as a fixed place in the text segment to compute the addresses of symbols. The GOT base is not used in the GOT indirection manner.