[lldb-dev] Accessing ELF/DWARF data

John McCutchan john at johnmccutchan.com
Mon Sep 13 22:31:46 PDT 2010


Hi Greg,

This looks like it does most of what I want. It's a great start. What
targets are supported? My ELFs are compiled for Cell Linux. If I just
want to find things inside an ELF does the target really matter? I
don't want decompilation or the ability to actually run the
executable. I'll need to load the main ELF and some shared ELF
libraries into certain memory addresses and then do lookups based on
PC samples. Is there a virtual or fake target that I could use if my
particular platform isn't targeted?

Thanks,
John

On Fri, Sep 10, 2010 at 11:35 AM, Greg Clayton <gclayton at apple.com> wrote:
>  I have checked in some missing bits to our API for address lookups, and added sample code in the repository that allows you to specify an executable and do an address lookup in that file. The new file is in the repository at:
>
> examples/lookup/main.cpp
>
> Let me know if this is enough to get you going. There are sure to be things that are in LLDB core that are not yet exposed through the script briding API (the classes that start with "lldb::SB"), so let me know if/when you run into issues and need more exposed).
>
> Greg Clayton
>
> On Sep 10, 2010, at 10:05 AM, John McCutchan wrote:
>
>> 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>
>
>
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>



-- 
John McCutchan <john at johnmccutchan.com>




More information about the lldb-dev mailing list