arm: Use _dl_find_object on __gnu_Unwind_Find_exidx (BZ 31405)
commitf4c142bb9fe6b02c0af8cfca8a920091e2dba44b
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 22 Feb 2024 13:42:55 +0000 (22 10:42 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 23 Feb 2024 11:50:00 +0000 (23 08:50 -0300)
tree2b4b576da6835eb847026dad5c1a89c3abf52985
parente2a65ecc4b30a797df7dc6529f09b712aa256029
arm: Use _dl_find_object on __gnu_Unwind_Find_exidx (BZ 31405)

Instead of __dl_iterate_phdr. On ARM dlfo_eh_frame/dlfo_eh_count
maps to PT_ARM_EXIDX vaddr start / length.

On a Neoverse N1 machine with 160 cores, the following program:

  $ cat test.c
  #include <stdlib.h>
  #include <pthread.h>
  #include <assert.h>

  enum {
    niter = 1024,
    ntimes = 128,
  };

  static void *
  tf (void *arg)
  {
    int a = (int) arg;

    for (int i = 0; i < niter; i++)
      {
        void *p[ntimes];
        for (int j = 0; j < ntimes; j++)
   p[j] = malloc (a * 128);
        for (int j = 0; j < ntimes; j++)
   free (p[j]);
      }

    return NULL;
  }

  int main (int argc, char *argv[])
  {
    enum { nthreads = 16 };
    pthread_t t[nthreads];

    for (int i = 0; i < nthreads; i ++)
      assert (pthread_create (&t[i], NULL, tf, (void *) i) == 0);

    for (int i = 0; i < nthreads; i++)
      {
        void *r;
        assert (pthread_join (t[i], &r) == 0);
        assert (r == NULL);
      }

    return 0;
  }
  $ arm-linux-gnueabihf-gcc -fsanitize=address test.c -o test

Improves from ~15s to 0.5s.

Checked on arm-linux-gnueabihf.
elf/Makefile
elf/dl-find_object.c
include/dlfcn.h
sysdeps/arm/find_exidx.c