Add -K support to gprof(1), which enables dynamic symbol resolution from
the currently-running kernel (and supercedes an executable file argument given). With this change, properly-compiled KLD modules are now able to be profiled. Obtained from: NAI Labs CBOSS project Funded by: DARPA
This commit is contained in:
parent
a296c021c2
commit
3fc980b135
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85739
@ -1,8 +1,9 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/29/93
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= gprof
|
||||
SRCS= gprof.c aout.c arcs.c dfn.c elf.c lookup.c ${MACHINE_ARCH}.c hertz.c \
|
||||
printgprof.c printlist.c
|
||||
printgprof.c printlist.c kernel.c
|
||||
|
||||
beforeinstall:
|
||||
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
|
@ -208,6 +208,17 @@ option may be given.
|
||||
Only one pair of routine names may be given with each
|
||||
.Fl k
|
||||
option.
|
||||
.It Fl K
|
||||
Gather information about symbols from the currently-running kernel using the
|
||||
.Xr sysctl 3
|
||||
and
|
||||
.Xr kldsym 2
|
||||
interfaces.
|
||||
This forces the
|
||||
.Pa a.out
|
||||
argument to be ignored, and allows for symbols in
|
||||
.Xr kld 4
|
||||
modules to be used.
|
||||
.It Fl l
|
||||
Suppresses the printing of the call-graph profile.
|
||||
.It Fl L
|
||||
|
@ -125,6 +125,9 @@ main(argc, argv)
|
||||
addlist( ktolist , *++argv );
|
||||
kflag = TRUE;
|
||||
break;
|
||||
case 'K':
|
||||
Kflag = TRUE;
|
||||
break;
|
||||
case 'l':
|
||||
lflag = 1;
|
||||
Lflag = 0;
|
||||
@ -162,8 +165,9 @@ main(argc, argv)
|
||||
/*
|
||||
* get information from the executable file.
|
||||
*/
|
||||
if (elf_getnfile(a_outname, &defaultEs) == -1 &&
|
||||
aout_getnfile(a_outname, &defaultEs) == -1)
|
||||
if ((Kflag && kernel_getnfile(a_outname, &defaultEs) == -1) ||
|
||||
(elf_getnfile(a_outname, &defaultEs) == -1 &&
|
||||
aout_getnfile(a_outname, &defaultEs) == -1))
|
||||
errx(1, "%s: bad format", a_outname);
|
||||
/*
|
||||
* sort symbol table.
|
||||
|
@ -238,6 +238,7 @@ bool Eflag; /* functions excluded with time */
|
||||
bool fflag; /* specific functions requested */
|
||||
bool Fflag; /* functions requested with time */
|
||||
bool kflag; /* arcs to be deleted */
|
||||
bool Kflag; /* use the running kernel for symbols */
|
||||
bool sflag; /* sum multiple gmon.out files */
|
||||
bool uflag; /* suppress symbols hidden from C */
|
||||
bool zflag; /* zero time/called functions, too */
|
||||
@ -295,6 +296,9 @@ int elf_getnfile(const char *, char ***);
|
||||
getpfile();
|
||||
gprofheader();
|
||||
gprofline();
|
||||
*/
|
||||
int kernel_getnfile(const char *, char ***);
|
||||
/*
|
||||
main();
|
||||
*/
|
||||
unsigned long max();
|
||||
|
64
usr.bin/gprof/kernel.c
Normal file
64
usr.bin/gprof/kernel.c
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gprof.h"
|
||||
|
||||
/* Things which get -E excluded by default. */
|
||||
static char *excludes[] = { ".mcount", "_mcleanup", NULL };
|
||||
|
||||
int
|
||||
kernel_getnfile(const char *unused, char ***defaultEs)
|
||||
{
|
||||
char *namelist;
|
||||
size_t len;
|
||||
char *name;
|
||||
|
||||
if (sysctlbyname("kern.function_list", NULL, &len, NULL, 0) == -1)
|
||||
err(1, "sysctlbyname: function_list size");
|
||||
for (;;) {
|
||||
namelist = malloc(len);
|
||||
if (namelist == NULL)
|
||||
err(1, "malloc");
|
||||
if (sysctlbyname("kern.function_list", namelist, &len, NULL,
|
||||
0) == 0)
|
||||
break;
|
||||
if (errno == ENOMEM)
|
||||
free(namelist);
|
||||
else
|
||||
err(1, "sysctlbyname: function_list");
|
||||
}
|
||||
nname = 0;
|
||||
for (name = namelist; *name != '\0'; name += strlen(name) + 1)
|
||||
nname++;
|
||||
/* Allocate memory for them, plus a terminating entry. */
|
||||
if ((nl = (nltype *)calloc(nname + 1, sizeof(nltype))) == NULL)
|
||||
errx(1, "Insufficient memory for symbol table");
|
||||
npe = nl;
|
||||
for (name = namelist; *name != '\0'; name += strlen(name) + 1) {
|
||||
struct kld_sym_lookup ksl;
|
||||
|
||||
ksl.version = sizeof(ksl);
|
||||
ksl.symname = name;
|
||||
if (kldsym(0, KLDSYM_LOOKUP, &ksl))
|
||||
err(1, "kldsym(%s)", name);
|
||||
/* aflag not supported */
|
||||
if (uflag && strchr(name, '.') != NULL)
|
||||
continue;
|
||||
npe->value = ksl.symvalue;
|
||||
npe->name = name;
|
||||
npe++;
|
||||
}
|
||||
npe->value = -1;
|
||||
|
||||
*defaultEs = excludes;
|
||||
}
|
@ -3,11 +3,12 @@
|
||||
# beforeinstall.
|
||||
|
||||
# @(#)Makefile 5.17 (Berkeley) 5/11/90
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= gprof4
|
||||
NOMAN= noman
|
||||
SRCS= gprof.c aout.c arcs.c dfn.c elf.c lookup.c ${MACHINE_ARCH}.c hertz.c \
|
||||
printgprof.c printlist.c
|
||||
printgprof.c printlist.c kernel.c
|
||||
CFLAGS+=-DGPROF4
|
||||
.PATH: ${.CURDIR}/../../usr.bin/gprof
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user