This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: Automatically test IFUNC implementations


On Wed, Sep 26, 2012 at 9:25 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Sep 26, 2012 at 9:11 AM, Richard Henderson <rth@twiddle.net> wrote:
>> On 09/24/2012 08:55 AM, H.J. Lu wrote:
>>> extern __typeof (memcpy) __memcpy_sse2;
>>> extern __typeof (memcpy) __memcpy_ssse3;
>>> extern __typeof (memcpy) __memcpy_ssse3_back;
>>>
>>> static const struct libc_func_test memcpy_list[] =
>>> {
>>>   LIBC_FUNC_INIT (__memcpy_ssse3_back),
>>>   LIBC_FUNC_INIT (__memcpy_ssse3),
>>>   LIBC_FUNC_INIT (__memcpy_sse2),
>>>   { NULL, NULL },
>>> };
>> ...
>>> const struct libc_func_test *
>>> __libc_func (const char *name)
>>
>>
>> Given that we're talking about building all shipped libcs with __libc_func included I think we should consider a different interface.  One that does not require so many runtime relocations in the library image.  And preferably, one in which we don't have to duplicate information between libc-func.c and all of the individual multiarch files.
>>
>> Let's first simply state that we'd like to avoid these relative relocs.  Let's hide the  detail of how we avoid them behind a target-specific wall, by not returning pre-allocated const arrays:
>>
>>   int __libc_func(const char *name, void **array, size_t n)
>>
>> where N says how large ARRAY is.  The return value is the number of implementations placed in ARRAY, or -1 for ENOSPC (i.e. increase the size of ARRAY).  This adds extra overhead to __libc_func itself, but since that's for testing only, we shouldn't care.
>>
>> As a next step we can encode these function pointers as PC relative.  We probably can't do this directly in C, but it's easy enough in assembler.  And given that these files are already target-specific that's trivial too.  Then __libc_func merely has to decode the pointers while copying to ARRAY.
>
> Let me see what I can do.

About this?

extern __typeof (memmove) __memmove_sse2 attribute_hidden;
extern __typeof (memmove) __memmove_ssse3 attribute_hidden;
extern __typeof (memmove) __memmove_ssse3_back attribute_hidden;

static struct libc_func_test *
find_memmove (void)
{
  size_t n = HAS_SSSE3 ? 3 : 1;
  struct libc_func_test *list
    = malloc ((n + 1) * sizeof (struct libc_func_test));
  if (list != NULL)
    {
      size_t i;

      if (HAS_SSSE3)
        {
          list[0].name = "__memmove_ssse3_back";
          list[0].fn = __memmove_ssse3_back;
          list[1].name = "__memmove_ssse3_back";
          list[1].fn = __memmove_ssse3;
          i = 2;
        }
      else
        i = 0;
      list[i].name = "__memmove_sse2";
      list[i].fn = __memmove_sse2;
      list[n].name = NULL;
      list[n].fn = NULL;
    }
  return list;
}

Relocation section '.rela.text' at offset 0x1110 contains 9 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000006  000f00000002 R_X86_64_PC32     0000000000000000 .LC0 - 4
000000000023  001400000002 R_X86_64_PC32     0000000000000000 __cpu_features + c
000000000030  001600000004 R_X86_64_PLT32    0000000000000000 malloc - 4
000000000043  001000000002 R_X86_64_PC32     000000000000001d .LC2 - 4
000000000053  001700000002 R_X86_64_PC32     0000000000000000 __memmove_sse2 - 4
000000000076  001600000004 R_X86_64_PLT32    0000000000000000 malloc - 4
000000000082  001100000002 R_X86_64_PC32     0000000000000008 .LC1 - 4
000000000089  001800000002 R_X86_64_PC32     0000000000000000 __memmove_ssse3_ba
ck - 4
00000000009c  001900000002 R_X86_64_PC32     0000000000000000 __memmove_ssse3 -
4

We can avoid malloc by caller allocates memory on stack.


-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]