[lldb-dev] Accessing ELF/DWARF data
Greg Clayton
gclayton at apple.com
Thu Sep 9 15:05:29 PDT 2010
On Sep 7, 2010, at 10:01 PM, John McCutchan wrote:
> Hi,
>
> I'm wondering how I could use lldb to access ELF and DWARF data.
> Examples being, the symbol table inside an ELF or being able to walk
> the DIE tree to find the compilation unit for a given PC.
>
> More specifically, I want to be able to perform these queries on an ELF:
>
> 1) For a given PC determine the file name
> 2) For a given PC determine the function name
> 3) For a given PC determine the line number
>
> Is this possible with lldb? If not is this something provided by llvm?
Yes this is possible with LLDB, and LLDB will insulate your from the specifics of the ELF/DWARF and represent the information in its own formats.
You can currently use the "lldb" command line tool to do address lookups:
lldb my.elf
(lldb) image lookup -a 0x1234
An example on MacOSX looks like:
% lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) image lookup --address 0x0000000100000e85
Address: a.out.__TEXT.__text + 121
Summary: a.out`main + 4 at test.c:19
You can also get more internal/verbose information by adding the verbose flag:
(lldb) image lookup --verbose --address 0x0000000100000e85
Address: a.out.__TEXT.__text + 121
Summary: a.out`main + 4 at test.c:19
Module: "/Volumes/work/gclayton/Documents/src/attach/a.out"
CompileUnit: "/Volumes/work/gclayton/Documents/src/attach/test.c", id = {0x00000000}, language = ISO C:1989
Function: "main", id = {0x0000008f}, range =
FuncType: id = {0x0000008f}, decl = /Volumes/work/gclayton/Documents/src/attach/test.c:18, clang_type = 0x04818850 int (int, char const **)
Blocks: range = [0x100000e81-0x100000eab), id = {0x0000008f}
LineEntry: range = /Volumes/work/gclayton/Documents/src/attach/test.c:19
Symbol: "main", id = {0x00000008}, range =
Since the symbol file parser gets to pick the IDs for the you can usually infer where the data came from in the dwarf. Above we see the function has an "id = {0x0000008f}" which means it was the DIE at offset 0x8f in the .debug_info. Also the Block ID "id = {0x0000008f}" will show you the deepest block in the DWARF where the address matched (in this case it is the same as the function at 0x8f).
The one thing you need to watch out for is that before you run, all addresses are "file virtual addresses", so if you have an executable and shared libraries that are based at address zero, you might get multiple matches for an address.
On MacOSX:
(lldb) image lookup --address 0x2000
Address: a.out.__PAGEZERO + 8192
Summary:
Address: libSystem.B.dylib.__TEXT.__text + 3392
Summary: libSystem.B.dylib`mach_ports_lookup + 120
Address: libmathCommon.A.dylib.__TEXT.__const + 512
Summary: libmathCommon.A.dylib`exp2table + 208
We see the "file virtual address" of 0x2000 matches our main executable, libSystem and libmathCommon. I didn't have debug symbols for these shared libraries so we only see the symbols that matched.
If you want to limit your search to just a specific executable/shared library you can add it on the command line:
(lldb) image lookup --address 0x2000 a.out
Address: a.out.__PAGEZERO + 8192
Summary:
Does this help and do all that you want it to do?
Greg Clayton
More information about the lldb-dev
mailing list