summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDima Kogan <dima@secretsauce.net>2014-07-11 17:04:48 -0700
committerChanho Park <chanho61.park@samsung.com>2014-08-22 20:38:26 +0900
commitbaa0a5cfd341752d95634f0c4118895bcd8cfe09 (patch)
treefd05a4de2cb2790e8f1616c945bfaee7dff3aa11
parent8bb22aff3b14947e69c070c82c4ad81e098183f3 (diff)
downloadltrace-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.c1
-rw-r--r--library.h2
-rw-r--r--ltrace-elf.c50
-rw-r--r--proc.c22
4 files changed, 46 insertions, 29 deletions
diff --git a/library.c b/library.c
index dfcd1dc..bb0e4cc 100644
--- a/library.c
+++ b/library.c
@@ -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)
diff --git a/library.h b/library.h
index 42a5a47..6f1dc0f 100644
--- a/library.h
+++ b/library.h
@@ -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, &lte, lib,
- symtabs, exports) < 0)
+ if (populate_symtab(proc, filename, &lte, lib,
+ symtabs, exports) < 0)
goto fail;
arch_elf_destroy(&lte);
diff --git a/proc.c b/proc.c
index 6c17a88..91af49f 100644
--- a/proc.c
+++ b/proc.c
@@ -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