aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-reloc.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-06-30 10:24:09 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-12-28 08:40:38 -0300
commit063f9ba220f434c7f30dd65c4cff17c0c458a7cf (patch)
tree00737e23f3b48e8d8dd338f16fc8cb98f0e6c051 /elf/dl-reloc.c
parent8c0664e2b861fd3789602cc0b0b1922b0e20cb3a (diff)
downloadglibc-063f9ba220f434c7f30dd65c4cff17c0c458a7cf.zip
glibc-063f9ba220f434c7f30dd65c4cff17c0c458a7cf.tar.gz
glibc-063f9ba220f434c7f30dd65c4cff17c0c458a7cf.tar.bz2
elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533)
The rtld-audit interfaces introduces a slowdown due to enabling profiling instrumentation (as if LD_AUDIT implied LD_PROFILE). However, instrumenting is only necessary if one of audit libraries provides PLT callbacks (la_pltenter or la_pltexit symbols). Otherwise, the slowdown can be avoided. The following patch adjusts the logic that enables profiling to iterate over all audit modules and check if any of those provides a PLT hook. To keep la_symbind to work even without PLT callbacks, _dl_fixup now calls the audit callback if the modules implements it. Co-authored-by: Alexander Monakov <amonakov@ispras.ru> Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu. Reviewed-by: Florian Weimer <fweimer@redhat.com>
Diffstat (limited to 'elf/dl-reloc.c')
-rw-r--r--elf/dl-reloc.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 0d5b727..98a24b3 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -205,12 +205,28 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
int skip_ifunc = reloc_mode & __RTLD_NOIFUNC;
#ifdef SHARED
+ bool consider_symbind = false;
/* If we are auditing, install the same handlers we need for profiling. */
if ((reloc_mode & __RTLD_AUDIT) == 0)
- consider_profiling |= GLRO(dl_audit) != NULL;
+ {
+ struct audit_ifaces *afct = GLRO(dl_audit);
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+ {
+ /* Profiling is needed only if PLT hooks are provided. */
+ if (afct->ARCH_LA_PLTENTER != NULL
+ || afct->ARCH_LA_PLTEXIT != NULL)
+ consider_profiling = 1;
+ if (afct->symbind != NULL)
+ consider_symbind = true;
+
+ afct = afct->next;
+ }
+ }
#elif defined PROF
/* Never use dynamic linker profiling for gprof profiling code. */
# define consider_profiling 0
+#else
+# define consider_symbind 0
#endif
if (l->l_relocated)
@@ -272,7 +288,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
#ifndef PROF
- if (__glibc_unlikely (consider_profiling)
+ if ((consider_profiling || consider_symbind)
&& l->l_info[DT_PLTRELSZ] != NULL)
{
/* Allocate the array which will contain the already found