[lldb-dev] Accessing ELF/DWARF data
John McCutchan
john at johnmccutchan.com
Fri Sep 10 10:05:49 PDT 2010
On Thu, Sep 9, 2010 at 3:05 PM, Greg Clayton <gclayton at apple.com> wrote:
>
> 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?
Hi Greg,
Thanks for all the great information. It confirms that I should be
able to use lldb for my project. But, what I'm actually after is the
programmable API to gather this information myself. I'll start
crawling the code from those commands to see what APIs they use, but
if you have any pointers or recommendations I would appreciate it.
--
John McCutchan <john at johnmccutchan.com>
More information about the lldb-dev
mailing list