Pull up following revision(s) (requested by mrg in ticket #572):

usr.bin/config/Makefile: up to 1.10
	usr.bin/config/TODO: up to 1.14
	usr.bin/config/config.1: up to 1.17
	usr.bin/config/config.5: up to 1.25
	usr.bin/config/defs.h: up to 1.64
	usr.bin/config/files.c: up to 1.18
	usr.bin/config/gram.y: up to 1.46
	usr.bin/config/hash.c: up to 1.11
	usr.bin/config/lint.c: up to 1.15
	usr.bin/config/main.c: up to 1.74
	usr.bin/config/mkdevsw.c: up to 1.12
	usr.bin/config/mkheaders.c: up to 1.26
	usr.bin/config/mkioconf.c: up to 1.28
	usr.bin/config/mkmakefile.c: up to 1.37
	usr.bin/config/mkswap.c: up to 1.8
	usr.bin/config/pack.c: up to 1.9
	usr.bin/config/scan.l: up to 1.22
	usr.bin/config/sem.c: up to 1.71
	usr.bin/config/sem.h: up to 1.19
	usr.bin/config/util.c: up to 1.19
sync config(1) with HEAD.
This commit is contained in:
snj 2015-03-06 21:00:23 +00:00
parent 0231d59176
commit eb0a43eb10
20 changed files with 1516 additions and 463 deletions

View File

@ -1,7 +1,8 @@
# $NetBSD: Makefile,v 1.8 2007/05/13 20:22:45 veego Exp $
# $NetBSD: Makefile,v 1.8.54.1 2015/03/06 21:00:23 snj Exp $
# from: @(#)Makefile 8.2 (Berkeley) 4/19/94
.include <bsd.own.mk>
WARNS=6
PROG= config
SRCS= files.c gram.y hash.c lint.c main.c mkdevsw.c mkheaders.c mkioconf.c \

264
usr.bin/config/TODO Normal file
View File

@ -0,0 +1,264 @@
o Call module as module.
Until now, everything is called as attribute. Separate module from it:
- Module is a collection of code (*.[cSo]), and provides a function.
Module can depend on other modules.
- Attribute provides metadata for modules. One module can have
multiple attributes. Attribute doesn't generate a module (*.o,
*.ko).
o Emit everything (ioconf.*, Makefile, ...) per-attribute.
config(9) related metadata (cfdriver, cfattach, cfdata, ...) should be
collected using linker. Create ELF sections like
.{rodata,data}.config.{cfdriver,cfattach,cfdata}. Provide reference
symbols (e.g. cfdriverinit[]) using linker script. Sort entries by name
to lookup entries by binary search in kernel.
o Generate modular(9) related information. Especially module dependency.
At this moment modular(9) modules hardcode dependency in *.c using the
MODULE() macro:
MODULE(MODULE_CLASS_DRIVER, hdaudio, "pci");
This information already exists in config(5) definitions (files.*).
Extend config(5) to be able to specify module's class.
Ideally these module metadata are kept somewhere in ELF headers, so that
loaders (e.g. boot(8)) can easily read. One idea is to abuse DYNAMIC
sections to record dependency, as shared library does. (Feasibility
unknown.)
o Rename "interface attribute" to "bus".
Instead of
define audiobus {}
attach audio at audiobus
Do like this
defbus audiobus {}
attach audio at audiobus
o Retire "attach foo at bar with foo_bar.c"
Most of these should be rewritten by defining a common interface attribute
"foobus", instead of writing multiple attachments. com(4), ld(4), ehci(4)
are typical examples. For ehci(4), EHCI-capable controller drivers implement
"ehcibus" interface, like:
defne ehcibus {}
device imxehci: ehcibus
These drivers' attach functions call config_found() to attach ehci(4) via
the "ehcibus" interface attribute, instead of calling ehci_init() directly.
Same for com(4) (com_attach_subr()) and ld(4) (ldattach()).
o Sort objects in more reasonable order.
Put machdep.ko in the lowest address. uvm.ko and kern.ko follow.
Kill alphabetical sort (${OBJS:O} in sys/conf/Makefile.inc.kern.
Use ldscript. Do like this
.text :
AT (ADDR(.text) & 0x0fffffff)
{
*(.text.machdep.locore.entry)
*(.text.machdep.locore)
*(.text.machdep)
*(.text)
*(.text.*)
:
Kill linker definitions in sys/conf/Makefile.inc.kern.
o Differentiate "options" and "flags"/"params".
"options" enables features by adding *.c files (via attributes).
"flags" and "params" are to change contents of *.c files. These don't add
*.c files to the result kernel, or don't build attributes (modules).
o Make flags/params per attributes (modules).
Basically flags and params are cpp(1) #define's generated in opt_*.h. Make
them local to one attributes (modules). Flags/params which affects files
across attributes (modules) are possible, but should be discouraged.
o Generate things only by definitions.
In the ideal dynamically modular world, "selection" will be done not at
compile time but at runtime. Users select their wanted modules, by
dynamically loading them.
This means that the system provides all choices; that is, build all modules
in the source tree. Necessary information is defined in the "definition"
part.
o Split cfdata.
cfdata is a set of pattern matching rules to enable devices at runtime device
auto-configuration. It is pure data and can (should) be generated separately
from the code.
o Allow easier adding and removing of options.
It should be possible to add or remove options, flags, etc.,
without regard to whether or not they are already defined.
For example, a configuration like this:
include GENERIC
options FOO
no options BAR
should work regardless of whether or not options FOO and/or
options BAR were defined in GENERIC. It should not give
errors like "options BAR was already defined" or "options FOO
was not defined".
o Introduce "class".
Every module should be classified as at least one class, as modular(9)
modules already do. For example, file systems are marked as "vfs", network
protocols are "netproto".
Consider to merge "devclass" into "class".
For syntax clarity, class names could be used as a keyword to select the
class's instance module:
# Define net80211 module as netproto class
class netproto
define net80211: netproto
# Select net80211 to be builtin
netproto net80211
Accordingly device/attach selection syntax should be revisited.
o Support kernel constructor/destructor (.kctors/.kdtors)
Initialization and finalization should be called via constructors and
destructors. Don't hardcode those sequences as sys/kern/init_main.c:main()
does.
The order of .kctors/.kdtors is resolved by dependency. The difference from
userland is that in kernel depended ones are located in lower addresses;
"machdep" module is the lowest. Thus the lowest entry in .ctors must be
executed the first.
The .kctors/.kdtors entries are executed by kernel's main() function, unlike
userland where start code executes .ctors/.dtors before main(). The hardcoded
sequence of various subsystem initializations in init_main.c:main() will be
replaced by an array of .kctors invocations, and #ifdef's there will be gone.
o Hide link-set in the final kernel.
Link-set is used to collect references (pointers) at link time. It relys on
the ld(1) behavior that it automatically generates `__start_X' and `__stop_X'
symbols for the section `X' to reduce coding.
Don't allow kernel subsystems create random ELF sections.
Pre-define all the available link-set names and pre-generate a linker script
to merge them into .rodata.
(For modular(9) modules, `link_set_modules' is looked up by kernel loader.
Provide only it.)
Provide a way for 3rd party modules to declare extra link-set.
o Shared kernel objects.
Since NetBSD has not established a clear kernel ABI, every single kernel
has to build all the objects by their own. As a result, similar kernels
(e.g. evbarm kernels) repeatedly compile similar objects, that is waste of
energy & space.
Share them if possible. For evb* ports, ideally everything except machdep.ko
should be shared.
While leaving optimizations as options (CPU specific optimizations, inlined
bus_space(9) operations, etc.) for users, the official binaries build
provided by TNF should be as portable as possible.
o Control ELF sections using linker script.
Now kernel is linked and built directly from object files (*.o). Each port
has an MD linker script, which does everything needed to be done at link
time. As a result, they do from MI alignment restriction (read_mostly,
cacheline_aligned) to load address specification for external boot loaders.
Make this into multiple stages to make linkage more structural. Especially,
reserve the final link for purely MD purpose. Note that in modular build,
*.ko are shared between build of kernel and modular(9) modules (*.kmod).
Monolithic build:
*.o ---> netbsd.ko Generic MI linkage
netbsd.ko ---> netbsd.ro Kernel MI linkage
netbsd.ro ---> netbsd Kernel MD linkage
Modular build (kernel):
*.o ---> *.ko Generic + Per-module MI linkage
*.ko ---> netbsd.ro Kernel MI linkage
netbsd.ro ---> netbsd Kernel MD linkage
Modular build (module):
*.o ---> *.ko Generic + Per-module MI linkage
*.ko ---> *.ro Modular MI linkage
*.ro ---> *.kmod Modular MD linkage
Genric MI linkage is for processing MI linkage that can be applied generally.
Data section alignment (.data.read_mostly and .data.cacheline_aligned) is
processed here.
Per-module MI linkage is for modules that want some ordering. For example,
machdep.ko wants to put entry code at the top of .text and .data.
Kernel MI linkage is for collecting kernel global section data, that is what
link-set is used for now. Once they are collected and symbols to the ranges
are assigned, those sections are merged into the pre-existing sections
(.rodata) because link-set sections in "netbsd" will never be interpreted by
external loaders.
Kernel MD linkage is used purely for MD purposes, that is, how kernels are
loaded by external loaders. It might be possible that one kernel relocatable
(netbsd.ro) is linked into multiple final kernel image (netbsd) for diferent
load addresses.
Modular MI linkage is to prepare a module to be loadable as modular(9). This
may add some extra sections and/or symbols.
Modular MD linkage is again for pure MD purposes like kernel MD linkage.
Adjustment and/or optimization may be done.
Kernel and modular MI linkages may change behavior depending on existence
of debug information. In the future .symtab will be copied using linker
during this stage.
o Redesign swapnetbsd.c (root/swap device specification)
Don't build a whole kernel only to specify root/swap devices.
Make these parameter re-configurable afterwards.
o Namespace.
Investigate namespace of attributes/modules/options. Figure out the hidden
design about these, document it, then re-design it.
At this moment, all of them share the single "selecttab", which means their
namespaces are common, but they also have respective tables (attrtab,
opttab, etc.).
Selecting an option (addoption()), that is also a module name, works only if
the module doesn't depend on anything, because addoption() doesn't select
module and its dependencies (selectattr()). In other words, an option is
only safely converted to a module (define), only if it doesn't depend on
anything. (One example is DDB.)

View File

@ -1,4 +1,4 @@
.\" $NetBSD: config.1,v 1.15 2014/05/05 20:52:45 wiz Exp $
.\" $NetBSD: config.1,v 1.15.2.1 2015/03/06 21:00:23 snj Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" from: @(#)config.8 8.2 (Berkeley) 4/19/94
.\"
.Dd May 5, 2014
.Dd October 10, 2014
.Dt CONFIG 1
.Os
.Sh NAME
@ -37,7 +37,7 @@
.Nd build kernel compilation directories
.Sh SYNOPSIS
.Nm
.Op Fl Ppv
.Op Fl MPpv
.Op Fl b Ar builddir
.Op Fl D Ar var=value
.Op Fl s Ar srcdir
@ -121,6 +121,12 @@ Generate a lint configuration.
See section
.Sx LINT CONFIGURATION
for details.
.It Fl M
Do modular build (experimental).
Instead of linking all object files (*.o) at once, collect related object
files into an intermediate relocatable object (*.ko), then link those *.ko
files into the final kernel.
This changes the order of objects in the kernel binary.
.It Fl P
Pack locators to save space in the resulting kernel binary.
The amount of space saved that way is so small that this option should

View File

@ -1,4 +1,4 @@
.\" $NetBSD: config.5,v 1.24 2014/05/29 08:13:17 wiz Exp $
.\" $NetBSD: config.5,v 1.24.2.1 2015/03/06 21:00:23 snj Exp $
.\"
.\" Copyright (c) 2006, 2007 The NetBSD Foundation.
.\" All rights reserved.
@ -24,7 +24,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 29, 2014
.Dd October 30, 2014
.Dt CONFIG 5
.Os
.Sh NAME
@ -620,8 +620,10 @@ Un-selects the option
If option
.Ar name
has not been previously selected, the statement produces an error.
.It Oo Ic no Oc Ic file-system Ar name Op , Ar name Op , Ar ...
Adds or removes support for all the listed file-systems.
.It Ic file-system Ar name Op , Ar name Op , Ar ...
Adds support for all the listed file-systems.
.It Ic no file-system Ar name Op , Ar name Op , Ar ...
Removes support for all the listed file-systems.
.It Ic config Ar name Ic root on Ar device Oo Ic type Ar fs Oc Op Ic dumps on \
Ar device
Adds
@ -696,6 +698,10 @@ again.
.It Ic no makeoptions Ar name Op , Ar name Op , Ar ...
Removes one or more definitions from the generated
.Pa Makefile .
.It Ic select Ar name
Adds the specified attribute and its dependencies.
.It Ic no select Ar name
Removes the specified attribute and all the attributes which depend on it.
.El
.Sh FILES
The files are relative to the kernel source top directory (e.g.,

View File

@ -1,4 +1,4 @@
/* $NetBSD: defs.h,v 1.45 2014/05/05 19:08:13 martin Exp $ */
/* $NetBSD: defs.h,v 1.45.2.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -107,7 +107,7 @@ extern const char *progname;
* The next two lines define the current version of the config(1) binary,
* and the minimum version of the configuration files it supports.
*/
#define CONFIG_VERSION 20140502
#define CONFIG_VERSION 20141030
#define CONFIG_MINVERSION 0
/*
@ -149,6 +149,19 @@ struct defoptlist {
struct nvlist *dl_depends;
};
struct module {
const char *m_name;
#if 1
struct attrlist *m_deps;
#else
struct attrlist *m_attrs;
struct modulelist *m_deps;
#endif
int m_expanding;
TAILQ_HEAD(, files) m_files;
int m_weight;
};
/*
* Attributes. These come in three flavors: "plain", "device class,"
* and "interface". Plain attributes (e.g., "ether") simply serve
@ -165,15 +178,23 @@ struct defoptlist {
* SCSI host adapter drivers such as the SPARC "esp").
*/
struct attr {
const char *a_name; /* name of this attribute */
/* XXX */
struct module a_m;
#define a_name a_m.m_name
#define a_deps a_m.m_deps
#define a_expanding a_m.m_expanding
#define a_files a_m.m_files
#define a_weight a_m.m_weight
/* "interface attribute" */
int a_iattr; /* true => allows children */
const char *a_devclass; /* device class described */
struct loclist *a_locs; /* locators required */
int a_loclen; /* length of above list */
struct nvlist *a_devs; /* children */
struct nvlist *a_refs; /* parents */
struct attrlist *a_deps; /* we depend on these other attrs */
int a_expanding; /* to detect cycles in attr graph */
/* "device class" */
const char *a_devclass; /* device class described */
};
/*
@ -299,8 +320,8 @@ struct devi {
/* created during packing or ioconf.c generation */
short i_collapsed; /* set => this alias no longer needed */
short i_cfindex; /* our index in cfdata */
short i_locoff; /* offset in locators.vec */
u_short i_cfindex; /* our index in cfdata */
int i_locoff; /* offset in locators.vec */
};
/* special units */
@ -319,10 +340,12 @@ struct filetype
char fit_lastc; /* last char from path */
const char *fit_path; /* full file path */
const char *fit_prefix; /* any file prefix */
size_t fit_len; /* path string length */
int fit_suffix; /* single char suffix */
struct attr *fit_attr; /* owner attr */
TAILQ_ENTRY(files) fit_anext; /* next file in attr */
};
/* Anything less than 0x10 is sub-type specific */
#define FIT_NOPROLOGUE 0x10 /* Don't prepend $S/ */
#define FIT_FORCESELECT 0x20 /* Always include this file */
/*
* Files. Each file is either standard (always included) or optional,
@ -350,6 +373,10 @@ struct files {
#define fi_lastc fi_fit.fit_lastc
#define fi_path fi_fit.fit_path
#define fi_prefix fi_fit.fit_prefix
#define fi_suffix fi_fit.fit_suffix
#define fi_len fi_fit.fit_len
#define fi_attr fi_fit.fit_attr
#define fi_anext fi_fit.fit_anext
/* flags */
#define FI_SEL 0x01 /* selected */
@ -476,6 +503,7 @@ struct dlhash *defoptlint; /* lint values for options */
struct nvhash *deffstab; /* defined file systems */
struct dlhash *optfiletab; /* "defopt"'d option .h files */
struct hashtab *attrtab; /* attributes (locators, etc.) */
struct hashtab *attrdeptab; /* attribute dependencies */
struct hashtab *bdevmtab; /* block devm lookup */
struct hashtab *cdevmtab; /* character devm lookup */
@ -502,6 +530,7 @@ SLIST_HEAD(, prefix) prefixes, /* prefix stack */
allprefixes; /* all prefixes used (after popped) */
SLIST_HEAD(, prefix) curdirs; /* curdir stack */
extern struct attr allattr;
struct devi **packed; /* arrayified table for packed devi's */
size_t npacked; /* size of packed table, <= ndevi */
@ -521,21 +550,27 @@ void checkfiles(void);
int fixfiles(void); /* finalize */
int fixobjects(void);
int fixdevsw(void);
void addfile(const char *, struct condexpr *, int, const char *);
void addobject(const char *, struct condexpr *, int);
void addfile(const char *, struct condexpr *, u_char, const char *);
void addobject(const char *, struct condexpr *, u_char);
int expr_eval(struct condexpr *, int (*)(const char *, void *), void *);
/* hash.c */
struct hashtab *ht_new(void);
void ht_free(struct hashtab *);
int ht_insrep2(struct hashtab *, const char *, const char *, void *, int);
int ht_insrep(struct hashtab *, const char *, void *, int);
#define ht_insert2(ht, nam1, nam2, val) ht_insrep2(ht, nam1, nam2, val, 0)
#define ht_insert(ht, nam, val) ht_insrep(ht, nam, val, 0)
#define ht_replace(ht, nam, val) ht_insrep(ht, nam, val, 1)
int ht_remove2(struct hashtab *, const char *, const char *);
int ht_remove(struct hashtab *, const char *);
void *ht_lookup2(struct hashtab *, const char *, const char *);
void *ht_lookup(struct hashtab *, const char *);
void initintern(void);
const char *intern(const char *);
typedef int (*ht_callback2)(const char *, const char *, void *, void *);
typedef int (*ht_callback)(const char *, void *, void *);
int ht_enumerate2(struct hashtab *, ht_callback2, void *);
int ht_enumerate(struct hashtab *, ht_callback, void *);
/* typed hash, named struct HT, whose type is string -> struct VT */
@ -558,6 +593,7 @@ void emit_options(void);
void emit_params(void);
/* main.c */
extern int Mflag;
void addoption(const char *, const char *);
void addfsoption(const char *);
void addmkoption(const char *, const char *);
@ -609,7 +645,7 @@ int mkswap(void);
void pack(void);
/* scan.l */
int currentline(void);
u_short currentline(void);
int firstfile(const char *);
void package(const char *);
int include(const char *, int, int, int);
@ -622,6 +658,11 @@ int onlist(struct nvlist *, void *);
void prefix_push(const char *);
void prefix_pop(void);
char *sourcepath(const char *);
extern int dflag;
#define CFGDBG(n, ...) \
do { if ((dflag) >= (n)) cfgdbg(__VA_ARGS__); } while (0)
void cfgdbg(const char *, ...) /* debug info */
__printflike(1, 2);
void cfgwarn(const char *, ...) /* immediate warns */
__printflike(1, 2);
void cfgxwarn(const char *, int, const char *, ...) /* delayed warns */

View File

@ -1,4 +1,4 @@
/* $NetBSD: files.c,v 1.12 2014/05/21 05:25:34 dholland Exp $ */
/* $NetBSD: files.c,v 1.12.2.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: files.c,v 1.12.2.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
@ -65,6 +68,7 @@ static struct hashtab *pathtab; /* full path names */
static struct files **unchecked;
static void addfiletoattr(const char *, struct files *);
static int checkaux(const char *, void *);
static int fixcount(const char *, void *);
static int fixfsel(const char *, void *);
@ -82,7 +86,7 @@ initfiles(void)
}
void
addfile(const char *path, struct condexpr *optx, int flags, const char *rule)
addfile(const char *path, struct condexpr *optx, u_char flags, const char *rule)
{
struct files *fi;
const char *dotp, *tail;
@ -111,7 +115,7 @@ addfile(const char *path, struct condexpr *optx, int flags, const char *rule)
tail++;
dotp = strrchr(tail, '.');
if (dotp == NULL || dotp[1] == 0 ||
(baselen = dotp - tail) >= sizeof(base)) {
(baselen = (size_t)(dotp - tail)) >= sizeof(base)) {
cfgerror("invalid pathname `%s'", path);
goto bad;
}
@ -154,9 +158,12 @@ addfile(const char *path, struct condexpr *optx, int flags, const char *rule)
fi->fi_base = intern(base);
fi->fi_prefix = SLIST_EMPTY(&prefixes) ? NULL :
SLIST_FIRST(&prefixes)->pf_prefix;
fi->fi_len = strlen(path);
fi->fi_suffix = path[fi->fi_len - 1];
fi->fi_optx = optx;
fi->fi_optf = NULL;
fi->fi_mkrule = rule;
fi->fi_attr = NULL;
TAILQ_INSERT_TAIL(&allfiles, fi, fi_next);
return;
bad:
@ -166,7 +173,7 @@ addfile(const char *path, struct condexpr *optx, int flags, const char *rule)
}
void
addobject(const char *path, struct condexpr *optx, int flags)
addobject(const char *path, struct condexpr *optx, u_char flags)
{
struct objects *oi;
@ -195,6 +202,20 @@ addobject(const char *path, struct condexpr *optx, int flags)
return;
}
static void
addfiletoattr(const char *name, struct files *fi)
{
struct attr *a;
a = ht_lookup(attrtab, name);
if (a == NULL) {
CFGDBG(1, "attr `%s' not found", name);
} else {
fi->fi_attr = a;
TAILQ_INSERT_TAIL(&a->a_files, fi, fi_anext);
}
}
/*
* We have finished reading some "files" file, either ../../conf/files
* or ./files.$machine. Make sure that everything that is flagged as
@ -254,12 +275,10 @@ fixfiles(void)
if (fi->fi_flags & FI_HIDDEN)
continue;
/* Optional: see if it is to be included. */
if (fi->fi_flags & FIT_FORCESELECT)
{
/* include it */ ;
if (fi->fi_optx != NULL) {
if (fi->fi_optx->cx_type == CX_ATOM) {
addfiletoattr(fi->fi_optx->cx_u.atom, fi);
}
else if (fi->fi_optx != NULL) {
flathead = NULL;
flatp = &flathead;
sel = expr_eval(fi->fi_optx,
@ -284,7 +303,7 @@ fixfiles(void)
if (ht_replace(basetab, fi->fi_base, fi) != 1)
panic("fixfiles ht_replace(%s)",
fi->fi_base);
ofi->fi_flags &= ~FI_SEL;
ofi->fi_flags &= (u_char)~FI_SEL;
ofi->fi_flags |= FI_HIDDEN;
} else {
cfgxerror(fi->fi_srcfile, fi->fi_srcline,
@ -297,6 +316,14 @@ fixfiles(void)
}
}
fi->fi_flags |= FI_SEL;
CFGDBG(3, "file selected `%s'", fi->fi_path);
/* Add other files to the default "netbsd" attribute. */
if (fi->fi_attr == NULL) {
addfiletoattr(allattr.a_name, fi);
}
CFGDBG(3, "file `%s' belongs to attr `%s'", fi->fi_path,
fi->fi_attr->a_name);
}
return (err);
}

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: gram.y,v 1.39 2014/05/29 07:47:45 mrg Exp $ */
/* $NetBSD: gram.y,v 1.39.2.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -41,6 +41,9 @@
* from: @(#)gram.y 8.1 (Berkeley) 6/6/93
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: gram.y,v 1.39.2.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <ctype.h>
@ -159,6 +162,9 @@ static struct loclist *namelocvals(const char *, struct loclist *);
const char *str;
struct numconst num;
int64_t val;
u_char flag;
devmajor_t devmajor;
int32_t i32;
}
%token AND AT ATTACH
@ -175,7 +181,7 @@ static struct loclist *namelocvals(const char *, struct loclist *);
%token XOBJECT OBSOLETE ON OPTIONS
%token PACKAGE PLUSEQ PREFIX PSEUDO_DEVICE PSEUDO_ROOT
%token ROOT
%token SINGLE SOURCE
%token SELECT SINGLE SOURCE
%token TYPE
%token VECTOR VERSION
%token WITH
@ -187,7 +193,7 @@ static struct loclist *namelocvals(const char *, struct loclist *);
%type <condexpr> cond_or_expr cond_and_expr cond_prefix_expr
%type <condexpr> cond_base_expr
%type <str> fs_spec
%type <val> fflags fflag oflags oflag
%type <flag> fflags fflag oflags oflag
%type <str> rule
%type <attr> depend
%type <devb> devbase
@ -204,9 +210,9 @@ static struct loclist *namelocvals(const char *, struct loclist *);
%type <str> device_instance
%type <str> attachment
%type <str> value
%type <val> major_minor npseudo
%type <val> major_minor
%type <num> signed_number
%type <val> device_flags
%type <i32> int32 npseudo device_flags
%type <str> deffs
%type <list> deffses
%type <defoptlist> defopt
@ -217,13 +223,13 @@ static struct loclist *namelocvals(const char *, struct loclist *);
%type <str> optfile_opt
%type <list> subarches
%type <str> filename stringvalue locname mkvarname
%type <val> device_major_block device_major_char
%type <devmajor> device_major_block device_major_char
%type <list> devnodes devnodetype devnodeflags devnode_dims
%%
/*
* A complete configuration consists of both the configuration part (a
* A complete configuration consists of both the selection part (a
* kernel config such as GENERIC or SKYNET, plus also the various
* std.* files), which selects the material to be in the kernel, and
* also the definition part (files, files.*, etc.) that declares what
@ -254,7 +260,7 @@ static struct loclist *namelocvals(const char *, struct loclist *);
/* Complete configuration. */
configuration:
topthings machine_spec definition_part configuration_part
topthings machine_spec definition_part selection_part
;
/* Sequence of zero or more topthings. */
@ -307,46 +313,134 @@ definitions:
/* A single definition. */
definition:
file
| object
| device_major { do_devsw = 1; }
| prefix
| DEVCLASS WORD { (void)defattr($2, NULL, NULL, 1); }
| DEFFS deffses optdepend_list { deffilesystem($2, $3); }
| DEFINE WORD interface_opt depend_list
{ (void)defattr($2, $3, $4, 0); }
| DEFOPT optfile_opt defopts optdepend_list
{ defoption($2, $3, $4); }
| DEFFLAG optfile_opt defopts optdepend_list
{ defflag($2, $3, $4, 0); }
| OBSOLETE DEFFLAG optfile_opt defopts
{ defflag($3, $4, NULL, 1); }
| DEFPARAM optfile_opt defopts optdepend_list
{ defparam($2, $3, $4, 0); }
| OBSOLETE DEFPARAM optfile_opt defopts
{ defparam($3, $4, NULL, 1); }
| DEVICE devbase interface_opt depend_list
{ defdev($2, $3, $4, 0); }
| ATTACH devbase AT atlist devattach_opt depend_list
{ defdevattach($5, $2, $4, $6); }
| MAXPARTITIONS NUMBER { maxpartitions = $2.val; }
| MAXUSERS NUMBER NUMBER NUMBER
{ setdefmaxusers($2.val, $3.val, $4.val); }
| MAKEOPTIONS condmkopt_list
/* interface_opt in DEFPSEUDO is for backwards compatibility */
| DEFPSEUDO devbase interface_opt depend_list
{ defdev($2, $3, $4, 1); }
| DEFPSEUDODEV devbase interface_opt depend_list
{ defdev($2, $3, $4, 2); }
| MAJOR '{' majorlist '}'
| VERSION NUMBER { setversion($2.val); }
define_file
| define_object
| define_device_major
| define_prefix
| define_devclass
| define_filesystems
| define_attribute
| define_option
| define_flag
| define_obsolete_flag
| define_param
| define_obsolete_param
| define_device
| define_device_attachment
| define_maxpartitions
| define_maxusers
| define_makeoptions
| define_pseudo
| define_pseudodev
| define_major
| define_version
;
/* source file: file foo/bar.c bar|baz needs-flag compile-with blah */
file:
define_file:
XFILE filename fopts fflags rule { addfile($2, $3, $4, $5); }
;
/* object file: object zot.o foo|zot needs-flag */
define_object:
XOBJECT filename fopts oflags { addobject($2, $3, $4); }
;
/* device major declaration */
define_device_major:
DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes
{
adddevm($2, $3, $4, $5, $6);
do_devsw = 1;
}
;
/* prefix delimiter */
define_prefix:
PREFIX filename { prefix_push($2); }
| PREFIX { prefix_pop(); }
;
define_devclass:
DEVCLASS WORD { (void)defdevclass($2, NULL, NULL, 1); }
;
define_filesystems:
DEFFS deffses optdepend_list { deffilesystem($2, $3); }
;
define_attribute:
DEFINE WORD interface_opt depend_list
{ (void)defattr0($2, $3, $4, 0); }
;
define_option:
DEFOPT optfile_opt defopts optdepend_list
{ defoption($2, $3, $4); }
;
define_flag:
DEFFLAG optfile_opt defopts optdepend_list
{ defflag($2, $3, $4, 0); }
;
define_obsolete_flag:
OBSOLETE DEFFLAG optfile_opt defopts
{ defflag($3, $4, NULL, 1); }
;
define_param:
DEFPARAM optfile_opt defopts optdepend_list
{ defparam($2, $3, $4, 0); }
;
define_obsolete_param:
OBSOLETE DEFPARAM optfile_opt defopts
{ defparam($3, $4, NULL, 1); }
;
define_device:
DEVICE devbase interface_opt depend_list
{ defdev($2, $3, $4, 0); }
;
define_device_attachment:
ATTACH devbase AT atlist devattach_opt depend_list
{ defdevattach($5, $2, $4, $6); }
;
define_maxpartitions:
MAXPARTITIONS int32 { maxpartitions = $2; }
;
define_maxusers:
MAXUSERS int32 int32 int32
{ setdefmaxusers($2, $3, $4); }
;
define_makeoptions:
MAKEOPTIONS condmkopt_list
;
define_pseudo:
/* interface_opt in DEFPSEUDO is for backwards compatibility */
DEFPSEUDO devbase interface_opt depend_list
{ defdev($2, $3, $4, 1); }
;
define_pseudodev:
DEFPSEUDODEV devbase interface_opt depend_list
{ defdev($2, $3, $4, 2); }
;
define_major:
MAJOR '{' majorlist '}'
;
define_version:
VERSION int32 { setversion($2); }
;
/* file options: optional expression of conditions */
fopts:
/* empty */ { $$ = NULL; }
@ -371,11 +465,6 @@ rule:
| COMPILE_WITH stringvalue { $$ = $2; }
;
/* object file: object zot.o foo|zot needs-flag */
object:
XOBJECT filename fopts oflags { addobject($2, $3, $4); }
;
/* zero or more flags for an object file */
oflags:
/* empty */ { $$ = 0; }
@ -387,22 +476,16 @@ oflag:
NEEDS_FLAG { $$ = OI_NEEDSFLAG; }
;
/* device major declaration */
device_major:
DEVICE_MAJOR WORD device_major_char device_major_block fopts devnodes
{ adddevm($2, $3, $4, $5, $6); }
;
/* char 55 */
device_major_char:
/* empty */ { $$ = -1; }
| CHAR NUMBER { $$ = $2.val; }
| CHAR int32 { $$ = $2; }
;
/* block 33 */
device_major_block:
/* empty */ { $$ = -1; }
| BLOCK NUMBER { $$ = $2.val; }
| BLOCK int32 { $$ = $2; }
;
/* device node specification */
@ -435,12 +518,6 @@ devnodeflags:
LINKZERO { $$ = new_s("DEVNODE_FLAG_LINKZERO");}
;
/* prefix delimiter */
prefix:
PREFIX filename { prefix_push($2); }
| PREFIX { prefix_pop(); }
;
/* one or more file system names */
deffses:
deffs { $$ = new_n($1); }
@ -479,11 +556,11 @@ locdef:
locname locdefault { $$ = MK3(loc, $1, $2, 0); }
| locname { $$ = MK3(loc, $1, NULL, 0); }
| '[' locname locdefault ']' { $$ = MK3(loc, $2, $3, 1); }
| locname '[' NUMBER ']' { $$ = locarray($1, $3.val, NULL, 0); }
| locname '[' NUMBER ']' locdefaults
{ $$ = locarray($1, $3.val, $5, 0); }
| '[' locname '[' NUMBER ']' locdefaults ']'
{ $$ = locarray($2, $4.val, $6, 1); }
| locname '[' int32 ']' { $$ = locarray($1, $3, NULL, 0); }
| locname '[' int32 ']' locdefaults
{ $$ = locarray($1, $3, $5, 0); }
| '[' locname '[' int32 ']' locdefaults ']'
{ $$ = locarray($2, $4, $6, 1); }
;
/* locator name */
@ -516,7 +593,7 @@ depends:
/* one depend item (which is an attribute) */
depend:
WORD { $$ = getattr($1); }
WORD { $$ = refattr($1); }
;
/* list of option depends, may be empty */
@ -594,51 +671,142 @@ majorlist:
/* one major number */
majordef:
devbase '=' NUMBER { setmajor($1, $3.val); }
devbase '=' int32 { setmajor($1, $3); }
;
int32:
NUMBER {
if ($1.val > INT_MAX || $1.val < INT_MIN)
cfgerror("overflow %" PRId64, $1.val);
else
$$ = (int32_t)$1.val;
}
;
/************************************************************/
/*
* The configuration grammar.
* The selection grammar.
*/
/* Complete configuration part: all std.* files plus selected config. */
configuration_part:
config_items
/* Complete selection part: all std.* files plus selected config. */
selection_part:
selections
;
/* Zero or more config items. Trap errors. */
config_items:
selections:
/* empty */
| config_items '\n'
| config_items config_item '\n' { wrap_continue(); }
| config_items error '\n' { wrap_cleanup(); }
| selections '\n'
| selections selection '\n' { wrap_continue(); }
| selections error '\n' { wrap_cleanup(); }
;
/* One config item. */
config_item:
selection:
definition
| NO FILE_SYSTEM no_fs_list
| FILE_SYSTEM fs_list
| NO MAKEOPTIONS no_mkopt_list
| MAKEOPTIONS mkopt_list
| NO OPTIONS no_opt_list
| OPTIONS opt_list
| MAXUSERS NUMBER { setmaxusers($2.val); }
| IDENT stringvalue { setident($2); }
| NO IDENT { setident(NULL); }
| CONFIG conf root_spec sysparam_list
| select_attr
| select_no_attr
| select_no_filesystems
| select_filesystems
| select_no_makeoptions
| select_makeoptions
| select_no_options
| select_options
| select_maxusers
| select_ident
| select_no_ident
| select_config
| select_no_config
| select_no_pseudodev
| select_pseudodev
| select_pseudoroot
| select_no_device_instance_attachment
| select_no_device_attachment
| select_no_device_instance
| select_device_instance
;
select_attr:
SELECT WORD { addattr($2); }
;
select_no_attr:
NO SELECT WORD { delattr($3); }
;
select_no_filesystems:
NO FILE_SYSTEM no_fs_list
;
select_filesystems:
FILE_SYSTEM fs_list
;
select_no_makeoptions:
NO MAKEOPTIONS no_mkopt_list
;
select_makeoptions:
MAKEOPTIONS mkopt_list
;
select_no_options:
NO OPTIONS no_opt_list
;
select_options:
OPTIONS opt_list
;
select_maxusers:
MAXUSERS int32 { setmaxusers($2); }
;
select_ident:
IDENT stringvalue { setident($2); }
;
select_no_ident:
NO IDENT { setident(NULL); }
;
select_config:
CONFIG conf root_spec sysparam_list
{ addconf(&conf); }
| NO CONFIG WORD { delconf($3); }
| NO PSEUDO_DEVICE WORD { delpseudo($3); }
| PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); }
| PSEUDO_ROOT device_instance { addpseudoroot($2); }
| NO device_instance AT attachment
;
select_no_config:
NO CONFIG WORD { delconf($3); }
;
select_no_pseudodev:
NO PSEUDO_DEVICE WORD { delpseudo($3); }
;
select_pseudodev:
PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); }
;
select_pseudoroot:
PSEUDO_ROOT device_instance { addpseudoroot($2); }
;
select_no_device_instance_attachment:
NO device_instance AT attachment
{ deldevi($2, $4); }
| NO DEVICE AT attachment { deldeva($4); }
| NO device_instance { deldev($2); }
| device_instance AT attachment locators device_flags
;
select_no_device_attachment:
NO DEVICE AT attachment { deldeva($4); }
;
select_no_device_instance:
NO device_instance { deldev($2); }
;
select_device_instance:
device_instance AT attachment locators device_flags
{ adddev($1, $3, $4, $5); }
;
@ -731,14 +899,16 @@ root_spec:
/* device for root fs or dump */
dev_spec:
'?' { $$ = new_si(intern("?"), NODEV); }
| WORD { $$ = new_si($1, NODEV); }
'?' { $$ = new_si(intern("?"),
(long long)NODEV); }
| WORD { $$ = new_si($1,
(long long)NODEV); }
| major_minor { $$ = new_si(NULL, $1); }
;
/* major and minor device number */
major_minor:
MAJOR NUMBER MINOR NUMBER { $$ = makedev($2.val, $4.val); }
MAJOR NUMBER MINOR NUMBER { $$ = (int64_t)makedev($2.val, $4.val); }
;
/* filesystem type for root fs specification */
@ -761,7 +931,7 @@ sysparam:
/* number of pseudo devices to configure (which is optional) */
npseudo:
/* empty */ { $$ = 1; }
| NUMBER { $$ = $1.val; }
| int32 { $$ = $1; }
;
/* name of a device to configure */
@ -792,7 +962,7 @@ locator:
/* optional device flags */
device_flags:
/* empty */ { $$ = 0; }
| FLAGS NUMBER { $$ = $2.val; }
| FLAGS int32 { $$ = $2; }
;
/************************************************************/

