[PATCH] D34355: [LLD][ELF] Define _GLOBAL_OFFSET_TABLE_ to base of .got for ARM

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 20 07:30:20 PDT 2017


Thanks for the comments,

I think that this is a little stronger than just bug compatibility. I
would characterise this as lld not supporting a platform ABI
convention for the value of _GLOBAL_OFFSET_TABLE_. The majority of
objects, especially modern ones don't require it to have the exact
value as they use relocations that don't use the value of the symbol.

Doing some research in binutils and in the respective ABIs I've found
out that _GLOBAL_OFFSET_TABLE_ is defined as:
start of .got:
ARM
AArch64
Mips

start of .got.plt (which should be the end of .got for the default
.got .got.plt ordering)
386
amd64

PPC32 defines _GLOBAL_OFFSET_TABLE_ as .got + 0x8000 (however lld
doesn't support any .got producing relocs for PPC32)
PPC64 doesn't use _GLOBAL_OFFSET_TABLE_ to the best of my knowledge,
there is an equivalent symbol called .TOC.

I'll post an update to the patch as I think that it should be possible
to set the value without a large increase in complexity.

Peter


On 19 June 2017 at 21:42, Rafael Avila de Espindola
<rafael.espindola at gmail.com> wrote:
> Peter Smith via Phabricator <reviews at reviews.llvm.org> writes:
>
>> Index: ELF/Writer.cpp
>> ===================================================================
>> --- ELF/Writer.cpp
>> +++ ELF/Writer.cpp
>> @@ -825,9 +825,16 @@
>>    // The situation is even stranger on x86_64 where the assembly doesn't
>>    // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
>>    // an undefined symbol in the .o files.
>> -  // Given that the symbol is effectively unused, we just create a dummy
>> -  // hidden one to avoid the undefined symbol error.
>> -  Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_");
>> +  // For ARM the clang assembler may not have treated _GLOBAL_OFFSET_TABLE_ as
>> +  // special so we may encounter a R_ARM_REL32 to _GLOBAL_OFFSET_TABLE_ which
>> +  // will only evaluate correctly if _GLOBAL_OFFSET_TABLE_ is at the base of the
>> +  // .got section. for other architectures, given that the symbol is
>> +  // effectively unused, we just create a dummy hidden one to avoid the
>> +  // undefined symbol error.
>> +  if (Config->EMachine == EM_ARM && InX::Got)
>> +    addOptionalRegular<ELFT>("_GLOBAL_OFFSET_TABLE_", InX::Got, 0);
>> +  else
>> +    Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_");
>
> Looking at the llvm side, I kept wondering why do ABIs even have
> relocations like R_386_GOTPC. Why not just have linker defined symbols
> _GLOBAL_OFFSET_TABLE_ and _GLOBAL_OFFSET_TABLE_END_?
>
> I also found more cases where MC doesn't convert _GLOBAL_OFFSET_TABLE_,
> so think I am not that opposed to something like this, but I would change
> it a bit. _GLOBAL_OFFSET_TABLE_ should always point to the start or end
> of the got depending on the architecture.
>
> Cheers,
> Rafael


More information about the llvm-commits mailing list