diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index ba4a1f6..af1b093 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -121,6 +121,8 @@ public: static unsigned RelocAddend64(const ELFRelocation &rel); + bool IsRela() { return (reloc.is<ELFRela *>()); } + private: typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion; @@ -2597,25 +2599,46 @@ unsigned ObjectFileELF::ApplyRelocations( } for (unsigned i = 0; i < num_relocations; ++i) { - if (!rel.Parse(rel_data, &offset)) + if (!rel.Parse(rel_data, &offset)) { + GetModule()->ReportError(".rel%s[%d] failed to parse relocation", + rel_section->GetName().AsCString(), i); break; - + } Symbol *symbol = nullptr; if (hdr->Is32Bit()) { switch (reloc_type(rel)) { case R_386_32: + symbol = symtab->FindSymbolByID(reloc_symbol(rel)); + if (symbol) { + addr_t f_offset = + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel); + DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); + uint32_t *dst = reinterpret_cast<uint32_t *>( + data_buffer->GetBytes() + f_offset); + + addr_t value = symbol->GetAddressRef().GetFileAddress(); + if (rel.IsRela()) { + value += ELFRelocation::RelocAddend32(rel); + } else { + value += *dst; + } + *dst = value; + } else { + GetModule()->ReportError(".rel%s[%u] unknown symbol id: %d", + rel_section->GetName().AsCString(), i, + reloc_symbol(rel)); + } + break; case R_386_PC32: default: - // FIXME: This asserts with this input: - // - // foo.cpp - // int main(int argc, char **argv) { return 0; } - // - // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o - // - // and running this on the foo.o module. - assert(false && "unexpected relocation type"); + GetModule()->ReportError("unsupported 32-bit relocation:" + " .rel%s[%u], type %u", + rel_section->GetName().AsCString(), i, + reloc_type(rel)); } } else { switch (reloc_type(rel)) { |