diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -121,6 +121,8 @@ static unsigned RelocAddend64(const ELFRelocation &rel); + bool IsRela() { return (reloc.is()); } + private: typedef llvm::PointerUnion RelocUnion; @@ -2597,14 +2599,40 @@ } 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(data_buffer_sp.get()); + uint32_t *dst = reinterpret_cast( + 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: @@ -2615,6 +2643,10 @@ // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o // // and running this on the foo.o module. + GetModule()->ReportError("unsupported 32-bit relocation:" + " .rel%s[%u], type %u", + rel_section->GetName().AsCString(), i, + reloc_type(rel)); assert(false && "unexpected relocation type"); } } else {