From df1dddf9ffcfc1e291de809c0e8b9060bfea02ee Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 7 Dec 2006 00:26:12 +0100 Subject: Imported from util-linux-2.12 tarball. --- sys-utils/readprofile.c | 156 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 52 deletions(-) (limited to 'sys-utils/readprofile.c') diff --git a/sys-utils/readprofile.c b/sys-utils/readprofile.c index c91c26521..d6ce884e3 100644 --- a/sys-utils/readprofile.c +++ b/sys-utils/readprofile.c @@ -31,20 +31,23 @@ * - skip step size (index 0) * 2002-03-09 John Levon * - make maplineno do something + * 2002-11-28 Mads Martin Joergensen + + * - also try /boot/System.map-`uname -r` + * 2003-04-09 Werner Almesberger + * - fixed off-by eight error and improved heuristics in byte order detection */ #include #include +#include #include #include #include #include #include -#include +#include #include "nls.h" -#define RELEASE "2.0, May 1996" - #define S_LEN 128 static char *prgname; @@ -54,24 +57,6 @@ static char defaultmap[]="/usr/src/linux/System.map"; static char defaultpro[]="/proc/profile"; static char optstring[]="M:m:np:itvarVb"; -static void -usage(void) { - fprintf(stderr, - _("%s: Usage: \"%s [options]\n" - "\t -m (default = \"%s\")\n" - "\t -p (default = \"%s\")\n" - "\t -M set the profiling multiplier to \n" - "\t -i print only info about the sampling step\n" - "\t -v print verbose data\n" - "\t -a print all symbols, even if count is 0\n" - "\t -b print individual histogram-bin counts\n" - "\t -r reset all the counters (root only)\n" - "\t -n disable byte order auto-detection\n" - "\t -V print version and exit\n") - ,prgname,prgname,defaultmap,defaultpro); - exit(1); -} - static void * xmalloc (size_t size) { void *t; @@ -105,8 +90,45 @@ myopen(char *name, char *mode, int *flag) { return fopen(name,mode); } +#ifndef BOOT_SYSTEM_MAP +#define BOOT_SYSTEM_MAP "/boot/System.map-" +#endif + +static char * +boot_uname_r_str(void) { + struct utsname uname_info; + char *s; + size_t len; + + if (uname(&uname_info)) + return ""; + len = strlen(BOOT_SYSTEM_MAP) + strlen(uname_info.release) + 1; + s = xmalloc(len); + strcpy(s, BOOT_SYSTEM_MAP); + strcat(s, uname_info.release); + return s; +} + +static void +usage(void) { + fprintf(stderr, + _("%s: Usage: \"%s [options]\n" + "\t -m (defaults: \"%s\" and\n\t\t\t\t \"%s\")\n" + "\t -p (default: \"%s\")\n" + "\t -M set the profiling multiplier to \n" + "\t -i print only info about the sampling step\n" + "\t -v print verbose data\n" + "\t -a print all symbols, even if count is 0\n" + "\t -b print individual histogram-bin counts\n" + "\t -r reset all the counters (root only)\n" + "\t -n disable byte order auto-detection\n" + "\t -V print version and exit\n"), + prgname, prgname, defaultmap, boot_uname_r_str(), defaultpro); + exit(1); +} + int -main (int argc, char **argv) { +main(int argc, char **argv) { FILE *map; int proFd; char *mapFile, *proFile, *mult=0; @@ -129,24 +151,45 @@ main (int argc, char **argv) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - prgname=argv[0]; - proFile=defaultpro; - mapFile=defaultmap; + prgname = argv[0]; + proFile = defaultpro; + mapFile = defaultmap; - while ((c = getopt(argc,argv,optstring)) != -1) { + while ((c = getopt(argc, argv, optstring)) != -1) { switch(c) { - case 'm': mapFile=optarg; break; - case 'n': optNative++; break; - case 'p': proFile=optarg; break; - case 'a': optAll++; break; - case 'b': optBins++; break; - case 'i': optInfo++; break; - case 'M': mult=optarg; break; - case 'r': optReset++; break; - case 'v': optVerbose++; break; - case 'V': printf(_("%s Version %s\n"),prgname,RELEASE); + case 'm': + mapFile = optarg; + break; + case 'n': + optNative++; + break; + case 'p': + proFile = optarg; + break; + case 'a': + optAll++; + break; + case 'b': + optBins++; + break; + case 'i': + optInfo++; + break; + case 'M': + mult = optarg; + break; + case 'r': + optReset++; + break; + case 'v': + optVerbose++; + break; + case 'V': + printf(_("%s version %s\n"), prgname, + UTIL_LINUX_VERSION); exit(0); - default: usage(); + default: + usage(); } } @@ -183,15 +226,15 @@ main (int argc, char **argv) { /* * Use an fd for the profiling buffer, to skip stdio overhead */ - if ( ((proFd=open(proFile,O_RDONLY)) < 0) + if (((proFd=open(proFile,O_RDONLY)) < 0) || ((int)(len=lseek(proFd,0,SEEK_END)) < 0) - || (lseek(proFd,0,SEEK_SET)<0) ) { + || (lseek(proFd,0,SEEK_SET) < 0)) { fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno)); exit(1); } - if ( !(buf=malloc(len)) ) { - fprintf(stderr,"%s: malloc(): %s\n",prgname, strerror(errno)); + if (!(buf=malloc(len))) { + fprintf(stderr,"%s: malloc(): %s\n", prgname, strerror(errno)); exit(1); } @@ -206,11 +249,12 @@ main (int argc, char **argv) { int big = 0,small = 0,i; unsigned *p; - for (p = buf+1; p < buf+entries; p++) - if (*p) { - if (*p >= 1 << (sizeof(*buf)/2)) big++; - else small++; - } + for (p = buf+1; p < buf+entries; p++) { + if (*p & ~0U << (sizeof(*buf)*4)) + big++; + if (*p & ((1 << (sizeof(*buf)*4))-1)) + small++; + } if (big > small) { fprintf(stderr,"Assuming reversed byte order. " "Use -n to force native byte order.\n"); @@ -226,16 +270,24 @@ main (int argc, char **argv) { } } - step=buf[0]; + step = buf[0]; if (optInfo) { - printf(_("Sampling_step: %i\n"),step); + printf(_("Sampling_step: %i\n"), step); exit(0); } - total=0; + total = 0; - if (!(map=myopen(mapFile,"r",&popenMap))) { - fprintf(stderr,"%s: ",prgname);perror(mapFile); + map = myopen(mapFile, "r", &popenMap); + if (map == NULL && mapFile == defaultmap) { + mapFile = boot_uname_r_str(); + map = myopen(mapFile, "r", &popenMap); + } + if (map == NULL) { + int errsv = errno; + fprintf(stderr, "%s: ", prgname); + errno = errsv; + perror(mapFile); exit(1); } @@ -273,7 +325,7 @@ main (int argc, char **argv) { /* ignore any LEADING (before a '[tT]' symbol is found) Absolute symbols */ - if (*mode == 'A' && total == 0) continue; + if ((*mode == 'A' || *mode == '?') && total == 0) continue; if (*mode != 'T' && *mode != 't' && *mode != 'W' && *mode != 'w') break; /* only text is profiled */ -- cgit v1.2.3-55-g7522