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)