Merge new symbols properly with the symbols already in the library
diff --git a/ChangeLog b/ChangeLog
index 8157273..c3095f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2012-09-28 Petr Machata <pmachata@redhat.com>
+ * ltrace-elf.c (symbol_with_address): New function.
+
+2012-09-28 Petr Machata <pmachata@redhat.com>
+
* ltrace-elf.c (mark_chain_latent): New function.
(populate_plt): New argument LATENT_PLTS.
(ltelf_read_library): Update calls to populate_plt.
diff --git a/ltrace-elf.c b/ltrace-elf.c
index e20c2de..cd88581 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -619,6 +619,13 @@
return sym_key->addr != sym_val->addr;
}
+static enum callback_status
+symbol_with_address(struct library_symbol *sym, void *addrptr)
+{
+ return sym->enter_addr == *(arch_addr_t *)addrptr
+ ? CBS_STOP : CBS_CONT;
+}
+
static int
populate_this_symtab(struct Process *proc, const char *filename,
struct ltelf *lte, struct library *lib,
@@ -767,13 +774,26 @@
}
}
+ /* Now we do the union of this set of unique symbols with
+ * what's already in the library. */
for (i = 0; i < num_symbols; ++i) {
- assert(symbols[i].libsym != NULL);
- library_add_symbol(lib, symbols[i].libsym);
+ struct library_symbol *this_sym = symbols[i].libsym;
+ assert(this_sym != NULL);
+ struct library_symbol *other
+ = library_each_symbol(lib, NULL, symbol_with_address,
+ &this_sym->enter_addr);
+ if (other != NULL) {
+ library_symbol_destroy(this_sym);
+ free(this_sym);
+ symbols[i].libsym = NULL;
+ }
}
- free(symbols);
+ for (i = 0; i < num_symbols; ++i)
+ if (symbols[i].libsym != NULL)
+ library_add_symbol(lib, symbols[i].libsym);
+ free(symbols);
return 0;
}