[lld] r184085 - [PECOFF] Connect defined atoms with layout before/after edges.

Rui Ueyama ruiu at google.com
Mon Jun 17 09:59:55 PDT 2013


Author: ruiu
Date: Mon Jun 17 11:59:54 2013
New Revision: 184085

URL: http://llvm.org/viewvc/llvm-project?rev=184085&view=rev
Log:
[PECOFF] Connect defined atoms with layout before/after edges.

Reviewers: shankarke

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D989

Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h?rev=184085&r1=184084&r2=184085&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h Mon Jun 17 11:59:54 2013
@@ -41,7 +41,7 @@ public:
   virtual Writer &writer() const;
   virtual bool validateImpl(raw_ostream &diagnostics);
 
-  virtual void addPasses(PassManager &pm) const {}
+  virtual void addPasses(PassManager &pm) const;
 
   void setStackReserve(uint64_t size) { _stackReserve = size; }
   void setStackCommit(uint64_t size) { _stackCommit = size; }

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp?rev=184085&r1=184084&r2=184085&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp Mon Jun 17 11:59:54 2013
@@ -9,6 +9,8 @@
 
 #include "lld/ReaderWriter/PECOFFTargetInfo.h"
 
+#include "lld/Core/PassManager.h"
+#include "lld/Passes/LayoutPass.h"
 #include "lld/ReaderWriter/Reader.h"
 #include "lld/ReaderWriter/Writer.h"
 
@@ -56,4 +58,8 @@ PECOFFTargetInfo::stringFromRelocKind(Re
   return make_error_code(yaml_reader_error::illegal_value);
 }
 
+void PECOFFTargetInfo::addPasses(PassManager &pm) const {
+  pm.add(std::unique_ptr<Pass>(new LayoutPass()));
+}
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=184085&r1=184084&r2=184085&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Mon Jun 17 11:59:54 2013
@@ -41,6 +41,10 @@ namespace { // anonymous
 /// to be fixed up so that the address points to atom Y's address.
 class COFFReference LLVM_FINAL : public Reference {
 public:
+  COFFReference(Kind kind) : _target(nullptr), _offsetInAtom(0) {
+    _kind = kind;
+  }
+
   COFFReference(const Atom *target, uint32_t offsetInAtom, uint16_t relocType)
       : _target(target), _offsetInAtom(offsetInAtom) {
     setKind(static_cast<Reference::Kind>(relocType));
@@ -431,6 +435,38 @@ private:
     return error_code::success();
   }
 
+  void addEdge(COFFDefinedAtom *a, COFFDefinedAtom *b,
+               lld::Reference::Kind kind) const {
+    auto ref = new (AtomStorage.Allocate<COFFReference>()) COFFReference(kind);
+    ref->setTarget(b);
+    a->addReference(ref);
+  }
+
+  void connectAtomsWithLayoutEdge(COFFDefinedAtom *a,
+                                  COFFDefinedAtom *b) const {
+    addEdge(a, b, lld::Reference::kindLayoutAfter);
+    addEdge(b, a, lld::Reference::kindLayoutBefore);
+  }
+
+  /// Connect atoms appeared in the same section with layout-{before,after}
+  /// edges. It has two purposes.
+  ///
+  ///   - To prevent atoms from being GC'ed (aka dead-stripped) if there is a
+  ///     reference to one of the atoms. In that case we want to emit all the
+  ///     atoms appeared in the same section, because the referenced "live"
+  ///     atom may reference other atoms in the same section. If we don't add
+  ///     edges between atoms, unreferenced atoms in the same section would be
+  ///     GC'ed.
+  ///   - To preserve the order of atmos. We want to emit the atoms in the
+  ///     same order as they appeared in the input object file.
+  void addLayoutEdges(vector<COFFDefinedAtom *> &definedAtoms) const {
+    if (definedAtoms.size() <= 1)
+      return;
+    for (auto it = definedAtoms.begin(), e = definedAtoms.end(); it + 1 != e;
+         ++it)
+      connectAtomsWithLayoutEdge(*it, *(it + 1));
+  }
+
   error_code AtomizeDefinedSymbols(SectionToSymbolsT &definedSymbols,
                                    vector<const DefinedAtom *> &definedAtoms,
                                    SymbolNameToAtomT &symbolToAtom,
@@ -445,6 +481,9 @@ private:
               AtomizeDefinedSymbolsInSection(section, symbols, atoms))
         return ec;
 
+      // Connect atoms with layout-before/layout-after edges.
+      addLayoutEdges(atoms);
+
       for (COFFDefinedAtom *atom : atoms) {
         if (!atom->name().empty())
           symbolToAtom[atom->name()] = atom;

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=184085&r1=184084&r2=184085&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Mon Jun 17 11:59:54 2013
@@ -336,6 +336,11 @@ public:
         auto relocSite = reinterpret_cast<llvm::support::ulittle32_t *>(
             fileBuffer + layout->_fileOffset + ref->offsetInAtom());
         uint64_t targetAddr = atomToVirtualAddr[ref->target()];
+
+        // Skip if this reference is not for relocation.
+        if (ref->kind() < lld::Reference::kindTargetLow)
+          continue;
+
         switch (ref->kind()) {
         case llvm::COFF::IMAGE_REL_I386_DIR32:
           *relocSite = targetAddr;





More information about the llvm-commits mailing list