Forcing BIND_NOW for a symbol

Adhemerval Zanella adhemerval.zanella@linaro.org
Tue Apr 26 14:13:00 GMT 2016



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



More information about the Libc-help mailing list