* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)kgmon.c 5.3 (Berkeley) %G%";
* froms is actually a bunch of unsigned shorts indexing tos
#define clear(x) ((x) &~ 0x80000000)
#define clear(x) ((x) &~ 0xc0000000)
char *system
= "/vmunix";
char *kmemf
= "/dev/kmem";
int bflag
, hflag
, kflag
, rflag
, pflag
;
int mode
, disp
, openmode
= O_RDONLY
;
while (argc
> 0 && argv
[0][0] == '-') {
printf("Usage: kgmon [ -b -h -r -p system memory ]\n");
fprintf(stderr
, "%s: no namelist\n", system
);
kmem
= open(kmemf
, openmode
);
kmem
= open(kmemf
, openmode
);
fprintf(stderr
, "cannot open ");
fprintf(stderr
, "%s opened read-only\n", kmemf
);
fprintf(stderr
, "-r supressed\n");
fprintf(stderr
, "-b supressed\n");
fprintf(stderr
, "-h supressed\n");
off
= clear(nl
[N_SYSMAP
].n_value
);
nl
[N_SYSSIZE
].n_value
*= 4;
Sysmap
= (struct pte
*)malloc(nl
[N_SYSSIZE
].n_value
);
read(kmem
, Sysmap
, nl
[N_SYSSIZE
].n_value
);
mode
= kfetch(N_PROFILING
);
if (openmode
== O_RDONLY
&& mode
== PROFILING_ON
)
fprintf(stderr
, "data may be inconsistent\n");
fprintf(stdout
, "kernel profiling is %s.\n", disp
? "off" : "running");
int fromindex
, endfrom
, fromssize
, tossize
;
turnonoff(PROFILING_OFF
);
fd
= creat("gmon.out", 0666);
klseek(kmem
, (off_t
)sbuf
, L_SET
);
for (i
= ssiz
; i
> 0; i
-= BUFSIZ
) {
read(kmem
, buf
, i
< BUFSIZ
? i
: BUFSIZ
);
write(fd
, buf
, i
< BUFSIZ
? i
: BUFSIZ
);
s_textsize
= kfetch(N_S_TEXTSIZE
);
fromssize
= s_textsize
/ HASHFRACTION
;
froms
= (u_short
*)malloc(fromssize
);
kfroms
= kfetch(N_FROMS
);
klseek(kmem
, kfroms
, L_SET
);
i
= read(kmem
, ((char *)(froms
)), fromssize
);
fprintf(stderr
, "read froms: request %d, got %d", fromssize
, i
);
tossize
= (s_textsize
* ARCDENSITY
/ 100) * sizeof(struct tostruct
);
tos
= (struct tostruct
*)malloc(tossize
);
klseek(kmem
, ktos
, L_SET
);
i
= read(kmem
, ((char *)(tos
)), tossize
);
fprintf(stderr
, "read tos: request %d, got %d", tossize
, i
);
s_lowpc
= (char *)kfetch(N_S_LOWPC
);
fprintf(stderr
, "s_lowpc 0x%x, s_textsize 0x%x\n",
endfrom
= fromssize
/ sizeof(*froms
);
for (fromindex
= 0; fromindex
< endfrom
; fromindex
++) {
if (froms
[fromindex
] == 0)
frompc
= (u_long
)s_lowpc
+
(fromindex
* HASHFRACTION
* sizeof(*froms
));
for (toindex
= froms
[fromindex
]; toindex
!= 0;
toindex
= tos
[toindex
].link
) {
"[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" ,
frompc
, tos
[toindex
].selfpc
, tos
[toindex
].count
);
rawarc
.raw_frompc
= frompc
;
rawarc
.raw_selfpc
= (u_long
)tos
[toindex
].selfpc
;
rawarc
.raw_count
= tos
[toindex
].count
;
write(fd
, &rawarc
, sizeof (rawarc
));
turnonoff(PROFILING_OFF
);
ssiz
-= sizeof(struct phdr
);
sbuf
+= sizeof(struct phdr
);
klseek(kmem
, (off_t
)sbuf
, L_SET
);
for (i
= ssiz
; i
> 0; i
-= BUFSIZ
)
if (write(kmem
, buf
, i
< BUFSIZ
? i
: BUFSIZ
) < 0) {
s_textsize
= kfetch(N_S_TEXTSIZE
);
fromssize
= s_textsize
/ HASHFRACTION
;
kfroms
= kfetch(N_FROMS
);
klseek(kmem
, kfroms
, L_SET
);
for (i
= fromssize
; i
> 0; i
-= BUFSIZ
)
if (write(kmem
, buf
, i
< BUFSIZ
? i
: BUFSIZ
) < 0) {
tossize
= (s_textsize
* ARCDENSITY
/ 100) * sizeof(struct tostruct
);
klseek(kmem
, ktos
, L_SET
);
for (i
= tossize
; i
> 0; i
-= BUFSIZ
)
if (write(kmem
, buf
, i
< BUFSIZ
? i
: BUFSIZ
) < 0) {
if ((off
= nl
[N_PROFILING
].n_value
) == 0) {
printf("profiling: not defined in kernel\n");
klseek(kmem
, off
, L_SET
);
write(kmem
, (char *)&onoff
, sizeof (onoff
));
if ((off
= nl
[index
].n_value
) == 0) {
printf("%s: not defined in kernel\n", nl
[index
].n_name
);
if (klseek(kmem
, off
, L_SET
) == -1) {
if (read(kmem
, (char *)&value
, sizeof (value
)) != sizeof (value
)) {
base
= ((int)ptob(Sysmap
[btop(base
)].pg_pfnum
))+(base
&(NBPG
-1));
return (lseek(fd
, base
, off
));