diff options
author | Sid Manning <sidneym@codeaurora.org> | 2012-09-25 18:22:09 +0000 |
---|---|---|
committer | Sid Manning <sidneym@codeaurora.org> | 2012-09-25 18:22:09 +0000 |
commit | dd11020739dfcf312d8231b7dfb44e1aa9cbe247 (patch) | |
tree | dd756744d08e0c2db120ff44d04b1a5b5c4d33d8 /lld | |
parent | 65b1f5055da45e4e9bef43e7b0f3db4507682c0f (diff) | |
download | bcm5719-llvm-dd11020739dfcf312d8231b7dfb44e1aa9cbe247.tar.gz bcm5719-llvm-dd11020739dfcf312d8231b7dfb44e1aa9cbe247.zip |
This patch makes use of recently added relocation reference data. The bulk
of this is derived from the Mach-O writer. Reviewed by: Nick Kledzik.
* Adds loop to SectionChunk::write traverse references calling the
writer's fixup handler, applyFixup.
* Adds method, ELFWriter::buildAtomToAddressMap to that creates a
mapping from an atom to its runtime address.
* Adds method, ELFWriter::addressOfAtom to return the runtime address
of the atom.
llvm-svn: 164618
Diffstat (limited to 'lld')
-rw-r--r-- | lld/lib/ReaderWriter/ELF/WriterELF.cpp | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp index 7030ee1102a..e01efd11c88 100644 --- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp +++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp @@ -425,7 +425,20 @@ void SectionChunk<target_endianness, is64Bits>::write(uint8_t *chunkBuffer) { continue; uint8_t *atomContent = chunkBuffer + std::get<1>(ai); std::copy_n(content.data(), contentSize, atomContent); - // TODO Apply fixups to file buffer + + for (const Reference *ref : *std::get<0>(ai)){ + uint32_t offset = ref->offsetInAtom(); + uint64_t targetAddress = 0; + + if ( ref->target() != nullptr ) + targetAddress = _writer.addressOfAtom(ref->target()); + + uint64_t fixupAddress = _writer.addressOfAtom(std::get<0>(ai)) + offset; + _writer.kindHandler()->applyFixup(ref->kind(), ref->addend(), + &atomContent[offset], + fixupAddress, + targetAddress); + } } } // @@ -685,8 +698,9 @@ public: typedef object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; ELFWriter(const WriterOptionsELF &options); virtual error_code writeFile(const lld::File &File, StringRef path); + uint64_t addressOfAtom(const Atom *atom); ArrayRef<Chunk<target_endianness, is64Bits>*> chunks() { return _chunks; } - KindHandler *kindHandler() { return _referenceKindHandler; } + KindHandler *kindHandler() { return _referenceKindHandler.get(); } std::vector<SectionChunk<target_endianness, is64Bits>*> sectionChunks() { return _sectionChunks ; @@ -699,11 +713,18 @@ public: private: void build(const lld::File &file); void createChunks(const lld::File &file); + void buildAtomToAddressMap(); void assignFileOffsets(); const WriterOptionsELF &_options; + +/// \brief AtomToAddress: Is a mapping from an Atom to the address where +/// it will live in the output file. + typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress; + ELFStringSectionChunk<target_endianness, is64Bits> *_shstrtable ; std::unique_ptr<KindHandler> _referenceKindHandler; ELFSectionHeaderChunk<target_endianness, is64Bits> *_sectionHeaderChunk; + AtomToAddress _atomToAddress; std::vector<Chunk<target_endianness, is64Bits>*> _chunks; const DefinedAtom *_entryAtom; std::vector<SectionChunk<target_endianness, is64Bits>*> _sectionChunks; @@ -725,6 +746,7 @@ void ELFWriter<target_endianness, is64Bits>::build(const lld::File &file){ // Create objects for each chunk. createChunks(file); assignFileOffsets(); + buildAtomToAddressMap(); } template<support::endianness target_endianness, bool is64Bits> @@ -794,6 +816,20 @@ void ELFWriter<target_endianness, is64Bits> _chunks.push_back(_shstrtable); } +template<support::endianness target_endianness, bool is64Bits> +void ELFWriter<target_endianness, is64Bits> + ::buildAtomToAddressMap () { + +// _atomToAddress is a DenseMap that maps an atom its file address. +// std::get<1>(ai) is the offset from the start of the section to the atom. + for (auto &chunk : _sectionChunks){ + for (auto &ai : chunk->atoms() ) { + _atomToAddress[std::get<0>(ai)] = chunk->address() + std::get<1>(ai); + } + } + + +} template<support::endianness target_endianness, bool is64Bits> void ELFWriter<target_endianness, is64Bits>::assignFileOffsets() { @@ -844,6 +880,11 @@ error_code ELFWriter<target_endianness, is64Bits> return buffer->commit(); } +template<support::endianness target_endianness, bool is64Bits> +uint64_t ELFWriter<target_endianness, is64Bits> + ::addressOfAtom(const Atom *atom) { + return _atomToAddress[atom]; +} } // namespace elf Writer *createWriterELF(const WriterOptionsELF &options) { |