|
From: Josef W. <Jos...@gm...> - 2005-09-11 23:32:24
|
Hi Tom, On Thursday 01 September 2005 09:47, Tom Hughes wrote: > In message <200...@gm...> > > Josef Weidendorfer <Jos...@gm...> wrote: > > For (2) I need a heuristic for detecting the function for lazy symbol > > relocation in the runtime linker. Some background: > > When I see a JMP crossing functions (e.g. A calls B, B jumps to C), I > > have two possibilities to map this onto a call graph: > > a) A calls B, returns to A, A calls C > > b) A calls B, B calls C > > I default to (b), as this gives nice graphs e.g. with tail recursion. > > With one exception: every call to a shared lib usually first calls the > > runtime linker, which jumps to the right function at the end. So using > > (b) here gives call chains with the relocation function multiple times > > showing up, and this looks like recursive cycles for KCachegrind. This > > leads to profiles showing most functions in a recursive cycle, which is > > bad. So I want (a) for the relocation function. > > x86 used "push <addr>;ret" at end of relocation, and in a bad hack I used > > this to decide for (a). But AMD64 uses a normal JMP instruction. > > The thing is, that with a stripped runtime linker, the relocation > > function gets no symbol name (how is this possible?). How should I decide > > that I want (a) in this case? > > Ideas welcome. > > When this happens do you still know the original address that the > first jump went to? So if foo() calls bar() which is in a different > shared library then foo jumps to the PLT entry which jumps to the > dynamic linker which eventually jumps to bar. Yes. > Do you know when that > last jump to bar happens the target address of the original jump from > foo into the PLT? Sorry, I do not understand this question... > If you do then the trick is that when you read the ELF header for > each shared library you remember the address and size of the PLT > section for each one and if that original jump was into a PLT then > you know you've just done a lazy symbol resolution. > > I guess the problem is that future calls will still go through > the PLT and if the called functions then tail calls it will get > confusing. Yes. Calls will always go through PLT. At least on x86/AMD64, the PLT code does an indirect jump, which usually first jumps into the runtime linker. The "usually" is a problem here: for prelinked code, this is of course not true. And then, a call into the runtime linker does not have to be about symbol resolution at all... Detecting PLT sections is no problem, and looking up if a function was jumped to from PLT would also be possible, but this all is getting quite complex and probably fragile. > Maybe you have to look for a jump into the PLT followed by a jump > into ld.so followed by a another jump... It's all getting a bit > horrible though ;-) Yes. The easiest way would be to look at the symbol "dl_runtime_resolve". I just do not understand why this symbol on some systems seems not to be available. Does this happen on your system? I think I'll go with the symbol name, which can be configured via command line option. Josef > > Tom |