/*
* 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
*
* 02110-1301 USA
*/
+#include "config.h"
+
#include <stdlib.h>
#include <string.h>
#include <assert.h>
lib->symbols = NULL;
library_exported_names_init(&lib->exported_names);
+ lib->should_activate_latent = false;
lib->type = type;
#if defined(HAVE_LIBDW)
-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);
}
{
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
return 0;
}
- if(result != 0)
+ if (result != 0)
return result;
// push to the addr->names map
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)
// 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)
// 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)
{
library_set_pathname(retp, pathname, lib->own_pathname);
retp->key = lib->key;
+ retp->should_activate_latent = lib->should_activate_latent;
/* Clone symbols. */
{
goto fail;
}
+#if defined(HAVE_LIBDW)
+ /* Wipe DWFL_MODULE, leave it to proc_add_library to
+ * initialize. */
+ lib->dwfl_module = NULL;
+#endif
+
return 0;
}