Commit d1116697 authored by Wolfgang Pieb's avatar Wolfgang Pieb
Browse files

[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
parent 7e29e579
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -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);
+87 −0
Original line number Diff line number Diff line
# 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'
...