This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
dwfl_module_getsym vs. prelink
- From: Josh Stone <jistone at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Thu, 14 Nov 2013 16:00:16 -0800
- Subject: dwfl_module_getsym vs. prelink
On IRC, I mentioned to Mark some bias issues I was having with values
from dwfl_module_getsym, and I promised a smaller reproducer than using
systemtap, so here's my attempt to recreate it with test code that
already exists in elfutils.
The problem I'm having surrounds gnu_debugdata, and tests/dwflsyms
already covers this scenario with testfilebazmdb and testfilebazmin. So
let's experiment with prelinking these.
Note, I extracted all testfilebaz* in my working directory, mainly to
make sure the .debug was also available. I'm also grepping output to
reduce how long this email gets. :)
First testfilebazmdb (dynsym + gnu_debugdata + .debug):
> $ ./dwflsyms -e testfilebazmdb | grep -w FUNC | grep -wE 'main|foo|bar'
> 45: FUNC LOCAL foo (20) 0x814
> 58: FUNC GLOBAL bar (44) 0x828
> 70: FUNC GLOBAL main (35) 0x7f0
> $ /usr/sbin/prelink -N testfilebazmdb
> $ ./dwflsyms -e testfilebazmdb | grep -w FUNC | grep -wE 'main|foo|bar'
> 45: FUNC LOCAL foo (20) 0x3005800814
> 58: FUNC GLOBAL bar (44) 0x3005800828
> 70: FUNC GLOBAL main (35) 0x30058007f0
> $ /usr/sbin/prelink -u testfilebazmdb
> $ /usr/sbin/prelink -r 0x70000000 testfilebazmdb
> $ ./dwflsyms -e testfilebazmdb | grep -w FUNC | grep -wE 'main|foo|bar'
> 45: FUNC LOCAL foo (20) 0x70000814
> 58: FUNC GLOBAL bar (44) 0x70000828
> 70: FUNC GLOBAL main (35) 0x700007f0
This all looks fine; all three functions move around together.
Now testfilebazmin (dynsym + gnu_debugdata)
> $ ./dwflsyms -e testfilebazmin | grep -w FUNC | grep -wE 'main|foo|bar'
> 6: FUNC LOCAL foo (18) 0x400498
> 42: FUNC GLOBAL main (35) 0x7f0
> 45: FUNC GLOBAL bar (44) 0x4004aa
Already a bad start - foo/bar look like symbols that would belong in
ET_EXEC (which indeed the embedded gnu_debugdata really is). I would
not expect that to show up in the main file getsym list, even though
run-dwflsyms.sh is asserting this output.
> $ /usr/sbin/prelink -N testfilebazmin
> $ ./dwflsyms -e testfilebazmin | grep -w FUNC | grep -wE 'main|foo|bar'
> 12: FUNC GLOBAL main (35) 0x30058007f0
Here we completely lost foo/bar!
> $ /usr/sbin/prelink -u testfilebazmin
> $ /usr/sbin/prelink -r 0x70000000 testfilebazmin
> $ ./dwflsyms -e testfilebazmin | grep -w FUNC | grep -wE 'main|foo|bar'
> 6: FUNC LOCAL foo (18) 0x400498
> 42: FUNC GLOBAL main (35) 0x700007f0
> 45: FUNC GLOBAL bar (44) 0x4004aa
Ok, foo/bar came back but still refuse to relocate with main.
I would expect testfilebazmdb and testfilebazmin to behave the same way.
Even if the latter's symbol tables are less complete, the symbols that
are presented ought to be consistent in their base offset, so any can be
used with dwfl_module_relocate_address.
The ET_EXEC gnu_debugdata in both bazmdb and bazmin is suspicious. I
followed your directions to generate all these testfilebaz* on Fedora
19, and I got ET_DYN gnu_debugdata. The symbols are also the same size
and location in my bazmdb and bazmin, whereas you can see above the test
files in elfutils.git are not.
Repeating my prelink sequence on these new binaries, bazmdb still looks
good, and now bazmin looks like this:
> $ ./dwflsyms -e testfilebazmin | grep -w FUNC | grep -wE 'main|foo|bar'
> 8: FUNC LOCAL foo (20) 0x75c
> 47: FUNC GLOBAL bar (40) 0x770
> 51: FUNC GLOBAL main (35) 0x738
> $ /usr/sbin/prelink -N testfilebazmin
> $ ./dwflsyms -e testfilebazmin | grep -w FUNC | grep -wE 'main|foo|bar'
> 8: FUNC LOCAL foo (20) 0x300580075c
> 47: FUNC GLOBAL bar (40) 0x3005800770
> 51: FUNC GLOBAL main (35) 0x3005800738
> $ /usr/sbin/prelink -u testfilebazmin
> $ /usr/sbin/prelink -r 0x70000000 testfilebazmin
> $ ./dwflsyms -e testfilebazmin | grep -w FUNC | grep -wE 'main|foo|bar'
> 8: FUNC LOCAL foo (20) 0x75c
> 47: FUNC GLOBAL bar (40) 0x770
> 51: FUNC GLOBAL main (35) 0x738
Normal prelink is better here, but now prelink -r didn't actually appear
to move any of foo, bar, or main!?! However, this grep is too tight,
because some a few symbols did report moved, like _end. I'll end with
that full output:
> $ ./dwflsyms -e testfilebazmin
> 0: NOTYPE LOCAL (0) 0
> 1: SECTION LOCAL (0) 0x70000238
> 2: FUNC LOCAL deregister_tm_clones (0) 0x650
> 3: FUNC LOCAL register_tm_clones (0) 0x680
> 4: FUNC LOCAL __do_global_dtors_aux (0) 0x6c0
> 5: OBJECT LOCAL __do_global_dtors_aux_fini_array_entry (0) 0x200df0
> 6: FUNC LOCAL frame_dummy (0) 0x700
> 7: OBJECT LOCAL __frame_dummy_init_array_entry (0) 0x200de8
> 8: FUNC LOCAL foo (20) 0x75c
> 9: NOTYPE LOCAL __init_array_end (0) 0x200df0
> 10: NOTYPE LOCAL __init_array_start (0) 0x200de8
> 11: SECTION LOCAL (0) 0x238
> 12: SECTION LOCAL (0) 0x254
> 13: SECTION LOCAL (0) 0x274
> 14: SECTION LOCAL (0) 0x298
> 15: SECTION LOCAL (0) 0x2c8
> 16: SECTION LOCAL (0) 0x3d0
> 17: SECTION LOCAL (0) 0x47a
> 18: SECTION LOCAL (0) 0x490
> 19: SECTION LOCAL (0) 0x4b0
> 20: SECTION LOCAL (0) 0x570
> 21: SECTION LOCAL (0) 0x5b8
> 22: SECTION LOCAL (0) 0x5e0
> 23: SECTION LOCAL (0) 0x620
> 24: SECTION LOCAL (0) 0x814
> 25: SECTION LOCAL (0) 0x820
> 26: SECTION LOCAL (0) 0x824
> 27: SECTION LOCAL (0) 0x868
> 28: SECTION LOCAL (0) 0x200de8
> 29: SECTION LOCAL (0) 0x200df0
> 30: SECTION LOCAL (0) 0x200df8
> 31: SECTION LOCAL (0) 0x200e00
> 32: SECTION LOCAL (0) 0x200e08
> 33: SECTION LOCAL (0) 0x200fd8
> 34: SECTION LOCAL (0) 0x201000
> 35: SECTION LOCAL (0) 0x201030
> 36: SECTION LOCAL (0) 0x20103c
> 37: NOTYPE WEAK _ITM_deregisterTMCloneTable (0) 0
> 38: FUNC GLOBAL __libc_start_main (0) 0
> 39: NOTYPE WEAK __gmon_start__ (0) 0
> 40: NOTYPE WEAK _Jv_RegisterClasses (0) 0
> 41: NOTYPE WEAK _ITM_registerTMCloneTable (0) 0
> 42: FUNC WEAK __cxa_finalize (0) 0
> 43: NOTYPE GLOBAL _edata (0) 0x7020103c
> 44: NOTYPE GLOBAL _end (0) 0x70201040
> 45: NOTYPE GLOBAL __bss_start (0) 0x7020103c
> 46: FUNC GLOBAL __libc_csu_fini (2) 0x810
> 47: FUNC GLOBAL bar (40) 0x770
> 48: FUNC GLOBAL _fini (0) 0x814
> 49: FUNC GLOBAL __libc_csu_init (101) 0x7a0
> 50: FUNC GLOBAL _start (0) 0x620
> 51: FUNC GLOBAL main (35) 0x738
> 52: FUNC GLOBAL _init (0) 0x5b8