View File

@ -1,4 +1,4 @@
/* $NetBSD: hash.c,v 1.8 2012/03/12 02:58:55 dholland Exp $ */
/* $NetBSD: hash.c,v 1.8.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: hash.c,v 1.8.10.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <assert.h>
#include <stdlib.h>
@ -58,15 +61,18 @@
struct hashent {
// XXXLUKEM: a SIMPLEQ might be more appropriate
TAILQ_ENTRY(hashent) h_next;
const char *h_name; /* the string */
const char *h_names[2]; /* the string */
#define h_name1 h_names[0]
#define h_name2 h_names[1]
#define h_name h_name1
u_int h_hash; /* its hash value */
void *h_value; /* other values (for name=value) */
};
struct hashtab {
size_t ht_size; /* size (power of 2) */
u_int ht_mask; /* == ht_size - 1 */
u_int ht_used; /* number of entries used */
u_int ht_lim; /* when to expand */
size_t ht_mask; /* == ht_size - 1 */
size_t ht_used; /* number of entries used */
size_t ht_lim; /* when to expand */
TAILQ_HEAD(hashenthead, hashent) *ht_tab;
};
@ -81,7 +87,8 @@ static struct hashtab strings;
static void ht_expand(struct hashtab *);
static void ht_init(struct hashtab *, size_t);
static inline u_int hash(const char *);
static inline u_int hash(u_int, const char *);
static inline u_int hash2(u_int, const char *, const char *);
static inline struct hashent *newhashent(const char *, u_int);
/*
@ -109,7 +116,7 @@ ht_expand(struct hashtab *ht)
{
struct hashenthead *h, *oldh;
struct hashent *p;
u_int n, i;
size_t n, i;
n = ht->ht_size * 2;
h = emalloc(n * sizeof *h);
@ -137,27 +144,51 @@ ht_expand(struct hashtab *ht)
* otherwise allocate a new entry.
*/
static inline struct hashent *
newhashent(const char *name, u_int h)
newhashent2(const char *name1, const char *name2, u_int h)
{
struct hashent *hp;
hp = ecalloc(1, sizeof(*hp));
hp->h_name = name;
hp->h_name1 = name1;
hp->h_name2 = name2;
hp->h_hash = h;
return (hp);
}
static inline struct hashent *
newhashent(const char *name, u_int h)
{
return newhashent2(name, NULL, h);
}
static inline u_int
hv(u_int h, char c)
{
return (h << 5) + h + (unsigned char)c;
}
/*
* Hash a string.
*/
static inline u_int
hash(const char *str)
hash(u_int h, const char *str)
{
u_int h;
for (h = 0; *str;)
h = (h << 5) + h + *str++;
while (str && *str)
h = hv(h, *str++);
return (h);
}
#define HASH2DELIM ' '
static inline u_int
hash2(u_int h, const char *str1, const char *str2)
{
h = hash(h, str1);
h = hv(h, HASH2DELIM);
h = hash(h, str2);
return (h);
}
@ -182,7 +213,7 @@ intern(const char *s)
char *p;
ht = &strings;
h = hash(s);
h = hash2(0, s, NULL);
hpp = &ht->ht_tab[h & ht->ht_mask];
TAILQ_FOREACH(hp, hpp, h_next) {
if (hp->h_hash == h && strcmp(hp->h_name, s) == 0)
@ -231,22 +262,23 @@ ht_free(struct hashtab *ht)
* Insert and/or replace.
*/
int
ht_insrep(struct hashtab *ht, const char *nam, void *val, int replace)
ht_insrep2(struct hashtab *ht, const char *nam1, const char *nam2, void *val, int replace)
{
struct hashent *hp;
struct hashenthead *hpp;
u_int h;
h = hash(nam);
h = hash2(0, nam1, nam2);
hpp = &ht->ht_tab[h & ht->ht_mask];
TAILQ_FOREACH(hp, hpp, h_next) {
if (hp->h_name == nam) {
if (hp->h_name1 == nam1 &&
hp->h_name2 == nam2) {
if (replace)
hp->h_value = val;
return (1);
}
}
hp = newhashent(nam, h);
hp = newhashent2(nam1, nam2, h);
TAILQ_INSERT_TAIL(hpp, hp, h_next);
hp->h_value = val;
if (++ht->ht_used > ht->ht_lim)
@ -254,21 +286,27 @@ ht_insrep(struct hashtab *ht, const char *nam, void *val, int replace)
return (0);
}
int
ht_insrep(struct hashtab *ht, const char *nam, void *val, int replace)
{
return ht_insrep2(ht, nam, NULL, val, replace);
}
/*
* Remove.
*/
int
ht_remove(struct hashtab *ht, const char *name)
ht_remove2(struct hashtab *ht, const char *name1, const char *name2)
{
struct hashent *hp;
struct hashenthead *hpp;
u_int h;
h = hash(name);
h = hash2(0, name1, name2);
hpp = &ht->ht_tab[h & ht->ht_mask];
TAILQ_FOREACH(hp, hpp, h_next) {
if (hp->h_name != name)
if (hp->h_name1 != name1 || hp->h_name2 != name2)
continue;
TAILQ_REMOVE(hpp, hp, h_next);
@ -279,27 +317,55 @@ ht_remove(struct hashtab *ht, const char *name)
return (1);
}
int
ht_remove(struct hashtab *ht, const char *name)
{
return ht_remove2(ht, name, NULL);
}
void *
ht_lookup(struct hashtab *ht, const char *nam)
ht_lookup2(struct hashtab *ht, const char *nam1, const char *nam2)
{
struct hashent *hp;
struct hashenthead *hpp;
u_int h;
h = hash(nam);
h = hash2(0, nam1, nam2);
hpp = &ht->ht_tab[h & ht->ht_mask];
TAILQ_FOREACH(hp, hpp, h_next)
if (hp->h_name == nam)
if (hp->h_name == nam1)
return (hp->h_value);
return (NULL);
}
void *
ht_lookup(struct hashtab *ht, const char *nam)
{
return ht_lookup2(ht, nam, NULL);
}
/*
* first parameter to callback is the entry name from the hash table
* second parameter is the value from the hash table
* third argument is passed through from the "arg" parameter to ht_enumerate()
*/
int
ht_enumerate2(struct hashtab *ht, ht_callback2 cbfunc2, void *arg)
{
struct hashent *hp;
struct hashenthead *hpp;
size_t i;
int rval = 0;
for (i = 0; i < ht->ht_size; i++) {
hpp = &ht->ht_tab[i];
TAILQ_FOREACH(hp, hpp, h_next)
rval += (*cbfunc2)(hp->h_name1, hp->h_name2, hp->h_value, arg);
}
return rval;
}
int
ht_enumerate(struct hashtab *ht, ht_callback cbfunc, void *arg)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: lint.c,v 1.14 2012/03/20 20:34:57 matt Exp $ */
/* $NetBSD: lint.c,v 1.14.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 2007 The NetBSD Foundation.
@ -30,6 +30,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: lint.c,v 1.14.10.1 2015/03/06 21:00:23 snj Exp $");
#include <assert.h>
#include <stdlib.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.54 2014/08/09 12:40:14 bad Exp $ */
/* $NetBSD: main.c,v 1.54.2.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: main.c,v 1.54.2.1 2015/03/06 21:00:23 snj Exp $");
#ifndef MAKE_BOOTSTRAP
#include <sys/cdefs.h>
#define COPYRIGHT(x) __COPYRIGHT(x)
@ -86,6 +89,7 @@ COPYRIGHT("@(#) Copyright (c) 1992, 1993\
int vflag; /* verbose output */
int Pflag; /* pack locators */
int Lflag; /* lint config generation */
int Mflag; /* modular build */
int handling_cmdlineopts; /* currently processing -D/-U options */
int yyparse(void);
@ -93,6 +97,7 @@ int yyparse(void);
#ifndef MAKE_BOOTSTRAP
extern int yydebug;
#endif
int dflag;
static struct dlhash *obsopttab;
static struct hashtab *mkopttab;
@ -148,6 +153,7 @@ static int extract_config(const char *, const char *, int);
int badfilename(const char *fname);
const char *progname;
extern const char *yyfile;
int
main(int argc, char **argv)
@ -160,14 +166,19 @@ main(int argc, char **argv)
pflag = 0;
xflag = 0;
while ((ch = getopt(argc, argv, "D:LPU:dgpvb:s:x")) != -1) {
while ((ch = getopt(argc, argv, "D:LMPU:dgpvb:s:x")) != -1) {
switch (ch) {
#ifndef MAKE_BOOTSTRAP
case 'd':
#ifndef MAKE_BOOTSTRAP
yydebug = 1;
break;
#endif
dflag++;
break;
case 'M':
Mflag = 1;
break;
case 'L':
Lflag = 1;
@ -281,8 +292,6 @@ main(int argc, char **argv)
minmaxusers = 1;
maxmaxusers = 10000;
initintern();
initfiles();
initsem();
ident = NULL;
devbasetab = ht_new();
devroottab = ht_new();
@ -310,6 +319,8 @@ main(int argc, char **argv)
nextappmkopt = &appmkoptions;
nextcndmkopt = &condmkoptions;
nextfsopt = &fsoptions;
initfiles();
initsem();
/*
* Handle profiling (must do this before we try to create any
@ -401,16 +412,19 @@ main(int argc, char **argv)
/*
* Handle command line overrides
*/
yyfile = "handle_cmdline_makeoptions";
handle_cmdline_makeoptions();
/*
* Detect and properly ignore orphaned devices
*/
yyfile = "kill_orphans";
kill_orphans();
/*
* Select devices and pseudo devices and their attributes
*/
yyfile = "fixdevis";
if (fixdevis())
stop();
@ -418,33 +432,44 @@ main(int argc, char **argv)
* If working on an ioconf-only config, process here and exit
*/
if (ioconfname) {
yyfile = "pack";
pack();
yyfile = "mkioconf";
mkioconf();
yyfile = "emitlocs";
emitlocs();
yyfile = "emitioconfh";
emitioconfh();
return 0;
}
yyfile = "dependattrs";
dependattrs();
/*
* Deal with option dependencies.
*/
yyfile = "dependopts";
dependopts();
/*
* Fix (as in `set firmly in place') files.
*/
yyfile = "fixfiles";
if (fixfiles())
stop();
/*
* Fix objects and libraries.
*/
yyfile = "fixobjects";
if (fixobjects())
stop();
/*
* Fix device-majors.
*/
yyfile = "fixdevsw";
if (fixdevsw())
stop();
@ -468,10 +493,13 @@ main(int argc, char **argv)
* Squeeze things down and finish cross-checks (STAR checks must
* run after packing).
*/
yyfile = "pack";
pack();
yyfile = "badstar";
if (badstar())
stop();
yyfile = NULL;
/*
* Ready to go. Build all the various files.
*/
@ -525,6 +553,8 @@ dependopts_one(const char *name)
if (fs != NULL) {
do_depends(fs->nv_ptr);
}
CFGDBG(3, "depend `%s' searched", name);
}
static void
@ -548,6 +578,7 @@ do_depend(struct nvlist *nv)
* If the dependency is an attribute, then just add
* it to the selecttab.
*/
CFGDBG(3, "depend attr `%s'", nv->nv_name);
if ((a = ht_lookup(attrtab, nv->nv_name)) != NULL) {
if (a->a_iattr)
panic("do_depend(%s): dep `%s' is an iattr",
@ -692,6 +723,13 @@ deffilesystem(struct nvlist *fses, struct nvlist *deps)
nv->nv_name);
add_fs_dependencies(nv, deps);
/*
* Implicit attribute definition for filesystem.
*/
const char *n;
n = strtolower(nv->nv_name);
refattr(n);
}
}
@ -954,12 +992,14 @@ addoption(const char *name, const char *value)
/* make lowercase, then add to select table */
n = strtolower(name);
(void)ht_insert(selecttab, n, (void *)__UNCONST(n));
CFGDBG(3, "option selected `%s'", n);
}
void
deloption(const char *name)
{
CFGDBG(4, "deselecting opt `%s'", name);
if (undo_option(opttab, &options, &nextopt, name, "options"))
return;
if (undo_option(selecttab, NULL, NULL, strtolower(name), "options"))
@ -993,6 +1033,14 @@ addfsoption(const char *name)
/* Add to select table. */
(void)ht_insert(selecttab, n, __UNCONST(n));
CFGDBG(3, "fs selected `%s'", name);
/*
* Select attribute if one exists.
*/
struct attr *a;
if ((a = ht_lookup(attrtab, n)) != NULL)
selectattr(a);
}
void
@ -1000,6 +1048,7 @@ delfsoption(const char *name)
{
const char *n;
CFGDBG(4, "deselecting fs `%s'", name);
n = strtolower(name);
if (undo_option(fsopttab, &fsoptions, &nextfsopt, name, "file-system"))
return;
@ -1021,6 +1070,7 @@ void
delmkoption(const char *name)
{
CFGDBG(4, "deselecting mkopt `%s'", name);
(void)undo_option(mkopttab, &mkoptions, &nextmkopt, name,
"makeoptions");
}
@ -1097,8 +1147,10 @@ undo_option(struct hashtab *ht, struct nvlist **npp,
cfgwarn("%s `%s' is not defined", type, name);
return (1);
}
if (npp == NULL)
if (npp == NULL) {
CFGDBG(2, "opt `%s' deselected", name);
return (0);
}
for ( ; *npp != NULL; npp = &(*npp)->nv_next) {
if ((*npp)->nv_name != name)
@ -1106,6 +1158,7 @@ undo_option(struct hashtab *ht, struct nvlist **npp,
if (next != NULL && *next == &(*npp)->nv_next)
*next = npp;
nv = (*npp)->nv_next;
CFGDBG(2, "opt `%s' deselected", (*npp)->nv_name);
nvfree(*npp);
*npp = nv;
return (0);
@ -1501,11 +1554,11 @@ strtolower(const char *name)
{
const char *n;
char *p, low[500];
unsigned char c;
char c;
for (n = name, p = low; (c = *n) != '\0'; n++)
*p++ = isupper(c) ? tolower(c) : c;
*p = 0;
*p++ = (char)(isupper((u_char)c) ? tolower((u_char)c) : c);
*p = '\0';
return (intern(low));
}
@ -1529,8 +1582,9 @@ static int
extract_config(const char *kname, const char *cname, int cfd)
{
char *ptr;
int found, kfd, i;
int found, kfd;
struct stat st;
off_t i;
found = 0;
@ -1540,7 +1594,7 @@ extract_config(const char *kname, const char *cname, int cfd)
err(EXIT_FAILURE, "cannot open %s", kname);
if (fstat(kfd, &st) == -1)
err(EXIT_FAILURE, "cannot stat %s", kname);
ptr = mmap(0, st.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
ptr = mmap(0, (size_t)st.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
kfd, 0);
if (ptr == MAP_FAILED)
err(EXIT_FAILURE, "cannot mmap %s", kname);

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkdevsw.c,v 1.10 2010/07/30 16:23:49 cube Exp $ */
/* $NetBSD: mkdevsw.c,v 1.10.24.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -33,6 +33,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: mkdevsw.c,v 1.10.24.1 2015/03/06 21:00:23 snj Exp $");
#include <stdio.h>
#include <string.h>
#include <errno.h>
@ -86,37 +89,54 @@ emitheader(FILE *fp)
"#include <sys/conf.h>\n", fp);
}
static void
dentry(FILE *fp, struct hashtab *t, devmajor_t i, char p)
{
const struct devm *dm;
char mstr[16];
(void)snprintf(mstr, sizeof(mstr), "%d", i);
if ((dm = ht_lookup(t, intern(mstr))) == NULL)
return;
fprintf(fp, "extern const struct %cdevsw %s_%cdevsw;\n",
p, dm->dm_name, p);
}
static void
pentry(FILE *fp, struct hashtab *t, devmajor_t i, char p)
{
const struct devm *dm;
char mstr[16];
(void)snprintf(mstr, sizeof(mstr), "%d", i);
dm = ht_lookup(t, intern(mstr));
if (dm)
fprintf(fp, "\t&%s_%cdevsw", dm->dm_name, p);
else
fputs("\tNULL", fp);
fprintf(fp, ",\t// %3d\n", i);
}
/*
* Emit device switch table for character/block device.
*/
static void
emitdevm(FILE *fp)
{
struct devm *dm;
char mstr[16];
devmajor_t i;
fputs("\n/* device switch table for block device */\n", fp);
for (i = 0 ; i <= maxbdevm ; i++) {
(void)snprintf(mstr, sizeof(mstr), "%d", i);
if ((dm = ht_lookup(bdevmtab, intern(mstr))) == NULL)
continue;
fprintf(fp, "extern const struct bdevsw %s_bdevsw;\n",
dm->dm_name);
}
for (i = 0; i <= maxbdevm ; i++)
dentry(fp, cdevmtab, i, 'b');
fputs("\nconst struct bdevsw *bdevsw0[] = {\n", fp);
for (i = 0 ; i <= maxbdevm ; i++) {
(void)snprintf(mstr, sizeof(mstr), "%d", i);
if ((dm = ht_lookup(bdevmtab, intern(mstr))) == NULL) {
fprintf(fp, "\tNULL,\n");
} else {
fprintf(fp, "\t&%s_bdevsw,\n", dm->dm_name);
}
}
for (i = 0; i <= maxbdevm; i++)
pentry(fp, bdevmtab, i, 'b');
fputs("};\n\nconst struct bdevsw **bdevsw = bdevsw0;\n", fp);
@ -125,25 +145,13 @@ emitdevm(FILE *fp)
fputs("\n/* device switch table for character device */\n", fp);
for (i = 0 ; i <= maxcdevm ; i++) {
(void)snprintf(mstr, sizeof(mstr), "%d", i);
if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL)
continue;
fprintf(fp, "extern const struct cdevsw %s_cdevsw;\n",
dm->dm_name);
}
for (i = 0; i <= maxcdevm; i++)
dentry(fp, cdevmtab, i, 'c');
fputs("\nconst struct cdevsw *cdevsw0[] = {\n", fp);
for (i = 0 ; i <= maxcdevm ; i++) {
(void)snprintf(mstr, sizeof(mstr), "%d", i);
if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL) {
fprintf(fp, "\tNULL,\n");
} else {
fprintf(fp, "\t&%s_cdevsw,\n", dm->dm_name);
}
}
for (i = 0; i <= maxcdevm; i++)
pentry(fp, cdevmtab, i, 'c');
fputs("};\n\nconst struct cdevsw **cdevsw = cdevsw0;\n", fp);
@ -189,7 +197,9 @@ emitconv(FILE *fp)
d_flags = nv->nv_str;
break;
}
d_vec[i++] = nv->nv_num;
if (nv->nv_num > INT_MAX || nv->nv_num < INT_MIN)
panic("out of range devnode definition");
d_vec[i++] = (int)nv->nv_num;
}
fprintf(fp, "\t{ \"%s\", %d, %d, %s, %s, { %d, %d }},\n",

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkheaders.c,v 1.21 2012/03/12 02:58:55 dholland Exp $ */
/* $NetBSD: mkheaders.c,v 1.21.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: mkheaders.c,v 1.21.10.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <ctype.h>
#include <errno.h>
@ -137,10 +140,14 @@ fprint_global(FILE *fp, const char *name, long long value)
static unsigned int
global_hash(const char *str)
{
unsigned int h;
unsigned long h;
char *ep;
/* If the value is a valid numeric, just use it */
/*
* If the value is a valid numeric, just use it
* We don't care about negative values here, we
* just use the value as a hash.
*/
h = strtoul(str, &ep, 0);
if (*ep != 0)
/* Otherwise shove through a 32bit CRC function */
@ -148,7 +155,7 @@ global_hash(const char *str)
/* Avoid colliding with the value used for undefined options. */
/* At least until I stop any options being set to zero */
return h != UNDEFINED ? h : DEFINED;
return (unsigned int)(h != UNDEFINED ? h : DEFINED);
}
static void
@ -316,7 +323,7 @@ locators_print(const char *name, void *value, void *arg)
locdup = estrdup(name);
for (cp = locdup; *cp; cp++)
if (islower((unsigned char)*cp))
*cp = toupper((unsigned char)*cp);
*cp = (char)toupper((unsigned char)*cp);
for (i = 0, ll = a->a_locs; ll; ll = ll->ll_next, i++) {
if (strchr(ll->ll_name, ' ') != NULL ||
strchr(ll->ll_name, '\t') != NULL)
@ -328,7 +335,7 @@ locators_print(const char *name, void *value, void *arg)
namedup = estrdup(ll->ll_name);
for (cp = namedup; *cp; cp++)
if (islower((unsigned char)*cp))
*cp = toupper((unsigned char)*cp);
*cp = (char)toupper((unsigned char)*cp);
else if (*cp == ARRCHR)
*cp = '_';
fprintf(fp, "#define %sCF_%s %d\n", locdup, namedup, i);
@ -520,13 +527,13 @@ static char *
cntname(const char *src)
{
char *dst;
unsigned char c;
char c;
static char buf[100];
dst = buf;
*dst++ = 'N';
while ((c = *src++) != 0)
*dst++ = islower(c) ? toupper(c) : c;
*dst++ = (char)(islower((u_char)c) ? toupper((u_char)c) : c);
*dst = 0;
return (buf);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkioconf.c,v 1.21 2012/03/11 21:16:08 dholland Exp $ */
/* $NetBSD: mkioconf.c,v 1.21.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: mkioconf.c,v 1.21.10.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <err.h>
#include <errno.h>
@ -136,7 +139,7 @@ static void
emithdr(FILE *ofp)
{
FILE *ifp;
int n;
size_t n;
char ifnbuf[200], buf[BUFSIZ];
char *ifn;
@ -174,12 +177,14 @@ cf_locators_print(const char *name, void *value, void *arg)
a = value;
if (!a->a_iattr)
return (0);
if (ht_lookup(selecttab, name) == NULL)
return (0);
if (a->a_locs) {
fprintf(fp,
"static const struct cfiattrdata %scf_iattrdata = {\n",
name);
fprintf(fp, "\t\"%s\", %d,\n\t{\n", name, a->a_loclen);
fprintf(fp, "\t\"%s\", %d, {\n", name, a->a_loclen);
for (ll = a->a_locs; ll; ll = ll->ll_next)
fprintf(fp, "\t\t{ \"%s\", \"%s\", %s },\n",
ll->ll_name,
@ -319,10 +324,6 @@ emitloc(FILE *fp)
for (i = 0; i < locators.used; i++)
fprintf(fp, "%s%s,", SEP(i, 8), locators.vec[i]);
fprintf(fp, "\n};\n");
} else if (*packed != NULL) {
/* We need to have *something*. */
fprintf(fp, "\n/* locators */\n"
"static int loc[1] = { -1 };\n");
}
}
@ -375,7 +376,7 @@ emitcfdata(FILE *fp)
"\n"
"%sstruct cfdata cfdata%s%s[] = {\n"
" /* driver attachment unit state "
"loc flags pspec */\n",
" loc flags pspec */\n",
ioconfname ? "static " : "",
ioconfname ? "_ioconf_" : "",
ioconfname ? ioconfname : "");
@ -428,9 +429,9 @@ emitcfdata(FILE *fp)
i->i_locoff);
loc = locbuf;
} else
loc = "loc";
loc = "NULL";
fprintf(fp, " { \"%s\",%s\"%s\",%s%2d, %s, %7s, %#6x, ",
basename, strlen(basename) < 8 ? "\t\t"
basename, strlen(basename) < 7 ? "\t\t"
: "\t",
attachment, strlen(attachment) < 5 ? "\t\t"
: "\t",
@ -441,7 +442,7 @@ emitcfdata(FILE *fp)
fputs("NULL },\n", fp);
}
fprintf(fp, " { %s,%s%s,%s%2d, %s, %7s, %#6x, %s }\n};\n",
"NULL", "\t\t", "NULL", "\t\t", 0, "0", "NULL", 0, "NULL");
"NULL", "\t\t", "NULL", "\t\t", 0, " 0", "NULL", 0, "NULL");
}
/*
@ -479,7 +480,7 @@ emitpseudo(FILE *fp)
fprintf(fp, "void %sattach(int);\n",
i->i_base->d_name);
}
fputs("\nstruct pdevinit pdevinit[] = {\n", fp);
fputs("\nconst struct pdevinit pdevinit[] = {\n", fp);
TAILQ_FOREACH(i, &allpseudo, i_next) {
d = i->i_base;
fprintf(fp, "\t{ %sattach, %d },\n",

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkmakefile.c,v 1.15 2012/06/08 08:56:45 martin Exp $ */
/* $NetBSD: mkmakefile.c,v 1.15.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: mkmakefile.c,v 1.15.10.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <ctype.h>
#include <errno.h>
@ -51,6 +54,7 @@
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <util.h>
#include "defs.h"
#include "sem.h"
@ -68,6 +72,11 @@ static void emitdefs(FILE *);
static void emitfiles(FILE *, int, int);
static void emitobjs(FILE *);
static void emitallkobjs(FILE *);
static int emitallkobjscb(const char *, void *, void *);
static void emitattrkobjs(FILE *);
static int emitattrkobjscb(const char *, void *, void *);
static void emitkobjs(FILE *);
static void emitcfiles(FILE *);
static void emitsfiles(FILE *);
static void emitrules(FILE *);
@ -77,6 +86,8 @@ static void emitappmkoptions(FILE *);
static void emitsubs(FILE *, const char *, const char *, int);
static int selectopt(const char *, void *);
int has_build_kernel;
int
mkmakefile(void)
{
@ -86,13 +97,36 @@ mkmakefile(void)
char *ifname;
char line[BUFSIZ], buf[200];
/* Try a makefile for the port first.
/*
* Check if conf/Makefile.kern.inc defines "build_kernel".
*
* (This is usually done by checking "version" in sys/conf/files;
* unfortunately the "build_kernel" change done around 2014 Aug didn't
* bump that version. Thus this hack.)
*/
(void)snprintf(buf, sizeof(buf), "conf/Makefile.kern.inc");
ifname = sourcepath(buf);
if ((ifp = fopen(ifname, "r")) == NULL) {
warn("cannot read %s", ifname);
goto bad2;
}
while (fgets(line, sizeof(line), ifp) != NULL) {
if (strncmp(line, "build_kernel:", 13) == 0) {
has_build_kernel = 1;
break;
}
}
(void)fclose(ifp);
/*
* Try a makefile for the port first.
*/
(void)snprintf(buf, sizeof(buf), "arch/%s/conf/Makefile.%s",
machine, machine);
ifname = sourcepath(buf);
if ((ifp = fopen(ifname, "r")) == NULL) {
/* Try a makefile for the architecture second.
/*
* Try a makefile for the architecture second.
*/
(void)snprintf(buf, sizeof(buf), "arch/%s/conf/Makefile.%s",
machinearch, machinearch);
@ -120,7 +154,7 @@ mkmakefile(void)
continue;
}
if (strcmp(line, "%OBJS\n") == 0)
fn = emitobjs;
fn = Mflag ? emitkobjs : emitobjs;
else if (strcmp(line, "%CFILES\n") == 0)
fn = emitcfiles;
else if (strcmp(line, "%SFILES\n") == 0)
@ -224,11 +258,13 @@ emitsubs(FILE *fp, const char *line, const char *file, int lineno)
if (option != NULL)
fputs(option->nv_str ? option->nv_str : "1",
fp);
/* Otherwise it's not a selected option and we don't
* output anything. */
/*
* Otherwise it's not a selected option and we don't
* output anything.
*/
}
line = nextpct+1;
line = nextpct + 1;
}
}
@ -261,52 +297,48 @@ srcpath(struct files *fi)
static const char *
filetype_prologue(struct filetype *fit)
{
if (fit->fit_flags & FIT_NOPROLOGUE || *fit->fit_path == '/')
return ("");
else
return ("$S/");
return (*fit->fit_path == '/') ? "" : "$S/";
}
static const char *
prefix_prologue(const char *path)
{
if (*path == '/')
return ("");
else
return ("$S/");
return (*path == '/') ? "" : "$S/";
}
static void
emitdefs(FILE *fp)
{
struct nvlist *nv;
const char *sp;
fprintf(fp, "KERNEL_BUILD=%s\n", conffile);
fputs("IDENT=", fp);
sp = "";
fputs("IDENT= \\\n", fp);
for (nv = options; nv != NULL; nv = nv->nv_next) {
/* skip any options output to a header file */
/* Skip any options output to a header file */
if (DEFINED_OPTION(nv->nv_name))
continue;
fprintf(fp, "%s-D%s", sp, nv->nv_name);
if (nv->nv_str)
fprintf(fp, "=\"%s\"", nv->nv_str);
sp = " ";
const char *s = nv->nv_str;
fprintf(fp, "\t-D%s%s%s%s \\\n", nv->nv_name,
s ? "=\"" : "",
s ? s : "",
s ? "\"" : "");
}
putc('\n', fp);
fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers);
fprintf(fp, "MACHINE=%s\n", machine);
if (*srcdir == '/' || *srcdir == '.') {
fprintf(fp, "S=\t%s\n", srcdir);
} else {
const char *subdir = "";
if (*srcdir != '/' && *srcdir != '.') {
/*
* libkern and libcompat "Makefile.inc"s want relative S
* specification to begin with '.'.
*/
fprintf(fp, "S=\t./%s\n", srcdir);
subdir = "./";
}
fprintf(fp, "S=\t%s%s\n", subdir, srcdir);
for (nv = mkoptions; nv != NULL; nv = nv->nv_next)
fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str);
}
@ -316,61 +348,144 @@ emitobjs(FILE *fp)
{
struct files *fi;
struct objects *oi;
int lpos, len, sp;
fputs("OBJS=", fp);
sp = '\t';
lpos = 7;
fputs("OBJS= \\\n", fp);
TAILQ_FOREACH(fi, &allfiles, fi_next) {
if ((fi->fi_flags & FI_SEL) == 0)
continue;
len = strlen(fi->fi_base) + 2;
if (lpos + len > 72) {
fputs(" \\\n", fp);
sp = '\t';
lpos = 7;
}
fprintf(fp, "%c%s.o", sp, fi->fi_base);
lpos += len + 1;
sp = ' ';
fprintf(fp, "\t%s.o \\\n", fi->fi_base);
}
TAILQ_FOREACH(oi, &allobjects, oi_next) {
const char *prologue, *prefix, *sep;
if ((oi->oi_flags & OI_SEL) == 0)
continue;
len = strlen(oi->oi_path);
if (*oi->oi_path != '/')
{
/* e.g. "$S/" */
if (oi->oi_prefix != NULL)
len += strlen(prefix_prologue(oi->oi_path)) +
strlen(oi->oi_prefix) + 1;
else
len += strlen(filetype_prologue(&oi->oi_fit));
}
if (lpos + len > 72) {
fputs(" \\\n", fp);
sp = '\t';
lpos = 7;
}
if (*oi->oi_path == '/') {
fprintf(fp, "%c%s", sp, oi->oi_path);
} else {
prologue = prefix = sep = "";
if (*oi->oi_path != '/') {
if (oi->oi_prefix != NULL) {
fprintf(fp, "%c%s%s/%s", sp,
prefix_prologue(oi->oi_path),
oi->oi_prefix, oi->oi_path);
prologue = prefix_prologue(oi->oi_path);
prefix = oi->oi_prefix;
sep = "/";
} else {
fprintf(fp, "%c%s%s", sp,
filetype_prologue(&oi->oi_fit),
prologue = filetype_prologue(&oi->oi_fit);
}
}
fprintf(fp, "\t%s%s%s%s \\\n", prologue, prefix, sep,
oi->oi_path);
}
}
lpos += len + 1;
sp = ' ';
}
putc('\n', fp);
}
static void
emitkobjs(FILE *fp)
{
emitallkobjs(fp);
emitattrkobjs(fp);
}
static int emitallkobjsweighcb(const char *name, void *v, void *arg);
static void weighattr(struct attr *a);
static int attrcmp(const void *l, const void *r);
struct attr **attrbuf;
size_t attridx;
static void
emitallkobjs(FILE *fp)
{
size_t i;
attrbuf = emalloc(nattrs * sizeof(*attrbuf));
ht_enumerate(attrtab, emitallkobjsweighcb, NULL);
ht_enumerate(attrtab, emitallkobjscb, NULL);
qsort(attrbuf, attridx, sizeof(struct attr *), attrcmp);
fputs("OBJS= \\\n", fp);
for (i = 0; i < attridx; i++)
fprintf(fp, "\t%s.ko \\\n", attrbuf[i]->a_name);
putc('\n', fp);
free(attrbuf);
}
static int
emitallkobjscb(const char *name, void *v, void *arg)
{
struct attr *a = v;
if (ht_lookup(selecttab, name) == NULL)
return 0;
if (TAILQ_EMPTY(&a->a_files))
return 0;
attrbuf[attridx++] = a;
/* XXX nattrs tracking is not exact yet */
if (attridx == nattrs) {
nattrs *= 2;
attrbuf = erealloc(attrbuf, nattrs * sizeof(*attrbuf));
}
return 0;
}
static int
emitallkobjsweighcb(const char *name, void *v, void *arg)
{
struct attr *a = v;
weighattr(a);
return 0;
}
static void
weighattr(struct attr *a)
{
struct attrlist *al;
for (al = a->a_deps; al != NULL; al = al->al_next) {
weighattr(al->al_this);
}
a->a_weight++;
}
static int
attrcmp(const void *l, const void *r)
{
const struct attr * const *a = l, * const *b = r;
const int wa = (*a)->a_weight, wb = (*b)->a_weight;
return (wa > wb) ? -1 : (wa < wb) ? 1 : 0;
}
static void
emitattrkobjs(FILE *fp)
{
extern struct hashtab *attrtab;
ht_enumerate(attrtab, emitattrkobjscb, fp);
}
static int
emitattrkobjscb(const char *name, void *v, void *arg)
{
struct attr *a = v;
struct files *fi;
FILE *fp = arg;
if (ht_lookup(selecttab, name) == NULL)
return 0;
if (TAILQ_EMPTY(&a->a_files))
return 0;
fputc('\n', fp);
fprintf(fp, "# %s (%d)\n", name, a->a_weight);
fprintf(fp, "OBJS.%s= \\\n", name);
TAILQ_FOREACH(fi, &a->a_files, fi_anext) {
fprintf(fp, "\t%s.o \\\n", fi->fi_base);
}
fputc('\n', fp);
fprintf(fp, "%s.ko: ${OBJS.%s}\n", name, name);
fprintf(fp, "\t${LINK_O}\n");
return 0;
}
static void
emitcfiles(FILE *fp)
{
@ -389,49 +504,31 @@ static void
emitfiles(FILE *fp, int suffix, int upper_suffix)
{
struct files *fi;
int lpos, len, sp;
const char *fpath;
struct config *cf;
char swapname[100];
fprintf(fp, "%cFILES=", toupper(suffix));
sp = '\t';
lpos = 7;
fprintf(fp, "%cFILES= \\\n", toupper(suffix));
TAILQ_FOREACH(fi, &allfiles, fi_next) {
const char *prologue, *prefix, *sep;
if ((fi->fi_flags & FI_SEL) == 0)
continue;
fpath = srcpath(fi);
len = strlen(fpath);
if (fpath[len - 1] != suffix && fpath[len - 1] != upper_suffix)
if (fi->fi_suffix != suffix && fi->fi_suffix != upper_suffix)
continue;
if (*fpath != '/') {
/* "$S/" */
if (fi->fi_prefix != NULL)
len += strlen(prefix_prologue(fi->fi_prefix)) +
strlen(fi->fi_prefix) + 1;
else
len += strlen(filetype_prologue(&fi->fi_fit));
}
if (lpos + len > 72) {
fputs(" \\\n", fp);
sp = '\t';
lpos = 7;
}
if (*fi->fi_path == '/') {
fprintf(fp, "%c%s", sp, fpath);
} else {
prologue = prefix = sep = "";
if (*fi->fi_path != '/') {
if (fi->fi_prefix != NULL) {
fprintf(fp, "%c%s%s/%s", sp,
prefix_prologue(fi->fi_prefix),
fi->fi_prefix, fpath);
prologue = prefix_prologue(fi->fi_prefix);
prefix = fi->fi_prefix;
sep = "/";
} else {
fprintf(fp, "%c%s%s", sp,
filetype_prologue(&fi->fi_fit),
fpath);
prologue = filetype_prologue(&fi->fi_fit);
}
}
lpos += len + 1;
sp = ' ';
fprintf(fp, "\t%s%s%s%s \\\n",
prologue, prefix, sep, fpath);
}
/*
* The allfiles list does not include the configuration-specific
@ -442,15 +539,7 @@ emitfiles(FILE *fp, int suffix, int upper_suffix)
TAILQ_FOREACH(cf, &allcf, cf_next) {
(void)snprintf(swapname, sizeof(swapname), "swap%s.c",
cf->cf_name);
len = strlen(swapname);
if (lpos + len > 72) {
fputs(" \\\n", fp);
sp = '\t';
lpos = 7;
}
fprintf(fp, "%c%s", sp, swapname);
lpos += len + 1;
sp = ' ';
fprintf(fp, "\t%s \\\n", swapname);
}
}
putc('\n', fp);
@ -463,37 +552,30 @@ static void
emitrules(FILE *fp)
{
struct files *fi;
const char *cp, *fpath;
int ch;
const char *fpath;
TAILQ_FOREACH(fi, &allfiles, fi_next) {
const char *prologue, *prefix, *sep;
if ((fi->fi_flags & FI_SEL) == 0)
continue;
fpath = srcpath(fi);
if (*fpath == '/') {
fprintf(fp, "%s.o: %s\n", fi->fi_base, fpath);
} else {
prologue = prefix = sep = "";
if (*fpath != '/') {
if (fi->fi_prefix != NULL) {
fprintf(fp, "%s.o: %s%s/%s\n", fi->fi_base,
prefix_prologue(fi->fi_prefix),
fi->fi_prefix, fpath);
prologue = prefix_prologue(fi->fi_prefix);
prefix = fi->fi_prefix;
sep = "/";
} else {
fprintf(fp, "%s.o: %s%s\n",
fi->fi_base,
filetype_prologue(&fi->fi_fit),
fpath);
prologue = filetype_prologue(&fi->fi_fit);
}
}
fprintf(fp, "%s.o: %s%s%s%s\n", fi->fi_base,
prologue, prefix, sep, fpath);
if (fi->fi_mkrule != NULL) {
fprintf(fp, "\t%s\n\n", fi->fi_mkrule);
} else {
fputs("\t${NORMAL_", fp);
cp = strrchr(fpath, '.');
cp = cp == NULL ? fpath : cp + 1;
while ((ch = *cp++) != '\0') {
fputc(toupper(ch), fp);
}
fputs("}\n\n", fp);
fprintf(fp, "\t${NORMAL_%c}\n\n", toupper(fi->fi_suffix));
}
}
}
@ -507,9 +589,9 @@ static void
emitload(FILE *fp)
{
struct config *cf;
const char *nm, *swname;
fputs(".MAIN: all\nall:", fp);
fputs(".MAIN: all\n", fp);
fputs("all:", fp);
TAILQ_FOREACH(cf, &allcf, cf_next) {
fprintf(fp, " %s", cf->cf_name);
/*
@ -521,20 +603,28 @@ emitload(FILE *fp)
fprintf(fp, " .WAIT");
}
fputs("\n\n", fp);
TAILQ_FOREACH(cf, &allcf, cf_next) {
nm = cf->cf_name;
swname =
cf->cf_root != NULL ? cf->cf_name : "generic";
fprintf(fp, "KERNELS+=%s\n", nm);
fprintf(fp, "%s: ${SYSTEM_DEP} swap${.TARGET}.o vers.o", nm);
fprintf(fp, "\n"
/*
* Generate the backward-compatible "build_kernel" rule if
* sys/conf/Makefile.kern.inc doesn't define any (pre-2014 Aug).
*/
if (has_build_kernel == 0) {
fprintf(fp, "build_kernel: .USE\n"
"\t${SYSTEM_LD_HEAD}\n"
"\t${SYSTEM_LD} swap${.TARGET}.o\n"
"\t${SYSTEM_LD_TAIL}\n"
"\n"
"swap%s.o: swap%s.c\n"
"\t${NORMAL_C}\n\n", swname, swname);
"\n");
}
/*
* Generate per-kernel rules.
*/
TAILQ_FOREACH(cf, &allcf, cf_next) {
fprintf(fp, "KERNELS+=%s\n", cf->cf_name);
fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o vers.o build_kernel\n",
cf->cf_name, cf->cf_name);
fprintf(fp, "swap%s.o: swap%s.c\n"
"\t${NORMAL_C}\n\n", cf->cf_name, cf->cf_name);
}
fputs("\n", fp);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkswap.c,v 1.7 2009/01/20 18:20:48 drochner Exp $ */
/* $NetBSD: mkswap.c,v 1.7.26.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: mkswap.c,v 1.7.26.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
@ -114,7 +117,7 @@ mkoneswap(struct config *cf)
cf->cf_root->nv_str);
fprintf(fp, "const char *rootspec = %s;\n", specinfo);
fprintf(fp, "dev_t\trootdev = %s;\t/* %s */\n\n",
mkdevstr(nv->nv_num),
mkdevstr((dev_t)nv->nv_num),
nv->nv_str == s_qmark ? "wildcarded" : nv->nv_str);
/*
@ -127,7 +130,7 @@ mkoneswap(struct config *cf)
snprintf(specinfo, sizeof(specinfo), "\"%s\"", cf->cf_dump->nv_str);
fprintf(fp, "const char *dumpspec = %s;\n", specinfo);
fprintf(fp, "dev_t\tdumpdev = %s;\t/* %s */\n\n",
nv ? mkdevstr(nv->nv_num) : "NODEV",
nv ? mkdevstr((dev_t)nv->nv_num) : "NODEV",
nv ? nv->nv_str : "unspecified");
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: pack.c,v 1.8 2010/03/08 10:19:14 pooka Exp $ */
/* $NetBSD: pack.c,v 1.8.24.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: pack.c,v 1.8.24.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
@ -137,7 +140,7 @@ packdevi(void)
{
struct devi *firststar, *i, **ip, *l, *p;
struct devbase *d;
int j, m, n;
u_short j, m, n;
/*
* Sort all the cloning units to after the non-cloning units,

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: scan.l,v 1.17 2012/03/20 20:34:57 matt Exp $ */
/* $NetBSD: scan.l,v 1.17.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -41,6 +41,9 @@
* from: @(#)scan.l 8.1 (Berkeley) 6/6/93
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: scan.l,v 1.17.10.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <errno.h>
#include <libgen.h>
@ -108,12 +111,12 @@ static int getcurifdef(void);
%}
%option noyywrap
%option noyywrap nounput noinput
PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./]*
QCHARS ([^"\n]|\\\")+
QCHARS \"(\\.|[^\\"])*\"
WORD [A-Za-z_][-A-Za-z_0-9]*
FILENAME ({PATH}|\"{QCHARS}\")
FILENAME ({PATH}|{QCHARS})
RESTOFLINE [ \t]*(#[^\n]*)?\n
%x IGNORED
@ -164,6 +167,7 @@ prefix return PREFIX;
pseudo-device return PSEUDO_DEVICE;
pseudo-root return PSEUDO_ROOT;
root return ROOT;
select return SELECT;
single return SINGLE;
source return SOURCE;
type return TYPE;
@ -319,12 +323,11 @@ package[ \t]+{FILENAME}{RESTOFLINE} {
return EMPTYSTRING;
}
\"{QCHARS} {
tok = input(); /* eat closing quote */
if (tok != '"') {
cfgerror("closing quote missing\n");
unput(tok);
}
{QCHARS} {
size_t l = strlen(yytext);
if (l > 1 && yytext[l - 1] == '"')
yytext[l - 1] = '\0';
yylval.str = intern(yytext + 1);
return QSTRING;
}
@ -335,7 +338,7 @@ package[ \t]+{FILENAME}{RESTOFLINE} {
}
0[xX][0-9a-fA-F]+ {
yylval.num.fmt = 16;
yylval.num.val = strtoull(yytext + 2, NULL, 16);
yylval.num.val = (long long)strtoull(yytext + 2, NULL, 16);
return NUMBER;
}
[1-9][0-9]* {
@ -397,8 +400,7 @@ curdir_push(const char *fname)
free(f);
return (-1);
}
p = emalloc(strlen(cwd) + strlen(d) + 2);
sprintf(p, "%s/%s", cwd, d);
easprintf(&p, "%s/%s", cwd, d);
}
free(f);
pf = ecalloc(1, sizeof(*pf));
@ -498,8 +500,7 @@ include(const char *fname, int ateof, int conditional, int direct)
s = estrdup(fname);
else if (fname[0] == '.' && fname[1] == '/') {
struct prefix *pf = SLIST_FIRST(&curdirs);
s = emalloc(strlen(pf->pf_prefix) + strlen(fname));
sprintf(s, "%s/%s", pf->pf_prefix, fname + 2);
easprintf(&s, "%s/%s", pf->pf_prefix, fname + 2);
} else
s = sourcepath(fname);
if ((fp = fopen(s, "r")) == NULL) {
@ -530,6 +531,7 @@ include(const char *fname, int ateof, int conditional, int direct)
if (interesting)
logconfig_include(fp, fname);
incl = in;
CFGDBG(1, "include `%s' from `%s' line %d", fname, yyfile, yyline);
yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
yyfile = intern(s);
yyline = 1;
@ -604,12 +606,12 @@ endinclude(void)
* us to consume a newline, we have to subtract one. yychar is yacc's
* token lookahead, so we can tell.
*/
int
u_short
currentline(void)
{
extern int yychar;
return (yyline - (yychar == '\n'));
return (u_short)(yyline - (yychar == '\n'));
}
static int

View File

@ -1,4 +1,4 @@
/* $NetBSD: sem.c,v 1.43 2014/05/29 07:47:45 mrg Exp $ */
/* $NetBSD: sem.c,v 1.43.2.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: sem.c,v 1.43.2.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/param.h>
#include <ctype.h>
#include <stdio.h>
@ -65,6 +68,8 @@ const char *s_none;
static struct hashtab *cfhashtab; /* for config lookup */
struct hashtab *devitab; /* etc */
struct attr allattr;
size_t nattrs;
static struct attr errattr;
static struct devbase errdev;
@ -95,6 +100,13 @@ initsem(void)
{
attrtab = ht_new();
attrdeptab = ht_new();
allattr.a_name = "netbsd";
TAILQ_INIT(&allattr.a_files);
(void)ht_insert(attrtab, allattr.a_name, &allattr);
selectattr(&allattr);
errattr.a_name = "<internal>";
TAILQ_INIT(&allbases);
@ -121,11 +133,79 @@ initsem(void)
/* Name of include file just ended (set in scan.l) */
extern const char *lastfile;
static struct attr *
finddep(struct attr *a, const char *name)
{
struct attrlist *al;
for (al = a->a_deps; al != NULL; al = al->al_next) {
struct attr *this = al->al_this;
if (strcmp(this->a_name, name) == 0)
return this;
}
return NULL;
}
static void
mergedeps(const char *dname, const char *name)
{
struct attr *a, *newa;
CFGDBG(4, "merging attr `%s' to devbase `%s'", name, dname);
a = refattr(dname);
if (finddep(a, name) == NULL) {
newa = refattr(name);
a->a_deps = attrlist_cons(a->a_deps, newa);
CFGDBG(3, "attr `%s' merged to attr `%s'", newa->a_name,
a->a_name);
}
}
static void
fixdev(struct devbase *dev)
{
struct attrlist *al;
struct attr *devattr, *a;
devattr = refattr(dev->d_name);
if (devattr->a_devclass)
panic("%s: dev %s is devclass!", __func__, devattr->a_name);
CFGDBG(4, "fixing devbase `%s'", dev->d_name);
for (al = dev->d_attrs; al != NULL; al = al->al_next) {
a = al->al_this;
CFGDBG(4, "fixing devbase `%s' attr `%s'", dev->d_name, a->a_name);
if (a->a_iattr) {
a->a_refs = addtoattr(a->a_refs, dev);
CFGDBG(3, "device `%s' has iattr `%s'", dev->d_name,
a->a_name);
} else if (a->a_devclass != NULL) {
if (dev->d_classattr != NULL && dev->d_classattr != a) {
cfgwarn("device `%s' has multiple classes "
"(`%s' and `%s')",
dev->d_name, dev->d_classattr->a_name,
a->a_name);
}
if (dev->d_classattr == NULL) {
dev->d_classattr = a;
CFGDBG(3, "device `%s' is devclass `%s'", dev->d_name,
a->a_name);
}
} else {
if (strcmp(dev->d_name, a->a_name) != 0) {
mergedeps(dev->d_name, a->a_name);
}
}
}
}
void
enddefs(void)
{
struct devbase *dev;
yyfile = "enddefs";
TAILQ_FOREACH(dev, &allbases, d_next) {
if (!dev->d_isdef) {
(void)fprintf(stderr,
@ -134,6 +214,7 @@ enddefs(void)
errors++;
continue;
}
fixdev(dev);
}
if (errors) {
(void)fprintf(stderr, "*** Stop.\n");
@ -196,20 +277,25 @@ setident(const char *i)
* Since an empty locator list is logically different from "no interface",
* all locator lists include a dummy head node, which we discard here.
*/
int
defattr0(const char *name, struct loclist *locs, struct attrlist *deps,
int devclass)
{
if (locs != NULL)
return defiattr(name, locs, deps, devclass);
else if (devclass)
return defdevclass(name, locs, deps, devclass);
else
return defattr(name, locs, deps, devclass);
}
int
defattr(const char *name, struct loclist *locs, struct attrlist *deps,
int devclass)
{
struct attr *a, *dep;
struct attrlist *al;
struct loclist *ll;
int len;
if (locs != NULL && devclass)
panic("defattr(%s): locators and devclass", name);
if (deps != NULL && devclass)
panic("defattr(%s): dependencies and devclass", name);
/*
* If this attribute depends on any others, make sure none of
@ -222,31 +308,88 @@ defattr(const char *name, struct loclist *locs, struct attrlist *deps,
"attribute", name, dep->a_name);
return (1);
}
(void)ht_insert2(attrdeptab, name, dep->a_name, NULL);
CFGDBG(2, "attr `%s' depends on attr `%s'", name, dep->a_name);
}
a = ecalloc(1, sizeof *a);
if (ht_insert(attrtab, name, a)) {
free(a);
if (getrefattr(name, &a)) {
cfgerror("attribute `%s' already defined", name);
loclist_destroy(locs);
return (1);
}
if (a == NULL)
a = mkattr(name);
a->a_deps = deps;
expandattr(a, NULL);
CFGDBG(3, "attr `%s' defined", a->a_name);
return (0);
}
struct attr *
mkattr(const char *name)
{
struct attr *a;
a = ecalloc(1, sizeof *a);
if (ht_insert(attrtab, name, a)) {
free(a);
return NULL;
}
a->a_name = name;
if (locs != NULL) {
TAILQ_INIT(&a->a_files);
CFGDBG(3, "attr `%s' allocated", name);
return a;
}
/* "interface attribute" initialization */
int
defiattr(const char *name, struct loclist *locs, struct attrlist *deps,
int devclass)
{
struct attr *a;
int len;
struct loclist *ll;
if (devclass)
panic("defattr(%s): locators and devclass", name);
if (defattr(name, locs, deps, devclass) != 0)
return (1);
a = getattr(name);
a->a_iattr = 1;
/* unwrap */
a->a_locs = locs->ll_next;
locs->ll_next = NULL;
loclist_destroy(locs);
} else {
a->a_iattr = 0;
a->a_locs = NULL;
}
if (devclass) {
len = 0;
for (ll = a->a_locs; ll != NULL; ll = ll->ll_next)
len++;
a->a_loclen = len;
if (deps)
CFGDBG(2, "attr `%s' iface with deps", a->a_name);
return (0);
}
/* "device class" initialization */
int
defdevclass(const char *name, struct loclist *locs, struct attrlist *deps,
int devclass)
{
struct attr *a;
char classenum[256], *cp;
int errored = 0;
if (deps)
panic("defattr(%s): dependencies and devclass", name);
if (defattr(name, locs, deps, devclass) != 0)
return (1);
a = getattr(name);
(void)snprintf(classenum, sizeof(classenum), "DV_%s", name);
for (cp = classenum + 3; *cp; cp++) {
if (!errored &&
@ -256,22 +399,9 @@ defattr(const char *name, struct loclist *locs, struct attrlist *deps,
"lower-case alphanumeric characters");
errored = 1;
}
*cp = toupper((unsigned char)*cp);
*cp = (char)toupper((unsigned char)*cp);
}
a->a_devclass = intern(classenum);
} else
a->a_devclass = NULL;
len = 0;
for (ll = a->a_locs; ll != NULL; ll = ll->ll_next)
len++;
a->a_loclen = len;
a->a_devs = NULL;
a->a_refs = NULL;
a->a_deps = deps;
a->a_expanding = 0;
/* Expand the attribute to check for cycles in the graph. */
expandattr(a, NULL);
return (0);
}
@ -332,7 +462,6 @@ defdev(struct devbase *dev, struct loclist *loclist, struct attrlist *attrs,
{
struct loclist *ll;
struct attrlist *al;
struct attr *a;
if (dev == &errdev)
goto bad;
@ -354,7 +483,7 @@ defdev(struct devbase *dev, struct loclist *loclist, struct attrlist *attrs,
if (loclist != NULL) {
ll = loclist;
loclist = NULL; /* defattr disposes of them for us */
if (defattr(dev->d_name, ll, NULL, 0))
if (defiattr(dev->d_name, ll, NULL, 0))
goto bad;
attrs = attrlist_cons(attrs, getattr(dev->d_name));
/* This used to be stored but was never used */
@ -386,6 +515,12 @@ defdev(struct devbase *dev, struct loclist *loclist, struct attrlist *attrs,
dev->d_ispseudo = ispseudo;
dev->d_attrs = attrs;
dev->d_classattr = NULL; /* for now */
CFGDBG(3, "dev `%s' defined", dev->d_name);
/*
* Implicit attribute definition for device.
*/
refattr(dev->d_name);
/*
* For each interface attribute this device refers to, add this
@ -397,18 +532,13 @@ defdev(struct devbase *dev, struct loclist *loclist, struct attrlist *attrs,
* device has two classes).
*/
for (al = attrs; al != NULL; al = al->al_next) {
a = al->al_this;
if (a->a_iattr)
a->a_refs = addtoattr(a->a_refs, dev);
if (a->a_devclass != NULL) {
if (dev->d_classattr != NULL) {
cfgerror("device `%s' has multiple classes "
"(`%s' and `%s')",
dev->d_name, dev->d_classattr->a_name,
a->a_name);
}
dev->d_classattr = a;
}
/*
* Implicit attribute definition for device dependencies.
*/
refattr(al->al_this->a_name);
(void)ht_insert2(attrdeptab, dev->d_name, al->al_this->a_name, NULL);
CFGDBG(2, "device `%s' depends on attr `%s'", dev->d_name,
al->al_this->a_name);
}
return;
bad:
@ -453,6 +583,7 @@ getdevbase(const char *name)
TAILQ_INSERT_TAIL(&allbases, dev, d_next);
if (ht_insert(devbasetab, name, dev))
panic("getdevbase(%s)", name);
CFGDBG(3, "devbase defined `%s'", dev->d_name);
}
return (dev);
}
@ -504,6 +635,12 @@ defdevattach(struct deva *deva, struct devbase *dev, struct nvlist *atlist,
deva->d_attrs = attrs;
deva->d_atlist = atlist;
deva->d_devbase = dev;
CFGDBG(3, "deva `%s' defined", deva->d_name);
/*
* Implicit attribute definition for device attachment.
*/
refattr(deva->d_name);
/*
* Turn the `at' list into interface attributes (map each
@ -604,6 +741,41 @@ getattr(const char *name)
return (a);
}
/*
* Implicit attribute definition.
*/
struct attr *
refattr(const char *name)
{
struct attr *a;
if ((a = ht_lookup(attrtab, name)) == NULL)
a = mkattr(name);
return a;
}
int
getrefattr(const char *name, struct attr **ra)
{
struct attr *a;
a = ht_lookup(attrtab, name);
if (a == NULL) {
*ra = NULL;
return (0);
}
/*
* Check if the existing attr is only referenced, not really defined.
*/
if (a->a_deps == NULL &&
a->a_iattr == 0 &&
a->a_devclass == 0) {
*ra = a;
return (0);
}
return (1);
}
/*
* Recursively expand an attribute and its dependencies, checking for
* cycles, and invoking a callback for each attribute found.
@ -717,7 +889,7 @@ resolve(struct nvlist **nvp, const char *name, const char *what,
const char *cp;
devmajor_t maj;
devminor_t min;
int i, l;
size_t i, l;
int unit;
char buf[NAMESIZE];
@ -737,7 +909,7 @@ resolve(struct nvlist **nvp, const char *name, const char *what,
cp = makedevstr(maj, min);
} else
cp = NULL;
*nvp = nv = newnv(NULL, cp, NULL, d, NULL);
*nvp = nv = newnv(NULL, cp, NULL, (long long)d, NULL);
}
if ((dev_t)nv->nv_num != NODEV) {
/*
@ -784,7 +956,7 @@ resolve(struct nvlist **nvp, const char *name, const char *what,
* don't bother making a device number.
*/
if (has_attr(dev->d_attrs, s_ifnet)) {
nv->nv_num = NODEV;
nv->nv_num = (long long)NODEV;
nv->nv_ifunit = unit; /* XXX XXX XXX */
} else {
maj = dev2major(dev);
@ -793,7 +965,7 @@ resolve(struct nvlist **nvp, const char *name, const char *what,
name, what, nv->nv_str);
return (1);
}
nv->nv_num = makedev(maj, unit * maxpartitions + part);
nv->nv_num = (long long)makedev(maj, unit * maxpartitions + part);
}
nv->nv_name = dev->d_name;
@ -877,6 +1049,7 @@ delconf(const char *name)
{
struct config *cf;
CFGDBG(5, "deselecting config `%s'", name);
if (ht_lookup(cfhashtab, name) == NULL) {
cfgerror("configuration `%s' undefined", name);
return;
@ -1075,6 +1248,7 @@ adddev(const char *name, const char *at, struct loclist *loclist, int flags)
i->i_pspec = p;
i->i_atdeva = iba;
i->i_cfflags = flags;
CFGDBG(3, "devi `%s' added", i->i_name);
*iba->d_ipp = i;
iba->d_ipp = &i->i_asame;
@ -1093,6 +1267,7 @@ deldevi(const char *name, const char *at)
int unit;
char base[NAMESIZE];
CFGDBG(5, "deselecting devi `%s'", name);
if (split(name, strlen(name), base, sizeof base, &unit)) {
cfgerror("invalid device name `%s'", name);
return;
@ -1131,6 +1306,7 @@ remove_devi(struct devi *i)
struct devi *f, *j, **ppi;
struct deva *iba;
CFGDBG(5, "removing devi `%s'", i->i_name);
f = ht_lookup(devitab, i->i_name);
if (f == NULL)
panic("remove_devi(): instance %s disappeared from devitab",
@ -1154,7 +1330,8 @@ remove_devi(struct devi *i)
* list.
*/
if (i != f) {
for (j = f; j->i_alias != i; j = j->i_alias);
for (j = f; j->i_alias != i; j = j->i_alias)
continue;
j->i_alias = i->i_alias;
} else {
if (i->i_alias == NULL) {
@ -1177,7 +1354,8 @@ remove_devi(struct devi *i)
*/
for (ppi = &d->d_ihead;
*ppi != NULL && *ppi != i && (*ppi)->i_bsame != i;
ppi = &(*ppi)->i_bsame);
ppi = &(*ppi)->i_bsame)
continue;
if (*ppi == NULL)
panic("deldev: dev (%s) doesn't list the devi"
" (%s at %s)", d->d_name, i->i_name, i->i_at);
@ -1203,7 +1381,8 @@ remove_devi(struct devi *i)
iba = i->i_atdeva;
for (ppi = &iba->d_ihead;
*ppi != NULL && *ppi != i && (*ppi)->i_asame != i;
ppi = &(*ppi)->i_asame);
ppi = &(*ppi)->i_asame)
continue;
if (*ppi == NULL)
panic("deldev: deva (%s) doesn't list the devi (%s)",
iba->d_name, i->i_name);
@ -1267,7 +1446,8 @@ remove_devi(struct devi *i)
panic("remove_devi(%s) - can't add to deaddevitab",
i->i_name);
} else {
for (j = f; j->i_alias != NULL; j = j->i_alias);
for (j = f; j->i_alias != NULL; j = j->i_alias)
continue;
j->i_alias = i;
}
/*
@ -1295,13 +1475,18 @@ deldeva(const char *at)
if (i->i_at == NULL)
stack = newnv(NULL, NULL, i, 0, stack);
} else {
int l;
size_t l;
CFGDBG(5, "deselecting deva `%s'", at);
if (at[0] == '\0')
goto out;
l = strlen(at) - 1;
if (at[l] == '?' || isdigit((unsigned char)at[l])) {
char base[NAMESIZE];
if (split(at, l+1, base, sizeof base, &unit)) {
out:
cfgerror("invalid attachment name `%s'", at);
return;
}
@ -1376,15 +1561,20 @@ deldeva(const char *at)
void
deldev(const char *name)
{
int l;
size_t l;
struct devi *firsti, *i;
struct nvlist *nv, *stack = NULL;
CFGDBG(5, "deselecting dev `%s'", name);
if (name[0] == '\0')
goto out;
l = strlen(name) - 1;
if (name[l] == '*' || isdigit((unsigned char)name[l])) {
/* `no mydev0' or `no mydev*' */
firsti = ht_lookup(devitab, name);
if (firsti == NULL) {
out:
cfgerror("unknown instance %s", name);
return;
}
@ -1530,6 +1720,7 @@ delpseudo(const char *name)
struct devbase *d;
struct devi *i;
CFGDBG(5, "deselecting pseudo `%s'", name);
d = ht_lookup(devbasetab, name);
if (d == NULL) {
cfgerror("undefined pseudo-device %s", name);
@ -1599,7 +1790,8 @@ fixdevis(void)
struct devi *i;
int error = 0;
TAILQ_FOREACH(i, &alldevi, i_next)
TAILQ_FOREACH(i, &alldevi, i_next) {
CFGDBG(3, "fixing devis `%s'", i->i_name);
if (i->i_active == DEVI_ACTIVE)
selectbase(i->i_base, i->i_atdeva);
else if (i->i_active == DEVI_ORPHAN) {
@ -1616,6 +1808,7 @@ fixdevis(void)
cfgxwarn(i->i_srcfile, i->i_lineno, "ignoring "
"explicitly orphaned instance `%s at %s'",
i->i_name, i->i_at);
}
if (error)
return error;
@ -1707,8 +1900,8 @@ concat(const char *name, int c)
len = sizeof(buf) - 2;
}
memmove(buf, name, len);
buf[len] = c;
buf[len + 1] = 0;
buf[len] = (char)c;
buf[len + 1] = '\0';
return (intern(buf));
}
@ -1760,11 +1953,74 @@ split(const char *name, size_t nlen, char *base, size_t bsize, int *aunit)
return (0);
}
void
addattr(const char *name)
{
struct attr *a;
a = refattr(name);
selectattr(a);
}
void
delattr(const char *name)
{
struct attr *a;
a = refattr(name);
deselectattr(a);
}
void
selectattr(struct attr *a)
{
struct attrlist *al;
struct attr *dep;
(void)ht_insert(selecttab, a->a_name, __UNCONST(a->a_name));
CFGDBG(5, "selecting attr `%s'", a->a_name);
for (al = a->a_deps; al != NULL; al = al->al_next) {
dep = al->al_this;
selectattr(dep);
}
if (ht_insert(selecttab, a->a_name, __UNCONST(a->a_name)) == 0)
nattrs++;
CFGDBG(3, "attr selected `%s'", a->a_name);
}
static int
deselectattrcb2(const char *name1, const char *name2, void *v, void *arg)
{
const char *name = arg;
if (strcmp(name, name2) == 0)
delattr(name1);
return 0;
}
void
deselectattr(struct attr *a)
{
CFGDBG(5, "deselecting attr `%s'", a->a_name);
ht_enumerate2(attrdeptab, deselectattrcb2, __UNCONST(a->a_name));
if (ht_remove(selecttab, a->a_name) == 0)
nattrs--;
CFGDBG(3, "attr deselected `%s'", a->a_name);
}
static int
dumpattrdepcb2(const char *name1, const char *name2, void *v, void *arg)
{
CFGDBG(3, "attr `%s' depends on attr `%s'", name1, name2);
return 0;
}
void
dependattrs(void)
{
ht_enumerate2(attrdeptab, dumpattrdepcb2, NULL);
}
/*
@ -1778,17 +2034,27 @@ selectbase(struct devbase *d, struct deva *da)
struct attrlist *al;
(void)ht_insert(selecttab, d->d_name, __UNCONST(d->d_name));
CFGDBG(3, "devbase selected `%s'", d->d_name);
CFGDBG(5, "selecting dependencies of devbase `%s'", d->d_name);
for (al = d->d_attrs; al != NULL; al = al->al_next) {
a = al->al_this;
expandattr(a, selectattr);
}
struct attr *devattr;
devattr = refattr(d->d_name);
expandattr(devattr, selectattr);
if (da != NULL) {
(void)ht_insert(selecttab, da->d_name, __UNCONST(da->d_name));
CFGDBG(3, "devattr selected `%s'", da->d_name);
for (al = da->d_attrs; al != NULL; al = al->al_next) {
a = al->al_this;
expandattr(a, selectattr);
}
}
fixdev(d);
}
/*
@ -1839,7 +2105,7 @@ fixloc(const char *name, struct attr *attr, struct loclist *got)
if (attr->a_loclen == 0) /* e.g., "at root" */
lp = nullvec;
else
lp = emalloc((attr->a_loclen + 1) * sizeof(const char *));
lp = emalloc((size_t)(attr->a_loclen + 1) * sizeof(const char *));
for (n = got; n != NULL; n = n->ll_next)
n->ll_num = -1;
nmissing = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sem.h,v 1.10 2012/03/11 21:16:08 dholland Exp $ */
/* $NetBSD: sem.h,v 1.10.10.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -46,15 +46,25 @@ void setversion(int);
void setdefmaxusers(int, int, int);
void setmaxusers(int);
void setident(const char *);
int defattr0(const char *, struct loclist *, struct attrlist *, int);
int defattr(const char *, struct loclist *, struct attrlist *, int);
int defiattr(const char *, struct loclist *, struct attrlist *, int);
int defdevclass(const char *, struct loclist *, struct attrlist *, int);
void defdev(struct devbase *, struct loclist *, struct attrlist *, int);
void defdevattach(struct deva *, struct devbase *, struct nvlist *,
struct attrlist *);
struct devbase *getdevbase(const char *);
struct deva *getdevattach(const char *);
struct attr *mkattr(const char *);
struct attr *getattr(const char *);
struct attr *refattr(const char *);
int getrefattr(const char *, struct attr **);
void expandattr(struct attr *, void (*)(struct attr *));
void addattr(const char *);
void delattr(const char *);
void selectattr(struct attr *);
void deselectattr(struct attr *);
void dependattrs(void);
void setmajor(struct devbase *, int);
void addconf(struct config *);
void setconf(struct nvlist **, const char *, struct nvlist *);
@ -67,7 +77,7 @@ void deldev(const char *);
void addpseudo(const char *, int);
void delpseudo(const char *);
void addpseudoroot(const char *);
void adddevm(const char *, int, int,
void adddevm(const char *, devmajor_t, devmajor_t,
struct condexpr *, struct nvlist *);
int fixdevis(void);
const char *ref(const char *);
@ -78,3 +88,4 @@ int has_attr(struct attrlist *, const char *);
extern const char *s_qmark;
extern const char *s_none;
extern const char *s_ifnet;
extern size_t nattrs;

View File

@ -1,4 +1,4 @@
/* $NetBSD: util.c,v 1.16 2013/11/01 21:39:13 christos Exp $ */
/* $NetBSD: util.c,v 1.16.4.1 2015/03/06 21:00:23 snj Exp $ */
/*
* Copyright (c) 1992, 1993
@ -44,6 +44,9 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: util.c,v 1.16.4.1 2015/03/06 21:00:23 snj Exp $");
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
@ -57,6 +60,8 @@
static void cfgvxerror(const char *, int, const char *, va_list)
__printflike(3, 0);
static void cfgvxdbg(const char *, int, const char *, va_list)
__printflike(3, 0);
static void cfgvxwarn(const char *, int, const char *, va_list)
__printflike(3, 0);
static void cfgvxmsg(const char *, int, const char *, const char *, va_list)
@ -413,6 +418,17 @@ condexpr_destroy(struct condexpr *expr)
* Diagnostic messages
*/
void
cfgdbg(const char *fmt, ...)
{
va_list ap;
extern const char *yyfile;
va_start(ap, fmt);
cfgvxdbg(yyfile, currentline(), fmt, ap);
va_end(ap);
}
void
cfgwarn(const char *fmt, ...)
{
@ -434,6 +450,12 @@ cfgxwarn(const char *file, int line, const char *fmt, ...)
va_end(ap);
}
static void
cfgvxdbg(const char *file, int line, const char *fmt, va_list ap)
{
cfgvxmsg(file, line, "debug: ", fmt, ap);
}
static void
cfgvxwarn(const char *file, int line, const char *fmt, va_list ap)
{