diff options
author | Petr Machata <pmachata@redhat.com> | 2012-12-05 01:46:13 +0100 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2013-03-08 22:55:28 +0100 |
commit | 08cdf328add7b723b94b151866e5d0173662f6c6 (patch) | |
tree | 02d1f28917d98824e18862771ad657892b59bd73 | |
parent | f70074cd77f82182cb234b673cad3e9618a52843 (diff) | |
download | ltrace-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.c | 41 | ||||
-rw-r--r-- | prototype.c | 36 | ||||
-rw-r--r-- | prototype.h | 14 | ||||
-rw-r--r-- | read_config_file.c | 28 | ||||
-rw-r--r-- | read_config_file.h | 3 |
5 files changed, 70 insertions, 52 deletions
@@ -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(¤t_column, fprintf(options.output, "%s", name)) < 0) @@ -475,7 +484,7 @@ output_left(enum tof type, struct process *proc, account_output(¤t_column, fprintf(options.output, "(")); - struct prototype *func = name2func(function_name); + struct prototype *func = lookup_symbol_prototype(libsym); if (func == NULL) { account_output(¤t_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_ */ |