[Lldb-commits] [PATCH] D61611: [JITLoaderGDB] Set eTypeJIT for objects read from JIT descriptors

Stefan Gränitz via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Mon May 6 14:06:23 PDT 2019

sgraenitz created this revision.
sgraenitz added reviewers: labath, JDevlieghere, bkoropoff, clayborg.
Herald added subscribers: MaskRay, arichardson, aprantl, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLDB.

First part of a fix for JITed code debugging. This has been a regression from 5.0 to 6.0 and it's is still reproducible on current master: https://bugs.llvm.org/show_bug.cgi?id=36209

The address of the breakpoint site is corrupt: the 0x4 value we end up with, looks like an offset on a zero base address. When we parse the ELF section headers from the JIT descriptor, the load address for the text section we find in `header.sh_addr` is correct.

The bug manifests in `VMAddressProvider::GetVMRange(const ELFSectionHeader &)` (follow it from `ObjectFileELF::CreateSections()`). Here we think the object type was `eTypeObjectFile` and unleash some extra logic [1] which essentially overwrites the address with a zero value.

The object type is deduced from the ELF header's `e_type` in `ObjectFileELF::CalculateType()`. It never returns `eTypeJIT`, because the ELF header has no representation for it [2]. Instead the in-memory ELF object states `ET_REL`, which leads to `eTypeObjectFile`. This is what we get from `lli` at least since 3.x. (Might it be better to write `ET_EXEC` on the JIT side instead? In fact, relocations were already applied at this point, so "Relocatable" is not quite exact.)

So, this patch proposes to set `eTypeJIT` explicitly whenever we read from a JIT descriptor. In `ObjectFileELF::CreateSections()` we can then call `GetType()`, which returns the explicit value or otherwise falls back to `CalculateType()`.

LLDB then sets the breakpoint successfully. Next step: debug info.

  Process 1056 stopped
  * thread #1, name = 'lli', stop reason = breakpoint 1.2
      frame #0: 0x00007ffff7ff7000 JIT(0x3ba2030)`jitbp()
  ->  0x7ffff7ff7000 <+0>:  pushq  %rbp
      0x7ffff7ff7001 <+1>:  movq   %rsp, %rbp
      0x7ffff7ff7004 <+4>:  movabsq $0x7ffff7ff6000, %rdi     ; imm = 0x7FFFF7FF6000 
      0x7ffff7ff700e <+14>: movabsq $0x7ffff6697e80, %rcx     ; imm = 0x7FFFF6697E80 

[1] It was first introduced with https://reviews.llvm.org/D38142#change-lF6csxV8HdlL, which has also been the original breaking change. The code has changed a lot since then.

[2] ELF object types: https://github.com/llvm/llvm-project/blob/2d2277f5/llvm/include/llvm/BinaryFormat/ELF.h#L110

  rG LLVM Github Monorepo



Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
--- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1865,7 +1865,7 @@
   m_sections_up = llvm::make_unique<SectionList>();
-  VMAddressProvider address_provider(CalculateType());
+  VMAddressProvider address_provider(GetType());
   size_t LoadID = 0;
   for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
Index: lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
--- lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -327,6 +327,10 @@
           FileSpec(jit_name), symbolfile_addr, symbolfile_size);
       if (module_sp && module_sp->GetObjectFile()) {
+        // Object formats (like ELF) have no representation for a JIT type.
+        // We will get it wrong, if we deduce it from the header.
+        module_sp->GetObjectFile()->SetType(ObjectFile::eTypeJIT);
         // load the symbol table right away

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61611.198337.patch
Type: text/x-patch
Size: 1220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20190506/0182ea11/attachment.bin>

More information about the lldb-commits mailing list