[llvm-branch-commits] [lldb] 6d3b767 - [LLDB][ObjectFileELF] Support LoongArch64 in ApplyReloctions
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 23 07:35:04 PDT 2023
Author: Weining Lu
Date: 2023-03-23T15:33:03+01:00
New Revision: 6d3b7679ef212fce3291af97eea625f252b4829b
URL: https://github.com/llvm/llvm-project/commit/6d3b7679ef212fce3291af97eea625f252b4829b
DIFF: https://github.com/llvm/llvm-project/commit/6d3b7679ef212fce3291af97eea625f252b4829b.diff
LOG: [LLDB][ObjectFileELF] Support LoongArch64 in ApplyReloctions
Currently ApplyReloctions() deals with different archs' relocation types
together (in a single `switch() {..}`). I think it is incorrect because
different relocation types of different archs may have same enum values.
For example:
`R_LARCH_32` and `R_X86_64_64` are both `1`;
`R_LARCH_64` and `R_X86_64_PC32` are both `2`.
This patch handles each arch in seperate `switch()` to solve the enum
values conflict issue.
And a new test is added for LoongArch64.
Reviewed By: DavidSpickett
Differential Revision: https://reviews.llvm.org/D145462
(cherry picked from commit c2c93873d1912a62685818ec9f4e020ee7a1c616)
Added:
lldb/test/Shell/ObjectFile/ELF/loongarch64-relocations.yaml
Modified:
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 9131367bf2230..d91b350af6fee 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2593,6 +2593,50 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
rel_data, symtab_data, strtab_data);
}
+static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel,
+ DataExtractor &debug_data,
+ Section *rel_section) {
+ Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
+ if (symbol) {
+ addr_t value = symbol->GetAddressRef().GetFileAddress();
+ DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
+ // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
+ WritableDataBuffer *data_buffer =
+ llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
+ uint64_t *dst = reinterpret_cast<uint64_t *>(
+ data_buffer->GetBytes() + rel_section->GetFileOffset() +
+ ELFRelocation::RelocOffset64(rel));
+ uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
+ memcpy(dst, &val_offset, sizeof(uint64_t));
+ }
+}
+
+static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel,
+ DataExtractor &debug_data,
+ Section *rel_section, bool is_signed) {
+ Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
+ if (symbol) {
+ addr_t value = symbol->GetAddressRef().GetFileAddress();
+ value += ELFRelocation::RelocAddend32(rel);
+ if ((!is_signed && (value > UINT32_MAX)) ||
+ (is_signed &&
+ ((int64_t)value > INT32_MAX || (int64_t)value < INT32_MIN))) {
+ Log *log = GetLog(LLDBLog::Modules);
+ LLDB_LOGF(log, "Failed to apply debug info relocations");
+ return;
+ }
+ uint32_t truncated_addr = (value & 0xFFFFFFFF);
+ 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() + rel_section->GetFileOffset() +
+ ELFRelocation::RelocOffset32(rel));
+ memcpy(dst, &truncated_addr, sizeof(uint32_t));
+ }
+}
+
unsigned ObjectFileELF::ApplyRelocations(
Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
@@ -2656,55 +2700,50 @@ unsigned ObjectFileELF::ApplyRelocations(
reloc_type(rel));
}
} else {
- switch (reloc_type(rel)) {
- case R_AARCH64_ABS64:
- case R_X86_64_64: {
- symbol = symtab->FindSymbolByID(reloc_symbol(rel));
- if (symbol) {
- addr_t value = symbol->GetAddressRef().GetFileAddress();
- DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
- // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
- WritableDataBuffer *data_buffer =
- llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
- uint64_t *dst = reinterpret_cast<uint64_t *>(
- data_buffer->GetBytes() + rel_section->GetFileOffset() +
- ELFRelocation::RelocOffset64(rel));
- uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
- memcpy(dst, &val_offset, sizeof(uint64_t));
+ switch (hdr->e_machine) {
+ case llvm::ELF::EM_AARCH64:
+ switch (reloc_type(rel)) {
+ case R_AARCH64_ABS64:
+ ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
+ break;
+ case R_AARCH64_ABS32:
+ ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
+ break;
+ default:
+ assert(false && "unexpected relocation type");
}
break;
- }
- case R_X86_64_32:
- case R_X86_64_32S:
- case R_AARCH64_ABS32: {
- symbol = symtab->FindSymbolByID(reloc_symbol(rel));
- if (symbol) {
- addr_t value = symbol->GetAddressRef().GetFileAddress();
- value += ELFRelocation::RelocAddend32(rel);
- if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) ||
- (reloc_type(rel) == R_X86_64_32S &&
- ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) ||
- (reloc_type(rel) == R_AARCH64_ABS32 &&
- ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
- Log *log = GetLog(LLDBLog::Modules);
- LLDB_LOGF(log, "Failed to apply debug info relocations");
- break;
- }
- uint32_t truncated_addr = (value & 0xFFFFFFFF);
- 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() + rel_section->GetFileOffset() +
- ELFRelocation::RelocOffset32(rel));
- memcpy(dst, &truncated_addr, sizeof(uint32_t));
+ case llvm::ELF::EM_LOONGARCH:
+ switch (reloc_type(rel)) {
+ case R_LARCH_64:
+ ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
+ break;
+ case R_LARCH_32:
+ ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
+ break;
+ default:
+ assert(false && "unexpected relocation type");
+ }
+ break;
+ case llvm::ELF::EM_X86_64:
+ switch (reloc_type(rel)) {
+ case R_X86_64_64:
+ ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
+ break;
+ case R_X86_64_32:
+ ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section,
+ false);
+ break;
+ case R_X86_64_32S:
+ ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
+ break;
+ case R_X86_64_PC32:
+ default:
+ assert(false && "unexpected relocation type");
}
break;
- }
- case R_X86_64_PC32:
default:
- assert(false && "unexpected relocation type");
+ assert(false && "unsupported machine");
}
}
}
diff --git a/lldb/test/Shell/ObjectFile/ELF/loongarch64-relocations.yaml b/lldb/test/Shell/ObjectFile/ELF/loongarch64-relocations.yaml
new file mode 100644
index 0000000000000..1be63870343bb
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/ELF/loongarch64-relocations.yaml
@@ -0,0 +1,45 @@
+# RUN: yaml2obj %s -o %t
+# RUN: lldb-test object-file -contents %t | FileCheck %s
+
+## Test that relocations are correctly applied to the .debug_info section on loongarch64.
+
+# CHECK: Name: .debug_info
+# CHECK: Data: (
+## Before relocation:
+## 0000: 00000000 00000000 00000000
+## After relocation:
+# CHECK-NEXT: 0000: 34120000 78560000 00000000
+# CHECK-NEXT: )
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_LOONGARCH
+Sections:
+ - Name: .debug_str
+ Type: SHT_PROGBITS
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ Content: 000000000000000000000000
+ - Name: .rela.debug_info
+ Type: SHT_RELA
+ Info: .debug_info
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: .debug_str
+ Type: R_LARCH_32
+ Addend: 0x1234
+ - Offset: 0x0000000000000004
+ Symbol: .debug_str
+ Type: R_LARCH_64
+ Addend: 0x5678
+Symbols:
+ - Name: .debug_str
+ Type: STT_SECTION
+ Section: .debug_str
+ - Name: .debug_info
+ Type: STT_SECTION
+ Section: .debug_info
+...
More information about the llvm-branch-commits
mailing list