I encountered an issue where p &variable was finding an incorrect address for
32-bit PIC ELF files loaded into a running process. The problem was that the
R_386_32 ELF relocations were not being applied to the DWARF section, so all
variables in that file were reporting as being at the start of their respective
section. There is an assert that catches this on debug builds, but silently
ignores the issue on non-debug builds.
In this changeset, I added handling for the R_386_32 relocation type to
ObjectFileELF, and a supporting function to ELFRelocation to differentiate
between DT_REL & DT_RELA in ObjectFileELF::ApplyRelocations().
Demonstration of issue:
# build a relocatable object file; [dmlary@host work]$ cat rel.c volatile char padding[32] = "make sure var isnt at .data+0"; volatile char var[] = "test"; [dmlary@host work]$ gcc -c rel.c -FPIC -fpic -g -m32 # start lldb debugging any binary; [dmlary@host work]$ lldb ./exec (lldb) target create "./exec" Current executable set to '/home/dmlary/src/work/exec' (i386). (lldb) process launch --stop-at-entry Process 21278 stopped * thread #1, name = 'exec', stop reason = signal SIGSTOP frame #0: 0xf7fdb150 ld-2.17.so`_start ld-2.17.so`_start: -> 0xf7fdb150 <+0>: movl %esp, %eax 0xf7fdb152 <+2>: calll 0xf7fdb990 ; _dl_start ld-2.17.so`_dl_start_user: 0xf7fdb157 <+0>: movl %eax, %edi 0xf7fdb159 <+2>: calll 0xf7fdb140 Process 21278 launched: '/home/dmlary/src/work/exec' (i386) # add the .o file, and load it at an arbitrary address (lldb) image add ./rel.o (lldb) image load --file rel.o .text 0x40000000 .data 0x50000000 section '.text' loaded at 0x40000000 section '.data' loaded at 0x50000000 # look where the `var` symbol should be loaded (0x50000020) (lldb) image dump symtab rel.o Symtab, file = rel.o, num_symbols = 13: Debug symbol |Synthetic symbol ||Externally Visible ||| Index UserID DSX Type File Address/Value Load Address Size Flags Name ------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ---------------------------------- [ 0] 1 SourceFile 0x0000000000000000 0x0000000000000000 0x00000004 rel.c [ 1] 2 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 2] 3 Invalid 0x0000000000000000 0x50000000 0x0000000000000020 0x00000003 [ 3] 4 Invalid 0x0000000000000025 0x0000000000000000 0x00000003 [ 4] 5 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 5] 6 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 6] 7 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 7] 8 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 8] 9 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 9] 10 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 10] 11 Invalid 0x0000000000000000 0x0000000000000020 0x00000003 [ 11] 12 X Data 0x0000000000000000 0x50000000 0x0000000000000020 0x00000011 padding [ 12] 13 X Data 0x0000000000000020 0x50000020 0x0000000000000005 0x00000011 var # eval reports it at the start of the section instead (lldb) p &var (volatile char (*)[5]) $1 = 0x50000000
Maybe just remove this assertion now.