unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* dlinfo for the calling shared library
@ 2019-07-10 13:06 Zack Weinberg
  2019-07-10 13:29 ` Carlos O'Donell
  2019-07-10 14:15 ` Florian Weimer
  0 siblings, 2 replies; 5+ messages in thread
From: Zack Weinberg @ 2019-07-10 13:06 UTC (permalink / raw)
  To: GNU C Library

Do we have a supported way to make dlinfo() queries for the shared
library from which the call originates, without the library having to
know its own soname?  (If it knows its own soname, it can call dlopen
on itself, but I'm looking into a scenario where that information is
not available.)

A library can retrieve its own "base address" using dladdr(), but it
is not clear to me whether that is the same thing as the handle
expected by dlsym and dlinfo.

zw

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: dlinfo for the calling shared library
  2019-07-10 13:06 dlinfo for the calling shared library Zack Weinberg
@ 2019-07-10 13:29 ` Carlos O'Donell
  2019-07-10 14:15 ` Florian Weimer
  1 sibling, 0 replies; 5+ messages in thread
From: Carlos O'Donell @ 2019-07-10 13:29 UTC (permalink / raw)
  To: Zack Weinberg, GNU C Library

On 7/10/19 9:06 AM, Zack Weinberg wrote:
> Do we have a supported way to make dlinfo() queries for the shared
> library from which the call originates, without the library having to
> know its own soname?  (If it knows its own soname, it can call dlopen
> on itself, but I'm looking into a scenario where that information is
> not available.)

It is not easy.

If I had to do it I would do:

(a) Call dladdr() to find your base address.
(b) Call dl_iterate_phdr() to find the object by matching
     struct dl_phdr_info -> dlpi_addr == Dl_info -> dli_fbase
(c) Via struct dl_phdr_info work through PT_DYNAMIC to find
     DT_SONAME and extract soname.
(d) Call dlopen() with SONAME to get handle.
(e) Use handle with dlinfo() to get data.

> A library can retrieve its own "base address" using dladdr(), but it
> is not clear to me whether that is the same thing as the handle
> expected by dlsym and dlinfo.

It is not. Internally the handle is a pointer to the identifying
struct link_map for the shared object.

What we want here is, unsuprisingly, Solaris's RTLD_SELF.
https://docs.oracle.com/cd/E19683-01/816-0213/6m6ne37t3/index.html

Though we should extend it such that dlopen accepts RTLD_SELF and
returns your associated link_map by doing much of the above internally.

-- 
Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: dlinfo for the calling shared library
  2019-07-10 13:06 dlinfo for the calling shared library Zack Weinberg
  2019-07-10 13:29 ` Carlos O'Donell
@ 2019-07-10 14:15 ` Florian Weimer
  2019-07-10 16:20   ` Carlos O'Donell
  1 sibling, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2019-07-10 14:15 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: GNU C Library

* Zack Weinberg:

> Do we have a supported way to make dlinfo() queries for the shared
> library from which the call originates, without the library having to
> know its own soname?  (If it knows its own soname, it can call dlopen
> on itself, but I'm looking into a scenario where that information is
> not available.)

dladdr1 with RTLD_DL_LINKMAP returns the link map, which has a public
l_name member in <link.h>.  If you do not want to use the handle/link
map equivalence, you could dlopen l_name, and that should give you back
the same handle in an official way.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: dlinfo for the calling shared library
  2019-07-10 14:15 ` Florian Weimer
@ 2019-07-10 16:20   ` Carlos O'Donell
  2019-07-10 16:32     ` Florian Weimer
  0 siblings, 1 reply; 5+ messages in thread
From: Carlos O'Donell @ 2019-07-10 16:20 UTC (permalink / raw)
  To: Florian Weimer, Zack Weinberg; +Cc: GNU C Library

On 7/10/19 10:15 AM, Florian Weimer wrote:
> * Zack Weinberg:
> 
>> Do we have a supported way to make dlinfo() queries for the shared
>> library from which the call originates, without the library having to
>> know its own soname?  (If it knows its own soname, it can call dlopen
>> on itself, but I'm looking into a scenario where that information is
>> not available.)
> 
> dladdr1 with RTLD_DL_LINKMAP returns the link map, which has a public
> l_name member in <link.h>.  If you do not want to use the handle/link
> map equivalence, you could dlopen l_name, and that should give you back
> the same handle in an official way.

What happens if l_name is different on disk now and has a distinct SONAME?
Doesn't this introduce a race condition?

If you open by SONAME then you should always get the already loaded in-memory
object which might have changed from the on-disk contents.

-- 
Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: dlinfo for the calling shared library
  2019-07-10 16:20   ` Carlos O'Donell
@ 2019-07-10 16:32     ` Florian Weimer
  0 siblings, 0 replies; 5+ messages in thread
From: Florian Weimer @ 2019-07-10 16:32 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: Zack Weinberg, GNU C Library

* Carlos O'Donell:

> On 7/10/19 10:15 AM, Florian Weimer wrote:
>> * Zack Weinberg:
>>
>>> Do we have a supported way to make dlinfo() queries for the shared
>>> library from which the call originates, without the library having to
>>> know its own soname?  (If it knows its own soname, it can call dlopen
>>> on itself, but I'm looking into a scenario where that information is
>>> not available.)
>>
>> dladdr1 with RTLD_DL_LINKMAP returns the link map, which has a public
>> l_name member in <link.h>.  If you do not want to use the handle/link
>> map equivalence, you could dlopen l_name, and that should give you back
>> the same handle in an official way.
>
> What happens if l_name is different on disk now and has a distinct SONAME?
> Doesn't this introduce a race condition?

I think we call _dl_name_match_p, and it starts like this:

| /* Test whether given NAME matches any of the names of the given object.  */
| int
| _dl_name_match_p (const char *name, const struct link_map *map)
| {
|   if (strcmp (name, map->l_name) == 0)
|     return 1;

So we should recognize this and treat the object as equivalent to an
already-loaded object.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-07-10 16:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-10 13:06 dlinfo for the calling shared library Zack Weinberg
2019-07-10 13:29 ` Carlos O'Donell
2019-07-10 14:15 ` Florian Weimer
2019-07-10 16:20   ` Carlos O'Donell
2019-07-10 16:32     ` Florian Weimer

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).