public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
From: Roland McGrath <roland@redhat.com>
To: Nurdin <npremji@redhat.com>
Cc: Frysk List <frysk@sourceware.org>
Subject: getting vDSO image into libdwfl
Date: Fri, 18 May 2007 16:53:00 -0000	[thread overview]
Message-ID: <20070518071438.4FF511F804E@magilla.localdomain> (raw)
In-Reply-To: Nurdin's message of  Thursday, 17 May 2007 13:17:17 -0400 <464C8E1D.6010007@redhat.com>

The normal kinds of modules in a process (or a kernel) correspond to ELF
files on disk.  We satisfy the Dwfl_Callbacks.find_elf callback for those
just by opening the file by name.  The vDSO does not exist as a file on
disk, so we need to read the ELF file image directly from memory in the
debuggee address space.

The find_elf callback normally supplies a file name and most often an fd.
But it can also supply an Elf * handle already opened, and then the file
name and fd are not required.  So, a find_elf callback dealing with the
vDSO module can get a copy of the vDSO image from the debugee address space
into local memory in the debugger and use elf_memory to create an Elf *
handle on it.

The dwfl_linux_proc_find_elf callback does this as a skeletal example.
It uses this function (see libdwfl/elf-from-memory.c):

    /* Reconstruct an ELF file by reading the segments out of remote memory
       based on the ELF file header at EHDR_VMA and the ELF program headers it
       points to.  If not null, *LOADBASEP is filled in with the difference
       between the addresses from which the segments were read, and the
       addresses the file headers put them at.

       The function READ_MEMORY is called to copy at least MINREAD and at most
       MAXREAD bytes from the remote memory at target address ADDRESS into the
       local buffer at DATA; it should return -1 for errors (with code in
       `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or
       the number of bytes read if >= MINREAD.  ARG is passed through.  */

    Elf *
    elf_from_remote_memory (GElf_Addr ehdr_vma,
			    GElf_Addr *loadbasep,
			    ssize_t (*read_memory) (void *arg, void *data,
						    GElf_Addr address,
						    size_t minread,
						    size_t maxread),
			    void *arg)

This is an internal function not exported in the DSO or declared anywhere.
I wrote it as the necessary and separable component (and analogous to the
BFD function bfd_elf_bfd_from_remote_memory I added for the gdb vDSO
support).  I tested it via dwfl_linux_proc_find_elf (-p option to
eu-addr2line et al).  (Back then, /proc/PID/mem had not been made so
"secure", so it even worked in eu-foo without ptrace.)  I figured the
details of interface to that code and how it integrates with everything
would be ironed out when a real user came along.  Now here we are.

If you read the function, you'll see a lot of libelf hooey to deal with the
format encoding in all cross-permutations, but it's not doing very much.
It just reads the ELF file header and phdrs enough to decide if the whole
file image is really in memory and exactly how big it is.  Then it reads it
all in, and calls elf_memory.

The signature of the read_memory callback is arbitrary.  
It just seemed like the roughly appropriate general thing.
It's easy to change.

This function doesn't really fit with the libelf interfaces.  It could be
exposed by libdwfl in some fashion I suppose.  I hadn't really figured out
what seemed right, which is why it's as it is.  I could just change its
name and signature slightly, and export it from libdwfl.

Alternatively, if you have Java libelf bindings for all the xlate stuff,
it's not very complex to code it up in Java.  Then you might have a cleaner
way to integrate the memory-reading stuff that might do less copying.
Maybe some existing buffer data structure of yours has a raw pointer you
can pass to elf_memory.

Finally, you can instead avoid all this ELF grovelling stuff altogether.
This certainly seems like simplest thing for Frysk to do to start with, so
naturally I mention it last.  All the ELF header grokking is basically to
determine how big the image is (and in the general case that does not apply
here, if the phdrs really say that the memory image matches the whole file).
You already know how big the mapping is (in practice so far always one page,
two on ia64, might be a few on ppc).  That's the page-rounded upper limit on
the size of the image.  On x86, the mapping is 4k (one page) and the vDSO
ELF file image is actually between 2k and 3k.  Past the end of the actual
image, the rest of the page is zero.  It doesn't hurt to give elf_memory a
buffer including this padding.  So if it's not too costly to read a whole
page of memory instead of 1/2 or 3/4 that much, you can just do that.


Thanks,
Roland

  parent reply	other threads:[~2007-05-18  7:14 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-17 18:04 Dwfl Callbacks, how would I pass a ByteBuffer to find_elf (possibly through user_data) Nurdin
2007-05-18  7:14 ` Dwfl Callbacks Roland McGrath
2007-05-18 16:53 ` Roland McGrath [this message]
2007-05-25 16:50   ` getting vDSO image into libdwfl Nurdin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070518071438.4FF511F804E@magilla.localdomain \
    --to=roland@redhat.com \
    --cc=frysk@sourceware.org \
    --cc=npremji@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).