[lld] r248490 - Add support for the _GLOBAL_OFFSET_TABLE_ symbol.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 06:34:02 PDT 2015


Author: rafael
Date: Thu Sep 24 08:34:01 2015
New Revision: 248490

URL: http://llvm.org/viewvc/llvm-project?rev=248490&view=rev
Log:
Add support for the _GLOBAL_OFFSET_TABLE_ symbol.

Added:
    lld/trunk/test/elf2/global_offset_table.s
Modified:
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.h

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=248490&r1=248489&r2=248490&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Sep 24 08:34:01 2015
@@ -61,6 +61,23 @@ template <class ELFT> void SymbolTable::
     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) {

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=248490&r1=248489&r2=248490&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Sep 24 08:34:01 2015
@@ -159,6 +159,8 @@ template <class ELFT> class DefinedAbsol
   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;

Added: lld/trunk/test/elf2/global_offset_table.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/global_offset_table.s?rev=248490&view=auto
==============================================================================
--- lld/trunk/test/elf2/global_offset_table.s (added)
+++ lld/trunk/test/elf2/global_offset_table.s Thu Sep 24 08:34:01 2015
@@ -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_




More information about the llvm-commits mailing list