Module Name: src
Committed By: snj
Date: Fri Mar 6 21:00:23 UTC 2015
Modified Files:
src/usr.bin/config [netbsd-7]: Makefile config.1 config.5 defs.h
files.c gram.y hash.c lint.c main.c mkdevsw.c mkheaders.c
mkioconf.c mkmakefile.c mkswap.c pack.c scan.l sem.c sem.h util.c
Added Files:
src/usr.bin/config [netbsd-7]: TODO
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.8.54.1 src/usr.bin/config/Makefile
cvs rdiff -u -r0 -r1.14.2.2 src/usr.bin/config/TODO
cvs rdiff -u -r1.15 -r1.15.2.1 src/usr.bin/config/config.1
cvs rdiff -u -r1.24 -r1.24.2.1 src/usr.bin/config/config.5
cvs rdiff -u -r1.45 -r1.45.2.1 src/usr.bin/config/defs.h
cvs rdiff -u -r1.12 -r1.12.2.1 src/usr.bin/config/files.c
cvs rdiff -u -r1.39 -r1.39.2.1 src/usr.bin/config/gram.y
cvs rdiff -u -r1.8 -r1.8.10.1 src/usr.bin/config/hash.c
cvs rdiff -u -r1.14 -r1.14.10.1 src/usr.bin/config/lint.c
cvs rdiff -u -r1.54 -r1.54.2.1 src/usr.bin/config/main.c
cvs rdiff -u -r1.10 -r1.10.24.1 src/usr.bin/config/mkdevsw.c
cvs rdiff -u -r1.21 -r1.21.10.1 src/usr.bin/config/mkheaders.c \
src/usr.bin/config/mkioconf.c
cvs rdiff -u -r1.15 -r1.15.10.1 src/usr.bin/config/mkmakefile.c
cvs rdiff -u -r1.7 -r1.7.26.1 src/usr.bin/config/mkswap.c
cvs rdiff -u -r1.8 -r1.8.24.1 src/usr.bin/config/pack.c
cvs rdiff -u -r1.17 -r1.17.10.1 src/usr.bin/config/scan.l
cvs rdiff -u -r1.43 -r1.43.2.1 src/usr.bin/config/sem.c
cvs rdiff -u -r1.10 -r1.10.10.1 src/usr.bin/config/sem.h
cvs rdiff -u -r1.16 -r1.16.4.1 src/usr.bin/config/util.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/config/Makefile
diff -u src/usr.bin/config/Makefile:1.8 src/usr.bin/config/Makefile:1.8.54.1
--- src/usr.bin/config/Makefile:1.8 Sun May 13 20:22:45 2007
+++ src/usr.bin/config/Makefile Fri Mar 6 21:00:23 2015
@@ -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 \
Index: src/usr.bin/config/config.1
diff -u src/usr.bin/config/config.1:1.15 src/usr.bin/config/config.1:1.15.2.1
--- src/usr.bin/config/config.1:1.15 Mon May 5 20:52:45 2014
+++ src/usr.bin/config/config.1 Fri Mar 6 21:00:23 2015
@@ -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
Index: src/usr.bin/config/config.5
diff -u src/usr.bin/config/config.5:1.24 src/usr.bin/config/config.5:1.24.2.1
--- src/usr.bin/config/config.5:1.24 Thu May 29 08:13:17 2014
+++ src/usr.bin/config/config.5 Fri Mar 6 21:00:23 2015
@@ -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.,
Index: src/usr.bin/config/defs.h
diff -u src/usr.bin/config/defs.h:1.45 src/usr.bin/config/defs.h:1.45.2.1
--- src/usr.bin/config/defs.h:1.45 Mon May 5 19:08:13 2014
+++ src/usr.bin/config/defs.h Fri Mar 6 21:00:23 2015
@@ -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 value
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
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 */
Index: src/usr.bin/config/files.c
diff -u src/usr.bin/config/files.c:1.12 src/usr.bin/config/files.c:1.12.2.1
--- src/usr.bin/config/files.c:1.12 Wed May 21 05:25:34 2014
+++ src/usr.bin/config/files.c Fri Mar 6 21:00:23 2015
@@ -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
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 condexp
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 condexp
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 condexp
}
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 conde
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 */ ;
- }
- else if (fi->fi_optx != NULL) {
+ if (fi->fi_optx != NULL) {
+ if (fi->fi_optx->cx_type == CX_ATOM) {
+ addfiletoattr(fi->fi_optx->cx_u.atom, fi);
+ }
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);
}
Index: src/usr.bin/config/gram.y
diff -u src/usr.bin/config/gram.y:1.39 src/usr.bin/config/gram.y:1.39.2.1
--- src/usr.bin/config/gram.y:1.39 Thu May 29 07:47:45 2014
+++ src/usr.bin/config/gram.y Fri Mar 6 21:00:23 2015
@@ -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
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
%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
%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
%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
%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
/* Complete configuration. */
configuration:
- topthings machine_spec definition_part configuration_part
+ topthings machine_spec definition_part selection_part
;
/* Sequence of zero or more topthings. */
@@ -307,44 +313,132 @@ 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
+ 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 */
+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); }
- | DEFFLAG optfile_opt defopts optdepend_list
+;
+
+define_flag:
+ DEFFLAG optfile_opt defopts optdepend_list
{ defflag($2, $3, $4, 0); }
- | OBSOLETE DEFFLAG optfile_opt defopts
+;
+
+define_obsolete_flag:
+ OBSOLETE DEFFLAG optfile_opt defopts
{ defflag($3, $4, NULL, 1); }
- | DEFPARAM optfile_opt defopts optdepend_list
+;
+
+define_param:
+ DEFPARAM optfile_opt defopts optdepend_list
{ defparam($2, $3, $4, 0); }
- | OBSOLETE DEFPARAM optfile_opt defopts
+;
+
+define_obsolete_param:
+ OBSOLETE DEFPARAM optfile_opt defopts
{ defparam($3, $4, NULL, 1); }
- | DEVICE devbase interface_opt depend_list
+;
+
+define_device:
+ DEVICE devbase interface_opt depend_list
{ defdev($2, $3, $4, 0); }
- | ATTACH devbase AT atlist devattach_opt depend_list
+;
+
+define_device_attachment:
+ 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
+;
+
+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
+ DEFPSEUDO devbase interface_opt depend_list
{ defdev($2, $3, $4, 1); }
- | DEFPSEUDODEV devbase interface_opt depend_list
+;
+
+define_pseudodev:
+ DEFPSEUDODEV devbase interface_opt depend_list
{ defdev($2, $3, $4, 2); }
- | MAJOR '{' majorlist '}'
- | VERSION NUMBER { setversion($2.val); }
;
-/* source file: file foo/bar.c bar|baz needs-flag compile-with blah */
-file:
- XFILE filename fopts fflags rule { addfile($2, $3, $4, $5); }
+define_major:
+ MAJOR '{' majorlist '}'
+;
+
+define_version:
+ VERSION int32 { setversion($2); }
;
/* file options: optional expression of conditions */
@@ -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; }
;
/************************************************************/
Index: src/usr.bin/config/hash.c
diff -u src/usr.bin/config/hash.c:1.8 src/usr.bin/config/hash.c:1.8.10.1
--- src/usr.bin/config/hash.c:1.8 Mon Mar 12 02:58:55 2012
+++ src/usr.bin/config/hash.c Fri Mar 6 21:00:23 2015
@@ -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
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,21 +317,33 @@ ht_remove(struct hashtab *ht, const char
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
@@ -301,6 +351,22 @@ ht_lookup(struct hashtab *ht, const char
*/
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)
{
struct hashent *hp;
Index: src/usr.bin/config/lint.c
diff -u src/usr.bin/config/lint.c:1.14 src/usr.bin/config/lint.c:1.14.10.1
--- src/usr.bin/config/lint.c:1.14 Tue Mar 20 20:34:57 2012
+++ src/usr.bin/config/lint.c Fri Mar 6 21:00:23 2015
@@ -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>
Index: src/usr.bin/config/main.c
diff -u src/usr.bin/config/main.c:1.54 src/usr.bin/config/main.c:1.54.2.1
--- src/usr.bin/config/main.c:1.54 Sat Aug 9 12:40:14 2014
+++ src/usr.bin/config/main.c Fri Mar 6 21:00:23 2015
@@ -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 *,
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, struc
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 *
/* 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 n
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 n
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
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);
Index: src/usr.bin/config/mkdevsw.c
diff -u src/usr.bin/config/mkdevsw.c:1.10 src/usr.bin/config/mkdevsw.c:1.10.24.1
--- src/usr.bin/config/mkdevsw.c:1.10 Fri Jul 30 16:23:49 2010
+++ src/usr.bin/config/mkdevsw.c Fri Mar 6 21:00:23 2015
@@ -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",
Index: src/usr.bin/config/mkheaders.c
diff -u src/usr.bin/config/mkheaders.c:1.21 src/usr.bin/config/mkheaders.c:1.21.10.1
--- src/usr.bin/config/mkheaders.c:1.21 Mon Mar 12 02:58:55 2012
+++ src/usr.bin/config/mkheaders.c Fri Mar 6 21:00:23 2015
@@ -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
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 *v
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 *v
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);
}
Index: src/usr.bin/config/mkioconf.c
diff -u src/usr.bin/config/mkioconf.c:1.21 src/usr.bin/config/mkioconf.c:1.21.10.1
--- src/usr.bin/config/mkioconf.c:1.21 Sun Mar 11 21:16:08 2012
+++ src/usr.bin/config/mkioconf.c Fri Mar 6 21:00:23 2015
@@ -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
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",
Index: src/usr.bin/config/mkmakefile.c
diff -u src/usr.bin/config/mkmakefile.c:1.15 src/usr.bin/config/mkmakefile.c:1.15.10.1
--- src/usr.bin/config/mkmakefile.c:1.15 Fri Jun 8 08:56:45 2012
+++ src/usr.bin/config/mkmakefile.c Fri Mar 6 21:00:23 2015
@@ -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, con
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,62 +348,145 @@ 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),
- oi->oi_path);
+ prologue = filetype_prologue(&oi->oi_fit);
}
}
- lpos += len + 1;
- sp = ' ';
+ fprintf(fp, "\t%s%s%s%s \\\n", prologue, prefix, sep,
+ oi->oi_path);
}
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 uppe
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);
+ /*
+ * 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");
+ }
+ /*
+ * Generate per-kernel rules.
+ */
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"
- "\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);
+ 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);
}
/*
Index: src/usr.bin/config/mkswap.c
diff -u src/usr.bin/config/mkswap.c:1.7 src/usr.bin/config/mkswap.c:1.7.26.1
--- src/usr.bin/config/mkswap.c:1.7 Tue Jan 20 18:20:48 2009
+++ src/usr.bin/config/mkswap.c Fri Mar 6 21:00:23 2015
@@ -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");
/*
Index: src/usr.bin/config/pack.c
diff -u src/usr.bin/config/pack.c:1.8 src/usr.bin/config/pack.c:1.8.24.1
--- src/usr.bin/config/pack.c:1.8 Mon Mar 8 10:19:14 2010
+++ src/usr.bin/config/pack.c Fri Mar 6 21:00:23 2015
@@ -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,
Index: src/usr.bin/config/scan.l
diff -u src/usr.bin/config/scan.l:1.17 src/usr.bin/config/scan.l:1.17.10.1
--- src/usr.bin/config/scan.l:1.17 Tue Mar 20 20:34:57 2012
+++ src/usr.bin/config/scan.l Fri Mar 6 21:00:23 2015
@@ -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, in
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, in
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
Index: src/usr.bin/config/sem.c
diff -u src/usr.bin/config/sem.c:1.43 src/usr.bin/config/sem.c:1.43.2.1
--- src/usr.bin/config/sem.c:1.43 Thu May 29 07:47:45 2014
+++ src/usr.bin/config/sem.c Fri Mar 6 21:00:23 2015
@@ -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");
@@ -197,19 +278,24 @@ setident(const char *i)
* 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,56 +308,100 @@ defattr(const char *name, struct loclist
"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_name = name;
- if (locs != NULL) {
- 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;
+ 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;
}
- if (devclass) {
- char classenum[256], *cp;
- int errored = 0;
-
- (void)snprintf(classenum, sizeof(classenum), "DV_%s", name);
- for (cp = classenum + 3; *cp; cp++) {
- if (!errored &&
- (!isalnum((unsigned char)*cp) ||
- (isalpha((unsigned char)*cp) && !islower((unsigned char)*cp)))) {
- cfgerror("device class names must be "
- "lower-case alphanumeric characters");
- errored = 1;
- }
- *cp = toupper((unsigned char)*cp);
- }
- a->a_devclass = intern(classenum);
- } else
- a->a_devclass = NULL;
+ a->a_name = name;
+ 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);
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;
+ if (deps)
+ CFGDBG(2, "attr `%s' iface with deps", a->a_name);
+ return (0);
+}
- /* Expand the attribute to check for cycles in the graph. */
- expandattr(a, NULL);
+/* "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 &&
+ (!isalnum((unsigned char)*cp) ||
+ (isalpha((unsigned char)*cp) && !islower((unsigned char)*cp)))) {
+ cfgerror("device class names must be "
+ "lower-case alphanumeric characters");
+ errored = 1;
+ }
+ *cp = (char)toupper((unsigned char)*cp);
+ }
+ a->a_devclass = intern(classenum);
return (0);
}
@@ -332,7 +462,6 @@ defdev(struct devbase *dev, struct locli
{
struct loclist *ll;
struct attrlist *al;
- struct attr *a;
if (dev == &errdev)
goto bad;
@@ -354,7 +483,7 @@ defdev(struct devbase *dev, struct locli
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 locli
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 locli
* 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 d
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
@@ -605,6 +742,41 @@ getattr(const char *name)
}
/*
+ * 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
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
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
* 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, 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,
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));
}
@@ -1761,10 +1954,73 @@ split(const char *name, size_t nlen, cha
}
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;
+
+ 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)
+{
- (void)ht_insert(selecttab, a->a_name, __UNCONST(a->a_name));
+ 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 dev
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 *at
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;
Index: src/usr.bin/config/sem.h
diff -u src/usr.bin/config/sem.h:1.10 src/usr.bin/config/sem.h:1.10.10.1
--- src/usr.bin/config/sem.h:1.10 Sun Mar 11 21:16:08 2012
+++ src/usr.bin/config/sem.h Fri Mar 6 21:00:23 2015
@@ -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 c
extern const char *s_qmark;
extern const char *s_none;
extern const char *s_ifnet;
+extern size_t nattrs;
Index: src/usr.bin/config/util.c
diff -u src/usr.bin/config/util.c:1.16 src/usr.bin/config/util.c:1.16.4.1
--- src/usr.bin/config/util.c:1.16 Fri Nov 1 21:39:13 2013
+++ src/usr.bin/config/util.c Fri Mar 6 21:00:23 2015
@@ -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)
@@ -414,6 +419,17 @@ condexpr_destroy(struct condexpr *expr)
*/
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, ...)
{
va_list ap;
@@ -435,6 +451,12 @@ cfgxwarn(const char *file, int line, con
}
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)
{
cfgvxmsg(file, line, "warning: ", fmt, ap);
Added files:
Index: src/usr.bin/config/TODO
diff -u /dev/null src/usr.bin/config/TODO:1.14.2.2
--- /dev/null Fri Mar 6 21:00:23 2015
+++ src/usr.bin/config/TODO Fri Mar 6 21:00:23 2015
@@ -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.)