[PATCH 0/3] Add _dl_find_eh_frame function for unwinder optimization

Florian Weimer fweimer@redhat.com
Wed Nov 3 16:27:18 GMT 2021


This patch series implements a new function, _dl_find_eh_frame, for use
by in-process unwinders.  The new function is lock-free and
async-signal-safe, and it scales logarithmically with the number of
shared objects in the process.  It does not write to global data at all,
unlike the current libgcc unwinder, which has a small global cache and
relies on the unwinder lock.  dlclose is fully supported.  The interface
itself is modelled on the __gnu_Unwind_Find_exidx function.

I'm going to post the GCC patches that enable use of this function
separately.

We may want to tweak the _dl_find_eh_frame interface somewhat.  For
example, we could also provide a pointer to the link map, and perhaps
the in-memory boundaries of the object.  With the link map, we can use
it to accelerate _dl_find_dso_for_object.  And we should really use it
to implement __gnu_Unwind_Find_exidx on arm.  Something like this:

struct dl_find_object
{
  struct link_map *dl_link_map;
  void *dl_eh_frame;
  void *dl_map_start;
  void *dl_map_end;
  void *dl_dbase;               // optional, i386 & nios2
  unsigned long int dl_pcount;  // optional, arm
};

int _dl_find_object (void *__address, struct dl_find_object *__result) __TRHOW;

I wanted to post this version so that the review of the GCC patches can
start now and hopefully finish in time for stage 1 close.

Tested on i686-linux-gnu, x86_64-linux-gnu with the old and new
unwinder.  Tested on powerpc-linux-gnu, powerpc64le-linux-gnu,
aarch64-linux-gnu with the old unwinder.

Thanks,
Florian

