summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:13:48 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:13:48 -0800
commit96faec945f39cab38403f60f515bff43660b4dab (patch)
treee6681330a42303bb34be80d347cd01ff79f5b80a /scripts
parent2926328554fa740518e2a6585b2cefb01e5f65f3 (diff)
parent9bb482476c6c9d1ae033306440c51ceac93ea80c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next: (25 commits) allow stripping of generated symbols under CONFIG_KALLSYMS_ALL kbuild: strip generated symbols from *.ko kbuild: simplify use of genksyms kernel-doc: check for extra kernel-doc notations kbuild: add headerdep used to detect inclusion cycles in header files kbuild: fix string equality testing in tags.sh kbuild: fix make tags/cscope kbuild: fix make incompatibility kbuild: remove TAR_IGNORE setlocalversion: add git-svn support setlocalversion: print correct subversion revision scripts: improve the decodecode script scripts/package: allow custom options to rpm genksyms: allow to ignore symbol checksum changes genksyms: track symbol checksum changes tags and cscope support really belongs in a shell script kconfig: fix options to check-lxdialog.sh kbuild: gen_init_cpio expands shell variables in file names remove bashisms from scripts/extract-ikconfig kbuild: teach mkmakfile to be silent ...
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include22
-rw-r--r--scripts/Makefile.build67
-rw-r--r--scripts/Makefile.lib15
-rw-r--r--scripts/Makefile.modinst3
-rwxr-xr-xscripts/decodecode32
-rwxr-xr-xscripts/extract-ikconfig8
-rw-r--r--scripts/genksyms/genksyms.c277
-rw-r--r--scripts/genksyms/genksyms.h7
-rw-r--r--scripts/genksyms/keywords.c_shipped189
-rw-r--r--scripts/genksyms/keywords.gperf2
-rwxr-xr-xscripts/headerdep.pl193
-rw-r--r--scripts/kallsyms.c21
-rw-r--r--scripts/kconfig/lxdialog/check-lxdialog.sh2
-rwxr-xr-xscripts/kernel-doc67
-rwxr-xr-xscripts/mkcompile_h6
-rw-r--r--scripts/mkmakefile4
-rw-r--r--scripts/mksysmap7
-rw-r--r--scripts/package/Makefile9
-rwxr-xr-xscripts/setlocalversion7
-rw-r--r--scripts/strip-symbols22
-rwxr-xr-xscripts/tags.sh160
21 files changed, 923 insertions, 197 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 982dcae7bbe2..c29be8f90248 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -25,6 +25,13 @@ basetarget = $(basename $(notdir $@))
escsq = $(subst $(squote),'\$(squote)',$1)
###
+# Easy method for doing a status message
+ kecho := :
+ quiet_kecho := echo
+silent_kecho := :
+kecho := $($(quiet)kecho)
+
+###
# filechk is used to check if the content of a generated file is updated.
# Sample usage:
# define filechk_sample
@@ -39,22 +46,15 @@ escsq = $(subst $(squote),'\$(squote)',$1)
# - If they are equal no change, and no timestamp update
# - stdin is piped in from the first prerequisite ($<) so one has
# to specify a valid file as first prerequisite (often the kbuild file)
- chk_filechk = :
- quiet_chk_filechk = echo ' CHK $@'
-silent_chk_filechk = :
- upd_filechk = :
- quiet_upd_filechk = echo ' UPD $@'
-silent_upd_filechk = :
-
define filechk
$(Q)set -e; \
- $($(quiet)chk_filechk); \
+ $(kecho) ' CHK $@'; \
mkdir -p $(dir $@); \
$(filechk_$(1)) < $< > $@.tmp; \
if [ -r $@ ] && cmp -s $@ $@.tmp; then \
rm -f $@.tmp; \
else \
- $($(quiet)upd_filechk); \
+ $(kecho) ' UPD $@'; \
mv -f $@.tmp $@; \
fi
endef
@@ -144,7 +144,9 @@ ld-option = $(call try-run,\
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
# Prefix -I with $(srctree) if it is not an absolute path.
-addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)
+# skip if -I has no parameter
+addtree = $(if $(patsubst -I%,%,$(1)), \
+$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1))
# Find all -I options and call addtree
flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 7a176773af85..5d900307de3e 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -151,14 +151,20 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
$(obj)/%.i: $(src)/%.c FORCE
$(call if_changed_dep,cc_i_c)
+cmd_genksyms = \
+ $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
+ $(GENKSYMS) -T $@ -A -a $(ARCH) \
+ $(if $(KBUILD_PRESERVE),-p) \
+ $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
+
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
-cmd_cc_symtypes_c = \
- $(CPP) -D__GENKSYMS__ $(c_flags) $< \
- | $(GENKSYMS) -T $@ >/dev/null; \
- test -s $@ || rm -f $@
+cmd_cc_symtypes_c = \
+ set -e; \
+ $(call cmd_genksyms, true) >/dev/null; \
+ test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.c FORCE
- $(call if_changed_dep,cc_symtypes_c)
+ $(call cmd,cc_symtypes_c)
# C (.c) files
# The C file is compiled and updated dependency information is generated.
@@ -171,30 +177,38 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
else
# When module versioning is enabled the following steps are executed:
-# o compile a .tmp_<file>.o from <file>.c
-# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
-# not export symbols, we just rename .tmp_<file>.o to <file>.o and
+# o compile a .tmp_<file>.s from <file>.c
+# o if .tmp_<file>.s doesn't contain a __ksymtab version, i.e. does
+# not export symbols, we just assemble .tmp_<file>.s to <file>.o and
# are done.
# o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way
-# that they are usable as a linker script
-# o generate <file>.o from .tmp_<file>.o using the linker to
-# replace the unresolved symbols __crc_exported_symbol with
-# the actual value of the checksum generated by genksyms
+# that they are usable as assembly source
+# o assemble <file>.o from .tmp_<file>.s forcing inclusion of directives
+# defining the actual values of __crc_*, followed by objcopy-ing them
+# to force these symbols to be local to permit stripping them later.
+s_file = $(@D)/.tmp_$(@F:.o=.s)
+v_file = $(@D)/.tmp_$(@F:.o=.v)
+tmp_o_file = $(@D)/.tmp_$(@F)
+no_g_c_flags = $(filter-out -g%,$(c_flags))
+
+cmd_cc_o_c = $(CC) $(c_flags) -S -o $(s_file) $<
-cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
cmd_modversions = \
- if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
- $(CPP) -D__GENKSYMS__ $(c_flags) $< \
- | $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \
- -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
+ if grep -q __ksymtab $(s_file); then \
+ if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \
+ && $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \
+ -o $(tmp_o_file) $(s_file) \
+ && $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \
+ $(tmp_o_file) $@; \
+ then \
+ : ; \
+ else \
+ rm -f $@; exit 1; \
+ fi; \
else \
- mv -f $(@D)/.tmp_$(@F) $@; \
+ rm -f $(v_file); \
+ $(CC) $(no_g_c_flags) -c -o $@ $(s_file); \
fi;
endif
@@ -211,7 +225,12 @@ define rule_cc_o_c
$(cmd_record_mcount) \
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
$(dot-target).tmp; \
- rm -f $(depfile); \
+ if [ -r $(@D)/.tmp_$(@F:.o=.v) ]; then \
+ echo >> $(dot-target).tmp; \
+ echo '$@: $(GENKSYMS)' >> $(dot-target).tmp; \
+ echo '$(GENKSYMS):: ;' >> $(dot-target).tmp; \
+ fi; \
+ rm -f $(depfile) $(@D)/.tmp_$(@F:.o=.?); \
mv -f $(dot-target).tmp $(dot-target).cmd
endef
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index b4ca38a21158..e06365775bdf 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -104,9 +104,11 @@ else
debug_flags =
endif
-orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
+orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
+ $(ccflags-y) $(CFLAGS_$(basetarget).o)
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
-_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
+_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \
+ $(asflags-y) $(AFLAGS_$(basetarget).o)
_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
# If building the kernel in a separate objtree expand all occurrences
@@ -127,15 +129,16 @@ __a_flags = $(call flags,_a_flags)
__cpp_flags = $(call flags,_cpp_flags)
endif
-c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
- $(__c_flags) $(modkern_cflags) \
+c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+ $(__c_flags) $(modkern_cflags) \
-D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
$(debug_flags)
-a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
+a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(__a_flags) $(modkern_aflags)
-cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
+cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+ $(__cpp_flags)
ld_flags = $(LDFLAGS) $(ldflags-y)
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index efa5d940e632..a5122dce1264 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -17,7 +17,8 @@ __modinst: $(modules)
@:
quiet_cmd_modules_install = INSTALL $@
- cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@)
+ cmd_modules_install = mkdir -p $(2); \
+ $(mod_strip_cmd) $@ $(2)/$(notdir $@) || cp $@ $(2)
# Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra
diff --git a/scripts/decodecode b/scripts/decodecode
index 235d3938529d..4b00647814bc 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -7,7 +7,7 @@
# AFLAGS=--32 decodecode < 386.oops
cleanup() {
- rm -f $T $T.s $T.o
+ rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa
exit 1
}
@@ -44,21 +44,33 @@ if [ $marker -eq 0 ]; then
marker=`expr index "$code" "\("`
fi
+touch $T.oo
if [ $marker -ne 0 ]; then
- beforemark=`echo "$code" | cut -c-$((${marker} - 1))`
+ echo All code >> $T.oo
+ echo ======== >> $T.oo
+ beforemark=`echo "$code"`
echo -n " .byte 0x" > $T.s
- echo $beforemark | sed -e 's/ /,0x/g' >> $T.s
- as $AFLAGS -o $T.o $T.s
- objdump -S $T.o
- rm $T.o $T.s
+ echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s
+ as $AFLAGS -o $T.o $T.s &> /dev/null
+ objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo
+ cat $T.ooo >> $T.oo
+ rm -f $T.o $T.s $T.ooo
# and fix code at-and-after marker
code=`echo "$code" | cut -c$((${marker} + 1))-`
fi
-
+echo Code starting with the faulting instruction > $T.aa
+echo =========================================== >> $T.aa
code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'`
echo -n " .byte 0x" > $T.s
echo $code >> $T.s
-as $AFLAGS -o $T.o $T.s
-objdump -S $T.o
-rm $T $T.s $T.o
+as $AFLAGS -o $T.o $T.s &> /dev/null
+objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa
+cat $T.aaa >> $T.aa
+
+faultline=`cat $T.aaa | head -1 | cut -d":" -f2`
+
+cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g"
+echo
+cat $T.aa
+cleanup
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig
index 8187e6f0dc2f..72997c353cb3 100755
--- a/scripts/extract-ikconfig
+++ b/scripts/extract-ikconfig
@@ -8,8 +8,8 @@ test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1
IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
-function dump_config {
- typeset file="$1"
+dump_config() {
+ file="$1"
start=`$binoffset $file $IKCFG_ST 2>/dev/null`
[ "$?" != "0" ] && start="-1"
@@ -18,8 +18,8 @@ function dump_config {
fi
end=`$binoffset $file $IKCFG_ED 2>/dev/null`
- let start="$start + 8"
- let size="$end - $start"
+ start=`expr $start + 8`
+ size=`expr $end - $start`
dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index c249274e005a..f8bb4cabd62d 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -42,7 +42,8 @@ static FILE *debugfile;
int cur_line = 1;
char *cur_filename;
-static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings;
+static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
+ flag_preserve, flag_warnings, flag_asm;
static const char *arch = "";
static const char *mod_prefix = "";
@@ -58,6 +59,8 @@ static const char *const symbol_type_name[] = {
static int equal_list(struct string_list *a, struct string_list *b);
static void print_list(FILE * f, struct string_list *list);
+static void print_location(void);
+static void print_type_name(enum symbol_type type, const char *name);
/*----------------------------------------------------------------------*/
@@ -151,27 +154,83 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns)
for (sym = symtab[h]; sym; sym = sym->hash_next)
if (map_to_ns(sym->type) == map_to_ns(ns) &&
- strcmp(name, sym->name) == 0)
+ strcmp(name, sym->name) == 0 &&
+ sym->is_declared)
break;
return sym;
}
-struct symbol *add_symbol(const char *name, enum symbol_type type,
- struct string_list *defn, int is_extern)
+static int is_unknown_symbol(struct symbol *sym)
+{
+ struct string_list *defn;
+
+ return ((sym->type == SYM_STRUCT ||
+ sym->type == SYM_UNION ||
+ sym->type == SYM_ENUM) &&
+ (defn = sym->defn) && defn->tag == SYM_NORMAL &&
+ strcmp(defn->string, "}") == 0 &&
+ (defn = defn->next) && defn->tag == SYM_NORMAL &&
+ strcmp(defn->string, "UNKNOWN") == 0 &&
+ (defn = defn->next) && defn->tag == SYM_NORMAL &&
+ strcmp(defn->string, "{") == 0);
+}
+
+struct symbol *__add_symbol(const char *name, enum symbol_type type,
+ struct string_list *defn, int is_extern,
+ int is_reference)
{
unsigned long h = crc32(name) % HASH_BUCKETS;
struct symbol *sym;
+ enum symbol_status status = STATUS_UNCHANGED;
for (sym = symtab[h]; sym; sym = sym->hash_next) {
- if (map_to_ns(sym->type) == map_to_ns(type)
- && strcmp(name, sym->name) == 0) {
- if (!equal_list(sym->defn, defn))
+ if (map_to_ns(sym->type) == map_to_ns(type) &&
+ strcmp(name, sym->name) == 0) {
+ if (is_reference)
+ /* fall through */ ;
+ else if (sym->type == type &&
+ equal_list(sym->defn, defn)) {
+ if (!sym->is_declared && sym->is_override) {
+ print_location();
+ print_type_name(type, name);
+ fprintf(stderr, " modversion is "
+ "unchanged\n");
+ }
+ sym->is_declared = 1;
+ return sym;
+ } else if (!sym->is_declared) {
+ if (sym->is_override && flag_preserve) {
+ print_location();
+ fprintf(stderr, "ignoring ");
+ print_type_name(type, name);
+ fprintf(stderr, " modversion change\n");
+ sym->is_declared = 1;
+ return sym;
+ } else {
+ status = is_unknown_symbol(sym) ?
+ STATUS_DEFINED : STATUS_MODIFIED;
+ }
+ } else {
error_with_pos("redefinition of %s", name);
- return sym;
+ return sym;
+ }
+ break;
}
}
+ if (sym) {
+ struct symbol **psym;
+
+ for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) {
+ if (*psym == sym) {
+ *psym = sym->hash_next;
+ break;
+ }
+ }
+ --nsyms;
+ }
+
sym = xmalloc(sizeof(*sym));
sym->name = name;
sym->type = type;
@@ -183,6 +242,10 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
sym->hash_next = symtab[h];
symtab[h] = sym;
+ sym->is_declared = !is_reference;
+ sym->status = status;
+ sym->is_override = 0;
+
if (flag_debug) {
fprintf(debugfile, "Defn for %s %s == <",
symbol_type_name[type], name);
@@ -196,6 +259,18 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
return sym;
}
+struct symbol *add_symbol(const char *name, enum symbol_type type,
+ struct string_list *defn, int is_extern)
+{
+ return __add_symbol(name, type, defn, is_extern, 0);
+}
+
+struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
+ struct string_list *defn, int is_extern)
+{
+ return __add_symbol(name, type, defn, is_extern, 1);
+}
+
/*----------------------------------------------------------------------*/
void free_node(struct string_list *node)
@@ -236,6 +311,90 @@ static int equal_list(struct string_list *a, struct string_list *b)
return !a && !b;
}
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+struct string_list *read_node(FILE *f)
+{
+ char buffer[256];
+ struct string_list node = {
+ .string = buffer,
+ .tag = SYM_NORMAL };
+ int c;
+
+ while ((c = fgetc(f)) != EOF) {
+ if (c == ' ') {
+ if (node.string == buffer)
+ continue;
+ break;
+ } else if (c == '\n') {
+ if (node.string == buffer)
+ return NULL;
+ ungetc(c, f);
+ break;
+ }
+ if (node.string >= buffer + sizeof(buffer) - 1) {
+ fprintf(stderr, "Token too long\n");
+ exit(1);
+ }
+ *node.string++ = c;
+ }
+ if (node.string == buffer)
+ return NULL;
+ *node.string = 0;
+ node.string = buffer;
+
+ if (node.string[1] == '#') {
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) {
+ if (node.string[0] == symbol_type_name[n][0]) {
+ node.tag = n;
+ node.string += 2;
+ return copy_node(&node);
+ }
+ }
+ fprintf(stderr, "Unknown type %c\n", node.string[0]);
+ exit(1);
+ }
+ return copy_node(&node);
+}
+
+static void read_reference(FILE *f)
+{
+ while (!feof(f)) {
+ struct string_list *defn = NULL;
+ struct string_list *sym, *def;
+ int is_extern = 0, is_override = 0;
+ struct symbol *subsym;
+
+ sym = read_node(f);
+ if (sym && sym->tag == SYM_NORMAL &&
+ !strcmp(sym->string, "override")) {
+ is_override = 1;
+ free_node(sym);
+ sym = read_node(f);
+ }
+ if (!sym)
+ continue;
+ def = read_node(f);
+ if (def && def->tag == SYM_NORMAL &&
+ !strcmp(def->string, "extern")) {
+ is_extern = 1;
+ free_node(def);
+ def = read_node(f);
+ }
+ while (def) {
+ def->next = defn;
+ defn = def;
+ def = read_node(f);
+ }
+ subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
+ defn, is_extern);
+ subsym->is_override = is_override;
+ free_node(sym);
+ }
+}
+
static void print_node(FILE * f, struct string_list *list)
{
if (list->tag != SYM_NORMAL) {
@@ -311,6 +470,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
case SYM_TYPEDEF:
subsym = find_symbol(cur->string, cur->tag);
+ /* FIXME: Bad reference files can segfault here. */
if (subsym->expansion_trail) {
if (flag_dump_defs)
fprintf(debugfile, "%s ", cur->string);
@@ -347,9 +507,22 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
t = n;
n = xmalloc(sizeof(*n));
- n->string = xstrdup("{ UNKNOWN }");
+ n->string = xstrdup("{");
+ n->tag = SYM_NORMAL;
+ n->next = t;
+ t = n;
+
+ n = xmalloc(sizeof(*n));
+ n->string = xstrdup("UNKNOWN");
+ n->tag = SYM_NORMAL;
+ n->next = t;
+ t = n;
+
+ n = xmalloc(sizeof(*n));
+ n->string = xstrdup("}");
n->tag = SYM_NORMAL;
n->next = t;
+ t = n;
subsym =
add_symbol(cur->string, cur->tag, n, 0);
@@ -397,37 +570,75 @@ void export_symbol(const char *name)
error_with_pos("export undefined symbol %s", name);
else {
unsigned long crc;
+ int has_changed = 0;
if (flag_dump_defs)
fprintf(debugfile, "Export %s == <", name);
expansion_trail = (struct symbol *)-1L;
+ sym->expansion_trail = expansion_trail;
+ expansion_trail = sym;
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail;
while (sym != (struct symbol *)-1L) {
struct symbol *n = sym->expansion_trail;
+
+ if (sym->status != STATUS_UNCHANGED) {
+ if (!has_changed) {
+ print_location();
+ fprintf(stderr, "%s: %s: modversion "
+ "changed because of changes "
+ "in ", flag_preserve ? "error" :
+ "warning", name);
+ } else
+ fprintf(stderr, ", ");
+ print_type_name(sym->type, sym->name);
+ if (sym->status == STATUS_DEFINED)
+ fprintf(stderr, " (became defined)");
+ has_changed = 1;
+ if (flag_preserve)
+ errors++;
+ }
sym->expansion_trail = 0;
sym = n;
}
+ if (has_changed)
+ fprintf(stderr, "\n");
if (flag_dump_defs)
fputs(">\n", debugfile);
- /* Used as a linker script. */
- printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc);
+ /* Used as assembly source or a linker script. */
+ printf(flag_asm
+ ? ".equiv %s__crc_%s, %#08lx\n"
+ : "%s__crc_%s = %#08lx ;\n",
+ mod_prefix, name, crc);
}
}
/*----------------------------------------------------------------------*/
+
+static void print_location(void)
+{
+ fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
+}
+
+static void print_type_name(enum symbol_type type, const char *name)
+{
+ if (type != SYM_NORMAL)
+ fprintf(stderr, "%s %s", symbol_type_name[type], name);
+ else
+ fprintf(stderr, "%s", name);
+}
+
void error_with_pos(const char *fmt, ...)
{
va_list args;
if (flag_warnings) {
- fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>",
- cur_line);
+ print_location();
va_start(args, fmt);
vfprintf(stderr, fmt, args);
@@ -440,21 +651,27 @@ void error_with_pos(const char *fmt, ...)
static void genksyms_usage(void)
{
- fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
+ fputs("Usage:\n" "genksyms [-aAdDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
#ifdef __GNU_LIBRARY__
" -a, --arch Select architecture\n"
+ " -A, --asm Generate assembly rather than linker script\n"
" -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
- " -T, --dump-types file Dump expanded types into file (for debugging only)\n"
+ " -r, --reference file Read reference symbols from a file\n"
+ " -T, --dump-types file Dump expanded types into file\n"
+ " -p, --preserve Preserve reference modversions or fail\n"
" -w, --warnings Enable warnings\n"
" -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n"
" -V, --version Print the release version\n"
#else /* __GNU_LIBRARY__ */
" -a Select architecture\n"
+ " -A Generate assembly rather than linker script\n"
" -d Increment the debug level (repeatable)\n"
" -D Dump expanded symbol defs (for debugging only)\n"
- " -T file Dump expanded types into file (for debugging only)\n"
+ " -r file Read reference symbols from a file\n"
+ " -T file Dump expanded types into file\n"
+ " -p Preserve reference modversions or fail\n"
" -w Enable warnings\n"
" -q Disable warnings (default)\n"
" -h Print this message\n"
@@ -465,26 +682,29 @@ static void genksyms_usage(void)
int main(int argc, char **argv)
{
- FILE *dumpfile = NULL;
+ FILE *dumpfile = NULL, *ref_file = NULL;
int o;
#ifdef __GNU_LIBRARY__
struct option long_opts[] = {
{"arch", 1, 0, 'a'},
+ {"asm", 0, 0, 'A'},
{"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'},
{"dump", 0, 0, 'D'},
+ {"reference", 1, 0, 'r'},
{"dump-types", 1, 0, 'T'},
+ {"preserve", 0, 0, 'p'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
- while ((o = getopt_long(argc, argv, "a:dwqVDT:h",
+ while ((o = getopt_long(argc, argv, "a:dwqVADr:T:ph",
&long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */
- while ((o = getopt(argc, argv, "a:dwqVDT:h")) != EOF)
+ while ((o = getopt(argc, argv, "a:dwqVADr:T:ph")) != EOF)
#endif /* __GNU_LIBRARY__ */
switch (o) {
case 'a':
@@ -502,9 +722,20 @@ int main(int argc, char **argv)
case 'V':
fputs("genksyms version 2.5.60\n", stderr);
break;
+ case 'A':
+ flag_asm = 1;
+ break;
case 'D':
flag_dump_defs = 1;
break;
+ case 'r':
+ flag_reference = 1;
+ ref_file = fopen(optarg, "r");
+ if (!ref_file) {
+ perror(optarg);
+ return 1;
+ }
+ break;
case 'T':
flag_dump_types = 1;
dumpfile = fopen(optarg, "w");
@@ -513,6 +744,9 @@ int main(int argc, char **argv)
return 1;
}
break;
+ case 'p':
+ flag_preserve = 1;
+ break;
case 'h':
genksyms_usage();
return 0;
@@ -533,12 +767,17 @@ int main(int argc, char **argv)
/* setlinebuf(debugfile); */
}
+ if (flag_reference)
+ read_reference(ref_file);
+
yyparse();
if (flag_dump_types && visited_symbols) {
while (visited_symbols != (struct symbol *)-1L) {
struct symbol *sym = visited_symbols;
+ if (sym->is_override)
+ fputs("override ", dumpfile);
if (sym->type != SYM_NORMAL) {
putc(symbol_type_name[sym->type][0], dumpfile);
putc('#', dumpfile);
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
index 2668287aa498..25c4d40cefc1 100644
--- a/scripts/genksyms/genksyms.h
+++ b/scripts/genksyms/genksyms.h
@@ -29,6 +29,10 @@ enum symbol_type {
SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
};
+enum symbol_status {
+ STATUS_UNCHANGED, STATUS_DEFINED, STATUS_MODIFIED
+};
+
struct string_list {
struct string_list *next;
enum symbol_type tag;
@@ -43,6 +47,9 @@ struct symbol {
struct symbol *expansion_trail;
struct symbol *visited;
int is_extern;
+ int is_declared;
+ enum symbol_status status;
+ int is_override;
};
typedef struct string_list **yystype;
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index 971e0113ae7a..83484fe93ede 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.2 */
+/* ANSI-C code produced by gperf version 3.0.1 */
/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -32,7 +32,7 @@
#line 3 "scripts/genksyms/keywords.gperf"
struct resword { const char *name; int token; };
-/* maximum key range = 62, duplicates = 0 */
+/* maximum key range = 64, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 5,
- 65, 65, 65, 65, 65, 65, 35, 65, 65, 65,
- 0, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 0, 65, 0, 65, 5,
- 20, 15, 10, 30, 65, 15, 65, 65, 20, 0,
- 10, 35, 20, 65, 10, 5, 0, 10, 5, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 0,
+ 67, 67, 67, 67, 67, 67, 15, 67, 67, 67,
+ 0, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 0, 67, 0, 67, 5,
+ 25, 20, 15, 30, 67, 15, 67, 67, 10, 0,
+ 10, 40, 20, 67, 10, 5, 0, 10, 15, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,