Add support for tracing of IRELATIVE PLT entries
- Because the IRELATIVE entries have no associated symbol name, we
need to allow arch_elf_add_plt_entry to override the name. This is
done by that callback returning PLT_OK and returning the new symbol
via libsym-chain return argument. Filtering is postponed until we
have that symbol, and the filter is applied to the whole returned
chain.
- Add linux_elf_add_plt_entry_irelative to support proper naming of
IRELATIVE PLT entries. This needs to be called from arch backend,
as the numbers of IRELATIVE relocations differ per-architecture.
diff --git a/ltrace-elf.c b/ltrace-elf.c
index 427c62a..5a228c5 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -668,6 +668,24 @@
}
}
+static void
+filter_symbol_chain(struct filter *filter,
+ struct library_symbol **libsymp, struct library *lib)
+{
+ assert(libsymp != NULL);
+ struct library_symbol **ptr = libsymp;
+ while (*ptr != NULL) {
+ if (filter_matches_symbol(filter, (*ptr)->name, lib)) {
+ ptr = &(*ptr)->next;
+ } else {
+ struct library_symbol *sym = *ptr;
+ *ptr = (*ptr)->next;
+ library_symbol_destroy(sym);
+ free(sym);
+ }
+ }
+}
+
static int
populate_plt(struct process *proc, const char *filename,
struct ltelf *lte, struct library *lib,
@@ -693,30 +711,36 @@
char const *name = lte->dynstr + sym.st_name;
- /* If the symbol wasn't matched, reject it, unless we
- * need to keep latent PLT breakpoints for tracing
- * exports. */
int matched = filter_matches_symbol(options.plt_filter,
name, lib);
- if (!matched && !latent_plts)
- continue;
struct library_symbol *libsym = NULL;
switch (arch_elf_add_plt_entry(proc, lte, name,
&rela, i, &libsym)) {
+ case PLT_FAIL:
+ return -1;
+
case PLT_DEFAULT:
+ /* Add default entry to the beginning of LIBSYM. */
if (default_elf_add_plt_entry(proc, lte, name,
&rela, i, &libsym) < 0)
- /* Fall through. */
- case PLT_FAIL:
return -1;
/* Fall through. */
case PLT_OK:
+ /* If we didn't match the PLT entry up there,
+ * filter the chain to only include the
+ * matching symbols (but include all if we are
+ * adding latent symbols). This is to allow
+ * arch_elf_add_plt_entry to override the PLT
+ * symbol's name. */
+ if (!matched && !latent_plts)
+ filter_symbol_chain(options.plt_filter,
+ &libsym, lib);
if (libsym != NULL) {
/* If we are adding those symbols just
* for tracing exports, mark them all
* latent. */
- if (!matched)
+ if (!matched && latent_plts)
mark_chain_latent(libsym);
library_add_symbol(lib, libsym);
}
@@ -795,7 +819,6 @@
continue;
}
- /* XXX support IFUNC as well. */
if (GELF_ST_TYPE(sym.st_info) != STT_FUNC
|| sym.st_value == 0
|| sym.st_shndx == STN_UNDEF)