On ELF we need to know which symbols are used in relocations to decide if
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 5 Oct 2010 15:11:03 +0000 (15:11 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 5 Oct 2010 15:11:03 +0000 (15:11 +0000)
they should be in the symbol table or not. Instead of "guessing", just compute
the symbol table after the relocations are known.

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

include/llvm/MC/ELFObjectWriter.h
include/llvm/MC/MCObjectWriter.h
include/llvm/MC/MachObjectWriter.h
lib/MC/ELFObjectWriter.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MachObjectWriter.cpp
lib/MC/WinCOFFObjectWriter.cpp

index c8a42fe57b5cef6a067f58be3519ea67fa5ab319..aba8b492324f1e8badcd52f9187e6bbdf8bd28fc 100644 (file)
@@ -44,7 +44,7 @@ public:
                                     bool IsPCRel,
                                     const MCFragment *DF) const;
 
-  virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+  virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
 };
 
 } // End llvm namespace
index 7571583e99a213d4b2f15f17e2d96ac6d93e8ba8..6814cb537bfc848ca56a55e3259ea9c11c3db9ac 100644 (file)
@@ -90,7 +90,7 @@ public:
   /// This routine is called by the assembler after layout and relaxation is
   /// complete, fixups have been evaluated and applied, and relocations
   /// generated.
-  virtual void WriteObject(const MCAssembler &Asm,
+  virtual void WriteObject(MCAssembler &Asm,
                            const MCAsmLayout &Layout) = 0;
 
   /// @}
index 198da8fc1736497ba875b605e5a34fb3f4a36044..f1079e3d7cce20e56556bb68bef27c9574631e86 100644 (file)
@@ -41,7 +41,7 @@ public:
                                     bool IsPCRel,
                                     const MCFragment *DF) const;
 
-  virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+  virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
 };
 
 } // End llvm namespace
index 6a2a6e53da502dc876fd386ec3bf4e08a373f076..b9d2acea4612fb74d880eebc289f1baf3b3d022f 100644 (file)
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/ELFObjectWriter.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/Twine.h"
@@ -102,7 +103,9 @@ namespace {
     struct ELFRelocationEntry {
       // Make these big enough for both 32-bit and 64-bit
       uint64_t r_offset;
-      uint64_t r_info;
+      int Index;
+      unsigned Type;
+      const MCSymbol *Symbol;
       uint64_t r_addend;
 
       // Support lexicographic sorting.
@@ -111,6 +114,8 @@ namespace {
       }
     };
 
+    SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
+
     llvm::DenseMap<const MCSectionData*,
                    std::vector<ELFRelocationEntry> > Relocations;
     DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
@@ -126,6 +131,8 @@ namespace {
 
     /// @}
 
+    int NumRegularSections;
+
     ELFObjectWriter *Writer;
 
     raw_ostream &OS;
@@ -262,8 +269,6 @@ namespace {
     void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout);
 
     void ExecutePostLayoutBinding(MCAssembler &Asm) {
-      // Compute symbol table information.
-      ComputeSymbolTable(Asm);
     }
 
     void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
@@ -279,7 +284,7 @@ namespace {
                               bool IsPCRel,
                               const MCFragment *DF) const;
 
-    void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+    void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
   };
 
 }
@@ -526,12 +531,13 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
                                            MCValue Target,
                                            uint64_t &FixedValue) {
   int64_t Addend = 0;
-  unsigned Index = 0;
+  int Index = 0;
   int64_t Value = Target.getConstant();
+  const MCSymbol *Symbol = 0;
 
   bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
   if (!Target.isAbsolute()) {
-    const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
+    Symbol = &Target.getSymA()->getSymbol();
     MCSymbolData &SD = Asm.getSymbolData(*Symbol);
     MCFragment *F = SD.getFragment();
 
@@ -560,13 +566,15 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
 
     bool RelocOnSymbol = ShouldRelocOnSymbol(SD, Target);
     if (!RelocOnSymbol) {
-      Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
+      Index = F->getParent()->getOrdinal();
 
       MCSectionData *FSD = F->getParent();
       // Offset of the symbol in the section
       Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
-    } else
-      Index = getSymbolIndexInSymbolTable(Asm, Symbol);
+    } else {
+      UsedInReloc.insert(Symbol);
+      Index = -1;
+    }
     Addend = Value;
     // Compensate for the addend on i386.
     if (Is64Bit)
@@ -641,15 +649,9 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
 
   ELFRelocationEntry ERE;
 
-  if (Is64Bit) {
-    struct ELF::Elf64_Rela ERE64;
-    ERE64.setSymbolAndType(Index, Type);
-    ERE.r_info = ERE64.r_info;
-  } else {
-    struct ELF::Elf32_Rela ERE32;
-    ERE32.setSymbolAndType(Index, Type);
-    ERE.r_info = ERE32.r_info;
-  }
+  ERE.Index = Index;
+  ERE.Type = Type;
+  ERE.Symbol = Symbol;
 
   ERE.r_offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
 
@@ -671,11 +673,12 @@ ELFObjectWriterImpl::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
     return SD.getIndex() + /* empty symbol */ 1;
 
   // External or undefined symbol.
-  return SD.getIndex() + Asm.size() + /* empty symbol */ 1;
+  return SD.getIndex() + NumRegularSections + /* empty symbol */ 1;
 }
 
 void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
   // Build section lookup table.
