Skip to content

Commit f4fc405

Browse files
dmlarylabath
authored andcommitted
lldb: Add support for R_386_32 relocations to ObjectFileELF
I encountered an issue where `p &variable` was finding an incorrect address for 32-bit PIC ELF files loaded into a running process. The problem was that the R_386_32 ELF relocations were not being applied to the DWARF section, so all variables in that file were reporting as being at the start of their respective section. There is an assert that catches this on debug builds, but silently ignores the issue on non-debug builds. In this changeset, I added handling for the R_386_32 relocation type to ObjectFileELF, and a supporting function to ELFRelocation to differentiate between DT_REL & DT_RELA in ObjectFileELF::ApplyRelocations(). Demonstration of issue: ``` [dmlary@host work]$ cat rel.c volatile char padding[32] = "make sure var isnt at .data+0"; volatile char var[] = "test"; [dmlary@host work]$ gcc -c rel.c -FPIC -fpic -g -m32 [dmlary@host work]$ lldb ./exec (lldb) target create "./exec" Current executable set to '/home/dmlary/src/work/exec' (i386). (lldb) process launch --stop-at-entry Process 21278 stopped * thread #1, name = 'exec', stop reason = signal SIGSTOP frame #0: 0xf7fdb150 ld-2.17.so`_start ld-2.17.so`_start: -> 0xf7fdb150 <+0>: movl %esp, %eax 0xf7fdb152 <+2>: calll 0xf7fdb990 ; _dl_start ld-2.17.so`_dl_start_user: 0xf7fdb157 <+0>: movl %eax, %edi 0xf7fdb159 <+2>: calll 0xf7fdb140 Process 21278 launched: '/home/dmlary/src/work/exec' (i386) (lldb) image add ./rel.o (lldb) image load --file rel.o .text 0x40000000 .data 0x50000000 section '.text' loaded at 0x40000000 section '.data' loaded at 0x50000000 (lldb) image dump symtab rel.o Symtab, file = rel.o, num_symbols = 13: Debug symbol |Synthetic symbol ||Externally Visible ||| Index UserID DSX Type File Address/Value Load Address Size Flags Name ------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ---------------------------------- [ 0] 1 SourceFile 0x0000000000000000 0x0000000000000000 0x00000004 rel.c [ 1] 2 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 2] 3 Invalid 0x0000000000000000 0x50000000 0x0000000000000020 0x00000003 [ 3] 4 Invalid 0x0000000000000025 0x0000000000000000 0x00000003 [ 4] 5 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 5] 6 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 6] 7 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 7] 8 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 8] 9 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 9] 10 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 10] 11 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 11] 12 X Data 0x0000000000000000 0x50000000 0x0000000000000020 0x00000011 padding [ 12] 13 X Data 0x0000000000000020 0x50000020 0x0000000000000005 0x00000011 var (lldb) p &var (volatile char (*)[5]) $1 = 0x50000000 ``` Reviewed By: labath Differential Revision: https://reviews.llvm.org/D132954
1 parent d3649c2 commit f4fc405

File tree

2 files changed

+91
-11
lines changed

2 files changed

+91
-11
lines changed

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

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ class ELFRelocation {
121121

122122
static unsigned RelocAddend64(const ELFRelocation &rel);
123123

124+
bool IsRela() { return (reloc.is<ELFRela *>()); }
125+
124126
private:
125127
typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
126128

@@ -2597,25 +2599,46 @@ unsigned ObjectFileELF::ApplyRelocations(
25972599
}
25982600

25992601
for (unsigned i = 0; i < num_relocations; ++i) {
2600-
if (!rel.Parse(rel_data, &offset))
2602+
if (!rel.Parse(rel_data, &offset)) {
2603+
GetModule()->ReportError(".rel%s[%d] failed to parse relocation",
2604+
rel_section->GetName().AsCString(), i);
26012605
break;
2602-
2606+
}
26032607
Symbol *symbol = nullptr;
26042608

26052609
if (hdr->Is32Bit()) {
26062610
switch (reloc_type(rel)) {
26072611
case R_386_32:
2612+
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2613+
if (symbol) {
2614+
addr_t f_offset =
2615+
rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel);
2616+
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2617+
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2618+
WritableDataBuffer *data_buffer =
2619+
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2620+
uint32_t *dst = reinterpret_cast<uint32_t *>(
2621+
data_buffer->GetBytes() + f_offset);
2622+
2623+
addr_t value = symbol->GetAddressRef().GetFileAddress();
2624+
if (rel.IsRela()) {
2625+
value += ELFRelocation::RelocAddend32(rel);
2626+
} else {
2627+
value += *dst;
2628+
}
2629+
*dst = value;
2630+
} else {
2631+
GetModule()->ReportError(".rel%s[%u] unknown symbol id: %d",
2632+
rel_section->GetName().AsCString(), i,
2633+
reloc_symbol(rel));
2634+
}
2635+
break;
26082636
case R_386_PC32:
26092637
default:
2610-
// FIXME: This asserts with this input:
2611-
//
2612-
// foo.cpp
2613-
// int main(int argc, char **argv) { return 0; }
2614-
//
2615-
// clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o
2616-
//
2617-
// and running this on the foo.o module.
2618-
assert(false && "unexpected relocation type");
2638+
GetModule()->ReportError("unsupported 32-bit relocation:"
2639+
" .rel%s[%u], type %u",
2640+
rel_section->GetName().AsCString(), i,
2641+
reloc_type(rel));
26192642
}
26202643
} else {
26212644
switch (reloc_type(rel)) {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: lldb-test object-file --contents %t | FileCheck %s
3+
#
4+
# CHECK-LABEL: Name: .debug_info
5+
# CHECK: Data: (
6+
# CHECK-NEXT: 0000: 22222222
7+
#
8+
# CHECK-LABEL: Name: .debug_lines
9+
# CHECK: Data: (
10+
# CHECK-NEXT: 0000: 33333333
11+
--- !ELF
12+
FileHeader:
13+
Class: ELFCLASS32
14+
Data: ELFDATA2LSB
15+
Type: ET_REL
16+
Machine: EM_386
17+
Sections:
18+
- Name: .data
19+
Type: SHT_PROGBITS
20+
Flags: [ SHF_WRITE, SHF_ALLOC ]
21+
AddressAlign: 0x20
22+
- Name: .debug_info
23+
Type: SHT_PROGBITS
24+
AddressAlign: 0x1
25+
Content: 11111111
26+
- Name: .debug_lines
27+
Type: SHT_PROGBITS
28+
AddressAlign: 0x1
29+
Content: 99999999
30+
- Name: .rel.debug_info
31+
Type: SHT_REL
32+
Flags: [ SHF_INFO_LINK ]
33+
Link: .symtab
34+
AddressAlign: 0x0
35+
Info: .debug_info
36+
Relocations:
37+
- Offset: 0x0
38+
Symbol: var
39+
Type: R_386_32
40+
- Name: .rela.debug_lines
41+
Type: SHT_RELA
42+
Link: .symtab
43+
AddressAlign: 0x4
44+
Info: .debug_lines
45+
Relocations:
46+
- Offset: 0x0
47+
Addend: 0x22222222
48+
Symbol: var
49+
Type: R_386_32
50+
Symbols:
51+
- Name: var
52+
Type: STT_OBJECT
53+
Section: .data
54+
Binding: STB_GLOBAL
55+
Value: 0x11111111
56+
Size: 0x5
57+
...

0 commit comments

Comments
 (0)