mirror of
https://sourceware.org/git/glibc.git
synced 2025-12-24 17:51:17 +03:00
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>
This commit is contained in:
@@ -124,6 +124,37 @@ _dl_fixup (
|
||||
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
|
||||
value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
|
||||
|
||||
#ifdef SHARED
|
||||
/* Auditing checkpoint: we have a new binding. Provide the auditing
|
||||
libraries the possibility to change the value and tell us whether further
|
||||
auditing is wanted.
|
||||
The l_reloc_result is only allocated if there is an audit module which
|
||||
provides a la_symbind. */
|
||||
if (l->l_reloc_result != NULL)
|
||||
{
|
||||
/* This is the address in the array where we store the result of previous
|
||||
relocations. */
|
||||
struct reloc_result *reloc_result
|
||||
= &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||
unsigned int init = atomic_load_acquire (&reloc_result->init);
|
||||
if (init == 0)
|
||||
{
|
||||
_dl_audit_symbind (l, reloc_result, sym, &value, result);
|
||||
|
||||
/* Store the result for later runs. */
|
||||
if (__glibc_likely (! GLRO(dl_bind_not)))
|
||||
{
|
||||
reloc_result->addr = value;
|
||||
/* Guarantee all previous writes complete before init is
|
||||
updated. See CONCURRENCY NOTES below. */
|
||||
atomic_store_release (&reloc_result->init, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
value = reloc_result->addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally, fix up the plt itself. */
|
||||
if (__glibc_unlikely (GLRO(dl_bind_not)))
|
||||
return value;
|
||||
|
||||
Reference in New Issue
Block a user