[lld][PECOFF] Fix data directory entry RVA of base relocations section

Summary:
This patch changes WriterPECOFF to actually write down the address instead of ignoring it.
Also, it changes the order of adding the BaseReloc chunk as otherwise the address wasn't set yet.

I think a better way of doing it would be to change DataDirectoryAtom to create a Reference
instead of using a number, and to change IdataPass accordingly, but I'm not sure how to do that.

Reviewers: ruiu

Reviewed By: ruiu

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1743

llvm-svn: 191220
This commit is contained in:
Ron Ofir 2013-09-23 20:21:24 +00:00
parent 213358aeaa
commit b7d3e6b76b
3 changed files with 11 additions and 6 deletions

View File

@ -240,8 +240,9 @@ private:
// COFF header.
class COFFDataDirectoryAtom : public COFFLinkerInternalAtom {
public:
COFFDataDirectoryAtom(const File &file, uint64_t ordinal, uint32_t entrySize)
: COFFLinkerInternalAtom(file, assembleRawContent(entrySize)),
COFFDataDirectoryAtom(const File &file, uint64_t ordinal, uint32_t entrySize,
uint32_t entryAddr = 0)
: COFFLinkerInternalAtom(file, assembleRawContent(entrySize, entryAddr)),
_ordinal(ordinal) {}
virtual uint64_t ordinal() const { return _ordinal; }
@ -249,9 +250,10 @@ public:
virtual ContentPermissions permissions() const { return permR__; }
private:
std::vector<uint8_t> assembleRawContent(uint32_t entrySize) {
std::vector<uint8_t> assembleRawContent(uint32_t entrySize, uint32_t entryAddr) {
std::vector<uint8_t> data = std::vector<uint8_t>(8, 0);
*(reinterpret_cast<uint32_t *>(&data[4])) = entrySize;
*(reinterpret_cast<llvm::support::ulittle32_t *>(&data[0])) = entryAddr;
*(reinterpret_cast<llvm::support::ulittle32_t *>(&data[4])) = entrySize;
return data;
}

View File

@ -425,7 +425,8 @@ public:
void setBaseRelocField(uint32_t addr, uint32_t size) {
auto *atom = new (_alloc) coff::COFFDataDirectoryAtom(
_file, llvm::COFF::DataDirectoryIndex::BASE_RELOCATION_TABLE, size);
_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));
}
@ -820,9 +821,9 @@ public:
if (baseReloc) {
baseReloc->setContents(_chunks);
if (baseReloc->size()) {
addSectionChunk(baseReloc, sectionTable);
dataDirectory->setBaseRelocField(baseReloc->getSectionRva(),
baseReloc->rawSize());
addSectionChunk(baseReloc, sectionTable);
}
}

View File

@ -31,6 +31,8 @@ BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
NOBASEREL-HEADER: IMAGE_FILE_RELOCS_STRIPPED
BASEREL-HEADER: BaseRelocationTableRVA: 0x3000
BASEREL-HEADER: BaseRelocationTableSize: 0xC
BASEREL-HEADER: Name: .reloc (2E 72 65 6C 6F 63 00 00)
BASEREL-HEADER-NEXT: VirtualSize: 0xC
BASEREL-HEADER-NEXT: VirtualAddress: 0x3000