Allow for module-path being a semicolon-separated list of dirs.
  This is consistent with kern.module_path sysctl and also compensates
  for the unconventional syntax of asf(8) where the last of multiple
  arguments is the output file, which prevents us from using the
  traditional Unix syntax "foo file ..." to specify multiple module
  dirs.

	asf.c	rev. 1.12
	asf.8	rev. 1.11
This commit is contained in:
yar 2006-12-27 06:22:44 +00:00
parent 60f4db4b7e
commit 880ddd5484
2 changed files with 64 additions and 43 deletions

View File

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 18, 2006
.Dd December 20, 2006
.Os
.Dt ASF 8
.Sh NAME
@ -53,16 +53,16 @@ This allows
.Xr gdb 1
to load the symbols into the debugging environment.
.Pp
If
An optional
.Ar modules-path
is specified,
.Nm
uses it for the modules directory instead of the default
.Pa modules .
This is useful when building in a non-standard location (i.e., not
.Pa /usr/src
and
.Pa /usr/obj ) .
argument can specify a semicolon-separated list of directory pathnames
similar to the
.Va kern.module_path
sysctl.
Each directory in the list will be searched in turn for modules.
The default list consists of just one element,
.Pa modules ,
which is suitable if the current directory is a kernel build directory.
.Pp
If
.Ar outfile
@ -152,11 +152,18 @@ Clear the list of suffixes
tries to append to KLD file names.
Only the null suffix is left in the list.
.El
.Sh EXAMPLES
To add symbol files from the system search path specified by the
.Va kern.module_path
sysctl, the following command can be used:
.Pp
.Dl asf -s `sysctl -n kern.module_path`
.Sh SEE ALSO
.Xr gdb 1 ,
.Xr kvm 3 ,
.Xr kld 4 ,
.Xr kldstat 8
.Xr kldstat 8 ,
.Xr sysctl 8
.Sh HISTORY
The
.Nm

View File

@ -186,9 +186,8 @@ doobj(const char *path, caddr_t addr, FILE *out)
}
static void
findmodules(const char *modules_path, const char *sfx[], FILE *out)
findmodules(char *path_argv[], const char *sfx[], FILE *out)
{
char *path_argv[2];
char *p;
FTS *fts;
FTSENT *ftsent;
@ -196,17 +195,12 @@ findmodules(const char *modules_path, const char *sfx[], FILE *out)
int i;
int sl;
/* Have to copy modules_path here because it's const */
if ((path_argv[0] = strdup(modules_path)) == NULL)
errx(2, "out of memory");
path_argv[1] = NULL;
/* Have to fts once per suffix to find preferred suffixes first */
do {
sl = *sfx ? strlen(*sfx) : 0; /* current suffix length */
fts = fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
if (fts == NULL)
err(2, "can't begin traversing path %s", modules_path);
err(2, "can't begin traversing module path");
while ((ftsent = fts_read(fts)) != NULL) {
if (ftsent->fts_info == FTS_DNR ||
ftsent->fts_info == FTS_ERR ||
@ -236,16 +230,14 @@ findmodules(const char *modules_path, const char *sfx[], FILE *out)
/* Optimization: stop fts as soon as seen all loaded modules */
if (kfile_allseen()) {
fts_close(fts);
goto done;
return;
}
}
}
if (ftsent == NULL && errno != 0)
err(2, "couldn't complete traversing path %s", modules_path);
err(2, "couldn't complete traversing module path");
fts_close(fts);
} while (*sfx++);
done:
free(path_argv[0]);
}
static void
@ -270,6 +262,7 @@ usage(const char *myname)
exit(2);
}
#define MAXPATHS 15
#define MAXSUFFIXES 15
/* KLD file names end in this */
@ -285,6 +278,9 @@ main(int argc, char *argv[])
{
char basename[PATH_MAX];
char path[PATH_MAX];
char *modules_argv[MAXPATHS + 1];
char *copy, *p;
char **ap;
const char *filemode = "w"; /* mode for outfile */
const char *modules_path = "modules"; /* path to kernel build directory */
const char *outfile = ".asf"; /* and where to write the output */
@ -382,32 +378,50 @@ main(int argc, char *argv[])
return (0);
}
if ((copy = strdup(modules_path)) == NULL)
errx(2, "out of memory");
for (
ap = modules_argv, p = copy;
(*ap = strsep(&p, ";")) != NULL && ap < &modules_argv[MAXPATHS];
ap++
);
if (*ap)
errx(2, "only %d module path elements can be specified", MAXPATHS);
if (!dofind)
STAILQ_FOREACH(kfp, &kfile_head, link) {
if (!nosubdir) {
/* prepare basename of KLD, w/o suffix */
strlcpy(basename, kfp->name, sizeof(basename) - 1);
i = strlen(basename);
if (i > sl && strcmp(basename + i - sl, KLDSUFFIX) == 0)
i -= sl;
basename[i] = '/';
basename[i + 1] = '\0';
}
for (sfx = suffixes;; sfx++) {
snprintf(path, sizeof(path),
"%s/%s%s%s",
modules_path,
nosubdir ? "" : basename,
kfp->name,
*sfx ? *sfx : "");
if (*sfx == NULL || stat(path, &st) == 0) {
doobj(path, kfp->addr, out);
break;
for (ap = modules_argv; *ap; ap++) {
if (!nosubdir) {
/* prepare basename of KLD, w/o suffix */
strlcpy(basename, kfp->name, sizeof(basename) - 1);
i = strlen(basename);
if (i > sl && strcmp(basename + i - sl, KLDSUFFIX) == 0)
i -= sl;
basename[i] = '/';
basename[i + 1] = '\0';
}
for (sfx = suffixes;; sfx++) {
snprintf(path, sizeof(path),
"%s/%s%s%s",
*ap,
nosubdir ? "" : basename,
kfp->name,
*sfx ? *sfx : "");
if (stat(path, &st) == 0) {
doobj(path, kfp->addr, out);
goto found;
}
if (*sfx == NULL)
break;
}
}
warnx("module %s not found in search path", kfp->name);
found:
;
}
else
findmodules(modules_path, suffixes, out);
findmodules(modules_argv, suffixes, out);
free(copy);
return (0);
}