diff options
author | Dima Kogan <dima@secretsauce.net> | 2014-07-11 17:04:48 -0700 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:38:26 +0900 |
commit | baa0a5cfd341752d95634f0c4118895bcd8cfe09 (patch) | |
tree | fd05a4de2cb2790e8f1616c945bfaee7dff3aa11 | |
parent | 8bb22aff3b14947e69c070c82c4ad81e098183f3 (diff) | |
download | ltrace-baa0a5cfd341752d95634f0c4118895bcd8cfe09.tar.gz ltrace-baa0a5cfd341752d95634f0c4118895bcd8cfe09.tar.bz2 ltrace-baa0a5cfd341752d95634f0c4118895bcd8cfe09.zip |
I now always build the export list
Previously I only built the export list when tracing with -l. Since I was using
this export list to resolve aliased symbols in addition to setting breakpoints,
this aliased symbol resolution was only working with -l. I now always build the
export list to make aliased symbol resolution always work.
I now have a separate variable to control whether we should activate latent
symbols or not; previously the existence of the export list was used to make
this determination.
Furthermore populate_this_symtab() now takes an extra argument to indicate that
ONLY the export list should be filled in
-rw-r--r-- | library.c | 1 | ||||
-rw-r--r-- | library.h | 2 | ||||
-rw-r--r-- | ltrace-elf.c | 50 | ||||
-rw-r--r-- | proc.c | 22 |
4 files changed, 46 insertions, 29 deletions
@@ -297,6 +297,7 @@ private_library_init(struct library *lib, enum library_type type) lib->symbols = NULL; library_exported_names_init(&lib->exported_names); + lib->should_activate_latent = false; lib->type = type; #if defined(HAVE_LIBDW) @@ -23,6 +23,7 @@ #define _LIBRARY_H_ #include <stdint.h> +#include <stdbool.h> #if defined(HAVE_LIBDW) # include <elfutils/libdwfl.h> @@ -184,6 +185,7 @@ struct library { char own_soname : 1; char own_pathname : 1; + bool should_activate_latent : 1; struct arch_library_data arch; struct os_library_data os; diff --git a/ltrace-elf.c b/ltrace-elf.c index a6a5531..24d02f0 100644 --- a/ltrace-elf.c +++ b/ltrace-elf.c @@ -901,7 +901,8 @@ static int populate_this_symtab(struct process *proc, const char *filename, struct ltelf *lte, struct library *lib, Elf_Data *symtab, const char *strtab, size_t count, - struct library_exported_names *names) + struct library_exported_names *names, + bool only_exported_names) { /* Using sorted array would be arguably better, but this * should be well enough for the number of symbols that we @@ -963,6 +964,11 @@ populate_this_symtab(struct process *proc, const char *filename, } } + /* If we're only dealing with the exported names list, there's + * nothing left to do with this symbol */ + if (only_exported_names) + continue; + /* If the symbol is not matched, skip it. We already * stored it to export list above. */ if (!filter_matches_symbol(options.static_filter, name, lib)) @@ -1067,6 +1073,12 @@ populate_this_symtab(struct process *proc, const char *filename, } } + /* If we're only dealing with the exported names list, there's nothing + * left to do */ + if (only_exported_names) + return 0; + + /* 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) { @@ -1099,20 +1111,20 @@ populate_symtab(struct process *proc, const char *filename, if (symtabs && lte->symtab != NULL && lte->strtab != NULL && (status = populate_this_symtab(proc, filename, lte, lib, lte->symtab, lte->strtab, - lte->symtab_count, NULL)) < 0) + lte->symtab_count, NULL, + false)) < 0) return status; /* Check whether we want to trace symbols implemented by this * library (-l). */ - struct library_exported_names *names = NULL; - if (exports) { - debug(DEBUG_FUNCTION, "-l matches %s", lib->soname); - names = &lib->exported_names; - } + struct library_exported_names *names = &lib->exported_names; + lib->should_activate_latent = exports != 0; + bool only_exported_names = symtabs == 0 && exports == 0; return populate_this_symtab(proc, filename, lte, lib, lte->dynsym, lte->dynstr, - lte->dynsym_count, names); + lte->dynsym_count, names, + only_exported_names); } static int @@ -1225,16 +1237,15 @@ read_module(struct library *lib, struct process *proc, * arch_addr_t becomes integral type. */ lib->dyn_addr = (arch_addr_t)(uintptr_t)lte.dyn_addr; - /* There are two reasons that we need to inspect symbol tables - * or populate PLT entries. Either the user requested - * corresponding tracing features (respectively -x and -e), or - * they requested tracing exported symbols (-l). + /* There are several reasons that we need to inspect symbol tables or + * populate PLT entries. The user may have requested corresponding + * tracing features (respectively -x and -e), or they requested tracing + * exported symbols (-l). We also do this to resolve symbol aliases * - * In the latter case we need to keep even those PLT slots - * that are not requested by -e (but we keep them latent). We - * also need to inspect .dynsym to find what exports this - * library provide, to turn on existing latent PLT - * entries. */ + * In the case of -l, we need to keep even those PLT slots that are not + * requested by -e (but we keep them latent). We also need to inspect + * .dynsym to find what exports this library provide, to turn on + * existing latent PLT entries. */ int plts = filter_matches_library(options.plt_filter, lib); if ((plts || options.export_filter != NULL) @@ -1243,9 +1254,8 @@ read_module(struct library *lib, struct process *proc, int exports = filter_matches_library(options.export_filter, lib); int symtabs = filter_matches_library(options.static_filter, lib); - if ((symtabs || exports) - && populate_symtab(proc, filename, <e, lib, - symtabs, exports) < 0) + if (populate_symtab(proc, filename, <e, lib, + symtabs, exports) < 0) goto fail; arch_elf_destroy(<e); @@ -987,15 +987,19 @@ proc_add_library(struct process *proc, struct library *lib) "Couldn't insert breakpoint for %s to %d: %s.\n", libsym->name, proc->pid, strerror(errno)); - /* Look through export list of the new library and compare it - * with latent symbols of all libraries (including this - * library itself). */ - struct library *lib2 = NULL; - while ((lib2 = proc_each_library(proc, lib2, activate_latent_in, - &lib->exported_names)) != NULL) - fprintf(stderr, - "Couldn't activate latent symbols for %s in %d: %s.\n", - lib2->soname, proc->pid, strerror(errno)); + if (lib->should_activate_latent != 0) { + /* Look through export list of the new library and compare it + * with latent symbols of all libraries (including this + * library itself). */ + struct library *lib2 = NULL; + + while ((lib2 = proc_each_library(proc, lib2, activate_latent_in, + &lib->exported_names)) != NULL) + fprintf(stderr, + "Couldn't activate latent symbols " + "for %s in %d: %s.\n", + lib2->soname, proc->pid, strerror(errno)); + } } int |