This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG64a2520bacb5: [lldb][ObjectFileELF] Support AArch32 in 
ApplyRelocations (authored by sgraenitz).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147642/new/

https://reviews.llvm.org/D147642

Files:
  lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  lldb/test/Shell/ObjectFile/ELF/aarch32-relocations.yaml

Index: lldb/test/Shell/ObjectFile/ELF/aarch32-relocations.yaml
===================================================================
--- /dev/null
+++ lldb/test/Shell/ObjectFile/ELF/aarch32-relocations.yaml
@@ -0,0 +1,62 @@
+# RUN: yaml2obj %s -o %t
+# RUN: lldb-test object-file -contents %t | FileCheck %s
+
+## Test that R_ARM_ABS32 relocations are resolved in .debug_info sections on aarch32.
+## REL-type relocations store implicit addend as signed values inline.
+## We relocate the symbol foo with 4 different addends and bar once in the .debug_info section.
+## Results that exceed the 32-bit range or overflow are logged and ignored.
+
+# CHECK:      Name: .debug_info
+# CHECK:      Data:  (
+#
+#              Addends: Zero     Positive Negative Overflow Out-of-range
+#                       00000000 04030201 D6FFFFFF D5FFFFFF FFFFFF7F
+# CHECK-NEXT:     0000: 2A000000 2E030201 00000000 D5FFFFFF FFFFFF7F
+# CHECK-NEXT: )
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    Content:         0000000004030201D6FFFFFFD5FFFFFFFFFFFF7F
+  - Name:            .rel.debug_info
+    Type:            SHT_REL
+    Info:            .debug_info
+    Relocations:
+      - Offset:          0x0
+        Symbol:          foo
+        Type:            R_ARM_ABS32
+      - Offset:          0x4
+        Symbol:          foo
+        Type:            R_ARM_ABS32
+      - Offset:          0x8
+        Symbol:          foo
+        Type:            R_ARM_ABS32
+      - Offset:          0xC
+        Symbol:          foo
+        Type:            R_ARM_ABS32
+      - Offset:          0x10
+        Symbol:          bar
+        Type:            R_ARM_ABS32
+Symbols:
+  - Name:            .debug_info
+    Type:            STT_SECTION
+    Section:         .debug_info
+  - Name:            foo
+    Type:            STT_FUNC
+    Section:         .debug_info
+    Value:           0x0000002A
+  - Name:            bar
+    Type:            STT_FUNC
+    Section:         .debug_info
+    Value:           0xFF000000
+...
Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2637,6 +2637,44 @@
   }
 }
 
+static void ApplyELF32ABS32RelRelocation(Symtab *symtab, ELFRelocation &rel,
+                                         DataExtractor &debug_data,
+                                         Section *rel_section) {
+  Log *log = GetLog(LLDBLog::Modules);
+  Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol32(rel));
+  if (symbol) {
+    addr_t value = symbol->GetAddressRef().GetFileAddress();
+    if (value == LLDB_INVALID_ADDRESS) {
+      const char *name = symbol->GetName().GetCString();
+      LLDB_LOGF(log, "Debug info symbol invalid: %s", name);
+      return;
+    }
+    assert(llvm::isUInt<32>(value) && "Valid addresses are 32-bit");
+    DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
+    // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
+    WritableDataBuffer *data_buffer =
+        llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
+    uint8_t *dst = data_buffer->GetBytes() + rel_section->GetFileOffset() +
+                   ELFRelocation::RelocOffset32(rel);
+    // Implicit addend is stored inline as a signed value.
+    int32_t addend;
+    memcpy(&addend, dst, sizeof(int32_t));
+    // The sum must be positive. This extra check prevents UB from overflow in
+    // the actual range check below.
+    if (addend < 0 && static_cast<uint32_t>(-addend) > value) {
+      LLDB_LOGF(log, "Debug info relocation overflow: 0x%" PRIx64,
+                static_cast<int64_t>(value) + addend);
+      return;
+    }
+    if (!llvm::isUInt<32>(value + addend)) {
+      LLDB_LOGF(log, "Debug info relocation out of range: 0x%" PRIx64, value);
+      return;
+    }
+    uint32_t addr = value + addend;
+    memcpy(dst, &addr, sizeof(uint32_t));
+  }
+}
+
 unsigned ObjectFileELF::ApplyRelocations(
     Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
     const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
@@ -2667,6 +2705,21 @@
 
     if (hdr->Is32Bit()) {
       switch (hdr->e_machine) {
+      case llvm::ELF::EM_ARM:
+        switch (reloc_type(rel)) {
+        case R_ARM_ABS32:
+          ApplyELF32ABS32RelRelocation(symtab, rel, debug_data, rel_section);
+          break;
+        case R_ARM_REL32:
+          GetModule()->ReportError("unsupported AArch32 relocation:"
+                                   " .rel{0}[{1}], type {2}",
+                                   rel_section->GetName().AsCString(), i,
+                                   reloc_type(rel));
+          break;
+        default:
+          assert(false && "unexpected relocation type");
+        }
+        break;
       case llvm::ELF::EM_386:
         switch (reloc_type(rel)) {
         case R_386_32:
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to