[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