Produce a undefined reference to _GLOBAL_OFFSET_TABLE_ when needed.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 5 Oct 2010 15:48:37 +0000 (15:48 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 5 Oct 2010 15:48:37 +0000 (15:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115623 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/ELFObjectWriter.cpp
test/MC/ELF/got.s

index b9d2acea4612fb74d880eebc289f1baf3b3d022f..b33b04703081d43a193ecde9e215095453903bf6 100644 (file)
@@ -70,6 +70,17 @@ static bool isFixupKindX86PCRel(unsigned Kind) {
   }
 }
 
+static bool RelocNeedsGOT(unsigned Type) {
+  switch (Type) {
+  default:
+    return false;
+  case ELF::R_X86_64_GOT32:
+  case ELF::R_X86_64_PLT32:
+  case ELF::R_X86_64_GOTPCREL:
+    return true;
+  }
+}
+
 namespace {
 
   class ELFObjectWriterImpl {
@@ -133,6 +144,8 @@ namespace {
 
     int NumRegularSections;
 
+    bool NeedsGOT;
+
     ELFObjectWriter *Writer;
 
     raw_ostream &OS;
@@ -153,7 +166,7 @@ namespace {
   public:
     ELFObjectWriterImpl(ELFObjectWriter *_Writer, bool _Is64Bit,
                         bool _HasRelAddend, Triple::OSType _OSType)
-      : Writer(_Writer), OS(Writer->getStream()),
+      : NeedsGOT(false), Writer(_Writer), OS(Writer->getStream()),
         Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend),
         OSType(_OSType) {
     }
@@ -647,6 +660,9 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
     }
   }
 
+  if (RelocNeedsGOT(Type))
+    NeedsGOT = true;
+
   ELFRelocationEntry ERE;
 
   ERE.Index = Index;
@@ -677,6 +693,14 @@ ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
 }
 
 void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
+  // FIXME: Is this the correct place to do this?
+  if (NeedsGOT) {
+    llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
+    MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
+    MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
+    Data.setExternal(true);
+  }
+
   // Build section lookup table.
   NumRegularSections = Asm.size();
   DenseMap<const MCSection*, uint8_t> SectionIndexMap;
index 47b0285a99dceeabf7f965cff41bd9959b054cde..866d25b8e05fa7f49b5353b751e36a0cb7925ea1 100644 (file)
@@ -1,10 +1,14 @@
 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump  | FileCheck %s
 
-// Test that this produces a R_X86_64_GOT32.
+// Test that this produces a R_X86_64_GOT32 and that we have an undefined
+// reference to _GLOBAL_OFFSET_TABLE_.
 
         movl   foo@GOT, %eax
         movl   foo@GOTPCREL(%rip), %eax
 
+// CHECK:     (('st_name', 5) # '_GLOBAL_OFFSET_TABLE_'
+// CHECK-NEXT: ('st_bind', 1)
+
 // CHECK:      ('_relocations', [
 // CHECK-NEXT:   # Relocation 0
 // CHECK-NEXT:    (('r_offset',