+  NumRegularSections = Asm.size();
   DenseMap<const MCSection*, uint8_t> SectionIndexMap;
   unsigned Index = 1;
   for (MCAssembler::iterator it = Asm.begin(),
@@ -698,6 +701,9 @@ void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
     if (it->isExternal() || Symbol.isUndefined())
       continue;
 
+    if (Symbol.isTemporary() && !UsedInReloc.count(&Symbol))
+      continue;
+
     uint64_t &Entry = StringIndexMap[Symbol.getName()];
     if (!Entry) {
       Entry = StringTable.size();
@@ -734,6 +740,10 @@ void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) {
     if (Symbol.isVariable())
       continue;
 
+    if (Symbol.isUndefined() && !UsedInReloc.count(&Symbol)
+        && Symbol.isTemporary())
+      continue;
+
     uint64_t &Entry = StringIndexMap[Symbol.getName()];
     if (!Entry) {
       Entry = StringTable.size();
@@ -843,13 +853,19 @@ void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler &Asm,
   for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
     ELFRelocationEntry entry = Relocs[e - i - 1];
 
+    if (entry.Index < 0)
+      entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
+    else
+      entry.Index += LocalSymbolData.size() + 1;
     if (Is64Bit) {
       char buf[8];
 
       String64(buf, entry.r_offset);
       F->getContents() += StringRef(buf, 8);
 
-      String64(buf, entry.r_info);
+      struct ELF::Elf64_Rela ERE64;
+      ERE64.setSymbolAndType(entry.Index, entry.Type);
+      String64(buf, ERE64.r_info);
       F->getContents() += StringRef(buf, 8);
 
       if (HasRelocationAddend) {
@@ -862,7 +878,9 @@ void ELFObjectWriterImpl::WriteRelocationsFragment(const MCAssembler &Asm,
       String32(buf, entry.r_offset);
       F->getContents() += StringRef(buf, 4);
 
-      String32(buf, entry.r_info);
+      struct ELF::Elf32_Rela ERE32;
+      ERE32.setSymbolAndType(entry.Index, entry.Type);
+      String32(buf, ERE32.r_info);
       F->getContents() += StringRef(buf, 4);
 
       if (HasRelocationAddend) {
@@ -976,8 +994,11 @@ bool ELFObjectWriterImpl::IsFixupFullyResolved(const MCAssembler &Asm,
   return !SectionB && BaseSection == SectionA;
 }
 
-void ELFObjectWriterImpl::WriteObject(const MCAssembler &Asm,
+void ELFObjectWriterImpl::WriteObject(MCAssembler &Asm,
                                       const MCAsmLayout &Layout) {
+  // Compute symbol table information.
+  ComputeSymbolTable(Asm);
+
   CreateMetadataSections(const_cast<MCAssembler&>(Asm),
                          const_cast<MCAsmLayout&>(Layout));
 
@@ -1142,7 +1163,7 @@ bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
                                                              IsPCRel, DF);
 }
 
-void ELFObjectWriter::WriteObject(const MCAssembler &Asm,
+void ELFObjectWriter::WriteObject(MCAssembler &Asm,
                                   const MCAsmLayout &Layout) {
   ((ELFObjectWriterImpl*) Impl)->WriteObject(Asm, Layout);
 }
index ecc72c26b701e7896056a11fd0a2a47f3a923689..b63bedc7030e53f5c10b5760defcc581915e977d 100644 (file)
@@ -156,22 +156,6 @@ void MCELFStreamer::InitSections() {
   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!");
 
@@ -179,11 +163,6 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
 
   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
@@ -520,36 +499,6 @@ void MCELFStreamer::Finish() {
       SectData.setAlignment(ByteAlignment);
   }
 
-  // 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();
 }
 
index 4bb05350edd231e1687304fdedd1afa5118d5e20..61df5bb35c761b234c6d31628bf97bb9deee5a80 100644 (file)
@@ -1360,7 +1360,7 @@ bool MachObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
                                                               IsPCRel, DF);
 }
 
-void MachObjectWriter::WriteObject(const MCAssembler &Asm,
+void MachObjectWriter::WriteObject(MCAssembler &Asm,
                                    const MCAsmLayout &Layout) {
   ((MachObjectWriterImpl*) Impl)->WriteObject(Asm, Layout);
 }
index 82ccddf81d98afa292bc68d3530a15eecfec3c4c..24c517b122dfa7993bdd80acedce53f37ba3fb61 100644 (file)
@@ -186,7 +186,7 @@ public:
                                     bool IsPCRel,
                                     const MCFragment *DF) const;
 
-  void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout);
+  void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
 };
 }
 
@@ -703,7 +703,7 @@ bool WinCOFFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm,
   return false;
 }
 
-void WinCOFFObjectWriter::WriteObject(const MCAssembler &Asm,
+void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
                                       const MCAsmLayout &Layout) {
   // Assign symbol and section indexes and offsets.
   Header.NumberOfSections = 0;