[llvm-commits] [llvm] r114786 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp lib/MC/MCELFStreamer.cpp lib/Target/X86/X86AsmBackend.cpp test/MC/ELF/basic-elf.ll test/MC/ELF/merge.s

Rafael Espindola rafael.espindola at gmail.com
Fri Sep 24 22:42:19 PDT 2010


Author: rafael
Date: Sat Sep 25 00:42:19 2010
New Revision: 114786

URL: http://llvm.org/viewvc/llvm-project?rev=114786&view=rev
Log:
Move ELF to HasReliableSymbolDifference=true. Also take the opportunity to put
symbols defined in merge sections in independent atoms.

Added:
    llvm/trunk/test/MC/ELF/merge.s
Modified:
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MCELFStreamer.cpp
    llvm/trunk/lib/Target/X86/X86AsmBackend.cpp
    llvm/trunk/test/MC/ELF/basic-elf.ll

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Sat Sep 25 00:42:19 2010
@@ -487,6 +487,13 @@
   }
 }
 
+static const MCSymbolData *getAtom(const MCSymbolData &SD) {
+  if (!SD.getFragment())
+    return 0;
+
+  return SD.getFragment()->getAtom();
+}
+
 // FIXME: this is currently X86/X86_64 only
 void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
                                            const MCAsmLayout &Layout,
@@ -502,7 +509,7 @@
   if (!Target.isAbsolute()) {
     const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
     MCSymbolData &SD = Asm.getSymbolData(*Symbol);
-    const MCSymbolData *Base = Asm.getAtom(Layout, &SD);
+    const MCSymbolData *Base = getAtom(SD);
     MCFragment *F = SD.getFragment();
 
     // Avoid relocations for cases like jumps and calls in the same file.
@@ -515,7 +522,7 @@
     }
 
     if (Base) {
-      if (F && !SD.isExternal()) {
+      if (Base != &SD) {
         Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
 
         MCSectionData *FSD = F->getParent();
@@ -523,8 +530,6 @@
         Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
       } else
         Index = getSymbolIndexInSymbolTable(Asm, Symbol);
-      if (Base != &SD)
-        Value += Layout.getSymbolAddress(&SD) - Layout.getSymbolAddress(Base);
       Addend = Value;
       // Compensate for the addend on i386.
       if (Is64Bit)
@@ -537,11 +542,14 @@
 
         MCSectionData *FSD = F->getParent();
         // Offset of the symbol in the section
-        Addend = Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
+        Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
       } else {
-        FixedValue = Value;
-        return;
+        Index = getSymbolIndexInSymbolTable(Asm, Symbol);
       }
+      Addend = Value;
+      // Compensate for the addend on i386.
+      if (Is64Bit)
+        Value = 0;
     }
   }
 

Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Sat Sep 25 00:42:19 2010
@@ -149,20 +149,43 @@
   SetSectionText();
 }
 
+static bool isSymbolLinkerVisible(const MCAssembler &Asm,
+                                  const MCSymbolData &Data) {
+  const MCSymbol &Symbol = Data.getSymbol();
+  // Absolute temporary labels are never visible.
+  if (!Symbol.isInSection())
+    return false;
+
+  if (Asm.getBackend().doesSectionRequireSymbols(Symbol.getSection()))
+    return true;
+
+  if (!Data.isExternal())
+    return false;
+
+  return Asm.isSymbolLinkerVisible(Symbol);
+}
+
 void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
 
+  Symbol->setSection(*CurSection);
+
+  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
+  // We have to create a new fragment if this is an atom defining symbol,
+  // fragments cannot span atoms.
+  if (isSymbolLinkerVisible(getAssembler(), SD))
+    new MCDataFragment(getCurrentSectionData());
+
   // FIXME: This is wasteful, we don't necessarily need to create a data
   // fragment. Instead, we should mark the symbol as pointing into the data
   // fragment if it exists, otherwise we should just queue the label and set its
   // fragment pointer when we emit the next fragment.
   MCDataFragment *F = getOrCreateDataFragment();
