This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: Forcing BIND_NOW for a symbol
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: libc-help at sourceware dot org
- Date: Tue, 26 Apr 2016 11:13:02 -0300
- Subject: Re: Forcing BIND_NOW for a symbol
- Authentication-results: sourceware.org; auth=none
- References: <56376829 dot 7050707 at redhat dot com> <56377C77 dot 2010209 at redhat dot com> <56377EEA dot 3030302 at redhat dot com> <56378B60 dot 7070803 at redhat dot com> <56378BFE dot 7010503 at redhat dot com> <56378C8D dot 3020706 at redhat dot com> <56378E9E dot 9060809 at redhat dot com> <571DE415 dot 7070705 at redhat dot com> <CAE2sS1hQwVA8hBamMSeDSkgpAMWw-SN8+jVNgY-q1CXvfh7ctg at mail dot gmail dot com> <571E8FFC dot 9060802 at redhat dot com>
On 25/04/2016 18:45, Florian Weimer wrote:
> On 04/25/2016 10:45 PM, Carlos O'Donell wrote:
>> On Mon, Apr 25, 2016 at 5:32 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>> Could we look at the âVersion needsâ section (.gnu.version_r) and perhaps
>>> use a special symbol version for getrandom?
>>
>> Such a special symbol would mark getrandom as needing early resolution?
>
> We already scan .gnu.version_r, so we can quickly detect special cases at very little extra cost. It's somewhat ugly because it's not a generic mechanism like IFUNC (but then, the IFUNC experience suggests it's better to gather internal users first before providing a generic interface).
>
> Florian
If I understood your problem correctly, why instead of using IFUNC+BIND_NOW
you provide the getrandom to check by itself if ENOSYS is returned and
then call either the alternative the getrandom or return the error to the
user?
Something like:
--
#define SYSCALL_UNDEFINED 0
#define SYSCALL_FOUND 1
#define SYSCALL_ALTERNATIVE 2
static atomic_int sc = SYSCALL_UNDEFINED;
int getrandom_alternative (void *buf, size_t buflen, unsigned int flags);
int getrandom(void *buf, size_t buflen, unsigned int flags)
{
atomic_int type = atomic_load_explicit (&sc, memory_order_relaxed);
if (type == SYSCALL_FOUND)
return INLINE_SYSCALL (getrandom, 3, buf, buflen, flags);
else if (type == SYSCALL_ALTERNATIVE)
return getrandom_alternative (buf, buflen, flags);
/* SYSCALL_UNDEFINED */
int type, ret;
unsigned long result = INTERNAL_SYSCALL (getrandom, 3, buf, buflen, flags);
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result), 0))
{
int err = INTERNAL_SYSCALL_ERRNO (_sys_result);
if (err == ENOSYS)
{
ret = getrandom_alternative (buf, buflen, flags);
type = SYSCALL_ALTERNATIVE;
}
else
{
ret = -1;
errno = err;
type = SYSCALL_FOUND;
}
}
atomic_store_explicit (&sc, ret, memory_order_seq_cst);
return ret;
}
--
First call will incur in sequential consistent atomic operation, but later calls should
only incur the atomic read (which for most architecture afaik is as fast a non-atomic
read).