[PATCH] [PECOFF] Connect defined atoms with layout before/after edges.
Rui Ueyama
ruiu at google.com
Sun Jun 16 20:59:35 PDT 2013
Hi shankarke,
I don't think there's an easy way to test this change because it wouldn't
change the order of atoms now. Previously we didn't have the layout pass for
the PE/COFF writer, and we emitted all the atoms in the same order as they
appeared in input object files, which is the same order with this patch.
I'm writing a new patch to merge sections. In PE/COFF, the linker is expected
to merge sections by discarding the dollar prefix. Thus, if there are sections
named .text$1 and .text$2, they will be merged to .text.
The characters following the dollar sign determines the ordering of the
sections. Naturally that should be modeled by the atom model in lld.
I think we will be able to test the layout pass in the next patch.
http://llvm-reviews.chandlerc.com/D989
Files:
include/lld/ReaderWriter/PECOFFTargetInfo.h
lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
Index: include/lld/ReaderWriter/PECOFFTargetInfo.h
===================================================================
--- include/lld/ReaderWriter/PECOFFTargetInfo.h
+++ include/lld/ReaderWriter/PECOFFTargetInfo.h
@@ -41,7 +41,7 @@
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; }
Index: lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
===================================================================
--- lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
+++ lib/ReaderWriter/PECOFF/PECOFFTargetInfo.cpp
@@ -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 @@
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
Index: lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
===================================================================
--- lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
+++ lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
@@ -41,6 +41,10 @@
/// 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 @@
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 @@
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;
Index: lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
===================================================================
--- lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
+++ lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
@@ -336,6 +336,11 @@
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D989.1.patch
Type: text/x-patch
Size: 4586 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130616/b5b6f21b/attachment.bin>
More information about the llvm-commits
mailing list