Skip to content

Commit c2c9387

Browse files
committed
[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
1 parent dab077c commit c2c9387

File tree

2 files changed

+128
-44
lines changed

2 files changed

+128
-44
lines changed

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Lines changed: 83 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,50 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
25932593
rel_data, symtab_data, strtab_data);
25942594
}
25952595

2596+
static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel,
2597+
DataExtractor &debug_data,
2598+
Section *rel_section) {
2599+
Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
2600+
if (symbol) {
2601+
addr_t value = symbol->GetAddressRef().GetFileAddress();
2602+
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2603+
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2604+
WritableDataBuffer *data_buffer =
2605+
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2606+
uint64_t *dst = reinterpret_cast<uint64_t *>(
2607+
data_buffer->GetBytes() + rel_section->GetFileOffset() +
2608+
ELFRelocation::RelocOffset64(rel));
2609+
uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
2610+
memcpy(dst, &val_offset, sizeof(uint64_t));
2611+
}
2612+
}
2613+
2614+
static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel,
2615+
DataExtractor &debug_data,
2616+
Section *rel_section, bool is_signed) {
2617+
Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
2618+
if (symbol) {
2619+
addr_t value = symbol->GetAddressRef().GetFileAddress();
2620+
value += ELFRelocation::RelocAddend32(rel);
2621+
if ((!is_signed && (value > UINT32_MAX)) ||
2622+
(is_signed &&
2623+
((int64_t)value > INT32_MAX || (int64_t)value < INT32_MIN))) {
2624+
Log *log = GetLog(LLDBLog::Modules);
2625+
LLDB_LOGF(log, "Failed to apply debug info relocations");
2626+
return;
2627+
}
2628+
uint32_t truncated_addr = (value & 0xFFFFFFFF);
2629+
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2630+
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2631+
WritableDataBuffer *data_buffer =
2632+
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2633+
uint32_t *dst = reinterpret_cast<uint32_t *>(
2634+
data_buffer->GetBytes() + rel_section->GetFileOffset() +
2635+
ELFRelocation::RelocOffset32(rel));
2636+
memcpy(dst, &truncated_addr, sizeof(uint32_t));
2637+
}
2638+
}
2639+
25962640
unsigned ObjectFileELF::ApplyRelocations(
25972641
Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
25982642
const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
@@ -2656,55 +2700,50 @@ unsigned ObjectFileELF::ApplyRelocations(
26562700
reloc_type(rel));
26572701
}
26582702
} else {
2659-
switch (reloc_type(rel)) {
2660-
case R_AARCH64_ABS64:
2661-
case R_X86_64_64: {
2662-
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2663-
if (symbol) {
2664-
addr_t value = symbol->GetAddressRef().GetFileAddress();
2665-
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2666-
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2667-
WritableDataBuffer *data_buffer =
2668-
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2669-
uint64_t *dst = reinterpret_cast<uint64_t *>(
2670-
data_buffer->GetBytes() + rel_section->GetFileOffset() +
2671-
ELFRelocation::RelocOffset64(rel));
2672-
uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
2673-
memcpy(dst, &val_offset, sizeof(uint64_t));
2703+
switch (hdr->e_machine) {
2704+
case llvm::ELF::EM_AARCH64:
2705+
switch (reloc_type(rel)) {
2706+
case R_AARCH64_ABS64:
2707+
ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
2708+
break;
2709+
case R_AARCH64_ABS32:
2710+
ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
2711+
break;
2712+
default:
2713+
assert(false && "unexpected relocation type");
26742714
}
26752715
break;
2676-
}
2677-
case R_X86_64_32:
2678-
case R_X86_64_32S:
2679-
case R_AARCH64_ABS32: {
2680-
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2681-
if (symbol) {
2682-
addr_t value = symbol->GetAddressRef().GetFileAddress();
2683-
value += ELFRelocation::RelocAddend32(rel);
2684-
if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) ||
2685-
(reloc_type(rel) == R_X86_64_32S &&
2686-
((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) ||
2687-
(reloc_type(rel) == R_AARCH64_ABS32 &&
2688-
((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
2689-
Log *log = GetLog(LLDBLog::Modules);
2690-
LLDB_LOGF(log, "Failed to apply debug info relocations");
2691-
break;
2692-
}
2693-
uint32_t truncated_addr = (value & 0xFFFFFFFF);
2694-
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2695-
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2696-
WritableDataBuffer *data_buffer =
2697-
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2698-
uint32_t *dst = reinterpret_cast<uint32_t *>(
2699-
data_buffer->GetBytes() + rel_section->GetFileOffset() +
2700-
ELFRelocation::RelocOffset32(rel));
2701-
memcpy(dst, &truncated_addr, sizeof(uint32_t));
2716+
case llvm::ELF::EM_LOONGARCH:
2717+
switch (reloc_type(rel)) {
2718+
case R_LARCH_64:
2719+
ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
2720+
break;
2721+
case R_LARCH_32:
2722+
ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
2723+
break;
2724+
default:
2725+
assert(false && "unexpected relocation type");
2726+
}
2727+
break;
2728+
case llvm::ELF::EM_X86_64:
2729+
switch (reloc_type(rel)) {
2730+
case R_X86_64_64:
2731+
ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
2732+
break;
2733+
case R_X86_64_32:
2734+
ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section,
2735+
false);
2736+
break;
2737+
case R_X86_64_32S:
2738+
ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
2739+
break;
2740+
case R_X86_64_PC32:
2741+
default:
2742+
assert(false && "unexpected relocation type");
27022743
}
27032744
break;
2704-
}
2705-
case R_X86_64_PC32:
27062745
default:
2707-
assert(false && "unexpected relocation type");
2746+
assert(false && "unsupported machine");
27082747
}
27092748
}
27102749
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: lldb-test object-file -contents %t | FileCheck %s
3+
4+
## Test that relocations are correctly applied to the .debug_info section on loongarch64.
5+
6+
# CHECK: Name: .debug_info
7+
# CHECK: Data: (
8+
## Before relocation:
9+
## 0000: 00000000 00000000 00000000
10+
## After relocation:
11+
# CHECK-NEXT: 0000: 34120000 78560000 00000000
12+
# CHECK-NEXT: )
13+
14+
--- !ELF
15+
FileHeader:
16+
Class: ELFCLASS64
17+
Data: ELFDATA2LSB
18+
Type: ET_REL
19+
Machine: EM_LOONGARCH
20+
Sections:
21+
- Name: .debug_str
22+
Type: SHT_PROGBITS
23+
- Name: .debug_info
24+
Type: SHT_PROGBITS
25+
Content: 000000000000000000000000
26+
- Name: .rela.debug_info
27+
Type: SHT_RELA
28+
Info: .debug_info
29+
Relocations:
30+
- Offset: 0x0000000000000000
31+
Symbol: .debug_str
32+
Type: R_LARCH_32
33+
Addend: 0x1234
34+
- Offset: 0x0000000000000004
35+
Symbol: .debug_str
36+
Type: R_LARCH_64
37+
Addend: 0x5678
38+
Symbols:
39+
- Name: .debug_str
40+
Type: STT_SECTION
41+
Section: .debug_str
42+
- Name: .debug_info
43+
Type: STT_SECTION
44+
Section: .debug_info
45+
...

0 commit comments

Comments
 (0)