[Lldb-commits] [lldb] f4fc405 - lldb: Add support for R_386_32 relocations to ObjectFileELF

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 13 09:39:06 PDT 2022


Author: David M. Lary
Date: 2022-09-13T18:38:48+02:00
New Revision: f4fc4056319dd8ddfb8759f71c7aec86882c9110

URL: https://github.com/llvm/llvm-project/commit/f4fc4056319dd8ddfb8759f71c7aec86882c9110
DIFF: https://github.com/llvm/llvm-project/commit/f4fc4056319dd8ddfb8759f71c7aec86882c9110.diff

LOG: 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 at host work]$ cat rel.c
volatile char padding[32] = "make sure var isnt at .data+0";
volatile char var[] = "test";
[dmlary at host work]$ gcc -c rel.c -FPIC -fpic -g -m32

[dmlary at 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

Added: 
    lldb/test/Shell/ObjectFile/ELF/i386-relocations.yaml

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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index ba4a1f62f342..af1b0930c1b7 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -121,6 +121,8 @@ class ELFRelocation {
 
   static unsigned RelocAddend64(const ELFRelocation &rel);
 
+  bool IsRela() { return (reloc.is<ELFRela *>()); }
+
 private:
   typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
 
@@ -2597,25 +2599,46 @@ unsigned ObjectFileELF::ApplyRelocations(
   }
 
   for (unsigned i = 0; i < num_relocations; ++i) {
-    if (!rel.Parse(rel_data, &offset))
+    if (!rel.Parse(rel_data, &offset)) {
+      GetModule()->ReportError(".rel%s[%d] failed to parse relocation",
+                               rel_section->GetName().AsCString(), i);
       break;
-
+    }
     Symbol *symbol = nullptr;
 
     if (hdr->Is32Bit()) {
       switch (reloc_type(rel)) {
       case R_386_32:
+        symbol = symtab->FindSymbolByID(reloc_symbol(rel));
+        if (symbol) {
+          addr_t f_offset =
+              rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel);
+          DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
+          // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
+          WritableDataBuffer *data_buffer =
+              llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
+          uint32_t *dst = reinterpret_cast<uint32_t *>(
+              data_buffer->GetBytes() + f_offset);
+
+          addr_t value = symbol->GetAddressRef().GetFileAddress();
+          if (rel.IsRela()) {
+            value += ELFRelocation::RelocAddend32(rel);
+          } else {
+            value += *dst;
+          }
+          *dst = value;
+        } else {
+          GetModule()->ReportError(".rel%s[%u] unknown symbol id: %d",
+                                   rel_section->GetName().AsCString(), i,
+                                   reloc_symbol(rel));
+        }
+        break;
       case R_386_PC32:
       default:
-        // FIXME: This asserts with this input:
-        //
-        // foo.cpp
-        // int main(int argc, char **argv) { return 0; }
-        //
-        // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o
-        //
-        // and running this on the foo.o module.
-        assert(false && "unexpected relocation type");
+        GetModule()->ReportError("unsupported 32-bit relocation:"
+                                 " .rel%s[%u], type %u",
+                                 rel_section->GetName().AsCString(), i,
+                                 reloc_type(rel));
       }
     } else {
       switch (reloc_type(rel)) {

diff  --git a/lldb/test/Shell/ObjectFile/ELF/i386-relocations.yaml b/lldb/test/Shell/ObjectFile/ELF/i386-relocations.yaml
new file mode 100644
index 000000000000..08eb9f1a8b1b
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/ELF/i386-relocations.yaml
@@ -0,0 +1,57 @@
+# RUN: yaml2obj %s -o %t
+# RUN: lldb-test object-file --contents %t | FileCheck %s
+#
+# CHECK-LABEL:  Name: .debug_info
+# CHECK:        Data: (
+# CHECK-NEXT:     0000: 22222222
+#
+# CHECK-LABEL:  Name: .debug_lines
+# CHECK:        Data: (
+# CHECK-NEXT:     0000: 33333333
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_386
+Sections:
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x20
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         11111111
+  - Name:            .debug_lines
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         99999999
+  - Name:            .rel.debug_info
+    Type:            SHT_REL
+    Flags:           [ SHF_INFO_LINK ]
+    Link:            .symtab
+    AddressAlign:    0x0
+    Info:            .debug_info
+    Relocations:
+      - Offset:          0x0
+        Symbol:          var
+        Type:            R_386_32
+  - Name:            .rela.debug_lines
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x4
+    Info:            .debug_lines
+    Relocations:
+      - Offset:          0x0
+        Addend:          0x22222222
+        Symbol:          var
+        Type:            R_386_32
+Symbols:
+  - Name:            var
+    Type:            STT_OBJECT
+    Section:         .data
+    Binding:         STB_GLOBAL
+    Value:           0x11111111
+    Size:            0x5
+...


        


More information about the lldb-commits mailing list