public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: Mark Wielaard <mark@klomp.org>
To: Luke Diamand <ldiamand@roku.com>
Cc: "elfutils-devel@sourceware.org" <elfutils-devel@sourceware.org>,
	"Dmitry V. Levin" <ldv@altlinux.org>
Subject: Re: [PATCHv2 1/2] libdwfl: specify optional sysroot to search for shared libraries
Date: Tue, 29 Jan 2019 15:11:00 -0000	[thread overview]
Message-ID: <20190129151138.GG9378@wildebeest.org> (raw)
In-Reply-To: <20190122101610.5301-2-ldiamand@roku.com>

On Tue, Jan 22, 2019 at 10:16:25AM +0000, Luke Diamand wrote:
> When searching the list of modules in a core file, if the core was
> generated on a different system to the current one, we need to look
> in a sysroot for the various shared objects.
> 
> For example, we might be looking at a core file from an ARM system
> using elfutils running on an x86 host.
> 
> This change adds a new function, dwfl_set_sysroot(), which then
> gets used when searching for libraries.

A few comments below.
Also a ChangeLog entry is missing. I added comments for them.

> Signed-off-by: Luke Diamand <ldiamand@roku.com>
> ---
>  libdw/libdw.map    |  7 ++++++-
>  libdwfl/dwfl_end.c |  1 +
>  libdwfl/libdwfl.h  |  5 +++++
>  libdwfl/libdwflP.h |  1 +
>  libdwfl/link_map.c | 26 ++++++++++++++++++++++++--
>  5 files changed, 37 insertions(+), 3 deletions(-)
> 
> diff --git a/libdw/libdw.map b/libdw/libdw.map
> index 55482d58..43a9de2e 100644
> --- a/libdw/libdw.map
> +++ b/libdw/libdw.map
> @@ -360,4 +360,9 @@ ELFUTILS_0.173 {
>  ELFUTILS_0.175 {
>    global:
>      dwelf_elf_begin;
> -} ELFUTILS_0.173;
> \ No newline at end of file
> +} ELFUTILS_0.173;
> +
> +ELFUTILS_0.176 {
> +  global:
> +    dwfl_set_sysroot;
> +} ELFUTILS_0.175;

OK.

       * libdw.map (ELFUTILS_0.176): New section, add dwfl_set_rootsysroot.

> diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c
> index 74ee9e07..345d9947 100644
> --- a/libdwfl/dwfl_end.c
> +++ b/libdwfl/dwfl_end.c
> @@ -45,6 +45,7 @@ dwfl_end (Dwfl *dwfl)
>    free (dwfl->lookup_addr);
>    free (dwfl->lookup_module);
>    free (dwfl->lookup_segndx);
> +  free (dwfl->sysroot);
>  
>    Dwfl_Module *next = dwfl->modulelist;
>    while (next != NULL)

OK.

	* libdwfl_end.c (dwfl_end): Free dwfl->sysroot.

> diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
> index a0c1d357..c11e2f24 100644
> --- a/libdwfl/libdwfl.h
> +++ b/libdwfl/libdwfl.h
> @@ -807,6 +807,11 @@ int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
>  bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation)
>    __nonnull_attribute__ (1, 2);
>  
> +/* Set the sysroot to use when searching for shared libraries. If not
> + specified, search in the system root.  */
> +void dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot)
> +  __nonnull_attribute__ (1);

This should document that a copy is made of sysroot which
is owned by the library, the passed in string is owned and
can be freed after the call.

It probably should return an int, so failure can be indicated
(you call realpath, which can fail).
What happens if sysroot was already set?
Does setting it to NULL clear it?

	* libdwfl.h (dwfl_set_sysroot): New function declaration.

> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
> index 941a8b66..db16ab57 100644
> --- a/libdwfl/libdwflP.h
> +++ b/libdwfl/libdwflP.h
> @@ -138,6 +138,7 @@ struct Dwfl
>    int lookup_tail_ndx;
>  
>    struct Dwfl_User_Core *user_core;
> +  char *sysroot;	/* sysroot, or NULL to search standard system paths */
>  };

OK.

	* libdwflP.h (struct Dwfl): Add sysroot field.
>  
>  #define OFFLINE_REDZONE		0x10000
> diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
> index 29307c74..cf18c0a2 100644
> --- a/libdwfl/link_map.c
> +++ b/libdwfl/link_map.c
> @@ -34,6 +34,7 @@
>  #include <byteswap.h>
>  #include <endian.h>
>  #include <fcntl.h>
> +#include <stdlib.h>
>  
>  /* This element is always provided and always has a constant value.
>     This makes it an easy thing to scan for to discern the format.  */
> @@ -388,8 +389,21 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
>        if (name != NULL)
>  	{
>  	  /* This code is mostly inlined dwfl_report_elf.  */
> -	  // XXX hook for sysroot
> -	  int fd = open (name, O_RDONLY);
> +	  char *path_name;
> +	  int rc;
> +	  const char *sysroot = dwfl->sysroot;
> +
> +	  /* don't look in the sysroot if the path is already inside the sysroot */
> +	  bool name_in_sysroot = sysroot && (strncmp(name, sysroot, strlen(sysroot)) == 0);
> +
> +	  if (!name_in_sysroot && sysroot)

The && sysroot is now redundant.

> +	    rc = asprintf(&path_name, "%s/%s", sysroot, name);
> +	  else
> +	    rc = asprintf(&path_name, "%s", name);
> +	  if (unlikely(rc == -1))
> +	    return release_buffer(-1);

Minor optimization.
In theory you could just assign name to path_name here and then...

> +
> +	  int fd = open (path_name, O_RDONLY);
>  	  if (fd >= 0)
>  	    {
>  	      Elf *elf;
> @@ -471,6 +485,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
>  		    close (fd);
>  		}
>  	    }
> +          free(path_name);

Guard this free with if (name_in_sysroot).
No worries if you think that is ugly, it does make for
easier error handling and resource cleanup.

Please use tab plus 2 spaces to indent.

	* link_map.c (report_r_debug): Check and use Dwfl sysroot.

>  	}
>  
>        if (mod != NULL)
> @@ -1037,3 +1052,10 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
>  			 &integrated_memory_callback, &mcb, r_debug_info);
>  }
>  INTDEF (dwfl_link_map_report)
> +
> +void
> +dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot)
> +{
> +  dwfl->sysroot = realpath(sysroot, NULL);
> +}
> +INTDEF (dwfl_set_sysroot)

I like it better if this goes into its own file (in theory every public
function has its own implementation file). Also see the comments above
for the function declaration. You probably want to handle sysroot
already been set (error or replace?) and sysroot being NULL (error or
clear sysroot setting?).

Cheers,

Mark

  reply	other threads:[~2019-01-29 15:11 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-22 10:16 [PATCHv2 0/2] specify a sysroot to search when examining a core file Luke Diamand
2019-01-22 10:16 ` [PATCHv2 1/2] libdwfl: specify optional sysroot to search for shared libraries Luke Diamand
2019-01-29 15:11   ` Mark Wielaard [this message]
2019-01-22 10:16 ` [PATCHv2 2/2] eu-stack: add support for sysroot option Luke Diamand
2019-01-29 15:12   ` Mark Wielaard

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=20190129151138.GG9378@wildebeest.org \
    --to=mark@klomp.org \
    --cc=elfutils-devel@sourceware.org \
    --cc=ldiamand@roku.com \
    --cc=ldv@altlinux.org \
    /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).