Florian Weimer (3):
  nptl: Extract <bits/atomic_wide_counter.h> from pthread_cond_common.c
  elf: Introduce GLRO (dl_libc_freeres), called from __libc_freeres
  elf: Add _dl_find_eh_frame function

 NEWS                                          |   4 +
 bits/atomic_wide_counter.h                    |  35 +
 bits/dlfcn_eh_frame.h                         |  33 +
 dlfcn/Makefile                                |   2 +-
 dlfcn/dlfcn.h                                 |   2 +
 elf/Makefile                                  |  33 +-
 elf/Versions                                  |   3 +
 elf/dl-close.c                                |   4 +
 elf/dl-find_eh_frame.c                        | 864 ++++++++++++++++++
 elf/dl-find_eh_frame.h                        |  90 ++
 elf/dl-find_eh_frame_slow.h                   |  55 ++
 elf/dl-libc_freeres.c                         |  26 +
 elf/dl-open.c                                 |   5 +
 elf/rtld.c                                    |   8 +
 elf/tst-dl_find_eh_frame-mod1.c               |  10 +
 elf/tst-dl_find_eh_frame-mod2.c               |  10 +
 elf/tst-dl_find_eh_frame-mod3.c               |  10 +
 elf/tst-dl_find_eh_frame-mod4.c               |  10 +
 elf/tst-dl_find_eh_frame-mod5.c               |  11 +
 elf/tst-dl_find_eh_frame-mod6.c               |  11 +
 elf/tst-dl_find_eh_frame-mod7.c               |  10 +
 elf/tst-dl_find_eh_frame-mod8.c               |  10 +
 elf/tst-dl_find_eh_frame-mod9.c               |  10 +
 elf/tst-dl_find_eh_frame-threads.c            | 237 +++++
 elf/tst-dl_find_eh_frame.c                    | 179 ++++
 include/atomic_wide_counter.h                 | 103 +++
 include/bits/atomic_wide_counter.h            |   1 +
 include/bits/dlfcn_eh_frame.h                 |   1 +
 include/link.h                                |   3 +
 malloc/set-freeres.c                          |   5 +
 manual/Makefile                               |   2 +-
 manual/dynlink.texi                           |  69 ++
 manual/libdl.texi                             |  10 -
 manual/probes.texi                            |   2 +-
 manual/threads.texi                           |   2 +-
 misc/Makefile                                 |   3 +-
 misc/atomic_wide_counter.c                    | 127 +++
 nptl/Makefile                                 |  13 +-
 nptl/pthread_cond_common.c                    | 204 +----
 nptl/tst-cond22.c                             |  14 +-
 sysdeps/generic/ldsodefs.h                    |   7 +
 sysdeps/i386/bits/dlfcn_eh_frame.h            |  34 +
 sysdeps/mach/hurd/i386/ld.abilist             |   1 +
 sysdeps/nios2/bits/dlfcn_eh_frame.h           |  34 +
 sysdeps/nptl/bits/thread-shared-types.h       |  22 +-
 sysdeps/unix/sysv/linux/aarch64/ld.abilist    |   1 +
 sysdeps/unix/sysv/linux/alpha/ld.abilist      |   1 +
 sysdeps/unix/sysv/linux/arc/ld.abilist        |   1 +
 sysdeps/unix/sysv/linux/arm/be/ld.abilist     |   1 +
 sysdeps/unix/sysv/linux/arm/le/ld.abilist     |   1 +
 sysdeps/unix/sysv/linux/csky/ld.abilist       |   1 +
 sysdeps/unix/sysv/linux/hppa/ld.abilist       |   1 +
 sysdeps/unix/sysv/linux/i386/ld.abilist       |   1 +
 sysdeps/unix/sysv/linux/ia64/ld.abilist       |   1 +
 .../unix/sysv/linux/m68k/coldfire/ld.abilist  |   1 +
 .../unix/sysv/linux/m68k/m680x0/ld.abilist    |   1 +
 sysdeps/unix/sysv/linux/microblaze/ld.abilist |   1 +
 .../unix/sysv/linux/mips/mips32/ld.abilist    |   1 +
 .../sysv/linux/mips/mips64/n32/ld.abilist     |   1 +
 .../sysv/linux/mips/mips64/n64/ld.abilist     |   1 +
 sysdeps/unix/sysv/linux/nios2/ld.abilist      |   1 +
 .../sysv/linux/powerpc/powerpc32/ld.abilist   |   1 +
 .../linux/powerpc/powerpc64/be/ld.abilist     |   1 +
 .../linux/powerpc/powerpc64/le/ld.abilist     |   1 +
 sysdeps/unix/sysv/linux/riscv/rv32/ld.abilist |   1 +
 sysdeps/unix/sysv/linux/riscv/rv64/ld.abilist |   1 +
 .../unix/sysv/linux/s390/s390-32/ld.abilist   |   1 +
 .../unix/sysv/linux/s390/s390-64/ld.abilist   |   1 +
 sysdeps/unix/sysv/linux/sh/be/ld.abilist      |   1 +
 sysdeps/unix/sysv/linux/sh/le/ld.abilist      |   1 +
 .../unix/sysv/linux/sparc/sparc32/ld.abilist  |   1 +
 .../unix/sysv/linux/sparc/sparc64/ld.abilist  |   1 +
 sysdeps/unix/sysv/linux/x86_64/64/ld.abilist  |   1 +
 sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist |   1 +
 74 files changed, 2143 insertions(+), 215 deletions(-)
 create mode 100644 bits/atomic_wide_counter.h
 create mode 100644 bits/dlfcn_eh_frame.h
 create mode 100644 elf/dl-find_eh_frame.c
 create mode 100644 elf/dl-find_eh_frame.h
 create mode 100644 elf/dl-find_eh_frame_slow.h
 create mode 100644 elf/dl-libc_freeres.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod1.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod2.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod3.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod4.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod5.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod6.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod7.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod8.c
 create mode 100644 elf/tst-dl_find_eh_frame-mod9.c
 create mode 100644 elf/tst-dl_find_eh_frame-threads.c
 create mode 100644 elf/tst-dl_find_eh_frame.c
 create mode 100644 include/atomic_wide_counter.h
 create mode 100644 include/bits/atomic_wide_counter.h
 create mode 100644 include/bits/dlfcn_eh_frame.h
 create mode 100644 manual/dynlink.texi
 delete mode 100644 manual/libdl.texi
 create mode 100644 misc/atomic_wide_counter.c
 create mode 100644 sysdeps/i386/bits/dlfcn_eh_frame.h
 create mode 100644 sysdeps/nios2/bits/dlfcn_eh_frame.h


base-commit: 6720d36b6623c5e48c070d86acf61198b33e144e
-- 
2.31.1



More information about the Gcc-patches mailing list