On 09/26/2013 01:55 AM, Hemant wrote:
Hi
I have been trying to understand how systemtap probes on the SDT markers
and trying to implement this functionality in perf. But I am having
trouble to understand that how systemtap handles prelinking issue for
shared libraries. From what I got till now is :
base = address of .stapsdt.base section.
Then, address of the base section is retrieved from the sdt notes'
description in .note.stapsdt section stored in say, base_ref. Prelinking
might change the base address.
Then, base_ref is subtracted from base and added to pc (pc contains the
location of the sdt note).
pc += base - base_ref
My point in the .note.stapsdt section, the markers' location is stored
as an "offset". And since, we need to specify only the offset inside the
uprobe_events file in the tracing directory, why do we need to handle/do
all the calculations regarding these base addresses. Can the offset
change after prelinking? Or am I wrong and some other things are
happening here which I am unaware of? Can anybody just throw some pointers?
The stored location in .note.stapsdt really is a virtual address, *not*
an offset. It just happen to look like an offset for ET_DYN binaries,
because .text is in the first mapped region, and before prelinking
libraries tend to use Offset==VirtAddr for the first loaded section.
(Check readelf -l for LOAD entries.)
This distinction should be clear if you look at some ET_EXEC binary
instead. It also will matter when you begin to look at semaphore
addresses, because the mapping with .data usually has some padding that
shifts the address compared to the file offset.
So, you do need to process the marker's location at least a little, if
only to deal with ET_EXEC where the recorded address != file offset.
I'm not sure if prelink ever changes the actual file offset, but you
might as well be prepared for this. It may be as simple as:
sdt_addr = location address stored in .note.stapsdt
base_addr = base address stored in .note.stapsdt
base_off = current file offset of .stapsdt.base
-->
sdt_off = base_off + (sdt_addr - base_addr)
... which is essentially the same computation you mentioned above, just
using the .stapsdt.base *offset* rather than its address.