8 |
*/ |
*/ |
9 |
|
|
10 |
/* |
/* |
11 |
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> |
* 1999-02-22 Arkadiusz Mickiewicz <misiek@pld.ORG.PL> |
12 |
* - added Native Language Support |
* - added Native Language Support |
13 |
* 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com> |
* 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com> |
14 |
* - 64bit clean patch |
* - 64bit clean patch |
32 |
* Paul Mundt <lethal@linux-sh.org>. |
* Paul Mundt <lethal@linux-sh.org>. |
33 |
*/ |
*/ |
34 |
|
|
35 |
#include "busybox.h" |
#include "libbb.h" |
36 |
#include <sys/utsname.h> |
#include <sys/utsname.h> |
37 |
|
|
38 |
#define S_LEN 128 |
#define S_LEN 128 |
39 |
|
|
40 |
/* These are the defaults */ |
/* These are the defaults */ |
41 |
static const char defaultmap[] = "/boot/System.map"; |
static const char defaultmap[] ALIGN1 = "/boot/System.map"; |
42 |
static const char defaultpro[] = "/proc/profile"; |
static const char defaultpro[] ALIGN1 = "/proc/profile"; |
43 |
|
|
44 |
int readprofile_main(int argc, char **argv) |
int readprofile_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
45 |
|
int readprofile_main(int argc UNUSED_PARAM, char **argv) |
46 |
{ |
{ |
47 |
FILE *map; |
FILE *map; |
48 |
const char *mapFile, *proFile, *mult = 0; |
const char *mapFile, *proFile; |
49 |
unsigned long indx = 1; |
unsigned long indx = 1; |
50 |
size_t len; |
size_t len; |
51 |
uint64_t add0 = 0; |
uint64_t add0 = 0; |
55 |
char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */ |
char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */ |
56 |
char mapline[S_LEN]; |
char mapline[S_LEN]; |
57 |
char mode[8]; |
char mode[8]; |
|
int optAll = 0, optInfo = 0, optReset = 0; |
|
|
int optVerbose = 0, optNative = 0; |
|
|
int optBins = 0, optSub = 0; |
|
58 |
int maplineno = 1; |
int maplineno = 1; |
59 |
int header_printed; |
int header_printed; |
60 |
|
int multiplier = 0; |
61 |
|
unsigned opt; |
62 |
|
enum { |
63 |
|
OPT_M = (1 << 0), |
64 |
|
OPT_m = (1 << 1), |
65 |
|
OPT_p = (1 << 2), |
66 |
|
OPT_n = (1 << 3), |
67 |
|
OPT_a = (1 << 4), |
68 |
|
OPT_b = (1 << 5), |
69 |
|
OPT_s = (1 << 6), |
70 |
|
OPT_i = (1 << 7), |
71 |
|
OPT_r = (1 << 8), |
72 |
|
OPT_v = (1 << 9), |
73 |
|
}; |
74 |
|
#define optMult (opt & OPT_M) |
75 |
|
#define optNative (opt & OPT_n) |
76 |
|
#define optAll (opt & OPT_a) |
77 |
|
#define optBins (opt & OPT_b) |
78 |
|
#define optSub (opt & OPT_s) |
79 |
|
#define optInfo (opt & OPT_i) |
80 |
|
#define optReset (opt & OPT_r) |
81 |
|
#define optVerbose (opt & OPT_v) |
82 |
|
|
83 |
#define next (current^1) |
#define next (current^1) |
84 |
|
|
85 |
proFile = defaultpro; |
proFile = defaultpro; |
86 |
mapFile = defaultmap; |
mapFile = defaultmap; |
87 |
|
|
88 |
opt_complementary = "nn:aa:bb:ss:ii:rr:vv"; |
opt_complementary = "M+"; /* -M N */ |
89 |
getopt32(argc, argv, "M:m:p:nabsirv", |
opt = getopt32(argv, "M:m:p:nabsirv", &multiplier, &mapFile, &proFile); |
|
&mult, &mapFile, &proFile, |
|
|
&optNative, &optAll, &optBins, &optSub, |
|
|
&optInfo, &optReset, &optVerbose); |
|
90 |
|
|
91 |
if (optReset || mult) { |
if (opt & (OPT_M|OPT_r)) { /* mult or reset, or both */ |
92 |
int multiplier, fd, to_write; |
int fd, to_write; |
93 |
|
|
94 |
/* |
/* |
95 |
* When writing the multiplier, if the length of the write is |
* When writing the multiplier, if the length of the write is |
96 |
* not sizeof(int), the multiplier is not changed |
* not sizeof(int), the multiplier is not changed |
97 |
*/ |
*/ |
98 |
if (mult) { |
to_write = sizeof(int); |
99 |
multiplier = xatoi_u(mult); |
if (!optMult) |
|
to_write = sizeof(int); |
|
|
} else { |
|
|
multiplier = 0; |
|
100 |
to_write = 1; /* sth different from sizeof(int) */ |
to_write = 1; /* sth different from sizeof(int) */ |
|
} |
|
101 |
|
|
102 |
fd = xopen(defaultpro, O_WRONLY); |
fd = xopen(defaultpro, O_WRONLY); |
103 |
|
xwrite(fd, &multiplier, to_write); |
|
if (full_write(fd, &multiplier, to_write) != to_write) |
|
|
bb_perror_msg_and_die("error writing %s", defaultpro); |
|
|
|
|
104 |
close(fd); |
close(fd); |
105 |
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
106 |
} |
} |
108 |
/* |
/* |
109 |
* Use an fd for the profiling buffer, to skip stdio overhead |
* Use an fd for the profiling buffer, to skip stdio overhead |
110 |
*/ |
*/ |
111 |
len = INT_MAX; |
len = MAXINT(ssize_t); |
112 |
buf = xmalloc_open_read_close(proFile, &len); |
buf = xmalloc_xopen_read_close(proFile, &len); |
113 |
if (!optNative) { |
if (!optNative) { |
114 |
int entries = len/sizeof(*buf); |
int entries = len / sizeof(*buf); |
115 |
int big = 0, small = 0, i; |
int big = 0, small = 0, i; |
116 |
unsigned *p; |
unsigned *p; |
117 |
|
|
144 |
|
|
145 |
total = 0; |
total = 0; |
146 |
|
|
147 |
map = xfopen(mapFile, "r"); |
map = xfopen_for_read(mapFile); |
148 |
|
|
149 |
while (fgets(mapline, S_LEN, map)) { |
while (fgets(mapline, S_LEN, map)) { |
150 |
if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3) |
if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3) |
199 |
if (optBins) { |
if (optBins) { |
200 |
if (optVerbose || this > 0) |
if (optVerbose || this > 0) |
201 |
printf(" total\t\t\t\t%u\n", this); |
printf(" total\t\t\t\t%u\n", this); |
202 |
} else if ((this || optAll) && |
} else if ((this || optAll) |
203 |
(fn_len = next_add-fn_add) != 0) { |
&& (fn_len = next_add-fn_add) != 0 |
204 |
|
) { |
205 |
if (optVerbose) |
if (optVerbose) |
206 |
printf("%016llx %-40s %6i %8.4f\n", fn_add, |
printf("%016llx %-40s %6i %8.4f\n", fn_add, |
207 |
fn_name, this, this/(double)fn_len); |
fn_name, this, this/(double)fn_len); |