summaryrefslogtreecommitdiffstats
path: root/lld
diff options
context:
space:
mode:
authorSid Manning <sidneym@codeaurora.org>2012-09-25 18:22:09 +0000
committerSid Manning <sidneym@codeaurora.org>2012-09-25 18:22:09 +0000
commitdd11020739dfcf312d8231b7dfb44e1aa9cbe247 (patch)
treedd756744d08e0c2db120ff44d04b1a5b5c4d33d8 /lld
parent65b1f5055da45e4e9bef43e7b0f3db4507682c0f (diff)
downloadbcm5719-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.cpp45
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) {
OpenPOWER on IntegriCloud