From: Nicolas Pitre <nicolas.pitre@linaro.org>
To: Michal Marek <mmarek@suse.com>, linux-kbuild@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Al Viro <viro@ZenIV.linux.org.uk>,
Rusty Russell <rusty@rustcorp.com.au>
Subject: [PATCH v2 4/6] fixdep: add fine grained build dependencies for exported symbols
Date: Wed, 10 Feb 2016 00:08:26 -0500 [thread overview]
Message-ID: <1455080908-22272-5-git-send-email-nicolas.pitre@linaro.org> (raw)
In-Reply-To: <1455080908-22272-1-git-send-email-nicolas.pitre@linaro.org>
Like for kconfig options, we now have the ability to compile in and
out individual EXPORT_SYMBOL() declarations based on the content of
include/generated/autoksyms.h. However we don't want the entire
world to be rebuilt whenever that file is touched.
Let's apply the same build dependency trick used with config symbols
to those EXPORT_SYMBOL() instances. The key in this case is the actual
symbol name being exported. All symbol names are collapsed to lowercase
path names whose time stamp provide fine grained dependencies.
Because of the lowercasing, there might be name collisions triggering
spurious rebuilds for similar symbols. But this shouldn't be a big issue
in practice. (This is the case for CONFIG symbols and I didn't want to
be different here, whatever the original reason for doing so.)
To avoid needless build overhead, the exported symbol name parsing is
performed only when CONFIG_TRIM_UNUSED_KSYMS is selected. A new cmdline
argument is added to that effect.
Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Rusty Russell <rusty@rustcorp.com.au>
---
scripts/Kbuild.include | 3 ++-
scripts/Makefile.build | 3 ++-
scripts/basic/fixdep.c | 69 ++++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 1db6d73c8d..e28afc039a 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -257,7 +257,8 @@ if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
- scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
+ scripts/basic/fixdep $(if $(CONFIG_TRIM_UNUSED_KSYMS),-e) \
+ $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp; \
rm -f $(depfile); \
mv -f $(dot-target).tmp $(dot-target).cmd)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index f4b4320e0d..01b3eae7ed 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -247,7 +247,8 @@ define rule_cc_o_c
$(cmd_modversions) \
$(call echo-cmd,record_mcount) \
$(cmd_record_mcount) \
- scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
+ scripts/basic/fixdep $(if $(CONFIG_TRIM_UNUSED_KSYMS),-e) \
+ $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
$(dot-target).tmp; \
rm -f $(depfile); \
mv -f $(dot-target).tmp $(dot-target).cmd
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 63f129021d..3fa3e00aca 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -120,13 +120,20 @@
#define INT_NFIG ntohl(0x4e464947)
#define INT_FIG_ ntohl(0x4649475f)
+#define INT_EXPO ntohl(0x4558504f)
+#define INT_XPOR ntohl(0x58504f52)
+#define INT_PORT ntohl(0x504f5254)
+#define INT_ORT_ ntohl(0x4f52545f)
+
+int parse_export_symbol;
char *target;
char *depfile;
char *cmdline;
static void usage(void)
{
- fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
+ fprintf(stderr, "Usage: fixdep [-e] <depfile> <target> <cmdline>\n");
+ fprintf(stderr, " -e parse EXPORT_SYMBOL_* too.\n");
exit(1);
}
@@ -140,6 +147,7 @@ static void print_cmdline(void)
struct item {
struct item *next;
+ const char *type;
unsigned int len;
unsigned int hash;
char name[0];
@@ -161,12 +169,12 @@ static unsigned int strhash(const char *str, unsigned int sz)
/*
* Lookup a value in the configuration string.
*/
-static int is_defined_config(const char *name, int len, unsigned int hash)
+static int is_defined_string(const char *type, const char *name, int len, unsigned int hash)
{
struct item *aux;
for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) {
- if (aux->hash == hash && aux->len == len &&
+ if (aux->hash == hash && aux->len == len && aux->type == type &&
memcmp(aux->name, name, len) == 0)
return 1;
}
@@ -176,7 +184,7 @@ static int is_defined_config(const char *name, int len, unsigned int hash)
/*
* Add a new value to the configuration string.
*/
-static void define_config(const char *name, int len, unsigned int hash)
+static void define_string(const char *type, const char *name, int len, unsigned int hash)
{
struct item *aux = malloc(sizeof(*aux) + len);
@@ -186,25 +194,26 @@ static void define_config(const char *name, int len, unsigned int hash)
}
memcpy(aux->name, name, len);
aux->len = len;
+ aux->type = type;
aux->hash = hash;
aux->next = hashtab[hash % HASHSZ];
hashtab[hash % HASHSZ] = aux;
}
/*
- * Record the use of a CONFIG_* word.
+ * Record the use of a CONFIG_* word, or the argument to EXPORT_MODULE*()
*/
-static void use_config(const char *m, int slen)
+static void use_dep(const char *type, const char *m, int slen)
{
unsigned int hash = strhash(m, slen);
int c, i;
- if (is_defined_config(m, slen, hash))
+ if (is_defined_string(type, m, slen, hash))
return;
- define_config(m, slen, hash);
+ define_string(type, m, slen, hash);
- printf(" $(wildcard include/config/");
+ printf(" $(wildcard include/%s/", type);
for (i = 0; i < slen; i++) {
c = m[i];
if (c == '_')
@@ -228,7 +237,17 @@ static void parse_config_file(const char *map, size_t len)
if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
+
+ if (!parse_export_symbol)
+ continue;
+
+ if (*m == INT_EXPO) { p = (char *) m ; goto export; }
+ if (*m == INT_XPOR) { p = (char *) m-1; goto export; }
+ if (*m == INT_PORT) { p = (char *) m-2; goto export; }
+ if (*m == INT_ORT_) { p = (char *) m-3; goto export; }
+
continue;
+
conf:
if (p > map + len - 7)
continue;
@@ -240,12 +259,36 @@ static void parse_config_file(const char *map, size_t len)
if (!memcmp(q - 7, "_MODULE", 7))
q -= 7;
if (q - p > 0)
- use_config(p, q - p);
+ use_dep("config", p, q - p);
break;
}
}
continue;
+ export:
+ if (p[-1] == '_' && (p >= map + 2 && p[-2] == '_'))
+ continue;
+ if (p > map + len - 7 || memcmp(p, "EXPORT_", 7) != 0)
+ continue;
+ p += 7;
+ if (p <= map + len - 6 && memcmp(p, "EARLY_", 6) == 0)
+ p += 6;
+ if (p <= map + len - 8 && memcmp(p, "PER_CPU_", 8) == 0)
+ p += 8;
+ if (p > map + len - 6 || memcmp(p, "SYMBOL", 6) != 0)
+ continue;
+ p += 6;
+ while (p < map + len && *p != '(' && *p != '\n')
+ p++;
+ q = p + 1;
+ while (q < map + len && *q != ')' && *q != '\n' && *q != '#')
+ q++;
+ if (q >= map + len || *p != '(' || *q != ')')
+ continue;
+ while (isblank(*++p));
+ while (isblank(q[-1])) q--;
+ if (q - p > 0)
+ use_dep("config/ksym", p, q - p);
}
}
@@ -330,6 +373,7 @@ static void parse_dep_file(void *map, size_t len)
if (strrcmp(s, "include/generated/autoconf.h") &&
strrcmp(s, "arch/um/include/uml-config.h") &&
strrcmp(s, "include/linux/kconfig.h") &&
+ strrcmp(s, "include/generated/autoksyms.h") &&
strrcmp(s, ".ver")) {
/*
* Do not list the source file as dependency,
@@ -429,7 +473,10 @@ int main(int argc, char *argv[])
{
traps();
- if (argc != 4)
+ if (argc == 5 && !strcmp(argv[1], "-e")) {
+ parse_export_symbol = 1;
+ argv++;
+ } else if (argc != 4)
usage();
depfile = argv[1];
--
2.5.0
next prev parent reply other threads:[~2016-02-10 5:09 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-10 5:08 [PATCH v2 0/6] Trim unused exported kernel symbols Nicolas Pitre
2016-02-10 5:08 ` [PATCH v2 1/6] kbuild: record needed exported symbols for modules Nicolas Pitre
2016-02-10 5:08 ` [PATCH v2 2/6] allow for per-symbol configurable EXPORT_SYMBOL() Nicolas Pitre
2016-02-10 5:08 ` [PATCH v2 3/6] fixdep: minor cleanup Nicolas Pitre
2016-02-10 5:08 ` Nicolas Pitre [this message]
2016-02-10 5:08 ` [PATCH v2 5/6] create/adjust generated/autoksyms.h Nicolas Pitre
2016-02-10 5:08 ` [PATCH v2 6/6] kconfig option for TRIM_UNUSED_KSYMS Nicolas Pitre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1455080908-22272-5-git-send-email-nicolas.pitre@linaro.org \
--to=nicolas.pitre@linaro.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mmarek@suse.com \
--cc=rusty@rustcorp.com.au \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).