Factor some logic into ShouldRelocOnSymbol. This simplifies the code and
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 30 Sep 2010 20:18:35 +0000 (20:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 30 Sep 2010 20:18:35 +0000 (20:18 +0000)
fixes some cases where we were producing relocations with at symbol that
should use a section instead.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115194 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/ELFObjectWriter.cpp
test/MC/ELF/basic-elf.ll
test/MC/ELF/relocation.s

index a80e7b6b08a39dcc6852eca17f2c6f3961ae862c..1890da72e0ecbb743df7a614fbb4d9c1682ed4eb 100644 (file)
@@ -500,11 +500,22 @@ void ELFObjectWriterImpl::WriteSymbolTable(MCDataFragment *F,
   }
 }
 
-static const MCSymbolData *getAtom(const MCSymbolData &SD) {
-  if (!SD.getFragment())
-    return 0;
+static bool ShouldRelocOnSymbol(const MCSymbolData &SD,
+                                const MCValue &Target) {
+  const MCSymbol &Symbol = SD.getSymbol();
+  if (Symbol.isUndefined())
+    return true;
+
+  const MCSectionELF &Section =
+    static_cast<const MCSectionELF&>(Symbol.getSection());
+
+  if (Section.getFlags() & MCSectionELF::SHF_MERGE)
+    return Target.getConstant() != 0;
 
-  return SD.getFragment()->getAtom();
+  if (SD.isExternal())
+    return true;
+
+  return false;
 }
 
 // FIXME: this is currently X86/X86_64 only
@@ -522,48 +533,30 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
   if (!Target.isAbsolute()) {
     const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
     MCSymbolData &SD = Asm.getSymbolData(*Symbol);
-    const MCSymbolData *Base = getAtom(SD);
     MCFragment *F = SD.getFragment();
 
-    // Avoid relocations for cases like jumps and calls in the same file.
+    // Check that this case has already been fully resolved before we get
+    // here.
     if (Symbol->isDefined() && !SD.isExternal() &&
         IsPCRel &&
         &Fragment->getParent()->getSection() == &Symbol->getSection()) {
-      uint64_t FixupAddr = Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
-      FixedValue = Layout.getSymbolAddress(&SD) + Target.getConstant() - FixupAddr;
+      llvm_unreachable("We don't need a relocation in this case.");
       return;
     }
 
-    if (Base) {
-      if (Base != &SD) {
-        Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
-
-        MCSectionData *FSD = F->getParent();
-        // Offset of the symbol in the section
-        Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
-      } else
-        Index = getSymbolIndexInSymbolTable(Asm, Symbol);
-      Addend = Value;
-      // Compensate for the addend on i386.
-      if (Is64Bit)
-        Value = 0;
-    } else {
-      if (F) {
-        // Index of the section in .symtab against this symbol
-        // is being relocated + 2 (empty section + abs. symbols).
-        Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
-
-        MCSectionData *FSD = F->getParent();
-        // Offset of the symbol in the section
-        Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
-      } else {
-        Index = getSymbolIndexInSymbolTable(Asm, Symbol);
-      }
-      Addend = Value;
-      // Compensate for the addend on i386.
-      if (Is64Bit)
-        Value = 0;
-    }
+    bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target);
+    if (!RelocOnSymbol) {
+      Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
+
+      MCSectionData *FSD = F->getParent();
+      // Offset of the symbol in the section
+      Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
+    } else
+      Index = getSymbolIndexInSymbolTable(Asm, Symbol);
+    Addend = Value;
+    // Compensate for the addend on i386.
+    if (Is64Bit)
+      Value = 0;
   }
 
   FixedValue = Value;
index b9be0678a71bb07f69d4d2d73ca3425bf36cb07b..f130ced7bbb465acbaba7660a2390243d2acdf32 100644 (file)
@@ -101,7 +101,7 @@ declare i32 @puts(i8* nocapture) nounwind
 ; 64:     # Relocation 2
 ; 64:     (('r_offset', 15)
 ; 64:      ('r_type', 10)
-; 64:      ('r_addend', 0)
+; 64:      ('r_addend', 6)
 ; 64:     ),
 ; 64:     # Relocation 3
 ; 64:     (('r_offset', 20)
index a8f4e5f29d3bb1d3925f9fe5bdfad2ad0dfc96a8..45c863e6de5627d52b7574c19fa5b1e125993e13 100644 (file)
@@ -10,39 +10,48 @@ bar:
         movq   bar, %rdx         // R_X86_64_32S
 .long bar                         // R_X86_64_32
 
+// CHECK:  # Section 1
+// CHECK: (('sh_name', 1) # '.text'
+
+// CHECK:   # Symbol 2
+// CHECK: (('st_name', 0) # ''
+// CHECK:  ('st_bind', 0)
+// CHECK   ('st_type', 3)
+// CHECK:  ('st_other', 0)
+// CHECK:  ('st_shndx', 1)
 
 // CHECK: # Relocation 0
 // CHECK-NEXT:  (('r_offset', 1)
-// CHECK-NEXT:   ('r_sym',
+// CHECK-NEXT:   ('r_sym', 2)
 // CHECK-NEXT:   ('r_type', 10)
 // CHECK-NEXT:   ('r_addend',
 
 // CHECK: # Relocation 1
 // CHECK-NEXT:  (('r_offset', 8)
-// CHECK-NEXT:   ('r_sym',
+// CHECK-NEXT:   ('r_sym', 2)
 // CHECK-NEXT:   ('r_type', 11)
 // CHECK-NEXT:   ('r_addend',
 
 // CHECK: # Relocation 2
 // CHECK-NEXT:  (('r_offset', 19)
-// CHECK-NEXT:   ('r_sym',
+// CHECK-NEXT:   ('r_sym', 2)
 // CHECK-NEXT:   ('r_type', 11)
 // CHECK-NEXT:   ('r_addend',
 
 // CHECK: # Relocation 3
 // CHECK-NEXT:  (('r_offset', 26)
-// CHECK-NEXT:   ('r_sym',
+// CHECK-NEXT:   ('r_sym', 2)
 // CHECK-NEXT:   ('r_type', 11)
 // CHECK-NEXT:   ('r_addend',
 
 // CHECK: # Relocation 4
 // CHECK-NEXT:  (('r_offset', 34)
-// CHECK-NEXT:   ('r_sym',
+// CHECK-NEXT:   ('r_sym', 2)
 // CHECK-NEXT:   ('r_type', 11)
 // CHECK-NEXT:   ('r_addend',
 
 // CHECK: # Relocation 5
 // CHECK-NEXT:  (('r_offset', 38)
-// CHECK-NEXT:   ('r_sym',
+// CHECK-NEXT:   ('r_sym', 2)
 // CHECK-NEXT:   ('r_type', 10)
 // CHECK-NEXT:   ('r_addend',