Fix bug in `expr_clone`
[platform/upstream/ltrace.git] / library.c
index 562b52a..2339153 100644 (file)
--- 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 <stdlib.h>
 #include <string.h>
 #include <assert.h>
@@ -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)
@@ -340,7 +343,7 @@ static int clone_vect(struct vect **to, const struct vect **from, void *data)
                           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);
        free(*tgt);
@@ -385,7 +388,7 @@ library_exported_names_clone(struct library_exported_names *retp,
 }
 
 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
@@ -428,54 +431,24 @@ int library_exported_names_push(struct library_exported_names *names,
        else
                aliases = *paliases;
 
-       const char *namedup = strdup(name);
+       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)
@@ -489,15 +462,13 @@ library_exported_names_each_alias_cb(const char **name, void *data)
        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)
@@ -507,26 +478,33 @@ bool library_exported_names_each_alias(
        uint64_t *addr = DICT_FIND_REF(&names->names,
                                       &aliasname, uint64_t);
        if (addr == NULL)
-               return false;
+               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;
 }