]> git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/readprofile.c
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / sys-utils / readprofile.c
1 /*
2 * readprofile.c - used to read /proc/profile
3 *
4 * Copyright (C) 1994,1996 Alessandro Rubini (rubini@ipvvis.unipv.it)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*
22 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
23 * - added Native Language Support
24 * 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com>
25 * - 64bit clean patch
26 */
27
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include "nls.h"
37
38 #define RELEASE "2.0, May 1996"
39
40 #define S_LEN 128
41
42 static char *prgname;
43
44 /* These are the defaults */
45 static char defaultmap[]="/usr/src/linux/System.map";
46 static char defaultpro[]="/proc/profile";
47 static char optstring[]="m:p:itvarV";
48
49 static void
50 usage(void) {
51 fprintf(stderr,
52 _("%s: Usage: \"%s [options]\n"
53 "\t -m <mapfile> (default = \"%s\")\n"
54 "\t -p <pro-file> (default = \"%s\")\n"
55 "\t -i print only info about the sampling step\n"
56 "\t -v print verbose data\n"
57 "\t -a print all symbols, even if count is 0\n"
58 "\t -r reset all the counters (root only)\n"
59 "\t -V print version and exit\n")
60 ,prgname,prgname,defaultmap,defaultpro);
61 exit(1);
62 }
63
64 static FILE *
65 myopen(char *name, char *mode, int *flag) {
66 static char cmdline[S_LEN];
67
68 if (!strcmp(name+strlen(name)-3,".gz"))
69 {
70 *flag=1;
71 sprintf(cmdline,"zcat %s", name);
72 return popen(cmdline,mode);
73 }
74 *flag=0;
75 return fopen(name,mode);
76 }
77
78 int
79 main (int argc, char **argv) {
80 FILE *pro;
81 FILE *map;
82 int proFd;
83 char *mapFile, *proFile;
84 unsigned long len=0, add0=0, indx=0;
85 unsigned int step;
86 unsigned int *buf, total, fn_len;
87 unsigned long fn_add, next_add; /* current and next address */
88 char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */
89 char mode[8];
90 int c;
91 int optAll=0, optInfo=0, optReset=0, optVerbose=0;
92 char mapline[S_LEN];
93 int maplineno=1;
94 int popenMap; /* flag to tell if popen() has been used */
95
96 #define next (current^1)
97
98 setlocale(LC_ALL, "");
99 bindtextdomain(PACKAGE, LOCALEDIR);
100 textdomain(PACKAGE);
101
102 prgname=argv[0];
103 proFile=defaultpro;
104 mapFile=defaultmap;
105
106 while ((c=getopt(argc,argv,optstring))!=-1)
107 {
108 switch(c)
109 {
110 case 'm': mapFile=optarg; break;
111 case 'p': proFile=optarg; break;
112 case 'a': optAll++; break;
113 case 'i': optInfo++; break;
114 case 'r': optReset++; break;
115 case 'v': optVerbose++; break;
116 case 'V': printf(_("%s Version %s\n"),prgname,RELEASE); exit(0);
117 default: usage();
118 }
119 }
120
121 if (optReset)
122 {
123 /* try to become root, just in case */
124 setuid(0);
125 pro=fopen(defaultpro,"w");
126 if (!pro)
127 {perror(proFile); exit(1);}
128 fprintf(pro,_("anything\n"));
129 fclose(pro);
130 exit(0);
131 }
132
133 /*
134 * Use an fd for the profiling buffer, to skip stdio overhead
135 */
136 if ( ((proFd=open(proFile,O_RDONLY)) < 0)
137 || ((int)(len=lseek(proFd,0,SEEK_END)) < 0)
138 || (lseek(proFd,0,SEEK_SET)<0) )
139 {
140 fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
141 exit(1);
142 }
143
144 if ( !(buf=malloc(len)) )
145 { fprintf(stderr,"%s: malloc(): %s\n",prgname, strerror(errno)); exit(1); }
146
147 if (read(proFd,buf,len) != len)
148 {
149 fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
150 exit(1);
151 }
152 close(proFd);
153
154 step=buf[0];
155 if (optInfo)
156 {
157 printf(_("Sampling_step: %i\n"),step);
158 exit(0);
159 }
160
161 total=0;
162
163 if (!(map=myopen(mapFile,"r",&popenMap)))
164 {fprintf(stderr,"%s: ",prgname);perror(mapFile);exit(1);}
165
166 while(fgets(mapline,S_LEN,map))
167 {
168 if (sscanf(mapline,"%lx %s %s",&fn_add,mode,fn_name)!=3)
169 {
170 fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
171 prgname,mapFile, maplineno);
172 exit(1);
173 }
174 if (!strcmp(fn_name,"_stext")) /* only elf works like this */
175 {
176 add0=fn_add;
177 break;
178 }
179 }
180
181 if (!add0)
182 {
183 fprintf(stderr,_("%s: can't find \"_stext\" in %s\n"),prgname, mapFile);
184 exit(1);
185 }
186
187 /*
188 * Main loop.
189 */
190 while(fgets(mapline,S_LEN,map))
191 {
192 unsigned int this=0;
193
194 if (sscanf(mapline,"%lx %s %s",&next_add,mode,next_name)!=3)
195 {
196 fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
197 prgname,mapFile, maplineno);
198 exit(1);
199 }
200 /* ignore any LEADING (before a '[tT]' symbol is found) Absolute symbols */
201 if (*mode == 'A' && total == 0) continue;
202 if (*mode!='T' && *mode!='t') break; /* only text is profiled */
203
204 while (indx < (next_add-add0)/step)
205 this += buf[indx++];
206 total += this;
207
208 fn_len = next_add-fn_add;
209 if (fn_len && (this || optAll))
210 {
211 if (optVerbose)
212 printf("%08lx %-40s %6i %8.4f\n",
213 fn_add,fn_name,this,this/(double)fn_len);
214 else
215 printf("%6i %-40s %8.4f\n",
216 this,fn_name,this/(double)fn_len);
217 }
218 fn_add=next_add; strcpy(fn_name,next_name);
219 }
220 /* trailer */
221 if (optVerbose)
222 printf("%08x %-40s %6i %8.4f\n",
223 0,"total",total,total/(double)(fn_add-add0));
224 else
225 printf("%6i %-40s %8.4f\n",
226 total,_("total"),total/(double)(fn_add-add0));
227
228 popenMap ? pclose(map) : fclose(map);
229 exit(0);
230 }
231
232
233