Skip to content

Commit d111669

Browse files
author
Wolfgang Pieb
committed
[ARM] Fix RELA relocations for 32bit ARM.
RELA relocations for 32 bit ARM ignored the addend. Some tools generate them instead of REL type relocations. This fixes PR50473. Reviewed By: MaskRay, peter.smith Differential Revision: https://reviews.llvm.org/D105214
1 parent 7e29e57 commit d111669

File tree

2 files changed

+101
-4
lines changed

2 files changed

+101
-4
lines changed

llvm/lib/Object/RelocationResolver.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,17 @@ static bool supportsARM(uint64_t Type) {
312312
}
313313

314314
static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
315-
uint64_t LocData, int64_t /*Addend*/) {
315+
uint64_t LocData, int64_t Addend) {
316+
// Support both RELA and REL relocations. The caller is responsible
317+
// for supplying the correct values for LocData and Addend, i.e.
318+
// Addend == 0 for REL and LocData == 0 for RELA.
319+
assert((LocData == 0 || Addend == 0) &&
320+
"one of LocData and Addend must be 0");
316321
switch (Type) {
317322
case ELF::R_ARM_ABS32:
318-
return (S + LocData) & 0xFFFFFFFF;
323+
return (S + LocData + Addend) & 0xFFFFFFFF;
319324
case ELF::R_ARM_REL32:
320-
return (S + LocData - Offset) & 0xFFFFFFFF;
325+
return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
321326
}
322327
llvm_unreachable("Invalid relocation type");
323328
}
@@ -744,8 +749,13 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
744749
return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
745750
};
746751

747-
if (GetRelSectionType() == ELF::SHT_RELA)
752+
if (GetRelSectionType() == ELF::SHT_RELA) {
748753
Addend = getELFAddend(R);
754+
// RISCV relocations use both LocData and Addend.
755+
if (Obj->getArch() != Triple::riscv32 &&
756+
Obj->getArch() != Triple::riscv64)
757+
LocData = 0;
758+
}
749759
}
750760

751761
return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Test if we are handling RELA relocations for ARM correctly using llvm-dwarfdump.
2+
#
3+
# RUN: yaml2obj %s -o %t
4+
# RUN: llvm-dwarfdump -i %t | FileCheck %s
5+
6+
# CHECK: DW_TAG_compile_unit
7+
# CHECK-NEXT: DW_AT_name {{.*}}("correct")
8+
# CHECK-NEXT: DW_AT_type ([[TYPEDIE:0x[0-9A-Fa-f]+]] "correct")
9+
# CHECK: [[TYPEDIE]]: DW_TAG_base_type
10+
# CHECK-NEXT: DW_AT_name {{.*}}("correct")
11+
12+
--- !ELF
13+
FileHeader:
14+
Class: ELFCLASS32
15+
Data: ELFDATA2LSB
16+
Type: ET_REL
17+
Machine: EM_ARM
18+
Flags: [ EF_ARM_EABI_VER5 ]
19+
Sections:
20+
# A rudimentary v5 compile unit with an AT_name and an AT_type referencing
21+
# a rudimentary DW_TAG_base_type DIE with an AT_name attribute.
22+
- Name: .debug_info
23+
Type: SHT_PROGBITS
24+
Content: 17000000050001040000000001A000000000000000020000000000
25+
- Name: .debug_abbrev
26+
Type: SHT_PROGBITS
27+
Content: 011101030E49130000022400030E0000
28+
- Name: .debug_str
29+
Type: SHT_PROGBITS
30+
- Name: .rela.debug_info
31+
Type: SHT_RELA
32+
Link: .symtab
33+
AddressAlign: 0x4
34+
Offset: 0x929
35+
Info: .debug_info
36+
Relocations:
37+
- Offset: 0x8
38+
Symbol: .debug_abbrev
39+
Type: R_ARM_ABS32
40+
# The compile unit name is found via a R_ARM_ABS32 relocation.
41+
- Offset: 0xD
42+
Symbol: .debug_str
43+
Type: R_ARM_ABS32
44+
Addend: 6
45+
# The DW_TAG_base_type is found via a R_ARM_REL32 relocation.
46+
# This is completely artificial and unlikely to be ever generated
47+
# by a compiler or other tool. We make sure that the relocation is
48+
# resolved by (Symbol - Offset + Addend).
49+
- Offset: 0x11
50+
Symbol: .debug_info
51+
Type: R_ARM_REL32
52+
Addend: 0x26
53+
- Offset: 0x16
54+
Symbol: .debug_str
55+
Type: R_ARM_ABS32
56+
Addend: 6
57+
- Type: SectionHeaderTable
58+
Sections:
59+
- Name: .symtab
60+
- Name: .strtab
61+
- Name: .shstrtab
62+
- Name: .debug_info
63+
- Name: .debug_abbrev
64+
- Name: .debug_str
65+
- Name: .rela.debug_info
66+
Symbols:
67+
- Name: test.cpp
68+
Type: STT_FILE
69+
Index: SHN_ABS
70+
- Name: .debug_info
71+
Type: STT_SECTION
72+
Section: .debug_info
73+
- Name: .debug_abbrev
74+
Type: STT_SECTION
75+
Section: .debug_abbrev
76+
- Name: .debug_str
77+
Type: STT_SECTION
78+
Section: .debug_str
79+
- Name: .debug_info_cudie
80+
Type: STT_OBJECT
81+
Section: .debug_info
82+
Value: 0xC
83+
DWARF:
84+
debug_str:
85+
- 'wrong'
86+
- 'correct'
87+
...

0 commit comments

Comments
 (0)