X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust-dl%2Flttng-ust-dl.c;h=e457e7a3cbdfa69697c3794465a82a66681a0ec3;hb=2c3f4c28698f497756f194ef88cd991e2cca6bb4;hp=13d2b435e6b421f16b802396d48b8c48066fc8a0;hpb=6d4658aa879ddabdd79fc6c637ee039413ad215b;p=lttng-ust.git diff --git a/liblttng-ust-dl/lttng-ust-dl.c b/liblttng-ust-dl/lttng-ust-dl.c index 13d2b435..e457e7a3 100644 --- a/liblttng-ust-dl/lttng-ust-dl.c +++ b/liblttng-ust-dl/lttng-ust-dl.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Paul Woegerer + * Copyright (C) 2015 Antoine Busque * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,23 +17,20 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define _LGPL_SOURCE #define _GNU_SOURCE -#include -#include -#include -#include -#include +#define _LGPL_SOURCE #include +#include #include -#include -#include -#include -#include +#include + +#include +#include +#include #include "usterr-signal-safe.h" -#include -#include +/* Include link.h last else it conflicts with ust-dlfcn. */ +#include #define TRACEPOINT_DEFINE #include "ust_dl.h" @@ -45,7 +43,7 @@ void *_lttng_ust_dl_libc_dlopen(const char *filename, int flag) { if (!__lttng_ust_plibc_dlopen) { __lttng_ust_plibc_dlopen = dlsym(RTLD_NEXT, "dlopen"); - if (__lttng_ust_plibc_dlopen == NULL) { + if (!__lttng_ust_plibc_dlopen) { fprintf(stderr, "%s\n", dlerror()); return NULL; } @@ -58,7 +56,7 @@ int _lttng_ust_dl_libc_dlclose(void *handle) { if (!__lttng_ust_plibc_dlclose) { __lttng_ust_plibc_dlclose = dlsym(RTLD_NEXT, "dlclose"); - if (__lttng_ust_plibc_dlclose == NULL) { + if (!__lttng_ust_plibc_dlclose) { fprintf(stderr, "%s\n", dlerror()); return -1; } @@ -67,45 +65,97 @@ int _lttng_ust_dl_libc_dlclose(void *handle) } static -void lttng_ust_dl_dlopen(void *so_base, const char *so_name) +void lttng_ust_dl_dlopen(void *so_base, const char *so_name, void *ip) { char resolved_path[PATH_MAX]; - struct stat sostat; + struct lttng_ust_elf *elf; + uint64_t memsz; + uint8_t *build_id = NULL; + size_t build_id_len; + char *dbg_file = NULL; + uint32_t crc; + int has_build_id = 0, has_debug_link = 0; + int ret; if (!realpath(so_name, resolved_path)) { ERR("could not resolve path '%s'", so_name); return; } - if (stat(resolved_path, &sostat)) { - ERR("could not access file status for %s", resolved_path); + elf = lttng_ust_elf_create(resolved_path); + if (!elf) { + ERR("could not acces file %s", resolved_path); return; } + ret = lttng_ust_elf_get_memsz(elf, &memsz); + if (ret) { + goto end; + } + ret = lttng_ust_elf_get_build_id( + elf, &build_id, &build_id_len, &has_build_id); + if (ret) { + goto end; + } + ret = lttng_ust_elf_get_debug_link( + elf, &dbg_file, &crc, &has_debug_link); + if (ret) { + goto end; + } + tracepoint(lttng_ust_dl, dlopen, - so_base, resolved_path, sostat.st_size, sostat.st_mtime); + ip, so_base, resolved_path, memsz, + has_build_id, has_debug_link); + + if (has_build_id) { + tracepoint(lttng_ust_dl, build_id, + ip, so_base, build_id, build_id_len); + } + + if (has_debug_link) { + tracepoint(lttng_ust_dl, debug_link, + ip, so_base, dbg_file, crc); + } + +end: + free(dbg_file); + free(build_id); + lttng_ust_elf_destroy(elf); return; } void *dlopen(const char *filename, int flag) { - void *handle = _lttng_ust_dl_libc_dlopen(filename, flag); + void *handle; + + handle = _lttng_ust_dl_libc_dlopen(filename, flag); if (__tracepoint_ptrs_registered && handle) { struct link_map *p = NULL; - if (dlinfo(handle, RTLD_DI_LINKMAP, &p) != -1 && p != NULL - && p->l_addr != 0) - lttng_ust_dl_dlopen((void *) p->l_addr, p->l_name); + int ret; + + ret = dlinfo(handle, RTLD_DI_LINKMAP, &p); + if (ret != -1 && p != NULL && p->l_addr != 0) { + lttng_ust_dl_dlopen((void *) p->l_addr, p->l_name, + LTTNG_UST_CALLER_IP()); + } } + return handle; } int dlclose(void *handle) { - if (__tracepoint_ptrs_registered && handle) { + if (__tracepoint_ptrs_registered) { struct link_map *p = NULL; - if (dlinfo(handle, RTLD_DI_LINKMAP, &p) != -1 && p != NULL - && p->l_addr != 0) - tracepoint(lttng_ust_dl, dlclose, (void *) p->l_addr); + int ret; + + ret = dlinfo(handle, RTLD_DI_LINKMAP, &p); + if (ret != -1 && p != NULL && p->l_addr != 0) { + tracepoint(lttng_ust_dl, dlclose, + LTTNG_UST_CALLER_IP(), + (void *) p->l_addr); + } } + return _lttng_ust_dl_libc_dlclose(handle); }