Add a "-f" flag for asf(8) which performs a search to find the each module

no matter where in the directory structure it may be.  Use this and the "-k"
flag in the generated gdbinit files so that the "getsyms" function in gdb
requires no user intervention to run and will find every module if they're
in the kernel build's module directory.  This is still quite useful for
cases where gdb knows that the path for some modules is /boot/kernel and
others are in the object directory for /usr/src/sys/$ARCH/compile/kernel.

Approved by:	grog
This commit is contained in:
Brian Feldman 2003-11-04 06:38:37 +00:00
parent a93efa3c97
commit afdc68c42f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122033
4 changed files with 130 additions and 27 deletions

View File

@ -57,7 +57,7 @@ install.debug reinstall.debug: gdbinit
gdbinit: gdbinit:
sed < ${S}/../tools/debugscripts/dot.gdbinit > .gdbinit \ sed < ${S}/../tools/debugscripts/dot.gdbinit > .gdbinit \
"s:MODPATH:modules${S}/modules:" "s:MODPATH:${.OBJDIR}/modules:"
cp ${S}/../tools/debugscripts/gdbinit.kernel \ cp ${S}/../tools/debugscripts/gdbinit.kernel \
${S}/../tools/debugscripts/gdbinit.vinum ${.CURDIR} ${S}/../tools/debugscripts/gdbinit.vinum ${.CURDIR}
cp ${S}/../tools/debugscripts/gdbinit.${MACHINE_ARCH} \ cp ${S}/../tools/debugscripts/gdbinit.${MACHINE_ARCH} \

View File

@ -16,11 +16,8 @@ end
# Get symbols from klds. This is a little fiddly, but very fast. # Get symbols from klds. This is a little fiddly, but very fast.
define getsyms define getsyms
kldstat
echo Select the list above with the mouse, paste into the screen\n
echo and then press ^D. Yes, this is annoying.\n
# This should be the path of the real modules directory. # This should be the path of the real modules directory.
shell asf MODPATH shell asf -f -k MODPATH
source .asf source .asf
end end

View File

@ -31,7 +31,7 @@
.Nd add symbol files .Nd add symbol files
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl aksx .Op Fl afksx
.Op Ar modules-path Op Ar outfile .Op Ar modules-path Op Ar outfile
.Sh DESCRIPTION .Sh DESCRIPTION
By default, By default,
@ -71,12 +71,19 @@ The following options modify the function of
When writing to an explicit When writing to an explicit
.Ar outfile , .Ar outfile ,
append to the file rather than overwriting it. append to the file rather than overwriting it.
.It Fl f
Instead of trying to simplistically guess the path for each module, perform
a traversal in the same way that
.Xr find 1
does to locate an exact path for each module, no matter where in
.Ar modules-path
it is located.
.It Fl k .It Fl k
Instead of reading from standard input, start a Instead of reading from standard input, start a
.Xr kldstat 8 .Xr kldstat 8
and read the information from it. and read the information from it.
.It Fl s .It Fl s
Don't prepend subdirectory of moudle path. Don't prepend a (guessed) subdirectory of the module path.
.It Fl x .It Fl x
Normally Normally
.Nm .Nm

View File

