Since r299449 "Make RuntimeDyld honor the ProcessAllSections flag." we
have been experiencing an assertion failure when evaluating expressions
on linux.
Based on my investigation, the sequence of events is as follows:
- lldb sets the ProcessAllSections flag
- RuntimeDyld starts loading all sections, .debug_frame in particular
- RuntimeDyld ask lldb for an address of the section, lldb provides an
address somewhere in its 64-bit address space
- RuntimeDyld proceeds to resolve relocations in this section
In my simple example the section consists of two entries: one CIE and
one FDE. It also contains a relocation of type R_X86_64_32 pointing from
the FDE to its CIE.
- RuntimeDyld tries to apply the relocation, but fails because the load
address of the section has high bits set
Removing the ProcessAllSections flag makes the assert go away (and
re-introduces the pre-r299449 lldb behavior of ignoring these sections),
but it seems that this could be just masking a bigger issue. However, my
knowledge of this part of the code is limited, so I don't know what the
actual issue should be:
- This is an intra-section relocation, and dwarf explicitly says that
this should be a relative offset. Should the relocation have been
emitted in the first place ? Is it the right relocation type this use
case?
- Is RuntimeDyld picking the wrong address to relocate?
- Should lldb be somehow detecting this situation and set the load
address of the section to zero to get this right?
I'd appreciate any input or pointers. The bug can be reproduced (on
linux) with:
echo 'int main() { return 0; }' >a.c
cc -g a.c
bin/lldb a.out
b main
run
expr main()