[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

      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

Does this help and do all that you want it to do?

Greg Clayton

More information about the lldb-dev mailing list