diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:34:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:34:56 +0900 |
commit | 517f5529d7008eba87b8b2fee5ec9ec0a5075f6e (patch) | |
tree | c71720a9b41309713c089478f921165bd2d63b25 /library.c | |
parent | 689b9dbb8d7f88ab91e7741932ed000b6e49be9a (diff) | |
download | ltrace-517f5529d7008eba87b8b2fee5ec9ec0a5075f6e.tar.gz ltrace-517f5529d7008eba87b8b2fee5ec9ec0a5075f6e.tar.bz2 ltrace-517f5529d7008eba87b8b2fee5ec9ec0a5075f6e.zip |
Imported Upstream version 0.7.91upstream/0.7.91upstream
Diffstat (limited to 'library.c')
-rw-r--r-- | library.c | 163 |
1 files changed, 119 insertions, 44 deletions
@@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2001,2009 Juan Cespedes * Copyright (C) 2006 Ian Wienand * @@ -31,10 +31,30 @@ #include "dict.h" #include "backend.h" // for arch_library_symbol_init, arch_library_init -#ifndef ARCH_HAVE_LIBRARY_DATA +#ifndef OS_HAVE_LIBRARY_DATA +int +os_library_init(struct library *lib) +{ + return 0; +} + void +os_library_destroy(struct library *lib) +{ +} + +int +os_library_clone(struct library *retp, struct library *lib) +{ + return 0; +} +#endif + +#ifndef ARCH_HAVE_LIBRARY_DATA +int arch_library_init(struct library *lib) { + return 0; } void @@ -42,9 +62,30 @@ arch_library_destroy(struct library *lib) { } -void +int arch_library_clone(struct library *retp, struct library *lib) { + return 0; +} +#endif + +#ifndef OS_HAVE_LIBRARY_SYMBOL_DATA +int +os_library_symbol_init(struct library_symbol *libsym) +{ + return 0; +} + +void +os_library_symbol_destroy(struct library_symbol *libsym) +{ +} + +int +os_library_symbol_clone(struct library_symbol *retp, + struct library_symbol *libsym) +{ + return 0; } #endif @@ -68,46 +109,39 @@ arch_library_symbol_clone(struct library_symbol *retp, } #endif -unsigned int -target_address_hash(const void *key) +size_t +arch_addr_hash(const arch_addr_t *addr) { - /* XXX this assumes that key is passed by value. */ union { arch_addr_t addr; - unsigned int ints[sizeof(arch_addr_t) - / sizeof(unsigned int)]; - } u = { .addr = (arch_addr_t)key }; + int ints[sizeof(arch_addr_t) + / sizeof(unsigned int)]; + } u = { .addr = *addr }; size_t i; - unsigned int h = 0; + size_t h = 0; for (i = 0; i < sizeof(u.ints) / sizeof(*u.ints); ++i) - h ^= dict_key2hash_int((void *)(uintptr_t)u.ints[i]); + h ^= dict_hash_int(&u.ints[i]); return h; } int -target_address_cmp(const void *key1, const void *key2) +arch_addr_eq(const arch_addr_t *addr1, const arch_addr_t *addr2) { - /* XXX this assumes that key is passed by value. */ - arch_addr_t addr1 = (arch_addr_t)key1; - arch_addr_t addr2 = (arch_addr_t)key2; - return addr1 < addr2 ? 1 - : addr1 > addr2 ? -1 : 0; + return *addr1 == *addr2; } -/* If the other symbol owns the name, we need to make the copy, so - * that the life-times of the two symbols are not dependent on each - * other. */ -static int -strdup_if_owned(const char **retp, const char *str, int owned) -{ - if (!owned || str == NULL) { - *retp = str; - return 0; - } else { - *retp = strdup(str); - return *retp != NULL ? 0 : -1; +int +strdup_if(const char **retp, const char *str, int whether) +{ + if (whether && str != NULL) { + str = strdup(str); + if (str == NULL) + return -1; } + + *retp = str; + return 0; } static void @@ -125,6 +159,7 @@ private_library_symbol_init(struct library_symbol *libsym, libsym->latent = latent; libsym->delayed = delayed; libsym->enter_addr = (void *)(uintptr_t)addr; + libsym->proto = NULL; } static void @@ -141,37 +176,55 @@ library_symbol_init(struct library_symbol *libsym, private_library_symbol_init(libsym, addr, name, own_name, type_of_plt, 0, 0); - /* If arch init fails, we've already set libsym->name and - * own_name. But we return failure, and the client code isn't - * supposed to call library_symbol_destroy in such a case. */ - return arch_library_symbol_init(libsym); + if (os_library_symbol_init(libsym) < 0) + /* We've already set libsym->name and own_name. But + * we return failure, and the client code isn't + * supposed to call library_symbol_destroy in such + * case. */ + return -1; + + if (arch_library_symbol_init(libsym) < 0) { + os_library_symbol_destroy(libsym); + return -1; + } + + return 0; } void library_symbol_destroy(struct library_symbol *libsym) { if (libsym != NULL) { - private_library_symbol_destroy(libsym); arch_library_symbol_destroy(libsym); + os_library_symbol_destroy(libsym); + private_library_symbol_destroy(libsym); } } int library_symbol_clone(struct library_symbol *retp, struct library_symbol *libsym) { + /* Make lifetimes of name stored at original independent of + * the one at the clone. */ const char *name; - if (strdup_if_owned(&name, libsym->name, libsym->own_name) < 0) + if (strdup_if(&name, libsym->name, libsym->own_name) < 0) return -1; private_library_symbol_init(retp, libsym->enter_addr, name, libsym->own_name, libsym->plt_type, libsym->latent, libsym->delayed); - if (arch_library_symbol_clone(retp, libsym) < 0) { + if (os_library_symbol_clone(retp, libsym) < 0) { + fail: private_library_symbol_destroy(retp); return -1; } + if (arch_library_symbol_clone(retp, libsym) < 0) { + os_library_symbol_destroy(retp); + goto fail; + } + return 0; } @@ -230,6 +283,7 @@ private_library_init(struct library *lib, enum library_type type) lib->base = 0; lib->entry = 0; lib->dyn_addr = 0; + lib->protolib = NULL; lib->soname = NULL; lib->own_soname = 0; @@ -242,11 +296,20 @@ private_library_init(struct library *lib, enum library_type type) lib->type = type; } -void +int library_init(struct library *lib, enum library_type type) { private_library_init(lib, type); - arch_library_init(lib); + + if (os_library_init(lib) < 0) + return -1; + + if (arch_library_init(lib) < 0) { + os_library_destroy(lib); + return -1; + } + + return 0; } static int @@ -266,9 +329,11 @@ library_clone(struct library *retp, struct library *lib) { const char *soname = NULL; const char *pathname; - if (strdup_if_owned(&soname, lib->soname, lib->own_soname) < 0 - || strdup_if_owned(&pathname, - lib->pathname, lib->own_pathname) < 0) { + + /* Make lifetimes of strings stored at original independent of + * those at the clone. */ + if (strdup_if(&soname, lib->soname, lib->own_soname) < 0 + || strdup_if(&pathname, lib->pathname, lib->own_pathname) < 0) { if (lib->own_soname) free((char *)soname); return -1; @@ -277,7 +342,6 @@ library_clone(struct library *retp, struct library *lib) private_library_init(retp, lib->type); library_set_soname(retp, soname, lib->own_soname); library_set_pathname(retp, pathname, lib->own_pathname); - arch_library_clone(retp, lib); retp->key = lib->key; @@ -290,6 +354,7 @@ library_clone(struct library *retp, struct library *lib) if (*nsymp == NULL || library_symbol_clone(*nsymp, it) < 0) { free(*nsymp); + *nsymp = NULL; fail: /* Release what we managed to allocate. */ library_destroy(retp); @@ -318,6 +383,14 @@ library_clone(struct library *retp, struct library *lib) *nnamep = NULL; } + if (os_library_clone(retp, lib) < 0) + goto fail; + + if (arch_library_clone(retp, lib) < 0) { + os_library_destroy(retp); + goto fail; + } + return 0; } @@ -328,6 +401,8 @@ library_destroy(struct library *lib) return; arch_library_destroy(lib); + os_library_destroy(lib); + library_set_soname(lib, NULL, 0); library_set_pathname(lib, NULL, 0); @@ -412,7 +487,7 @@ library_add_symbol(struct library *lib, struct library_symbol *first) } enum callback_status -library_named_cb(struct Process *proc, struct library *lib, void *name) +library_named_cb(struct process *proc, struct library *lib, void *name) { if (name == lib->soname || strcmp(lib->soname, (char *)name) == 0) @@ -422,7 +497,7 @@ library_named_cb(struct Process *proc, struct library *lib, void *name) } enum callback_status -library_with_key_cb(struct Process *proc, struct library *lib, void *keyp) +library_with_key_cb(struct process *proc, struct library *lib, void *keyp) { return lib->key == *(arch_addr_t *)keyp ? CBS_STOP : CBS_CONT; } |