Add support for the _GLOBAL_OFFSET_TABLE_ symbol.

llvm-svn: 248490
This commit is contained in:
Rafael Espindola 2015-09-24 13:34:01 +00:00
parent aed6dde955
commit d27adc42e6
3 changed files with 27 additions and 0 deletions

View File

@ -61,6 +61,23 @@ template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
return;
EntrySym = new (Alloc) Undefined<ELFT>("_start", Undefined<ELFT>::Synthetic);
resolve<ELFT>(EntrySym);
// In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol is magical
// and is used to produce a R_386_GOTPC relocation.
// The R_386_GOTPC relocation value doesn't actually depend on the
// symbol value, so it could use an index of STN_UNDEF which, according to the
// spec, means the symbol value is 0.
// Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
// the object file.
// 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.
DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN);
auto Got = new (Alloc) DefinedAbsolute<ELFT>(
"_GLOBAL_OFFSET_TABLE_", DefinedAbsolute<ELFT>::IgnoreUndef);
resolve<ELFT>(Got);
}
template <class ELFT> void SymbolTable::addELFFile(ELFFileBase *File) {

View File

@ -159,6 +159,8 @@ template <class ELFT> class DefinedAbsolute : public Defined<ELFT> {
typedef typename Base::Elf_Sym Elf_Sym;
public:
static Elf_Sym IgnoreUndef;
explicit DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
: Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {}
@ -167,6 +169,9 @@ public:
}
};
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::IgnoreUndef;
template <class ELFT> class DefinedCommon : public Defined<ELFT> {
typedef ELFSymbolBody<ELFT> Base;
typedef typename Base::Elf_Sym Elf_Sym;

View File

@ -0,0 +1,5 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
// RUN: lld -flavor gnu2 %t -o %t2
.global _start
_start:
.long _GLOBAL_OFFSET_TABLE_