[lld] r193854 - [PECOFF] Change data directory atom structure.
Rui Ueyama
ruiu at google.com
Thu Oct 31 22:51:15 PDT 2013
Author: ruiu
Date: Fri Nov 1 00:51:15 2013
New Revision: 193854
URL: http://llvm.org/viewvc/llvm-project?rev=193854&view=rev
Log:
[PECOFF] Change data directory atom structure.
The data directory in the PE/COFF header consisted of list of data directory
atoms. This patch changes it -- now there's only one data directory entry that
contains former data directories. That's easier to handle in the writer as well
as to write to/read from YAML/Native files. The main purpose of this refactoring
is to enable RoundTrip tests for PE/COFF.
There's no functionality change.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h
lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h
lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
Modified: lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h?rev=193854&r1=193853&r2=193854&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/Atoms.h Fri Nov 1 00:51:15 2013
@@ -247,24 +247,11 @@ private:
// COFF header.
class COFFDataDirectoryAtom : public COFFLinkerInternalAtom {
public:
- COFFDataDirectoryAtom(const File &file, uint64_t ordinal, uint32_t entrySize,
- uint32_t entryAddr = 0)
- : COFFLinkerInternalAtom(file, assembleRawContent(entrySize, entryAddr)),
- _ordinal(ordinal) {}
+ COFFDataDirectoryAtom(const File &file, std::vector<uint8_t> contents)
+ : COFFLinkerInternalAtom(file, contents) {}
- virtual uint64_t ordinal() const { return _ordinal; }
virtual ContentType contentType() const { return typeDataDirectoryEntry; }
virtual ContentPermissions permissions() const { return permR__; }
-
-private:
- std::vector<uint8_t> assembleRawContent(uint32_t entrySize, uint32_t entryAddr) {
- std::vector<uint8_t> data = std::vector<uint8_t>(8, 0);
- *(reinterpret_cast<llvm::support::ulittle32_t *>(&data[0])) = entryAddr;
- *(reinterpret_cast<llvm::support::ulittle32_t *>(&data[4])) = entrySize;
- return data;
- }
-
- uint64_t _ordinal;
};
// A COFFSharedLibraryAtom represents a symbol for data in an import library. A
Modified: lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h?rev=193854&r1=193853&r2=193854&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/IdataPass.h Fri Nov 1 00:51:15 2013
@@ -312,23 +312,35 @@ private:
/// 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 an entry in the data directory header. We create atoms of class
- /// COFFDataDirectoryAtom and set relocations to them, so that the address
- /// will be set by the writer.
+ /// 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, llvm::COFF::DataDirectoryIndex::IMPORT_TABLE,
- context.importDirectories.size() *
- context.importDirectories[0]->size());
- addDir32NBReloc(dir, context.importDirectories[0]);
- context.file.addAtom(*dir);
+ context.dummyFile, std::move(contents));
+ addDir32NBReloc(dir, context.importDirectories[0], importTableOffset);
+ addDir32NBReloc(dir, context.importAddressTables[0], iatOffset);
- auto *iat = new (_alloc) coff::COFFDataDirectoryAtom(
- context.dummyFile, llvm::COFF::DataDirectoryIndex::IAT,
- context.importAddressTables.size() *
- context.importAddressTables[0]->size());
- addDir32NBReloc(iat, context.importAddressTables[0]);
- context.file.addAtom(*iat);
+ context.file.addAtom(*dir);
}
/// Transforms a reference to a COFFSharedLibraryAtom to a real reference.
Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=193854&r1=193853&r2=193854&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Fri Nov 1 00:51:15 2013
@@ -412,13 +412,12 @@ protected:
/// in memory) and 8 byte entry data size.
class DataDirectoryChunk : public AtomChunk {
public:
- DataDirectoryChunk(const File &linkedFile)
- : AtomChunk(kindDataDirectory), _file(linkedFile) {
- // Extract atoms from the linked file and append them to this section.
+ DataDirectoryChunk(const File &linkedFile) : AtomChunk(kindDataDirectory) {
+ // Find the data directory atom.
for (const DefinedAtom *atom : linkedFile.defined()) {
if (atom->contentType() == DefinedAtom::typeDataDirectoryEntry) {
- uint64_t offset = atom->ordinal() * sizeof(llvm::object::data_directory);
- _atomLayouts.push_back(new (_alloc) AtomLayout(atom, offset, offset));
+ _atomLayouts.push_back(new (_alloc) AtomLayout(atom, 0, 0));
+ return;
}
}
}
@@ -428,24 +427,30 @@ public:
}
void setBaseRelocField(uint32_t addr, uint32_t size) {
- auto *atom = new (_alloc) coff::COFFDataDirectoryAtom(
- _file, llvm::COFF::DataDirectoryIndex::BASE_RELOCATION_TABLE, size,
- addr);
- uint64_t offset = atom->ordinal() * sizeof(llvm::object::data_directory);
- _atomLayouts.push_back(new (_alloc) AtomLayout(atom, offset, offset));
+ _baseRelocAddr = addr;
+ _baseRelocSize = size;
}
virtual void write(uint8_t *fileBuffer) {
- for (const AtomLayout *layout : _atomLayouts) {
- if (!layout)
- continue;
+ if (!_atomLayouts.empty()) {
+ assert(_atomLayouts.size() == 1);
+ const AtomLayout *layout = _atomLayouts[0];
ArrayRef<uint8_t> content = static_cast<const DefinedAtom *>(layout->_atom)->rawContent();
- std::memcpy(fileBuffer + layout->_fileOffset, content.data(), content.size());
+ std::memcpy(fileBuffer + _fileOffset, content.data(), content.size());
}
+
+ // Write base relocation table entry.
+ int baseRelocOffset = llvm::COFF::DataDirectoryIndex::BASE_RELOCATION_TABLE
+ * sizeof(llvm::object::data_directory);
+ auto *baseReloc = reinterpret_cast<llvm::object::data_directory *>(
+ fileBuffer + _fileOffset + baseRelocOffset);
+ baseReloc->RelativeVirtualAddress = _baseRelocAddr;
+ baseReloc->Size = _baseRelocSize;
}
private:
- const File &_file;
+ uint32_t _baseRelocAddr;
+ uint32_t _baseRelocSize;
mutable llvm::BumpPtrAllocator _alloc;
};
More information about the llvm-commits
mailing list