aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-12-05 01:46:13 +0100
committerPetr Machata <pmachata@redhat.com>2013-03-08 22:55:28 +0100
commit08cdf328add7b723b94b151866e5d0173662f6c6 (patch)
tree02d1f28917d98824e18862771ad657892b59bd73
parentf70074cd77f82182cb234b673cad3e9618a52843 (diff)
downloadltrace-08cdf328add7b723b94b151866e5d0173662f6c6.tar.gz
Start using per-library config files
We have one global cache, initialized in init_global_config. output.c was adjusted to load per-library config files on demand from that cache.
-rw-r--r--output.c41
-rw-r--r--prototype.c36
-rw-r--r--prototype.h14
-rw-r--r--read_config_file.c28
-rw-r--r--read_config_file.h3
5 files changed, 70 insertions, 52 deletions
diff --git a/output.c b/output.c
index b0ee0ae..dc5d90c 100644
--- a/output.c
+++ b/output.c
@@ -182,11 +182,22 @@ build_default_prototype(void)
}
static struct prototype *
-name2func(char const *name)
+lookup_symbol_prototype(struct library_symbol *libsym)
{
- struct prototype *p = protolib_lookup_prototype(&g_prototypes, name);
- if (p != NULL)
- return p;
+ struct library *lib = libsym->lib;
+ if (lib != NULL) {
+ if (lib->protolib == NULL)
+ lib->protolib = protolib_cache_search(&g_protocache,
+ lib->soname, 1);
+ if (lib->protolib != NULL) {
+ struct prototype *p
+ = protolib_lookup_prototype(lib->protolib,
+ libsym->name);
+ if (p != NULL)
+ return p;
+ }
+ }
+
return build_default_prototype();
}
@@ -436,8 +447,6 @@ void
output_left(enum tof type, struct process *proc,
struct library_symbol *libsym)
{
- const char *function_name = libsym->name;
-
if (options.summary) {
return;
}
@@ -455,10 +464,10 @@ output_left(enum tof type, struct process *proc,
fprintf(options.output, "%s->",
libsym->lib->soname));
- const char *name = function_name;
+ const char *name = libsym->name;
#ifdef USE_DEMANGLE
if (options.demangle)
- name = my_demangle(function_name);
+ name = my_demangle(libsym->name);
#endif
if (account_output(&current_column,
fprintf(options.output, "%s", name)) < 0)
@@ -475,7 +484,7 @@ output_left(enum tof type, struct process *proc,
account_output(&current_column, fprintf(options.output, "("));
- struct prototype *func = name2func(function_name);
+ struct prototype *func = lookup_symbol_prototype(libsym);
if (func == NULL) {
account_output(&current_column, fprintf(options.output, "???"));
return;
@@ -515,8 +524,7 @@ free_stringp_cb(const char **stringp, void *data)
void
output_right(enum tof type, struct process *proc, struct library_symbol *libsym)
{
- const char *function_name = libsym->name;
- struct prototype *func = name2func(function_name);
+ struct prototype *func = lookup_symbol_prototype(libsym);
if (func == NULL)
return;
@@ -538,10 +546,10 @@ again:
}
struct opt_c_struct *st
- = DICT_FIND_REF(dict_opt_c, &function_name,
+ = DICT_FIND_REF(dict_opt_c, &libsym->name,
struct opt_c_struct);
if (st == NULL) {
- const char *na = strdup(function_name);
+ const char *na = strdup(libsym->name);
struct opt_c_struct new_st = {.count = 0, .tv = {0, 0}};
if (na == NULL
|| DICT_INSERT(dict_opt_c, &na, &new_st) < 0) {
@@ -551,7 +559,7 @@ again:
free_stringp_cb, NULL, NULL);
goto oom;
}
- st = DICT_FIND_REF(dict_opt_c, &function_name,
+ st = DICT_FIND_REF(dict_opt_c, &libsym->name,
struct opt_c_struct);
assert(st != NULL);
}
@@ -577,10 +585,11 @@ again:
#ifdef USE_DEMANGLE
current_column +=
fprintf(options.output, "<... %s resumed> ",
- options.demangle ? my_demangle(function_name) : function_name);
+ options.demangle ? my_demangle(libsym->name)
+ : libsym->name);
#else
current_column +=
- fprintf(options.output, "<... %s resumed> ", function_name);
+ fprintf(options.output, "<... %s resumed> ", libsym->name);
#endif
}
diff --git a/prototype.c b/prototype.c
index c819a2d..462c0c7 100644
--- a/prototype.c
+++ b/prototype.c
@@ -32,7 +32,8 @@
#include "read_config_file.h"
#include "backend.h"
-struct protolib g_prototypes;
+struct protolib_cache g_protocache;
+static struct protolib legacy_typedefs;
void
prototype_init(struct prototype *proto)
@@ -578,3 +579,36 @@ protolib_cache_protolib(struct protolib_cache *cache,
{
return DICT_INSERT(&cache->protolibs, &filename, &plib);
}
+
+void
+init_global_config(void)
+{
+ protolib_init(&legacy_typedefs);
+ struct arg_type_info *void_info = type_get_simple(ARGTYPE_VOID);
+ static struct arg_type_info ptr_info;
+ type_init_pointer(&ptr_info, void_info, 0);
+
+ static struct named_type voidptr_type;
+ named_type_init(&voidptr_type, &ptr_info, 0);
+
+ if (protolib_add_named_type(&legacy_typedefs, "addr", 0,
+ &voidptr_type) < 0
+ || protolib_add_named_type(&legacy_typedefs, "file", 0,
+ &voidptr_type) < 0) {
+ fprintf(stderr,
+ "Couldn't initialize aliases `addr' and `file'.\n");
+ exit(1);
+ }
+
+ if (protolib_cache_init(&g_protocache, NULL) < 0) {
+ fprintf(stderr, "Couldn't init prototype cache\n");
+ abort();
+ }
+}
+
+void
+destroy_global_config(void)
+{
+ protolib_cache_destroy(&g_protocache);
+ protolib_destroy(&legacy_typedefs);
+}
diff --git a/prototype.h b/prototype.h
index 583b9f6..9d36ef0 100644
--- a/prototype.h
+++ b/prototype.h
@@ -210,9 +210,15 @@ int protolib_cache_protolib(struct protolib_cache *cache,
const char *filename,
struct protolib *plib);
-/* Single global prototype library.
- * XXX Eventually each struct library should have its own prototype
- * library, so that there is one prototype library per DSO. */
-extern struct protolib g_prototypes;
+/* Single global prototype cache.
+ *
+ * XXX Eventually each ABI should have its own cache. The idea is
+ * that there's one per-ABI config file that all others use for
+ * elementary typedefs (long, char, size_t). Ltrace then only deals
+ * in fixed-width integral types (and pointers etc.). */
+extern struct protolib_cache g_protocache;
+
+void init_global_config(void);
+void destroy_global_config(void);
#endif /* _PROTOTYPE_H_ */
diff --git a/read_config_file.c b/read_config_file.c
index d96b08d..38b854a 100644
--- a/read_config_file.c
+++ b/read_config_file.c
@@ -1252,31 +1252,3 @@ read_config_file(FILE *stream, const char *path, struct protolib *plib)
free(line);
return 0;
}
-
-void
-init_global_config(void)
-{
- protolib_init(&g_prototypes);
-
- struct arg_type_info *void_info = type_get_simple(ARGTYPE_VOID);
- static struct arg_type_info ptr_info;
- type_init_pointer(&ptr_info, void_info, 0);
-
- static struct named_type voidptr_type;
- named_type_init(&voidptr_type, &ptr_info, 0);
-
- if (protolib_add_named_type(&g_prototypes, "addr", 0,
- &voidptr_type) < 0
- || protolib_add_named_type(&g_prototypes, "file", 0,
- &voidptr_type) < 0) {
- fprintf(stderr,
- "Couldn't initialize aliases `addr' and `file'.\n");
- exit(1);
- }
-}
-
-void
-destroy_global_config(void)
-{
- protolib_destroy(&g_prototypes);
-}
diff --git a/read_config_file.h b/read_config_file.h
index f1895a1..19351be 100644
--- a/read_config_file.h
+++ b/read_config_file.h
@@ -25,7 +25,4 @@
int read_config_file(FILE *stream, const char *name, struct protolib *plib);
-void init_global_config(void);
-void destroy_global_config(void);
-
#endif /* _READ_CONFIG_FILE_H_ */