HomePhabricator

[lldb][ELF] Read symbols from .gnu_debugdata sect.

Description

[lldb][ELF] Read symbols from .gnu_debugdata sect.

Summary:
If the .symtab section is stripped from the binary it might be that
there's a .gnu_debugdata section which contains a smaller .symtab in
order to provide enough information to create a backtrace with function
names or to set and hit a breakpoint on a function name.

This change looks for a .gnu_debugdata section in the ELF object file.
The .gnu_debugdata section contains a xz-compressed ELF file with a
.symtab section inside. Symbols from that compressed .symtab section
are merged with the main object file's .dynsym symbols (if any).
In addition we always load the .dynsym even if there's a .symtab
section.

For example, the Fedora and RHEL operating systems strip their binaries
but keep a .gnu_debugdata section. While gdb already can read this
section, LLDB until this patch couldn't. To test this patch on a
Fedora or RHEL operating system, try to set a breakpoint on the "help"
symbol in the "zip" binary. Before this patch, only GDB can set this
breakpoint; now LLDB also can do so without installing extra debug
symbols:

lldb /usr/bin/zip -b -o "b help" -o "r" -o "bt" -- -h

The above line runs LLDB in batch mode and on the "/usr/bin/zip -h"
target:

(lldb) target create "/usr/bin/zip"
Current executable set to '/usr/bin/zip' (x86_64).
(lldb) settings set -- target.run-args  "-h"

Before the program starts, we set a breakpoint on the "help" symbol:

(lldb) b help
Breakpoint 1: where = zip`help, address = 0x00000000004093b0

Once the program is run and has hit the breakpoint we ask for a
backtrace:

(lldb) r
Process 10073 stopped
* thread #1, name = 'zip', stop reason = breakpoint 1.1
    frame #0: 0x00000000004093b0 zip`help
zip`help:
->  0x4093b0 <+0>:  pushq  %r12
    0x4093b2 <+2>:  movq   0x2af5f(%rip), %rsi       ;  + 4056
    0x4093b9 <+9>:  movl   $0x1, %edi
    0x4093be <+14>: xorl   %eax, %eax

Process 10073 launched: '/usr/bin/zip' (x86_64)
(lldb) bt
* thread #1, name = 'zip', stop reason = breakpoint 1.1
  * frame #0: 0x00000000004093b0 zip`help
    frame #1: 0x0000000000403970 zip`main + 3248
    frame #2: 0x00007ffff7d8bf33 libc.so.6`__libc_start_main + 243
    frame #3: 0x0000000000408cee zip`_start + 46

In order to support the .gnu_debugdata section, one has to have LZMA
development headers installed. The CMake section, that controls this
part looks for the LZMA headers and enables .gnu_debugdata support by
default if they are found; otherwise or if explicitly requested, the
minidebuginfo support is disabled.

GDB supports the "mini debuginfo" section .gnu_debugdata since v7.6
(2013).

Reviewers: espindola, labath, jankratochvil, alexshap

Reviewed By: labath

Subscribers: rnkovacs, wuzish, shafik, emaste, mgorny, arichardson, hiraditya, MaskRay, lldb-commits

Tags: #lldb, #llvm

Differential Revision: https://reviews.llvm.org/D66791

Details

Committed
kwkOct 7 2019, 3:32 AM
Reviewer
labath
Differential Revision
D66791: [lldb][ELF] Read symbols from .gnu_debugdata sect.
Parents
rL373890: [llvm-readelf/llvm-objdump] - Improve/refactor the implementation of…
Branches
Unknown
Tags
Unknown