18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file daemon/liblegacy/opd_kernel.c 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Dealing with the kernel and kernel module samples 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_kernel.h" 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_proc.h" 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_image.h" 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_mapping.h" 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_printf.h" 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "opd_24_stats.h" 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "oprofiled.h" 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_fileio.h" 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_config_24.h" 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_libiberty.h" 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "p_module.h" 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string.h> 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdlib.h> 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <errno.h> 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* kernel module */ 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct opd_module { 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * name; 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_image * image; 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unsigned long start; 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unsigned long end; 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head module_list; 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct opd_image * kernel_image; 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* kernel and module support */ 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic unsigned long kernel_start; 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic unsigned long kernel_end; 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct list_head opd_modules = { &opd_modules, &opd_modules }; 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic unsigned int nr_modules=0; 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_init_kernel_image(void) 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* for no vmlinux */ 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!vmlinux) 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vmlinux = "no-vmlinux"; 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kernel_image = opd_get_kernel_image(vmlinux, NULL, 0, 0); 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kernel_image->ref_count++; 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_parse_kernel_range(char const * arg) 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sscanf(arg, "%lx,%lx", &kernel_start, &kernel_end); 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "OPD_PARSE_KERNEL_RANGE: kernel_start = %lx, kernel_end = %lx\n", 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kernel_start, kernel_end); 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!kernel_start && !kernel_end) { 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fprintf(stderr, 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "Warning: mis-parsed kernel range: %lx-%lx\n", 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd kernel_start, kernel_end); 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fprintf(stderr, "kernel profiles will be wrong.\n"); 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_create_module - allocate and initialise a module description 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param name module name 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param start start address 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param end end address 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct opd_module * 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddopd_create_module(char * name, unsigned long start, unsigned long end) 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * module = xmalloc(sizeof(struct opd_module)); 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->name = xstrdup(name); 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->image = NULL; 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->start = start; 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->end = end; 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_add(&module->module_list, &opd_modules); 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return module; 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_find_module_by_name - find a module by name, ccreating a new once if 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * search fail 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param name module name 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct opd_module * opd_find_module_by_name(char * name) 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos; 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * module; 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each(pos, &opd_modules) { 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = list_entry(pos, struct opd_module, module_list); 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!strcmp(name, module->name)) 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return module; 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return opd_create_module(name, 0, 0); 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_clear_module_info(void) 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos; 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos2; 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * module; 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "Removing module list\n"); 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each_safe(pos, pos2, &opd_modules) { 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = list_entry(pos, struct opd_module, module_list); 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(module->name); 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(module); 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_init(&opd_modules); 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_clear_kernel_mapping(); 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_get_module_info - parse mapping information for kernel modules 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Parse the file /proc/ksyms to read in mapping information for 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * all kernel modules. The modutils package adds special symbols 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * to this file which allows determination of the module image 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * and mapping addresses of the form : 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * __insmod_modulename_Oobjectfile_Mmtime_Vversion 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * __insmod_modulename_Ssectionname_Llength 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Currently the image file "objectfile" is stored, and details of 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * ".text" sections. 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * There is no query_module API that allow to get directly the pathname 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * of a module so we need to parse all the /proc/ksyms. 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_get_module_info(void) 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * line; 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * cp, * cp2, * cp3; 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd FILE * fp; 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * mod; 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * modname; 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * filename; 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd nr_modules=0; 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fp = op_try_open_file("/proc/ksyms", "r"); 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!fp) { 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printf("oprofiled: /proc/ksyms not readable, can't process module samples.\n"); 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "Read module info.\n"); 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while (1) { 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd line = op_get_line(fp); 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!line) 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!strcmp("", line)) { 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(line); 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (strlen(line) < 9) { 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printf("oprofiled: corrupt /proc/ksyms line \"%s\"\n", line); 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (strncmp("__insmod_", line + 9, 9)) { 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(line); 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp = line + 18; 1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp2 = cp; 1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while ((*cp2) && !!strncmp("_S", cp2+1, 2) && !!strncmp("_O", cp2+1, 2)) 1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp2++; 1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!*cp2) { 1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd printf("oprofiled: corrupt /proc/ksyms line \"%s\"\n", line); 1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp2++; 2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd modname = xmalloc((size_t)((cp2-cp) + 1)); 2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd strncpy(modname, cp, (size_t)((cp2-cp))); 2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd modname[cp2-cp] = '\0'; 2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd mod = opd_find_module_by_name(modname); 2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(modname); 2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd switch (*(++cp2)) { 2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case 'O': 2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* get filename */ 2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp2++; 2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp3 = cp2; 2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while ((*cp3) && !!strncmp("_M", cp3+1, 2)) 2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp3++; 2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!*cp3) { 2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(line); 2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp3++; 2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd filename = xmalloc((size_t)(cp3 - cp2 + 1)); 2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd strncpy(filename, cp2, (size_t)(cp3 - cp2)); 2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd filename[cp3-cp2] = '\0'; 2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd mod->image = opd_get_kernel_image(filename, NULL, 0, 0); 2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd mod->image->ref_count++; 2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(filename); 2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case 'S': 2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* get extent of .text section */ 2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp2++; 2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (strncmp(".text_L", cp2, 7)) { 2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(line); 2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cp2 += 7; 2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sscanf(line, "%lx", &mod->start); 2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sscanf(cp2, "%lu", &mod->end); 2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd mod->end += mod->start; 2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(line); 2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (line) 2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(line); 2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_close_file(fp); 2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_drop_module_sample - drop a module sample efficiently 2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param eip eip of sample 2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This function is called to recover from failing to put a samples even 2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * after re-reading /proc/ksyms. It's either a rogue sample, or from a module 2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * that didn't create symbols (like in some initrd setups). So we check with 2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * query_module() if we can place it in a symbol-less module, and if so create 2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * a negative entry for it, to quickly ignore future samples. 2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Problem uncovered by Bob Montgomery <bobm@fc.hp.com> 2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_drop_module_sample(unsigned long eip) 2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * module_names; 2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * name; 2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd size_t size = 1024; 2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd size_t ret; 2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint nr_mods; 2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd uint mod = 0; 2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_LOST_MODULE]++; 2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module_names = xmalloc(size); 2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while (query_module(NULL, QM_MODULES, module_names, size, &ret)) { 2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (errno != ENOSPC) { 2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "query_module failed: %s\n", strerror(errno)); 2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd size = ret; 2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module_names = xrealloc(module_names, size); 2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd nr_mods = ret; 2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd name = module_names; 2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while (mod < nr_mods) { 2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct module_info info; 2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!query_module(name, QM_INFO, &info, sizeof(info), &ret)) { 2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (eip >= info.addr && eip < info.addr + info.size) { 2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "Sample from unprofilable module %s\n", name); 3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_create_module(name, info.addr, info.addr + info.size); 3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd mod++; 3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd name += strlen(name) + 1; 3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (module_names) 3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(module_names); 3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_find_module_by_eip - find a module by its eip 3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param eip EIP value 3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * find in the modules container the module which 3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * contain this eip return %NULL if not found. 3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * caller must check than the module image is valid 3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic struct opd_module * opd_find_module_by_eip(unsigned long eip) 3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct list_head * pos; 3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * module; 3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list_for_each(pos, &opd_modules) { 3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = list_entry(pos, struct opd_module, module_list); 3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (module->start <= eip && module->end > eip) 3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return module; 3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return NULL; 3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * opd_handle_module_sample - process a module sample 3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param eip EIP value 3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param counter counter number 3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Process a sample in module address space. The sample eip 3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * is matched against module information. If the search was 3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * successful, the sample is output to the relevant file. 3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Note that for modules and the kernel, the offset will be 3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * wrong in the file, as it is not a file offset, but the offset 3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * from the text section. This is fixed up in pp. 3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * If the sample could not be located in a module, it is treated 3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * as a kernel sample. 3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic void opd_handle_module_sample(unsigned long eip, u32 counter) 3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * module; 3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = opd_find_module_by_eip(eip); 3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!module) { 3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* not found in known modules, re-read our info and retry */ 3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_clear_module_info(); 3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_get_module_info(); 3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = opd_find_module_by_eip(eip); 3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (module) { 3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (module->image != NULL) { 3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_MODULE]++; 3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_put_image_sample(module->image, 3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd eip - module->start, counter); 3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_LOST_MODULE]++; 3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "No image for sampled module %s\n", 3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->name); 3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_drop_module_sample(eip); 3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_handle_kernel_sample(unsigned long eip, u32 counter) 3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (no_vmlinux || eip < kernel_end) { 3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_24_stats[OPD_KERNEL]++; 3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_put_image_sample(kernel_image, eip - kernel_start, counter); 3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* in a module */ 3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_handle_module_sample(eip, counter); 3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint opd_eip_is_kernel(unsigned long eip) 3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 39673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#ifdef __i386__ 3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define KERNEL_OFFSET 0xC0000000 3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* 3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * kernel_start == 0 when using --no-vmlinux. 4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This is wrong, wrong, wrong, wrong, but we don't have much 4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * choice. It obviously breaks for IA64. 4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!kernel_start) 4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return eip >= KERNEL_OFFSET; 4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif 4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return eip >= kernel_start; 4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opd_add_kernel_map(struct opd_proc * proc, unsigned long eip) 4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_module * module; 4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct opd_image * image; 4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char const * app_name; 4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd app_name = proc->name; 4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!app_name) { 4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "un-named proc for tid %d\n", proc->tid); 4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (eip < kernel_end) { 4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image = opd_get_kernel_image(vmlinux, app_name, proc->tid, proc->tgid); 4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!image) { 4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmisc, "Can't create image for %s %s\n", vmlinux, app_name); 4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_add_mapping(proc, image, kernel_start, 0, kernel_end); 4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 4338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = opd_find_module_by_eip(eip); 4368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!module) { 4378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* not found in known modules, re-read our info and retry */ 4388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_clear_module_info(); 4398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_get_module_info(); 4408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module = opd_find_module_by_eip(eip); 4428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (module) { 4458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* module->name is only the module name not the full path */ 4468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char const * module_name = 0; 4478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (module->image) 4488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module_name = module->image->name; 4498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!module_name) { 4508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "unable to get path name for module %s\n", 4518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->name); 4528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module_name = module->name; 4538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image = opd_get_kernel_image(module_name, app_name, proc->tid, proc->tgid); 4558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!image) { 4568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd verbprintf(vmodule, "Can't create image for %s %s\n", 4578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd module->name, app_name); 4588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 4598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_add_mapping(proc, image, module->start, 0, module->end); 4618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 4628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_drop_module_sample(eip); 4638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 465