diff --git a/lib/libpmcstat/libpmcstat_image.c b/lib/libpmcstat/libpmcstat_image.c --- a/lib/libpmcstat/libpmcstat_image.c +++ b/lib/libpmcstat/libpmcstat_image.c @@ -390,19 +390,21 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image, struct pmcstat_args *args) { - int fd; + int fd, dfd; size_t i, nph; const char *path, *elfbase; char *p, *endp; bool first_exec_segment; uintptr_t minva, maxva; - Elf *e; + Elf *e, *de; GElf_Ehdr eh; GElf_Phdr ph; enum pmcstat_image_type image_type; char buffer[PATH_MAX]; char buffer_modules[PATH_MAX]; - char *chosen_buffer; + char buffer_debug[PATH_MAX]; + char buffer_debug_modules[PATH_MAX]; + char *chosen_buffer, *chosen_buffer_debug; assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN); @@ -419,27 +421,51 @@ /* * Look for kernel modules under FSROOT/KERNELPATH/NAME and * FSROOT/boot/modules/NAME, and user mode executable objects - * under FSROOT/PATHNAME. + * under FSROOT/PATHNAME. Also look for debug files in the + * equivalent FSROOT/usr/lib/debug/.../NAME.debug. */ if (image->pi_iskernelmodule) { (void) snprintf(buffer, sizeof(buffer), "%s%s/%s", args->pa_fsroot, args->pa_kernel, path); (void) snprintf(buffer_modules, sizeof(buffer_modules), "%s/boot/modules/%s", args->pa_fsroot, path); + (void) snprintf(buffer_debug, sizeof(buffer_debug), + "%s/usr/lib/debug%s/%s.debug", args->pa_fsroot, + args->pa_kernel, path); + (void) snprintf(buffer_debug_modules, + sizeof(buffer_debug_modules), + "%s/usr/lib/debug/boot/modules/%s.debug", + args->pa_fsroot, path); } else { (void) snprintf(buffer, sizeof(buffer), "%s%s", args->pa_fsroot, path); + (void) snprintf(buffer_debug, sizeof(buffer_debug), + "%s/usr/lib/debug%s.debug", args->pa_fsroot, path); } e = NULL; + de = NULL; + dfd = -1; if ((fd = open(buffer, O_RDONLY, 0)) >= 0) { chosen_buffer = buffer; + dfd = open(buffer_debug, O_RDONLY, 0); + if (dfd >= 0) + chosen_buffer_debug = buffer_debug; + else if (args->pa_verbosity >= 2) + warnx("WARNING: Cannot open \"%s\".", + buffer_debug); } else if (!image->pi_iskernelmodule) { warnx("WARNING: Cannot open \"%s\".", buffer); goto done; } else if ((fd = open(buffer_modules, O_RDONLY, 0)) >= 0) { chosen_buffer = buffer_modules; + dfd = open(buffer_debug_modules, O_RDONLY, 0); + if (dfd >= 0) + chosen_buffer_debug = buffer_debug_modules; + else if (args->pa_verbosity >= 2) + warnx("WARNING: Cannot open \"%s\".", + buffer_debug_modules); } else { warnx("WARNING: Cannot open \"%s\" or \"%s\".", buffer, buffer_modules); @@ -526,8 +552,23 @@ endp = p+1; image->pi_name = pmcstat_string_intern(endp); + /* Also add symbols from the debug file if present. */ + if (dfd >= 0) { + de = pmcstat_image_open_elf(image, args, + chosen_buffer_debug, dfd, NULL); + if (de == NULL) + goto done; + if (!pmcstat_image_scan_elf_sections(image, + chosen_buffer_debug, de, NULL, NULL)) + goto done; + } + done: + if (de != NULL) + (void) elf_end(de); (void) elf_end(e); + if (dfd >= 0) + (void) close(dfd); if (fd >= 0) (void) close(fd); return;