unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Zack Weinberg <zackw@panix.com>
To: GNU C Library <libc-alpha@sourceware.org>
Subject: Are ifuncs intended to be allowed to resolve to symbols in another DSO?
Date: Thu, 9 Jan 2020 13:29:08 -0500	[thread overview]
Message-ID: <CAKCAbMjHxyv8ymquQWatGb+7OCkUu8VtrFpiQSk3owus5g8oWw@mail.gmail.com> (raw)

Suppose I have two major versions of the same shared library
(libfoo.so.1 and libfoo.so.2) and the only difference is that
libfoo.so.2 drops a whole bunch of compatibility aliases.  For
instance, libfoo.so.1 defines two names, `blurf` and `xblurf`, for the
same function, but libfoo.so.2 defines only the `blurf` name.

Any program that winds up loading both shared libraries (via
transitive dependencies) is going to have two copies of the actual
code for `blurf` in memory.  I could eliminate this duplication by
having libfoo.so.1 be a thin wrapper around libfoo.so.2, providing
only a definition for `xblurf` that calls `blurf`.  Good so far, but
now old applications are making two jumps through the PLT whenever
they call `xblurf`.  It occurred to me to wonder whether I could
eliminate the extra indirection (on the second and subsequent calls)
by making xblurf an ifunc:

extern int blurf(char *arg1, int arg2); // defined in libfoo.so.2
static int (*resolve_xblurf(void))(char *, int)
{
  return blurf;
}
int xblurf(char *, int) __attribute__((ifunc("resolve_xblurf")));

GCC 9.2 is perfectly happy to compile this and link it against a test
shared library containing an almost-trivial definition of 'blurf' (all
it does is call strlen and do some arithmetic), and a test program
that calls 'xblurf' will also compile, link, and even run to
completion correctly (using the dynamic loader from glibc 2.29).

However, reading https://sourceware.org/glibc/wiki/GNU_IFUNC gives me
the impression that this is probably *intended* to work but isn't
reliable in the current implementation, for reasons which I don't
follow.

So, my actual questions are: Is this intended to work?  If so, is this
actually reliable with current versions of the dynamic loader?  If so,
what is the oldest version of glibc where it's reliable?  Does it make
any difference if one or both of the libraries are linked with -z now?

zw

             reply	other threads:[~2020-01-09 18:29 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-09 18:29 Zack Weinberg [this message]
2020-01-09 20:37 ` Are ifuncs intended to be allowed to resolve to symbols in another DSO? Florian Weimer
2020-02-01  6:27   ` Carlos O'Donell
2020-02-03 20:06     ` Florian Weimer
2020-02-03 22:03       ` Carlos O'Donell
2020-02-04  7:15         ` Fangrui Song
2020-02-21 13:28         ` Florian Weimer

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

  List information: https://www.gnu.org/software/libc/involved.html

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

  git send-email \
    --in-reply-to=CAKCAbMjHxyv8ymquQWatGb+7OCkUu8VtrFpiQSk3owus5g8oWw@mail.gmail.com \
    --to=zackw@panix.com \
    --cc=libc-alpha@sourceware.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).