* Copyright (c) 1983 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)kgmon.c 5.9 (Berkeley) %G%";
off_t sbuf
, klseek(), lseek();
int bflag
, hflag
, kflag
, rflag
, pflag
;
int ch
, mode
, disp
, openmode
;
char *system
, *kmemf
, *malloc();
while ((ch
= getopt(argc
, argv
, "bhpr")) != EOF
)
"usage: kgmon [-bhrp] [system [core]]\n");
if (nlist(system
, nl
) < 0 || nl
[0].n_type
== 0) {
(void)fprintf(stderr
, "kgmon: %s: no namelist\n", system
);
if (!nl
[N_PROFILING
].n_value
) {
"kgmon: profiling: not defined in kernel.\n");
openmode
= (bflag
|| hflag
|| pflag
|| rflag
) ? O_RDWR
: O_RDONLY
;
kmem
= open(kmemf
, openmode
);
kmem
= open(kmemf
, openmode
);
(void)fprintf(stderr
, "%s opened read-only\n", kmemf
);
(void)fprintf(stderr
, "-r supressed\n");
(void)fprintf(stderr
, "-b supressed\n");
(void)fprintf(stderr
, "-h supressed\n");
rflag
= bflag
= hflag
= 0;
malloc((u_int
)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
"kgmon: can't get memory for Sysmap.\n");
off
= nl
[N_SYSMAP
].n_value
& ~KERNBASE
;
(void)lseek(kmem
, off
, L_SET
);
(void)read(kmem
, (char *)Sysmap
,
(int)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
mode
= kfetch(N_PROFILING
);
if (openmode
== O_RDONLY
&& mode
== PROFILING_ON
)
(void)fprintf(stderr
, "data may be inconsistent\n");
"kernel profiling is %s.\n", disp
? "off" : "running");
u_short
*froms
; /* froms is a bunch of u_shorts indexing tos */
int i
, fd
, fromindex
, endfrom
, fromssize
, tossize
, toindex
;
char buf
[BUFSIZ
], *s_lowpc
, *malloc(), *strerror();
turnonoff(PROFILING_OFF
);
fd
= creat("gmon.out", 0666);
(void)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((u_int
)fromssize
);
kfroms
= kfetch(N_FROMS
);
(void)klseek(kmem
, kfroms
, L_SET
);
i
= read(kmem
, ((char *)(froms
)), fromssize
);
(void)fprintf(stderr
, "read kmem: request %d, got %d: %s",
fromssize
, i
, strerror(errno
));
tossize
= (s_textsize
* ARCDENSITY
/ 100) * sizeof(struct tostruct
);
tos
= (struct tostruct
*)malloc((u_int
)tossize
);
(void)klseek(kmem
, ktos
, L_SET
);
i
= read(kmem
, ((char *)(tos
)), tossize
);
(void)fprintf(stderr
, "read kmem: request %d, got %d: %s",
tossize
, i
, strerror(errno
));
s_lowpc
= (char *)kfetch(N_S_LOWPC
);
(void)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
, (char *)&rawarc
, sizeof (rawarc
));
int i
, fromssize
, tossize
;
turnonoff(PROFILING_OFF
);
ssiz
-= sizeof(struct phdr
);
sbuf
+= sizeof(struct phdr
);
(void)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
);
(void)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
);
(void)klseek(kmem
, ktos
, L_SET
);
for (i
= tossize
; i
> 0; i
-= BUFSIZ
)
if (write(kmem
, buf
, i
< BUFSIZ
? i
: BUFSIZ
) < 0) {
(void)klseek(kmem
, (long)nl
[N_PROFILING
].n_value
, L_SET
);
(void)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
)) {
if (kflag
) { /* get kernel pte */
base
= ctob(Sysmap
[btop(base
)].pg_pfnum
) + (base
& PGOFSET
);
return (lseek(fd
, base
, off
));