@ -37,6 +37,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/types.h> #include <sys/types.h>
#include <fts.h>
#include <unistd.h> #include <unistd.h>
#define MAXTOKEN 10 #define MAXTOKEN 10
@ -91,16 +92,83 @@ tokenize(char *cptr, char *token[], int maxtoken)
return maxtoken; /* can't get here */ return maxtoken; /* can't get here */
} }
static char *
findmodule(char *modules_path, const char *module_name)
{
char *const path_argv[2] = { modules_path, NULL };
char *module_path = NULL;
int module_name_len = strlen(module_name);
FTS *fts;
FTSENT *ftsent;
if (modules_path == NULL) {
fprintf(stderr,
"Can't allocate memory to traverse a path: %s (%d)\n",
strerror(errno),
errno);
exit(1);
}
fts = fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
if (fts == NULL) {
fprintf(stderr,
"Can't begin traversing path %s: %s (%d)\n",
modules_path,
strerror(errno),
errno);
exit(1);
}
while ((ftsent = fts_read(fts)) != NULL) {
if (ftsent->fts_info == FTS_DNR ||
ftsent->fts_info == FTS_ERR ||
ftsent->fts_info == FTS_NS) {
fprintf(stderr,
"Error while traversing path %s: %s (%d)\n",
modules_path,
strerror(errno),
errno);
exit(1);
}
if (ftsent->fts_info != FTS_F ||
ftsent->fts_namelen != module_name_len ||
memcmp(module_name, ftsent->fts_name, module_name_len) != 0)
continue;
if (asprintf(&module_path,
"%.*s",
ftsent->fts_pathlen,
ftsent->fts_path) == -1) {
fprintf(stderr,
"Can't allocate memory traversing path %s: %s (%d)\n",
modules_path,
strerror(errno),
errno);
exit(1);
}
break;
}
if (ftsent == NULL && errno != 0) {
fprintf(stderr,
"Couldn't complete traversing path %s: %s (%d)\n",
modules_path,
strerror(errno),
errno);
exit(1);
}
fts_close(fts);
free(modules_path);
return (module_path);
}
static void static void
usage(const char *myname) usage(const char *myname)
{ {
fprintf(stderr, fprintf(stderr,
"Usage:\n" "Usage:\n"
"%s [-a] [-k] [-t] [modules-path [outfile]]\n\n" "%s [-a] [-f] [-k] [-s] [-x] [modules-path [outfile]]\n\n"
"\t-a\tappend to outfile)\n" "\t-a\tappend to outfile)\n"
"\t-f\tfind the module in any subdirectory of module-path\n"
"\t-k\ttake input from kldstat(8)\n" "\t-k\ttake input from kldstat(8)\n"
"\t-s\tdon't prepend subdir for module path\n"
"\t-x\tdon't append \".debug\" to module name\n", "\t-x\tdon't append \".debug\" to module name\n",
"\t-s\tdon't prepend subdir for module path\n",
myname); myname);
} }
@ -120,6 +188,7 @@ main(int argc, char *argv[])
const char *debugname = ".debug"; /* some file names end in this */ const char *debugname = ".debug"; /* some file names end in this */
char *token[MAXTOKEN]; char *token[MAXTOKEN];
int nosubdir = 0; int nosubdir = 0;
int dofind = 0;
getcwd(cwd, MAXPATHLEN); /* find where we are */ getcwd(cwd, MAXPATHLEN); /* find where we are */
kldstat = stdin; kldstat = stdin;
@ -136,6 +205,8 @@ main(int argc, char *argv[])
debugname = ""; /* nothing */ debugname = ""; /* nothing */
else if (strcmp(argv[i], "-s") == 0) /* no subdir */ else if (strcmp(argv[i], "-s") == 0) /* no subdir */
nosubdir = 1; /* nothing */ nosubdir = 1; /* nothing */
else if (strcmp(argv[i], "-f") == 0) /* find .ko (recursively) */
dofind = 1;
else { else {
fprintf(stderr, fprintf(stderr,
"Invalid option: %s, aborting\n", "Invalid option: %s, aborting\n",
@ -177,16 +248,30 @@ main(int argc, char *argv[])
tokens = tokenize(buf, token, MAXTOKEN); tokens = tokenize(buf, token, MAXTOKEN);
base = strtoll(token[2], NULL, 16); base = strtoll(token[2], NULL, 16);
strcpy(basetoken, token[4]); if (!dofind) {
basetoken[strlen(basetoken) - 3] = '/'; strcpy(basetoken, token[4]);
basetoken[strlen(basetoken) - 2] = '\0'; /* cut off the .ko */ basetoken[strlen(basetoken) - 3] = '/';
snprintf(ocbuf, basetoken[strlen(basetoken) - 2] = '\0'; /* cut off the .ko */
MAXLINE, snprintf(ocbuf,
"/usr/bin/objdump --section-headers %s/%s%s%s", MAXLINE,
modules_path, "/usr/bin/objdump --section-headers %s/%s%s%s",
nosubdir ? "" : basetoken, modules_path,
token[4], nosubdir ? "" : basetoken,
debugname); token[4],
debugname);
} else {
char *modpath;
modpath = findmodule(strdup(modules_path), token[4]);
if (modpath == NULL)
continue;
snprintf(ocbuf,
MAXLINE,
"/usr/bin/objdump --section-headers %s%s",
modpath,
debugname);
free(modpath);
}
if (!(objcopy = popen(ocbuf, "r"))) { if (!(objcopy = popen(ocbuf, "r"))) {
fprintf(stderr, fprintf(stderr,
"Can't start %s: %s (%d)\n", "Can't start %s: %s (%d)\n",
@ -210,14 +295,28 @@ main(int argc, char *argv[])
} }
} }
if (textaddr) { /* we must have a text address */ if (textaddr) { /* we must have a text address */
fprintf(out, if (!dofind) {
"add-symbol-file %s/%s/%s%s%s 0x%llx", fprintf(out,
cwd, "add-symbol-file %s/%s/%s%s%s 0x%llx",
modules_path, cwd,
nosubdir ? "" : basetoken, modules_path,
token[4], nosubdir ? "" : basetoken,
debugname, token[4],
textaddr); debugname,
textaddr);
} else {
char *modpath;
modpath = findmodule(strdup(modules_path), token[4]);
if (modpath == NULL)
continue;
fprintf(out,
"add-symbol-file %s%s 0x%llx",
modpath,
debugname,
textaddr);
free(modpath);
}
if (dataaddr) if (dataaddr)
fprintf(out, " -s .data 0x%llx", dataaddr); fprintf(out, " -s .data 0x%llx", dataaddr);
if (bssaddr) if (bssaddr)