public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Florian Weimer <fweimer@redhat.com>
To: Evan Green <evan@rivosinc.com>
Cc: libc-alpha@sourceware.org,  palmer@rivosinc.com,
	 slewis@rivosinc.com, vineetg@rivosinc.com
Subject: Re: [PATCH v4 1/3] riscv: Add Linux hwprobe syscall support
Date: Mon, 10 Jul 2023 11:17:41 +0200	[thread overview]
Message-ID: <87351wazwq.fsf@oldenburg.str.redhat.com> (raw)
In-Reply-To: <CALs-HsvEYNw9aUjOb_a9oG4X2zRKhR5YRT3gQ_OdTZfYuUPyFA@mail.gmail.com> (Evan Green's message of "Fri, 7 Jul 2023 15:10:30 -0700")

* Evan Green:

> On Fri, Jul 7, 2023 at 1:16 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * Evan Green:
>>
>> > Add awareness and a thin wrapper function around a new Linux system call
>> > that allows callers to get architecture and microarchitecture
>> > information about the CPUs from the kernel. This can be used to
>> > do things like dynamically choose a memcpy implementation.
>>
>> I missed before that you intend this for use in IFUNC resolvers, or at
>> the very least I think I forgot to raise this caveat.
>>
>> RISC-V is not a HIDDEN_VAR_NEEDS_DYNAMIC_RELOC target, so this is not
>> completely impossible, but in general, extern function calls in IFUNC
>> resolvers tend to not work well.  The issue is that the GOT pointer for
>> a function like __riscv_hwprobe may not have been set up when the
>> dynamic linker invokes the IFUNC resolver.  There are several ways to
>> solve this.  You could pass the function pointer to the IFUNC resolver
>> (which may require a marker symbol and GCC changes).  Or you could a
>> hidden wrapper function to libc_nonshared.a that checks if the function
>> pointer to the libc implementation has been set up by a relocation and
>> uses that, and falls back to a direct system call otherwise.
>
> That makes sense, but then I'm confused about how it's been working in
> my testing. What experiment should I try to see this problem in
> action? An early constructor maybe?

This script should reproduce it:

cat >libifunc.c <<'EOF'
#include <dlfcn.h>

typedef void *(*malloc_fptr) (size_t);

static malloc_fptr
malloc_address (void)
{
  malloc_fptr result = dlsym (RTLD_NEXT, "malloc");
  asm ("");                     /* Prevent tail call.  */
  return result;
}


static void *
malloc_impl_indirect (size_t size)
{
  return  malloc_address () (size);
}

static void *
malloc_resolve (void)
{
#ifdef DIRECT
  return malloc_address ();
#else
  return &malloc_impl_indirect;
#endif
}

void *malloc (size_t) __attribute__ ((ifunc ("malloc_resolve")));
EOF
gcc -DDIRECT -O2 -g -Wl,-z,now -shared -fPIC -o libifunc.so libifunc.c
LD_PRELOAD=./libifunc.so /bin/true --help

The problem here is that dlsym is called during relocation, and that
function pointer has not been set up yet.

It shouldn't be too hard to come up with a variant that uses
__riscv_hwprobe instead.

> Could I alternatively convert the implementation of the external
> function into one that calls an internal helper, and then just call
> the internal helper from the ifunc resolver (oh, I've reinvented a
> protected symbol)? Or is that a violation of some rule?

It depends on where the internal helper is located.  The issue manifests
in user-compiled code, not directly in glibc, so there is no straight
fix for this in glibc.

> Are there any examples of that last suggestion I can refer to?
> Specifically the part about checking if the symbol has been relocated
> yet or not.

You can load the symbol value using assembler code, so that you can
check if it is null, or perhaps you can make it weak (so that GCC treats
NULL as a valid value).

Thanks,
Florian


  reply	other threads:[~2023-07-10  9:17 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-06 19:29 [PATCH v4 0/3] RISC-V: ifunced memcpy using new kernel hwprobe interface Evan Green
2023-07-06 19:29 ` [PATCH v4 1/3] riscv: Add Linux hwprobe syscall support Evan Green
2023-07-07  8:15   ` Florian Weimer
2023-07-07 22:10     ` Evan Green
2023-07-10  9:17       ` Florian Weimer [this message]
2023-07-11 17:08         ` Evan Green
2023-07-06 19:29 ` [PATCH v4 2/3] riscv: Add hwprobe vdso call support Evan Green
2023-07-06 19:29 ` [PATCH v4 3/3] riscv: Add and use alignment-ignorant memcpy Evan Green
2023-07-07  9:22   ` Richard Henderson
2023-07-07 15:25     ` Jeff Law
2023-07-07 21:37       ` Evan Green
2023-07-07 22:15         ` Jeff Law
2023-07-08  2:16   ` Stefan O'Rear
2023-07-10 16:19     ` Evan Green
2023-07-12  5:22       ` Stefan O'Rear
2023-07-06 20:11 ` [PATCH v4 0/3] RISC-V: ifunced memcpy using new kernel hwprobe interface Palmer Dabbelt
2023-07-06 22:20   ` Jeff Law

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=87351wazwq.fsf@oldenburg.str.redhat.com \
    --to=fweimer@redhat.com \
    --cc=evan@rivosinc.com \
    --cc=libc-alpha@sourceware.org \
    --cc=palmer@rivosinc.com \
    --cc=slewis@rivosinc.com \
    --cc=vineetg@rivosinc.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).