[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
This commit is contained in:
Wolfgang Pieb 2021-06-25 10:54:24 -07:00
parent 7e29e57917
commit d1116697be
2 changed files with 101 additions and 4 deletions

View File

@ -312,12 +312,17 @@ static bool supportsARM(uint64_t Type) {
}
static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
uint64_t LocData, int64_t /*Addend*/) {
uint64_t LocData, int64_t Addend) {
// Support both RELA and REL relocations. The caller is responsible
// for supplying the correct values for LocData and Addend, i.e.
// Addend == 0 for REL and LocData == 0 for RELA.
assert((LocData == 0 || Addend == 0) &&
"one of LocData and Addend must be 0");
switch (Type) {
case ELF::R_ARM_ABS32:
return (S + LocData) & 0xFFFFFFFF;
return (S + LocData + Addend) & 0xFFFFFFFF;
case ELF::R_ARM_REL32:
return (S + LocData - Offset) & 0xFFFFFFFF;
return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
}
llvm_unreachable("Invalid relocation type");
}
@ -744,8 +749,13 @@ uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
};
if (GetRelSectionType() == ELF::SHT_RELA)
if (GetRelSectionType() == ELF::SHT_RELA) {
Addend = getELFAddend(R);
// RISCV relocations use both LocData and Addend.
if (Obj->getArch() != Triple::riscv32 &&
Obj->getArch() != Triple::riscv64)
LocData = 0;
}
}
return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);

View File

@ -0,0 +1,87 @@
# Test if we are handling RELA relocations for ARM correctly using llvm-dwarfdump.
#
# RUN: yaml2obj %s -o %t
# RUN: llvm-dwarfdump -i %t | FileCheck %s
# CHECK: DW_TAG_compile_unit
# CHECK-NEXT: DW_AT_name {{.*}}("correct")
# CHECK-NEXT: DW_AT_type ([[TYPEDIE:0x[0-9A-Fa-f]+]] "correct")
# CHECK: [[TYPEDIE]]: DW_TAG_base_type
# CHECK-NEXT: DW_AT_name {{.*}}("correct")
--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_ARM
Flags: [ EF_ARM_EABI_VER5 ]
Sections:
# A rudimentary v5 compile unit with an AT_name and an AT_type referencing
# a rudimentary DW_TAG_base_type DIE with an AT_name attribute.
- Name: .debug_info
Type: SHT_PROGBITS
Content: 17000000050001040000000001A000000000000000020000000000
- Name: .debug_abbrev
Type: SHT_PROGBITS
Content: 011101030E49130000022400030E0000
- Name: .debug_str
Type: SHT_PROGBITS
- Name: .rela.debug_info
Type: SHT_RELA
Link: .symtab
AddressAlign: 0x4
Offset: 0x929
Info: .debug_info
Relocations:
- Offset: 0x8
Symbol: .debug_abbrev
Type: R_ARM_ABS32
# The compile unit name is found via a R_ARM_ABS32 relocation.
- Offset: 0xD
Symbol: .debug_str
Type: R_ARM_ABS32
Addend: 6
# The DW_TAG_base_type is found via a R_ARM_REL32 relocation.
# This is completely artificial and unlikely to be ever generated
# by a compiler or other tool. We make sure that the relocation is
# resolved by (Symbol - Offset + Addend).
- Offset: 0x11
Symbol: .debug_info
Type: R_ARM_REL32
Addend: 0x26
- Offset: 0x16
Symbol: .debug_str
Type: R_ARM_ABS32
Addend: 6
- Type: SectionHeaderTable
Sections:
- Name: .symtab
- Name: .strtab
- Name: .shstrtab
- Name: .debug_info
- Name: .debug_abbrev
- Name: .debug_str
- Name: .rela.debug_info
Symbols:
- Name: test.cpp
Type: STT_FILE
Index: SHN_ABS
- Name: .debug_info
Type: STT_SECTION
Section: .debug_info
- Name: .debug_abbrev
Type: STT_SECTION
Section: .debug_abbrev
- Name: .debug_str
Type: STT_SECTION
Section: .debug_str
- Name: .debug_info_cudie
Type: STT_OBJECT
Section: .debug_info
Value: 0xC
DWARF:
debug_str:
- 'wrong'
- 'correct'
...