diff options
author | Rui Ueyama <ruiu@google.com> | 2013-11-25 06:21:42 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2013-11-25 06:21:42 +0000 |
commit | 52b9cbf880e275a0d51ce7420f61ccaa7979de2c (patch) | |
tree | cc44b16528345b0029d60e349609af5c022e3a8a | |
parent | 6194109c29791f000e5ba3327d838b4be4e6c651 (diff) | |
download | bcm5719-llvm-52b9cbf880e275a0d51ce7420f61ccaa7979de2c.tar.gz bcm5719-llvm-52b9cbf880e275a0d51ce7420f61ccaa7979de2c.zip |
[PECOFF] Move definitions to IdataPass.cpp.
llvm-svn: 195618
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/IdataPass.cpp | 244 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/IdataPass.h | 252 |
3 files changed, 278 insertions, 219 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/CMakeLists.txt b/lld/lib/ReaderWriter/PECOFF/CMakeLists.txt index 948578b6250..556e49b7412 100644 --- a/lld/lib/ReaderWriter/PECOFF/CMakeLists.txt +++ b/lld/lib/ReaderWriter/PECOFF/CMakeLists.txt @@ -1,4 +1,5 @@ add_lld_library(lldPECOFF + IdataPass.cpp PECOFFLinkingContext.cpp ReaderCOFF.cpp ReaderImportHeader.cpp diff --git a/lld/lib/ReaderWriter/PECOFF/IdataPass.cpp b/lld/lib/ReaderWriter/PECOFF/IdataPass.cpp new file mode 100644 index 00000000000..7cd8404e9f8 --- /dev/null +++ b/lld/lib/ReaderWriter/PECOFF/IdataPass.cpp @@ -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 diff --git a/lld/lib/ReaderWriter/PECOFF/IdataPass.h b/lld/lib/ReaderWriter/PECOFF/IdataPass.h index d85604f1a29..5b784185cb0 100644 --- a/lld/lib/ReaderWriter/PECOFF/IdataPass.h +++ b/lld/lib/ReaderWriter/PECOFF/IdataPass.h @@ -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 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); - } + void appendAtoms(std::vector<T *> &vec1, const std::vector<U *> &vec2); - /// 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 |