X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust-baddr%2Flttng-ust-baddr.c;h=841223349a146e3c5f1d821dab92c5abc20bfecb;hb=13436238c6418c33e4eb3c3ab8e2a466f1597fd2;hp=f24a1717277ab99c2c81f1aa6b47bc290fb9c5fd;hpb=b13d93c24dfd101dc7a7f8ea2567a2164f807cdc;p=lttng-ust.git diff --git a/liblttng-ust-baddr/lttng-ust-baddr.c b/liblttng-ust-baddr/lttng-ust-baddr.c index f24a1717..84122334 100644 --- a/liblttng-ust-baddr/lttng-ust-baddr.c +++ b/liblttng-ust-baddr/lttng-ust-baddr.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -32,33 +31,78 @@ #include #include "usterr.h" +#include "lttng-ust-baddr.h" + #define TRACEPOINT_DEFINE -#include "ust_baddr.h" +#include "ust_baddr_statedump.h" -int -lttng_ust_push_baddr(void *so_base, const char *so_name) +static int +extract_soinfo_events(struct dl_phdr_info *info, size_t size, void *data) { - char resolved_path[PATH_MAX]; - struct stat sostat; + int j; + int num_loadable_segment = 0; - if (!realpath(so_name, resolved_path)) { - ERR("could not resolve path '%s'", so_name); - return 0; - } + for (j = 0; j < info->dlpi_phnum; j++) { + char resolved_path[PATH_MAX]; + struct stat sostat; + void *base_addr_ptr; - if (stat(resolved_path, &sostat)) { - ERR("could not access file status for %s", resolved_path); - return 0; - } + if (info->dlpi_phdr[j].p_type != PT_LOAD) + continue; - tracepoint(ust_baddr, push, - so_base, resolved_path, sostat.st_size, sostat.st_mtime); + /* Calculate virtual memory address of the loadable segment */ + base_addr_ptr = (void *) info->dlpi_addr + + info->dlpi_phdr[j].p_vaddr; + + num_loadable_segment += 1; + if ((info->dlpi_name == NULL || info->dlpi_name[0] == 0) + && num_loadable_segment == 1) { + /* + * If the iterated element is the executable itself we + * have to use Dl_info to determine its full path + */ + Dl_info dl_info = { 0 }; + if (!dladdr(base_addr_ptr, &dl_info)) + return 0; + if (!realpath(dl_info.dli_fname, resolved_path)) + return 0; + } else { + /* + * For regular dl_phdr_info entries we have to check if + * the path to the shared object really exists + */ + if (!realpath(info->dlpi_name, resolved_path)) { + /* Found vDSO, put the 'path' into brackets */ + snprintf(resolved_path, PATH_MAX - 1, "[%s]", + info->dlpi_name); + } + } + + if (stat(resolved_path, &sostat)) { + sostat.st_size = 0; + sostat.st_mtime = -1; + } + + tracepoint(ust_baddr_statedump, soinfo, + (struct lttng_session *) data, base_addr_ptr, + resolved_path, sostat.st_size, sostat.st_mtime); + + /* + * We are only interested in the base address (lowest virtual + * address associated with the memory image), skip the rest + */ + break; + } return 0; } int -lttng_ust_pop_baddr(void *so_base) +lttng_ust_baddr_statedump(struct lttng_session *session) { - tracepoint(ust_baddr, pop, so_base); + /* + * Iterate through the list of currently loaded shared objects and + * generate events for loadable segments using extract_soinfo_events + */ + dl_iterate_phdr(extract_soinfo_events, session); return 0; }