X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=library.c;h=7fb14c15ac2f35f1bf36f978b90e0e2eb184ef20;hb=3ea27fbec92833a25a66f237706ca47a2791db10;hp=7ccd7da079aae0b4934ec3f8459be25994378925;hpb=5c5c38e500fd8f20bb8d6c0177948dbfe86b6fcd;p=platform%2Fupstream%2Fltrace.git diff --git a/library.c b/library.c index 7ccd7da..7fb14c1 100644 --- a/library.c +++ b/library.c @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. + * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc. * Copyright (C) 2001,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand * @@ -20,6 +20,8 @@ * 02110-1301 USA */ +#include "config.h" + #include #include #include @@ -297,6 +299,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) @@ -324,25 +327,25 @@ library_init(struct library *lib, enum library_type type) -static void _dtor_string(const char **tgt, void *data) +static void dtor_string(const char **tgt, void *data) { free((char*)*tgt); } -static int _clone_vect(struct vect **to, const struct vect **from, void *data) +static int clone_vect(struct vect **to, const struct vect **from, void *data) { *to = malloc(sizeof(struct vect)); - if(*to == NULL) + if (*to == NULL) return -1; return VECT_CLONE(*to, *from, const char*, dict_clone_string, - _dtor_string, + dtor_string, NULL); } -static void _dtor_vect(const struct vect **tgt, void *data) +static void dtor_vect(struct vect **tgt, void *data) { - VECT_DESTROY(*tgt, const char*, _dtor_string, NULL); + VECT_DESTROY(*tgt, const char*, dtor_string, NULL); free(*tgt); } @@ -362,42 +365,41 @@ library_exported_names_destroy(struct library_exported_names *names) { DICT_DESTROY(&names->names, const char*, uint64_t, - _dtor_string, NULL, NULL); + dtor_string, NULL, NULL); DICT_DESTROY(&names->addrs, uint64_t, struct vect*, - NULL, _dtor_vect, NULL); + NULL, dtor_vect, NULL); } static int library_exported_names_clone(struct library_exported_names *retp, const struct library_exported_names *names) { - return - DICT_CLONE(&retp->names, &names->names, + return (DICT_CLONE(&retp->names, &names->names, const char*, uint64_t, - dict_clone_string, _dtor_string, + dict_clone_string, dtor_string, NULL, NULL, - NULL) || + NULL) < 0 || DICT_CLONE(&retp->addrs, &names->addrs, uint64_t, struct vect*, NULL, NULL, - _clone_vect, _dtor_vect, - NULL); + clone_vect, dtor_vect, + NULL) < 0) ? -1 : 0; } int library_exported_names_push(struct library_exported_names *names, - uint64_t addr, const char *name, + uint64_t addr, char *name, int own_name ) { // first, take ownership of the name, if it's not yet ours - if(!own_name) + if (!own_name) name = strdup(name); - if(name == NULL) + if (name == NULL) return -1; // push to the name->addr map int result = DICT_INSERT(&names->names, &name, &addr); - if(result == 1) { + if (result > 0) { // This symbol is already present in the table. This library has // multiple copies of this symbol (probably corresponding to // different symbol versions). I should handle this gracefully @@ -407,7 +409,7 @@ int library_exported_names_push(struct library_exported_names *names, return 0; } - if(result != 0) + if (result != 0) return result; // push to the addr->names map @@ -418,64 +420,35 @@ int library_exported_names_push(struct library_exported_names *names, if (paliases == NULL) { aliases = malloc(sizeof(struct vect)); - if(aliases == NULL) + if (aliases == NULL) return -1; VECT_INIT(aliases, const char*); result = DICT_INSERT(&names->addrs, &addr, &aliases); - if(result != 0) + assert(result <= 0); + if (result < 0) return result; } else aliases = *paliases; - const char *namedup = strdup(name); - if(namedup == NULL) + char *namedup = strdup(name); + if (namedup == NULL) return -1; result = vect_pushback(aliases, &namedup); - if(result != 0) + if (result != 0) { + free(namedup); return result; + } return 0; } -struct library_exported_names_each_context -{ - enum callback_status (*inner_cb)(const char *, void *); - void *data; - bool failure : 1; -}; -static enum callback_status -library_exported_names_each_cb(const char **key, uint64_t *value, void *data) -{ - struct library_exported_names_each_context *context = - (struct library_exported_names_each_context*)data; - enum callback_status status = context->inner_cb(*key, context->data); - if(status == CBS_FAIL) - context->failure = true; - return status; -} -bool library_exported_names_each(const struct library_exported_names *names, - enum callback_status (*cb)(const char *, - void *), - void *data) -{ - struct library_exported_names_each_context context = - {.inner_cb = cb, - .data = data, - .failure = false}; - DICT_EACH(&names->names, - const char*, uint64_t, - NULL, library_exported_names_each_cb, &context); - return !context.failure; -} - struct library_exported_names_each_alias_context { enum callback_status (*inner_cb)(const char *, void *); const char *origname; void *data; - bool failure : 1; }; static enum callback_status library_exported_names_each_alias_cb(const char **name, void *data) @@ -486,18 +459,16 @@ library_exported_names_each_alias_cb(const char **name, void *data) // I do not report the original name we were asked about. Otherwise, any // time the caller asks for aliases of symbol "sym", I'll always report // "sym" along with any actual aliases - if(strcmp(*name, context->origname) == 0) + if (strcmp(*name, context->origname) == 0) return CBS_CONT; - enum callback_status status = context->inner_cb(*name, context->data); - if(status == CBS_FAIL) - context->failure = true; - return status; + return context->inner_cb(*name, context->data); } -bool library_exported_names_each_alias( - const struct library_exported_names *names, +const char** library_exported_names_each_alias( + struct library_exported_names *names, const char *aliasname, + const char **name_start_after, enum callback_status (*cb)(const char *, void *), void *data) @@ -506,27 +477,34 @@ bool library_exported_names_each_alias( // aliased names uint64_t *addr = DICT_FIND_REF(&names->names, &aliasname, uint64_t); - if(addr == NULL) - return false; + if (addr == NULL) + return NULL; // OK. I have an address. Get the list of symbols at this address struct vect **aliases = DICT_FIND_REF(&names->addrs, - addr, struct vect*); - if(aliases == NULL) - return false; + addr, struct vect*); + assert(aliases != NULL); struct library_exported_names_each_alias_context context = {.inner_cb = cb, .origname = aliasname, - .data = data, - .failure = false}; - VECT_EACH(*aliases, const char*, NULL, - library_exported_names_each_alias_cb, &context); + .data = data}; + return VECT_EACH(*aliases, const char*, name_start_after, + library_exported_names_each_alias_cb, &context); +} + +int library_exported_names_contains(struct library_exported_names* names, + const char* queryname) +{ + uint64_t *addr = DICT_FIND_REF(&names->names, + &queryname, uint64_t); + return (addr == NULL) ? 0 : 1; } + int library_clone(struct library *retp, struct library *lib) { @@ -547,6 +525,7 @@ library_clone(struct library *retp, struct library *lib) library_set_pathname(retp, pathname, lib->own_pathname); retp->key = lib->key; + retp->should_activate_latent = lib->should_activate_latent; /* Clone symbols. */ { @@ -583,6 +562,12 @@ library_clone(struct library *retp, struct library *lib) goto fail; } +#if defined(HAVE_LIBDW) + /* Wipe DWFL_MODULE, leave it to proc_add_library to + * initialize. */ + lib->dwfl_module = NULL; +#endif + return 0; }