[lld] r195618 - [PECOFF] Move definitions to IdataPass.cpp.
Rui Ueyama
ruiu at google.com
Sun Nov 24 22:21:42 PST 2013
Author: ruiu
Date: Mon Nov 25 00:21:42 2013
New Revision: 195618
URL: http://llvm.org/viewvc/llvm-project?rev=195618&view=rev
Log:
[PECOFF] Move definitions to IdataPass.cpp.
Added:
lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt
lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h
Modified: lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt?rev=195618&r1=195617&r2=195618&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/CMakeLists.txt Mon Nov 25 00:21:42 2013
@@ -1,4 +1,5 @@
add_lld_library(lldPECOFF
+ IdataPass.cpp
PECOFFLinkingContext.cpp
ReaderCOFF.cpp
ReaderImportHeader.cpp
Added: lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp?rev=195618&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp (added)
+++ lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.cpp Mon Nov 25 00:21:42 2013
@@ -0,0 +1,244 @@
+//===- lib/ReaderWriter/PECOFF/IdataPass.cpp ------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IdataPass.h"
+
+#include "lld/Core/File.h"
+#include "lld/Core/Pass.h"
+#include "lld/ReaderWriter/Simple.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+#include <map>
+
+namespace lld {
+namespace pecoff {
+
+static std::vector<uint8_t> stringRefToVector(StringRef name) {
+ std::vector<uint8_t> ret(name.size() + 1);
+ memcpy(&ret[0], name.data(), name.size());
+ ret[name.size()] = 0;
+ return ret;
+}
+
+static void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target,
+ size_t offsetInAtom = 0) {
+ atom->addReference(std::unique_ptr<COFFReference>(new COFFReference(
+ target, offsetInAtom, llvm::COFF::IMAGE_REL_I386_DIR32NB)));
+}
+
+namespace idata {
+class DLLNameAtom;
+class HintNameAtom;
+class ImportTableEntryAtom;
+
+IdataAtom::IdataAtom(Context &context, std::vector<uint8_t> data)
+ : COFFLinkerInternalAtom(context.dummyFile,
+ context.dummyFile.getNextOrdinal(), data) {
+ context.file.addAtom(*this);
+}
+
+DLLNameAtom::DLLNameAtom(Context &context, StringRef name)
+ : IdataAtom(context, stringRefToVector(name)) {
+ context.dllNameAtoms.push_back(this);
+}
+
+HintNameAtom::HintNameAtom(Context &context, uint16_t hint,
+ StringRef importName)
+ : IdataAtom(context, assembleRawContent(hint, importName)),
+ _importName(importName) {
+ context.hintNameAtoms.push_back(this);
+}
+
+std::vector<uint8_t> HintNameAtom::assembleRawContent(uint16_t hint,
+ StringRef importName) {
+ size_t size =
+ llvm::RoundUpToAlignment(sizeof(hint) + importName.size() + 1, 2);
+ std::vector<uint8_t> ret(size);
+ ret[importName.size()] = 0;
+ ret[importName.size() - 1] = 0;
+ *reinterpret_cast<llvm::support::ulittle16_t *>(&ret[0]) = hint;
+ std::memcpy(&ret[2], importName.data(), importName.size());
+ return ret;
+}
+
+std::vector<uint8_t>
+ImportTableEntryAtom::assembleRawContent(uint32_t contents) {
+ std::vector<uint8_t> ret(4);
+ *reinterpret_cast<llvm::support::ulittle32_t *>(&ret[0]) = contents;
+ return ret;
+}
+
+// Creates atoms for an import lookup table. The import lookup table is an
+// array of pointers to hint/name atoms. The array needs to be terminated with
+// the NULL entry.
+void ImportDirectoryAtom::addRelocations(
+ Context &context, StringRef loadName,
+ const std::vector<COFFSharedLibraryAtom *> &sharedAtoms) {
+ size_t lookupEnd = context.importLookupTables.size();
+ size_t addressEnd = context.importAddressTables.size();
+
+ // Create parallel arrays. The contents of the two are initially the
+ // same. The PE/COFF loader overwrites the import address tables with the
+ // pointers to the referenced items after loading the executable into
+ // memory.
+ addImportTableAtoms(context, sharedAtoms, false, context.importLookupTables);
+ addImportTableAtoms(context, sharedAtoms, true, context.importAddressTables);
+
+ addDir32NBReloc(this, context.importLookupTables[lookupEnd],
+ offsetof(ImportDirectoryTableEntry, ImportLookupTableRVA));
+ addDir32NBReloc(this, context.importAddressTables[addressEnd],
+ offsetof(ImportDirectoryTableEntry, ImportAddressTableRVA));
+ addDir32NBReloc(this, new (_alloc) DLLNameAtom(context, loadName),
+ offsetof(ImportDirectoryTableEntry, NameRVA));
+}
+
+void ImportDirectoryAtom::addImportTableAtoms(
+ Context &context, const std::vector<COFFSharedLibraryAtom *> &sharedAtoms,
+ bool shouldAddReference, std::vector<ImportTableEntryAtom *> &ret) const {
+ for (COFFSharedLibraryAtom *atom : sharedAtoms) {
+ ImportTableEntryAtom *entry = nullptr;
+ if (atom->importName().empty()) {
+ // Import by ordinal
+ uint32_t hint = (1U << 31) | atom->hint();
+ entry = new (_alloc) ImportTableEntryAtom(context, hint);
+ } else {
+ // Import by name
+ entry = new (_alloc) ImportTableEntryAtom(context, 0);
+ HintNameAtom *hintName = createHintNameAtom(context, atom);
+ addDir32NBReloc(entry, hintName);
+ }
+ ret.push_back(entry);
+ if (shouldAddReference)
+ atom->setImportTableEntry(entry);
+ }
+ // Add the NULL entry.
+ ret.push_back(new (_alloc) ImportTableEntryAtom(context, 0));
+}
+
+HintNameAtom *ImportDirectoryAtom::createHintNameAtom(
+ Context &context, const COFFSharedLibraryAtom *atom) const {
+ return new (_alloc) HintNameAtom(context, atom->hint(), atom->importName());
+}
+
+} // namespace idata
+
+void IdataPass::perform(std::unique_ptr<MutableFile> &file) {
+ if (file->sharedLibrary().size() == 0)
+ return;
+
+ idata::Context context(*file, _dummyFile);
+ std::map<StringRef, std::vector<COFFSharedLibraryAtom *> > sharedAtoms =
+ groupByLoadName(*file);
+ for (auto i : sharedAtoms) {
+ StringRef loadName = i.first;
+ std::vector<COFFSharedLibraryAtom *> &atoms = i.second;
+ createImportDirectory(context, loadName, atoms);
+ }
+
+ // All atoms, including those of tyep NullImportDirectoryAtom, are added to
+ // context.file in the IdataAtom's constructor.
+ new (_alloc) idata::NullImportDirectoryAtom(context);
+
+ connectAtoms(context);
+ createDataDirectoryAtoms(context);
+ replaceSharedLibraryAtoms(context);
+}
+
+std::map<StringRef, std::vector<COFFSharedLibraryAtom *> >
+IdataPass::groupByLoadName(MutableFile &file) {
+ std::map<StringRef, COFFSharedLibraryAtom *> uniqueAtoms;
+ for (const SharedLibraryAtom *atom : file.sharedLibrary())
+ uniqueAtoms[atom->name()] = (COFFSharedLibraryAtom *)atom;
+
+ std::map<StringRef, std::vector<COFFSharedLibraryAtom *> > ret;
+ for (auto i : uniqueAtoms) {
+ COFFSharedLibraryAtom *atom = i.second;
+ ret[atom->loadName()].push_back(atom);
+ }
+ return ret;
+}
+
+void IdataPass::createImportDirectory(
+ idata::Context &context, StringRef loadName,
+ std::vector<COFFSharedLibraryAtom *> &dllAtoms) {
+ new (_alloc) idata::ImportDirectoryAtom(context, loadName, dllAtoms);
+}
+
+template <typename T, typename U>
+void IdataPass::appendAtoms(std::vector<T *> &vec1,
+ const std::vector<U *> &vec2) {
+ vec1.insert(vec1.end(), vec2.begin(), vec2.end());
+}
+
+void IdataPass::connectAtoms(idata::Context &context) {
+ std::vector<COFFBaseDefinedAtom *> atoms;
+ appendAtoms(atoms, context.importDirectories);
+ appendAtoms(atoms, context.importLookupTables);
+ appendAtoms(atoms, context.importAddressTables);
+ appendAtoms(atoms, context.dllNameAtoms);
+ appendAtoms(atoms, context.hintNameAtoms);
+ coff::connectAtomsWithLayoutEdge(atoms);
+}
+
+/// The addresses of the import dirctory and the import address table needs to
+/// be set to the COFF Optional Data Directory header. A COFFDataDirectoryAtom
+/// represents the data directory header. We create a COFFDataDirectoryAtom
+/// and set relocations to them, so that the address will be set by the
+/// writer.
+void IdataPass::createDataDirectoryAtoms(idata::Context &context) {
+ // CLR_RUNTIME_HEADER is the last index of the data directory.
+ int nentries = llvm::COFF::CLR_RUNTIME_HEADER + 1;
+ int entSize = sizeof(llvm::object::data_directory);
+ std::vector<uint8_t> contents(nentries * entSize, 0);
+
+ auto importTableOffset =
+ llvm::COFF::DataDirectoryIndex::IMPORT_TABLE * entSize;
+ auto iatOffset = llvm::COFF::DataDirectoryIndex::IAT * entSize;
+
+ auto *importTableEntry = reinterpret_cast<llvm::object::data_directory *>(
+ &contents[0] + importTableOffset);
+ auto *iatEntry = reinterpret_cast<llvm::object::data_directory *>(
+ &contents[0] + iatOffset);
+
+ importTableEntry->Size =
+ context.importDirectories.size() * context.importDirectories[0]->size();
+ iatEntry->Size = context.importAddressTables.size() *
+ context.importAddressTables[0]->size();
+
+ auto *dir = new (_alloc) coff::COFFDataDirectoryAtom(
+ context.dummyFile, context.dummyFile.getNextOrdinal(),
+ std::move(contents));
+ addDir32NBReloc(dir, context.importDirectories[0], importTableOffset);
+ addDir32NBReloc(dir, context.importAddressTables[0], iatOffset);
+
+ context.file.addAtom(*dir);
+}
+
+/// Transforms a reference to a COFFSharedLibraryAtom to a real reference.
+void IdataPass::replaceSharedLibraryAtoms(idata::Context &context) {
+ for (const DefinedAtom *atom : context.file.defined()) {
+ for (const Reference *ref : *atom) {
+ const Atom *target = ref->target();
+ auto *sharedAtom = dyn_cast<SharedLibraryAtom>(target);
+ if (!sharedAtom)
+ continue;
+ auto *coffSharedAtom = (COFFSharedLibraryAtom *)sharedAtom;
+ const DefinedAtom *entry = coffSharedAtom->getImportTableEntry();
+ const_cast<Reference *>(ref)->setTarget(entry);
+ }
+ }
+}
+
+} // namespace pecoff
+} // namespace lld
Modified: lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h?rev=195618&r1=195617&r2=195618&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h Mon Nov 25 00:21:42 2013
@@ -25,12 +25,8 @@
#include "lld/Core/Pass.h"
#include "lld/ReaderWriter/Simple.h"
#include "llvm/Support/COFF.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Endian.h"
#include <algorithm>
-#include <cstddef>
-#include <cstring>
#include <map>
using lld::coff::COFFBaseDefinedAtom;
@@ -40,24 +36,16 @@ using lld::coff::COFFReference;
using lld::coff::COFFSharedLibraryAtom;
using lld::coff::COFFSharedLibraryAtom;
using llvm::COFF::ImportDirectoryTableEntry;
-using std::map;
-using std::vector;
namespace lld {
namespace pecoff {
-class IdataPassFile;
+namespace idata {
-namespace {
class DLLNameAtom;
class HintNameAtom;
+class IdataPassFile;
class ImportTableEntryAtom;
-void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target,
- size_t offsetInAtom = 0) {
- atom->addReference(std::unique_ptr<COFFReference>(new COFFReference(
- target, offsetInAtom, llvm::COFF::IMAGE_REL_I386_DIR32NB)));
-}
-
// A state object of this pass.
struct Context {
Context(MutableFile &f, IdataPassFile &g) : file(f), dummyFile(g) {}
@@ -69,13 +57,13 @@ struct Context {
// type and be continuous in the output file. To force such layout, we
// accumulate all atoms created in the pass in the following vectors, and add
// layout edges when finishing the pass.
- vector<COFFBaseDefinedAtom *> importDirectories;
- vector<ImportTableEntryAtom *> importLookupTables;
- vector<ImportTableEntryAtom *> importAddressTables;
- vector<HintNameAtom *> hintNameAtoms;
- vector<DLLNameAtom *> dllNameAtoms;
+ std::vector<COFFBaseDefinedAtom *> importDirectories;
+ std::vector<ImportTableEntryAtom *> importLookupTables;
+ std::vector<ImportTableEntryAtom *> importAddressTables;
+ std::vector<HintNameAtom *> hintNameAtoms;
+ std::vector<DLLNameAtom *> dllNameAtoms;
- map<StringRef, COFFBaseDefinedAtom *> sharedToDefinedAtom;
+ std::map<StringRef, COFFBaseDefinedAtom *> sharedToDefinedAtom;
};
/// The root class of all idata atoms.
@@ -85,25 +73,14 @@ public:
virtual ContentPermissions permissions() const { return permR__; }
protected:
- IdataAtom(Context &context, vector<uint8_t> data);
+ IdataAtom(Context &context, std::vector<uint8_t> data);
};
/// A DLLNameAtom contains a name of a DLL and is referenced by the Name RVA
/// field in the import directory table entry.
class DLLNameAtom : public IdataAtom {
public:
- DLLNameAtom(Context &context, StringRef name)
- : IdataAtom(context, stringRefToVector(name)) {
- context.dllNameAtoms.push_back(this);
- }
-
-private:
- vector<uint8_t> stringRefToVector(StringRef name) {
- vector<uint8_t> ret(name.size() + 1);
- memcpy(&ret[0], name.data(), name.size());
- ret[name.size()] = 0;
- return ret;
- }
+ DLLNameAtom(Context &context, StringRef name);
};
/// A HintNameAtom represents a symbol that will be imported from a DLL at
@@ -116,28 +93,12 @@ private:
/// loader can find the symbol quickly.
class HintNameAtom : public IdataAtom {
public:
- HintNameAtom(Context &context, uint16_t hint, StringRef importName)
- : IdataAtom(context, assembleRawContent(hint, importName)),
- _importName(importName) {
- context.hintNameAtoms.push_back(this);
- }
+ HintNameAtom(Context &context, uint16_t hint, StringRef importName);
StringRef getContentString() { return _importName; }
private:
- // The first two bytes of the content is a hint, followed by a null-terminated
- // symbol name. The total size needs to be multiple of 2.
- vector<uint8_t> assembleRawContent(uint16_t hint, StringRef importName) {
- size_t size =
- llvm::RoundUpToAlignment(sizeof(hint) + importName.size() + 1, 2);
- vector<uint8_t> ret(size);
- ret[importName.size()] = 0;
- ret[importName.size() - 1] = 0;
- *reinterpret_cast<llvm::support::ulittle16_t *>(&ret[0]) = hint;
- std::memcpy(&ret[2], importName.data(), importName.size());
- return ret;
- }
-
+ std::vector<uint8_t> assembleRawContent(uint16_t hint, StringRef importName);
StringRef _importName;
};
@@ -147,11 +108,7 @@ public:
: IdataAtom(context, assembleRawContent(contents)) {}
private:
- vector<uint8_t> assembleRawContent(uint32_t contents) {
- vector<uint8_t> ret(4);
- *reinterpret_cast<llvm::support::ulittle32_t *>(&ret[0]) = contents;
- return ret;
- }
+ std::vector<uint8_t> assembleRawContent(uint32_t contents);
};
/// An ImportDirectoryAtom includes information to load a DLL, including a DLL
@@ -161,66 +118,20 @@ private:
class ImportDirectoryAtom : public IdataAtom {
public:
ImportDirectoryAtom(Context &context, StringRef loadName,
- const vector<COFFSharedLibraryAtom *> &sharedAtoms)
- : IdataAtom(context, vector<uint8_t>(20, 0)) {
+ const std::vector<COFFSharedLibraryAtom *> &sharedAtoms)
+ : IdataAtom(context, std::vector<uint8_t>(20, 0)) {
addRelocations(context, loadName, sharedAtoms);
context.importDirectories.push_back(this);
}
private:
void addRelocations(Context &context, StringRef loadName,
- const vector<COFFSharedLibraryAtom *> &sharedAtoms) {
- size_t lookupEnd = context.importLookupTables.size();
- size_t addressEnd = context.importAddressTables.size();
-
- // Create parallel arrays. The contents of the two are initially the
- // same. The PE/COFF loader overwrites the import address tables with the
- // pointers to the referenced items after loading the executable into
- // memory.
- addImportTableAtoms(context, sharedAtoms, false,
- context.importLookupTables);
- addImportTableAtoms(context, sharedAtoms, true,
- context.importAddressTables);
-
- addDir32NBReloc(this, context.importLookupTables[lookupEnd],
- offsetof(ImportDirectoryTableEntry, ImportLookupTableRVA));
- addDir32NBReloc(this, context.importAddressTables[addressEnd],
- offsetof(ImportDirectoryTableEntry, ImportAddressTableRVA));
- addDir32NBReloc(this, new (_alloc) DLLNameAtom(context, loadName),
- offsetof(ImportDirectoryTableEntry, NameRVA));
- }
-
- // Creates atoms for an import lookup table. The import lookup table is an
- // array of pointers to hint/name atoms. The array needs to be terminated with
- // the NULL entry.
- void addImportTableAtoms(Context &context,
- const vector<COFFSharedLibraryAtom *> &sharedAtoms,
- bool shouldAddReference,
- vector<ImportTableEntryAtom *> &ret) const {
- for (COFFSharedLibraryAtom *atom : sharedAtoms) {
- ImportTableEntryAtom *entry = nullptr;
- if (atom->importName().empty()) {
- // Import by ordinal
- uint32_t hint = (1U << 31) | atom->hint();
- entry = new (_alloc) ImportTableEntryAtom(context, hint);
- } else {
- // Import by name
- entry = new (_alloc) ImportTableEntryAtom(context, 0);
- HintNameAtom *hintName = createHintNameAtom(context, atom);
- addDir32NBReloc(entry, hintName);
- }
- ret.push_back(entry);
- if (shouldAddReference)
- atom->setImportTableEntry(entry);
- }
- // Add the NULL entry.
- ret.push_back(new (_alloc) ImportTableEntryAtom(context, 0));
- }
-
+ const std::vector<COFFSharedLibraryAtom *> &sharedAtoms);
+ void addImportTableAtoms(
+ Context &context, const std::vector<COFFSharedLibraryAtom *> &sharedAtoms,
+ bool shouldAddReference, std::vector<ImportTableEntryAtom *> &ret) const;
HintNameAtom *createHintNameAtom(Context &context,
- const COFFSharedLibraryAtom *atom) const {
- return new (_alloc) HintNameAtom(context, atom->hint(), atom->importName());
- }
+ const COFFSharedLibraryAtom *atom) const;
mutable llvm::BumpPtrAllocator _alloc;
};
@@ -229,13 +140,11 @@ private:
class NullImportDirectoryAtom : public IdataAtom {
public:
explicit NullImportDirectoryAtom(Context &context)
- : IdataAtom(context, vector<uint8_t>(20, 0)) {
+ : IdataAtom(context, std::vector<uint8_t>(20, 0)) {
context.importDirectories.push_back(this);
}
};
-} // anonymous namespace
-
// An instance of this class represents "input file" for atoms created in this
// pass. Only one instance of this class is created as a field of IdataPass.
class IdataPassFile : public SimpleFile {
@@ -251,131 +160,36 @@ private:
uint64_t _nextOrdinal;
};
+} // namespace idata
+
class IdataPass : public lld::Pass {
public:
IdataPass(const LinkingContext &ctx) : _dummyFile(ctx) {}
- virtual void perform(std::unique_ptr<MutableFile> &file) {
- if (file->sharedLibrary().size() == 0)
- return;
-
- Context context(*file, _dummyFile);
- map<StringRef, vector<COFFSharedLibraryAtom *> > sharedAtoms =
- groupByLoadName(*file);
- for (auto i : sharedAtoms) {
- StringRef loadName = i.first;
- vector<COFFSharedLibraryAtom *> &atoms = i.second;
- createImportDirectory(context, loadName, atoms);
- }
-
- // All atoms, including those of tyep NullImportDirectoryAtom, are added to
- // context.file in the IdataAtom's constructor.
- new (_alloc) NullImportDirectoryAtom(context);
-
- connectAtoms(context);
- createDataDirectoryAtoms(context);
- replaceSharedLibraryAtoms(context);
- }
+ virtual void perform(std::unique_ptr<MutableFile> &file);
private:
- map<StringRef, vector<COFFSharedLibraryAtom *>>
- groupByLoadName(MutableFile &file) {
- map<StringRef, COFFSharedLibraryAtom *> uniqueAtoms;
- for (const SharedLibraryAtom *atom : file.sharedLibrary())
- uniqueAtoms[atom->name()] = (COFFSharedLibraryAtom *)atom;
-
- map<StringRef, vector<COFFSharedLibraryAtom *>> ret;
- for (auto i : uniqueAtoms) {
- COFFSharedLibraryAtom *atom = i.second;
- ret[atom->loadName()].push_back(atom);
- }
- return ret;
- }
+ std::map<StringRef, std::vector<COFFSharedLibraryAtom *> >
+ groupByLoadName(MutableFile &file);
- void createImportDirectory(Context &context, StringRef loadName,
- vector<COFFSharedLibraryAtom *> &dllAtoms) {
- new (_alloc) ImportDirectoryAtom(context, loadName, dllAtoms);
- }
+ void createImportDirectory(idata::Context &context, StringRef loadName,
+ std::vector<COFFSharedLibraryAtom *> &dllAtoms);
- // Append vec2's elements at the end of vec1.
template <typename T, typename U>
- void appendAtoms(vector<T *> &vec1, const vector<U *> &vec2) {
- vec1.insert(vec1.end(), vec2.begin(), vec2.end());
- }
+ void appendAtoms(std::vector<T *> &vec1, const std::vector<U *> &vec2);
- void connectAtoms(Context &context) {
- vector<COFFBaseDefinedAtom *> atoms;
- appendAtoms(atoms, context.importDirectories);
- appendAtoms(atoms, context.importLookupTables);
- appendAtoms(atoms, context.importAddressTables);
- appendAtoms(atoms, context.dllNameAtoms);
- appendAtoms(atoms, context.hintNameAtoms);
- coff::connectAtomsWithLayoutEdge(atoms);
- }
-
- /// The addresses of the import dirctory and the import address table needs to
- /// be set to the COFF Optional Data Directory header. A COFFDataDirectoryAtom
- /// represents the data directory header. We create a COFFDataDirectoryAtom
- /// and set relocations to them, so that the address will be set by the
- /// writer.
- void createDataDirectoryAtoms(Context &context) {
- // CLR_RUNTIME_HEADER is the last index of the data directory.
- int nentries = llvm::COFF::CLR_RUNTIME_HEADER + 1;
- int entSize = sizeof(llvm::object::data_directory);
- std::vector<uint8_t> contents(nentries * entSize, 0);
-
- auto importTableOffset = llvm::COFF::DataDirectoryIndex::IMPORT_TABLE
- * entSize;
- auto iatOffset = llvm::COFF::DataDirectoryIndex::IAT * entSize;
-
- auto *importTableEntry = reinterpret_cast<llvm::object::data_directory *>(
- &contents[0] + importTableOffset);
- auto *iatEntry = reinterpret_cast<llvm::object::data_directory *>(
- &contents[0] + iatOffset);
-
- importTableEntry->Size = context.importDirectories.size()
- * context.importDirectories[0]->size();
- iatEntry->Size = context.importAddressTables.size()
- * context.importAddressTables[0]->size();
-
- auto *dir = new (_alloc) coff::COFFDataDirectoryAtom(
- context.dummyFile, context.dummyFile.getNextOrdinal(),
- std::move(contents));
- addDir32NBReloc(dir, context.importDirectories[0], importTableOffset);
- addDir32NBReloc(dir, context.importAddressTables[0], iatOffset);
-
- context.file.addAtom(*dir);
- }
-
- /// Transforms a reference to a COFFSharedLibraryAtom to a real reference.
- void replaceSharedLibraryAtoms(Context &context) {
- for (const DefinedAtom *atom : context.file.defined()) {
- for (const Reference *ref : *atom) {
- const Atom *target = ref->target();
- auto *sharedAtom = dyn_cast<SharedLibraryAtom>(target);
- if (!sharedAtom)
- continue;
- auto *coffSharedAtom = (COFFSharedLibraryAtom *)sharedAtom;
- const DefinedAtom *entry = coffSharedAtom->getImportTableEntry();
- const_cast<Reference *>(ref)->setTarget(entry);
- }
- }
- }
+ void connectAtoms(idata::Context &context);
+ void createDataDirectoryAtoms(idata::Context &context);
+ void replaceSharedLibraryAtoms(idata::Context &context);
// A dummy file with which all the atoms created in the pass will be
// associated. Atoms need to be associated to an input file even if it's not
// read from a file, so we use this object.
- IdataPassFile _dummyFile;
+ idata::IdataPassFile _dummyFile;
llvm::BumpPtrAllocator _alloc;
};
-IdataAtom::IdataAtom(Context &context, vector<uint8_t> data)
- : COFFLinkerInternalAtom(context.dummyFile,
- context.dummyFile.getNextOrdinal(), data) {
- context.file.addAtom(*this);
-}
-
} // namespace pecoff
} // namespace lld
More information about the llvm-commits
mailing list