-  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
   SD.setFragment(F);
   SD.setOffset(F->getContents().size());
-
-  Symbol->setSection(*CurSection);
 }
 
 void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
@@ -476,7 +499,37 @@
 }
 
 void MCELFStreamer::Finish() {
-  getAssembler().Finish();
+  // FIXME: We create more atoms than it is necessary. Some relocations to
+  // merge sections can be implemented with section address + offset,
+  // figure out which ones and why.
+
+  // First, scan the symbol table to build a lookup table from fragments to
+  // defining symbols.
+  DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
+  for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(),
+         ie = getAssembler().symbol_end(); it != ie; ++it) {
+    if (isSymbolLinkerVisible(getAssembler(), *it) &&
+        it->getFragment()) {
+      // An atom defining symbol should never be internal to a fragment.
+      assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!");
+      DefiningSymbolMap[it->getFragment()] = it;
+    }
+  }
+
+  // Set the fragment atom associations by tracking the last seen atom defining
+  // symbol.
+  for (MCAssembler::iterator it = getAssembler().begin(),
+         ie = getAssembler().end(); it != ie; ++it) {
+    MCSymbolData *CurrentAtom = 0;
+    for (MCSectionData::iterator it2 = it->begin(),
+           ie2 = it->end(); it2 != ie2; ++it2) {
+      if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
+        CurrentAtom = SD;
+      it2->setAtom(CurrentAtom);
+    }
+  }
+
+  this->MCObjectStreamer::Finish();
 }
 
 MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,

Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Sat Sep 25 00:42:19 2010
@@ -191,6 +191,12 @@
     : X86AsmBackend(T), OSType(_OSType) {
     HasAbsolutizedSet = true;
     HasScatteredSymbols = true;
+    HasReliableSymbolDifference = true;
+  }
+
+  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+    const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section);
+    return ES.getFlags() & MCSectionELF::SHF_MERGE;
   }
 
   bool isVirtualSection(const MCSection &Section) const {

Modified: llvm/trunk/test/MC/ELF/basic-elf.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/basic-elf.ll?rev=114786&r1=114785&r2=114786&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/basic-elf.ll (original)
+++ llvm/trunk/test/MC/ELF/basic-elf.ll Sat Sep 25 00:42:19 2010
@@ -83,7 +83,7 @@
 ; 64:     # Relocation 2
 ; 64:     (('r_offset', 15)
 ; 64:      ('r_type', 10)
-; 64:      ('r_addend', 6)
+; 64:      ('r_addend', 0)
 ; 64:     ),
 ; 64:     # Relocation 3
 ; 64:     (('r_offset', 20)

Added: llvm/trunk/test/MC/ELF/merge.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/merge.s?rev=114786&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/merge.s (added)
+++ llvm/trunk/test/MC/ELF/merge.s Sat Sep 25 00:42:19 2010
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump  --dump-section-data | FileCheck  %s
+
+// Test that relocations with local symbols in a mergeable section are done
+// with a reference to the symbol. Not sure if this is a linker limitation,
+// but this matches the behavior of gas.
+
+        .section        .sec1,"aM", at progbits,16
+.Lfoo:
+        .text
+        movsd   .Lfoo(%rip), %xmm1
+
+// Relocation refers to symbol 1
+
+// CHECK:       ('_relocations', [
+// CHECK-NEXT:   # Relocation 0
+// CHECK-NEXT:   (('r_offset',
+// CHECK-NEXT:    ('r_sym', 1)
+// CHECK-NEXT:    ('r_type',
+// CHECK-NEXT:    ('r_addend',
+// CHECK-NEXT:   ),
+// CHECK-NEXT:  ])
+
+// Symbol number 1 is .Lfoo
+
+// CHECK:      # Symbol 1
+// CHECK-NEXT: (('st_name', 1) # '.Lfoo'





More information about the llvm-commits mailing list