aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp45
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)) {