aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Kbuild.include136
-rw-r--r--scripts/Kconfig.include30
-rw-r--r--scripts/Makefile8
-rw-r--r--scripts/Makefile.build192
-rw-r--r--scripts/Makefile.clean4
-rw-r--r--scripts/Makefile.extrawarn4
-rw-r--r--scripts/Makefile.gcc-plugins118
-rw-r--r--scripts/Makefile.host24
-rw-r--r--scripts/Makefile.kcov10
-rw-r--r--scripts/Makefile.lib99
-rw-r--r--scripts/Makefile.modbuiltin8
-rw-r--r--scripts/Makefile.modinst4
-rw-r--r--scripts/Makefile.modpost6
-rw-r--r--scripts/Makefile.modsign3
-rw-r--r--scripts/Makefile.ubsan4
-rwxr-xr-xscripts/adjust_autoksyms.sh12
-rw-r--r--scripts/asn1_compiler.c4
-rw-r--r--scripts/basic/.gitignore1
-rw-r--r--scripts/basic/Makefile1
-rw-r--r--scripts/basic/fixdep.c14
-rw-r--r--scripts/bin2c.c (renamed from scripts/basic/bin2c.c)0
-rwxr-xr-xscripts/bloat-o-meter4
-rwxr-xr-xscripts/bpf_helpers_doc.py421
-rwxr-xr-xscripts/cc-can-link.sh11
-rwxr-xr-xscripts/check_00index.sh67
-rwxr-xr-xscripts/checkpatch.pl484
-rwxr-xr-xscripts/checkstack.pl18
-rwxr-xr-xscripts/clang-version.sh23
-rwxr-xr-xscripts/coccicheck5
-rw-r--r--scripts/coccinelle/api/alloc/zalloc-simple.cocci41
-rw-r--r--scripts/coccinelle/api/atomic_as_refcounter.cocci129
-rw-r--r--scripts/coccinelle/api/drm-get-put.cocci20
-rw-r--r--scripts/coccinelle/locks/mini_lock.cocci6
-rw-r--r--scripts/coccinelle/null/deref_null.cocci40
-rw-r--r--scripts/coccinelle/tests/doubletest.cocci34
-rwxr-xr-xscripts/depmod.sh30
-rwxr-xr-xscripts/documentation-file-ref-check173
-rw-r--r--scripts/dtc/.gitignore3
-rw-r--r--scripts/dtc/Makefile28
-rw-r--r--scripts/dtc/Makefile.dtc4
-rw-r--r--scripts/dtc/checks.c782
-rw-r--r--scripts/dtc/data.c4
-rw-r--r--scripts/dtc/dtc-lexer.l7
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped2259
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped2321
-rw-r--r--scripts/dtc/dtc-parser.tab.h_shipped125
-rw-r--r--scripts/dtc/dtc-parser.y68
-rw-r--r--scripts/dtc/dtc.c18
-rw-r--r--scripts/dtc/dtc.h28
-rw-r--r--scripts/dtc/flattree.c4
l---------scripts/dtc/include-prefixes/cris1
l---------scripts/dtc/include-prefixes/metag1
-rw-r--r--scripts/dtc/libfdt/fdt.c94
-rw-r--r--scripts/dtc/libfdt/fdt.h6
-rw-r--r--scripts/dtc/libfdt/fdt_addresses.c35
-rw-r--r--scripts/dtc/libfdt/fdt_overlay.c57
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c319
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c114
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c129
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c10
-rw-r--r--scripts/dtc/libfdt/libfdt.h117
-rw-r--r--scripts/dtc/libfdt/libfdt_env.h34
-rw-r--r--scripts/dtc/libfdt/libfdt_internal.h35
-rw-r--r--scripts/dtc/livetree.c48
-rw-r--r--scripts/dtc/srcpos.c5
-rw-r--r--scripts/dtc/srcpos.h6
-rw-r--r--scripts/dtc/treesource.c225
-rwxr-xr-xscripts/dtc/update-dtc-source.sh9
-rw-r--r--scripts/dtc/util.c23
-rw-r--r--scripts/dtc/util.h29
-rw-r--r--scripts/dtc/version_gen.h2
-rw-r--r--scripts/dtc/yamltree.c247
-rwxr-xr-xscripts/extract-vmlinux8
-rwxr-xr-xscripts/extract_xc3028.pl2
-rwxr-xr-xscripts/faddr2line31
-rwxr-xr-xscripts/file-size.sh4
-rw-r--r--scripts/gcc-plugins/Kconfig193
-rw-r--r--scripts/gcc-plugins/Makefile10
-rw-r--r--scripts/gcc-plugins/gcc-common.h26
-rw-r--r--scripts/gcc-plugins/randomize_layout_plugin.c4
-rw-r--r--scripts/gcc-plugins/stackleak_plugin.c427
-rwxr-xr-xscripts/gcc-x86_32-has-stack-protector.sh7
-rwxr-xr-xscripts/gcc-x86_64-has-stack-protector.sh7
-rwxr-xr-xscripts/gen_initramfs_list.sh328
-rw-r--r--scripts/genksyms/.gitignore3
-rw-r--r--scripts/genksyms/Makefile27
-rw-r--r--scripts/genksyms/genksyms.c11
-rw-r--r--scripts/genksyms/lex.lex.c_shipped2291
-rw-r--r--scripts/genksyms/parse.tab.c_shipped2394
-rw-r--r--scripts/genksyms/parse.tab.h_shipped119
-rwxr-xr-xscripts/get_maintainer.pl73
-rwxr-xr-xscripts/headers_install.sh10
-rw-r--r--scripts/kallsyms.c54
-rw-r--r--scripts/kconfig/.gitignore7
-rw-r--r--scripts/kconfig/Makefile245
-rw-r--r--scripts/kconfig/POTFILES.in12
-rwxr-xr-xscripts/kconfig/check.sh14
-rw-r--r--scripts/kconfig/conf.c151
-rw-r--r--scripts/kconfig/confdata.c195
-rw-r--r--scripts/kconfig/expr.c86
-rw-r--r--scripts/kconfig/expr.h10
-rwxr-xr-xscripts/kconfig/gconf-cfg.sh30
-rw-r--r--scripts/kconfig/gconf.c51
-rw-r--r--scripts/kconfig/kconf_id.c1
-rw-r--r--scripts/kconfig/kxgettext.c235
-rw-r--r--scripts/kconfig/lkc.h22
-rw-r--r--scripts/kconfig/lkc_proto.h19
-rwxr-xr-xscripts/kconfig/lxdialog/check-lxdialog.sh93
-rw-r--r--scripts/kconfig/lxdialog/checklist.c4
-rw-r--r--scripts/kconfig/lxdialog/dialog.h8
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c4
-rw-r--r--scripts/kconfig/lxdialog/menubox.c10
-rw-r--r--scripts/kconfig/lxdialog/textbox.c2
-rw-r--r--scripts/kconfig/lxdialog/yesno.c4
-rwxr-xr-xscripts/kconfig/mconf-cfg.sh47
-rw-r--r--scripts/kconfig/mconf.c150
-rw-r--r--scripts/kconfig/menu.c37
-rwxr-xr-xscripts/kconfig/merge_config.sh11
-rw-r--r--scripts/kconfig/nconf-cfg.sh47
-rw-r--r--scripts/kconfig/nconf.c156
-rw-r--r--scripts/kconfig/nconf.h5
-rw-r--r--scripts/kconfig/preprocess.c572
-rwxr-xr-xscripts/kconfig/qconf-cfg.sh32
-rw-r--r--scripts/kconfig/qconf.cc107
-rwxr-xr-xscripts/kconfig/streamline_config.pl4
-rw-r--r--scripts/kconfig/symbol.c220
-rw-r--r--scripts/kconfig/tests/auto_submenu/Kconfig50
-rw-r--r--scripts/kconfig/tests/auto_submenu/__init__.py12
-rw-r--r--scripts/kconfig/tests/auto_submenu/expected_stdout10
-rw-r--r--scripts/kconfig/tests/choice/Kconfig54
-rw-r--r--scripts/kconfig/tests/choice/__init__.py40
-rw-r--r--scripts/kconfig/tests/choice/alldef_expected_config5
-rw-r--r--scripts/kconfig/tests/choice/allmod_expected_config9
-rw-r--r--scripts/kconfig/tests/choice/allno_expected_config5
-rw-r--r--scripts/kconfig/tests/choice/allyes_expected_config9
-rw-r--r--scripts/kconfig/tests/choice/oldask0_expected_stdout10
-rw-r--r--scripts/kconfig/tests/choice/oldask1_config2
-rw-r--r--scripts/kconfig/tests/choice/oldask1_expected_stdout15
-rw-r--r--scripts/kconfig/tests/choice_value_with_m_dep/Kconfig19
-rw-r--r--scripts/kconfig/tests/choice_value_with_m_dep/__init__.py15
-rw-r--r--scripts/kconfig/tests/choice_value_with_m_dep/config2
-rw-r--r--scripts/kconfig/tests/choice_value_with_m_dep/expected_config3
-rw-r--r--scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout4
-rw-r--r--scripts/kconfig/tests/conftest.py291
-rw-r--r--scripts/kconfig/tests/err_recursive_dep/Kconfig63
-rw-r--r--scripts/kconfig/tests/err_recursive_dep/__init__.py10
-rw-r--r--scripts/kconfig/tests/err_recursive_dep/expected_stderr38
-rw-r--r--scripts/kconfig/tests/err_recursive_inc/Kconfig1
-rw-r--r--scripts/kconfig/tests/err_recursive_inc/Kconfig.inc14
-rw-r--r--scripts/kconfig/tests/err_recursive_inc/Kconfig.inc23
-rw-r--r--scripts/kconfig/tests/err_recursive_inc/Kconfig.inc31
-rw-r--r--scripts/kconfig/tests/err_recursive_inc/__init__.py10
-rw-r--r--scripts/kconfig/tests/err_recursive_inc/expected_stderr6
-rw-r--r--scripts/kconfig/tests/inter_choice/Kconfig23
-rw-r--r--scripts/kconfig/tests/inter_choice/__init__.py14
-rw-r--r--scripts/kconfig/tests/inter_choice/defconfig1
-rw-r--r--scripts/kconfig/tests/inter_choice/expected_config4
-rw-r--r--scripts/kconfig/tests/new_choice_with_dep/Kconfig37
-rw-r--r--scripts/kconfig/tests/new_choice_with_dep/__init__.py14
-rw-r--r--scripts/kconfig/tests/new_choice_with_dep/config3
-rw-r--r--scripts/kconfig/tests/new_choice_with_dep/expected_stdout10
-rw-r--r--scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig14
-rw-r--r--scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py19
-rw-r--r--scripts/kconfig/tests/no_write_if_dep_unmet/config1
-rw-r--r--scripts/kconfig/tests/no_write_if_dep_unmet/expected_config5
-rw-r--r--scripts/kconfig/tests/preprocess/builtin_func/Kconfig27
-rw-r--r--scripts/kconfig/tests/preprocess/builtin_func/__init__.py9
-rw-r--r--scripts/kconfig/tests/preprocess/builtin_func/expected_stderr5
-rw-r--r--scripts/kconfig/tests/preprocess/builtin_func/expected_stdout1
-rw-r--r--scripts/kconfig/tests/preprocess/circular_expansion/Kconfig5
-rw-r--r--scripts/kconfig/tests/preprocess/circular_expansion/__init__.py11
-rw-r--r--scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr1
-rw-r--r--scripts/kconfig/tests/preprocess/escape/Kconfig44
-rw-r--r--scripts/kconfig/tests/preprocess/escape/__init__.py8
-rw-r--r--scripts/kconfig/tests/preprocess/escape/expected_stderr10
-rw-r--r--scripts/kconfig/tests/preprocess/variable/Kconfig53
-rw-r--r--scripts/kconfig/tests/preprocess/variable/__init__.py8
-rw-r--r--scripts/kconfig/tests/preprocess/variable/expected_stderr9
-rw-r--r--scripts/kconfig/tests/pytest.ini7
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/Kconfig33
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/__init__.py16
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/expected_stdout02
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/expected_stdout14
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/expected_stdout25
-rw-r--r--scripts/kconfig/util.c61
-rw-r--r--scripts/kconfig/zconf.l136
-rw-r--r--scripts/kconfig/zconf.y58
-rwxr-xr-xscripts/kernel-doc691
-rwxr-xr-xscripts/leaking_addresses.pl372
-rwxr-xr-xscripts/link-vmlinux.sh109
-rwxr-xr-xscripts/mkmakefile22
-rw-r--r--scripts/mod/Makefile2
-rw-r--r--scripts/mod/devicetable-offsets.c7
-rw-r--r--scripts/mod/file2alias.c50
-rw-r--r--scripts/mod/modpost.c115
-rw-r--r--scripts/mod/sumversion.c9
-rwxr-xr-xscripts/namespace.pl2
-rw-r--r--scripts/package/Makefile34
-rwxr-xr-xscripts/package/builddeb227
-rwxr-xr-xscripts/package/buildtar12
-rwxr-xr-xscripts/package/mkdebian223
-rwxr-xr-xscripts/package/mkspec13
-rw-r--r--scripts/recordmcount.c22
-rw-r--r--scripts/recordmcount.h2
-rwxr-xr-xscripts/recordmcount.pl32
-rw-r--r--scripts/selinux/mdp/mdp.c1
-rwxr-xr-xscripts/spdxcheck.py285
-rw-r--r--scripts/spelling.txt90
-rwxr-xr-xscripts/split-man.pl28
-rw-r--r--scripts/subarch.include13
-rwxr-xr-xscripts/tags.sh22
-rwxr-xr-xscripts/tracing/draw_functrace.py2
-rwxr-xr-xscripts/ver_linux75
214 files changed, 8219 insertions, 13596 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 0442c06eefcb..12d302d70128 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,6 +1,7 @@
1# 1#
2# Generated files 2# Generated files
3# 3#
4bin2c
4conmakehash 5conmakehash
5kallsyms 6kallsyms
6pnmtologo 7pnmtologo
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 065324a8046f..bb015551c2d9 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -8,8 +8,7 @@ squote := '
8empty := 8empty :=
9space := $(empty) $(empty) 9space := $(empty) $(empty)
10space_escape := _-_SPACE_-_ 10space_escape := _-_SPACE_-_
11right_paren := ) 11pound := \#
12left_paren := (
13 12
14### 13###
15# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o 14# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
@@ -56,9 +55,8 @@ kecho := $($(quiet)kecho)
56# to specify a valid file as first prerequisite (often the kbuild file) 55# to specify a valid file as first prerequisite (often the kbuild file)
57define filechk 56define filechk
58 $(Q)set -e; \ 57 $(Q)set -e; \
59 $(kecho) ' CHK $@'; \
60 mkdir -p $(dir $@); \ 58 mkdir -p $(dir $@); \
61 $(filechk_$(1)) < $< > $@.tmp; \ 59 $(filechk_$(1)) > $@.tmp; \
62 if [ -r $@ ] && cmp -s $@ $@.tmp; then \ 60 if [ -r $@ ] && cmp -s $@ $@.tmp; then \
63 rm -f $@.tmp; \ 61 rm -f $@.tmp; \
64 else \ 62 else \
@@ -82,71 +80,6 @@ cc-cross-prefix = \
82 echo $(c); \ 80 echo $(c); \
83 fi))) 81 fi)))
84 82
85# Tools for caching Makefile variables that are "expensive" to compute.
86#
87# Here we want to help deal with variables that take a long time to compute
88# by making it easy to store these variables in a cache.
89#
90# The canonical example here is testing for compiler flags. On a simple system
91# each call to the compiler takes 10 ms, but on a system with a compiler that's
92# called through various wrappers it can take upwards of 100 ms. If we have
93# 100 calls to the compiler this can take 1 second (on a simple system) or 10
94# seconds (on a complicated system).
95#
96# The "cache" will be in Makefile syntax and can be directly included.
97# Any time we try to reference a variable that's not in the cache we'll
98# calculate it and store it in the cache for next time.
99
100# Include values from last time
101make-cache := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/,$(if $(obj),$(obj)/)).cache.mk
102$(make-cache): ;
103-include $(make-cache)
104
105cached-data := $(filter __cached_%, $(.VARIABLES))
106
107# If cache exceeds 1000 lines, shrink it down to 500.
108ifneq ($(word 1000,$(cached-data)),)
109$(shell tail -n 500 $(make-cache) > $(make-cache).tmp; \
110 mv $(make-cache).tmp $(make-cache))
111endif
112
113create-cache-dir := $(if $(KBUILD_SRC),$(if $(cache-data),,1))
114
115# Usage: $(call __sanitize-opt,Hello=Hola$(comma)Goodbye Adios)
116#
117# Convert all '$', ')', '(', '\', '=', ' ', ',', ':' to '_'
118__sanitize-opt = $(subst $$,_,$(subst $(right_paren),_,$(subst $(left_paren),_,$(subst \,_,$(subst =,_,$(subst $(space),_,$(subst $(comma),_,$(subst :,_,$(1)))))))))
119
120# Usage: $(call shell-cached,shell_command)
121# Example: $(call shell-cached,md5sum /usr/bin/gcc)
122#
123# If we've already seen a call to this exact shell command (even in a
124# previous invocation of make!) we'll return the value. If not, we'll
125# compute it and store the result for future runs.
126#
127# This is a bit of voodoo, but basic explanation is that if the variable
128# was undefined then we'll evaluate the shell command and store the result
129# into the variable. We'll then store that value in the cache and finally
130# output the value.
131#
132# NOTE: The $$(2) here isn't actually a parameter to __run-and-store. We
133# happen to know that the caller will have their shell command in $(2) so the
134# result of "call"ing this will produce a reference to that $(2). The reason
135# for this strangeness is to avoid an extra level of eval (and escaping) of
136# $(2).
137define __run-and-store
138ifeq ($(origin $(1)),undefined)
139 $$(eval $(1) := $$(shell $$(2)))
140ifeq ($(create-cache-dir),1)
141 $$(shell mkdir -p $(dir $(make-cache)))
142 $$(eval create-cache-dir :=)
143endif
144 $$(shell echo '$(1) := $$($(1))' >> $(make-cache))
145endif
146endef
147__shell-cached = $(eval $(call __run-and-store,$(1)))$($(1))
148shell-cached = $(call __shell-cached,__cached_$(call __sanitize-opt,$(1)),$(1))
149
150# output directory for tests below 83# output directory for tests below
151TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) 84TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
152 85
@@ -154,41 +87,37 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
154# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) 87# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
155# Exit code chooses option. "$$TMP" serves as a temporary file and is 88# Exit code chooses option. "$$TMP" serves as a temporary file and is
156# automatically cleaned up. 89# automatically cleaned up.
157__try-run = set -e; \ 90try-run = $(shell set -e; \
158 TMP="$(TMPOUT).$$$$.tmp"; \ 91 TMP="$(TMPOUT).$$$$.tmp"; \
159 TMPO="$(TMPOUT).$$$$.o"; \ 92 TMPO="$(TMPOUT).$$$$.o"; \
160 if ($(1)) >/dev/null 2>&1; \ 93 if ($(1)) >/dev/null 2>&1; \
161 then echo "$(2)"; \ 94 then echo "$(2)"; \
162 else echo "$(3)"; \ 95 else echo "$(3)"; \
163 fi; \ 96 fi; \
164 rm -f "$$TMP" "$$TMPO" 97 rm -f "$$TMP" "$$TMPO")
165
166try-run = $(shell $(__try-run))
167
168# try-run-cached
169# This works like try-run, but the result is cached.
170try-run-cached = $(call shell-cached,$(__try-run))
171 98
172# as-option 99# as-option
173# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) 100# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
174 101
175as-option = $(call try-run-cached,\ 102as-option = $(call try-run,\
176 $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2)) 103 $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))
177 104
178# as-instr 105# as-instr
179# Usage: cflags-y += $(call as-instr,instr,option1,option2) 106# Usage: cflags-y += $(call as-instr,instr,option1,option2)
180 107
181as-instr = $(call try-run-cached,\ 108as-instr = $(call try-run,\
182 printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) 109 printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
183 110
184# __cc-option 111# __cc-option
185# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) 112# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586)
186__cc-option = $(call try-run-cached,\ 113__cc-option = $(call try-run,\
187 $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) 114 $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4))
188 115
189# Do not attempt to build with gcc plugins during cc-option tests. 116# Do not attempt to build with gcc plugins during cc-option tests.
190# (And this uses delayed resolution so the flags will be up to date.) 117# (And this uses delayed resolution so the flags will be up to date.)
191CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) 118# In addition, do not include the asm macros which are built later.
119CC_OPTION_FILTERED = $(GCC_PLUGINS_CFLAGS) $(ASM_MACRO_FLAGS)
120CC_OPTION_CFLAGS = $(filter-out $(CC_OPTION_FILTERED),$(KBUILD_CFLAGS))
192 121
193# cc-option 122# cc-option
194# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) 123# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
@@ -199,56 +128,42 @@ cc-option = $(call __cc-option, $(CC),\
199# hostcc-option 128# hostcc-option
200# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586) 129# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586)
201hostcc-option = $(call __cc-option, $(HOSTCC),\ 130hostcc-option = $(call __cc-option, $(HOSTCC),\
202 $(HOSTCFLAGS) $(HOST_EXTRACFLAGS),$(1),$(2)) 131 $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS),$(1),$(2))
203 132
204# cc-option-yn 133# cc-option-yn
205# Usage: flag := $(call cc-option-yn,-march=winchip-c6) 134# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
206cc-option-yn = $(call try-run-cached,\ 135cc-option-yn = $(call try-run,\
207 $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) 136 $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
208 137
209# cc-disable-warning 138# cc-disable-warning
210# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) 139# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
211cc-disable-warning = $(call try-run-cached,\ 140cc-disable-warning = $(call try-run,\
212 $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) 141 $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
213 142
214# cc-name
215# Expands to either gcc or clang
216cc-name = $(call shell-cached,$(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc)
217
218# cc-version 143# cc-version
219cc-version = $(call shell-cached,$(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) 144cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
220
221# cc-fullversion
222cc-fullversion = $(call shell-cached,$(CONFIG_SHELL) \
223 $(srctree)/scripts/gcc-version.sh -p $(CC))
224 145
225# cc-ifversion 146# cc-ifversion
226# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) 147# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
227cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4)) 148cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4))
228 149
229# cc-if-fullversion
230# Usage: EXTRA_CFLAGS += $(call cc-if-fullversion, -lt, 040502, -O1)
231cc-if-fullversion = $(shell [ $(cc-fullversion) $(1) $(2) ] && echo $(3) || echo $(4))
232
233# cc-ldoption 150# cc-ldoption
234# Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) 151# Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
235cc-ldoption = $(call try-run-cached,\ 152cc-ldoption = $(call try-run,\
236 $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) 153 $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
237 154
238# ld-option 155# ld-option
239# Usage: LDFLAGS += $(call ld-option, -X) 156# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
240ld-option = $(call try-run-cached,\ 157ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
241 $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -x c /dev/null -c -o "$$TMPO"; \
242 $(LD) $(LDFLAGS) $(1) "$$TMPO" -o "$$TMP",$(1),$(2))
243 158
244# ar-option 159# ar-option
245# Usage: KBUILD_ARFLAGS := $(call ar-option,D) 160# Usage: KBUILD_ARFLAGS := $(call ar-option,D)
246# Important: no spaces around options 161# Important: no spaces around options
247ar-option = $(call try-run-cached, $(AR) rc$(1) "$$TMP",$(1),$(2)) 162ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))
248 163
249# ld-version 164# ld-version
250# Note this is mainly for HJ Lu's 3 number binutil versions 165# Note this is mainly for HJ Lu's 3 number binutil versions
251ld-version = $(call shell-cached,$(LD) --version | $(srctree)/scripts/ld-version.sh) 166ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
252 167
253# ld-ifversion 168# ld-ifversion
254# Usage: $(call ld-ifversion, -ge, 22252, y) 169# Usage: $(call ld-ifversion, -ge, 22252, y)
@@ -272,7 +187,7 @@ modbuiltin := -f $(srctree)/scripts/Makefile.modbuiltin obj
272# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj= 187# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
273# Usage: 188# Usage:
274# $(Q)$(MAKE) $(dtbinst)=dir 189# $(Q)$(MAKE) $(dtbinst)=dir
275dtbinst := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.dtbinst obj 190dtbinst := -f $(srctree)/scripts/Makefile.dtbinst obj
276 191
277### 192###
278# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj= 193# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
@@ -289,7 +204,7 @@ hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj
289# Prefix -I with $(srctree) if it is not an absolute path. 204# Prefix -I with $(srctree) if it is not an absolute path.
290# skip if -I has no parameter 205# skip if -I has no parameter
291addtree = $(if $(patsubst -I%,%,$(1)), \ 206addtree = $(if $(patsubst -I%,%,$(1)), \
292$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1))) 207$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1))
293 208
294# Find all -I options and call addtree 209# Find all -I options and call addtree
295flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) 210flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
@@ -324,11 +239,11 @@ endif
324 239
325# Replace >$< with >$$< to preserve $ when reloading the .cmd file 240# Replace >$< with >$$< to preserve $ when reloading the .cmd file
326# (needed for make) 241# (needed for make)
327# Replace >#< with >\#< to avoid starting a comment in the .cmd file 242# Replace >#< with >$(pound)< to avoid starting a comment in the .cmd file
328# (needed for make) 243# (needed for make)
329# Replace >'< with >'\''< to be able to enclose the whole string in '...' 244# Replace >'< with >'\''< to be able to enclose the whole string in '...'
330# (needed for the shell) 245# (needed for the shell)
331make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1))))) 246make-cmd = $(call escsq,$(subst $(pound),$$(pound),$(subst $$,$$$$,$(cmd_$(1)))))
332 247
333# Find any prerequisites that is newer than target or that does not exist. 248# Find any prerequisites that is newer than target or that does not exist.
334# PHONY targets skipped in both cases. 249# PHONY targets skipped in both cases.
@@ -368,7 +283,7 @@ ksym_dep_filter = \
368 $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \ 283 $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \
369 boot*|build*|cpp_its_S|*cpp_lds_S|dtc|host*|vdso*) : ;; \ 284 boot*|build*|cpp_its_S|*cpp_lds_S|dtc|host*|vdso*) : ;; \
370 *) echo "Don't know how to preprocess $(1)" >&2; false ;; \ 285 *) echo "Don't know how to preprocess $(1)" >&2; false ;; \
371 esac | tr ";" "\n" | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' 286 esac | tr ";" "\n" | sed -n 's/^.*=== __KSYM_\(.*\) ===.*$$/_\1/p'
372 287
373cmd_and_fixdep = \ 288cmd_and_fixdep = \
374 $(echo-cmd) $(cmd_$(1)); \ 289 $(echo-cmd) $(cmd_$(1)); \
@@ -475,3 +390,6 @@ endif
475endef 390endef
476# 391#
477############################################################################### 392###############################################################################
393
394# delete partially updated (i.e. corrupted) files on error
395.DELETE_ON_ERROR:
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
new file mode 100644
index 000000000000..dad5583451af
--- /dev/null
+++ b/scripts/Kconfig.include
@@ -0,0 +1,30 @@
1# Kconfig helper macros
2
3# Convenient variables
4comma := ,
5quote := "
6squote := '
7empty :=
8space := $(empty) $(empty)
9dollar := $
10right_paren := )
11left_paren := (
12
13# $(if-success,<command>,<then>,<else>)
14# Return <then> if <command> exits with 0, <else> otherwise.
15if-success = $(shell,{ $(1); } >/dev/null 2>&1 && echo "$(2)" || echo "$(3)")
16
17# $(success,<command>)
18# Return y if <command> exits with 0, n otherwise
19success = $(if-success,$(1),y,n)
20
21# $(cc-option,<flag>)
22# Return y if the compiler supports <flag>, n otherwise
23cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null)
24
25# $(ld-option,<flag>)
26# Return y if the linker supports <flag>, n otherwise
27ld-option = $(success,$(LD) -v $(1))
28
29# gcc version including patch level
30gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh -p $(CC) | sed 's/^0*//')
diff --git a/scripts/Makefile b/scripts/Makefile
index 25ab143cbe14..ece52ff20171 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -10,6 +10,7 @@
10 10
11HOST_EXTRACFLAGS += -I$(srctree)/tools/include 11HOST_EXTRACFLAGS += -I$(srctree)/tools/include
12 12
13hostprogs-$(CONFIG_BUILD_BIN2C) += bin2c
13hostprogs-$(CONFIG_KALLSYMS) += kallsyms 14hostprogs-$(CONFIG_KALLSYMS) += kallsyms
14hostprogs-$(CONFIG_LOGO) += pnmtologo 15hostprogs-$(CONFIG_LOGO) += pnmtologo
15hostprogs-$(CONFIG_VT) += conmakehash 16hostprogs-$(CONFIG_VT) += conmakehash
@@ -22,8 +23,8 @@ hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
22 23
23HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include 24HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
24HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include 25HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
25HOSTLOADLIBES_sign-file = -lcrypto 26HOSTLDLIBS_sign-file = -lcrypto
26HOSTLOADLIBES_extract-cert = -lcrypto 27HOSTLDLIBS_extract-cert = -lcrypto
27 28
28always := $(hostprogs-y) $(hostprogs-m) 29always := $(hostprogs-y) $(hostprogs-m)
29 30
@@ -38,8 +39,7 @@ build_unifdef: $(obj)/unifdef
38subdir-$(CONFIG_MODVERSIONS) += genksyms 39subdir-$(CONFIG_MODVERSIONS) += genksyms
39subdir-y += mod 40subdir-y += mod
40subdir-$(CONFIG_SECURITY_SELINUX) += selinux 41subdir-$(CONFIG_SECURITY_SELINUX) += selinux
41subdir-$(CONFIG_DTC) += dtc
42subdir-$(CONFIG_GDB_SCRIPTS) += gdb 42subdir-$(CONFIG_GDB_SCRIPTS) += gdb
43 43
44# Let clean descend into subdirs 44# Let clean descend into subdirs
45subdir- += basic kconfig package gcc-plugins 45subdir- += basic dtc kconfig package gcc-plugins
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 4f2b25d43ec9..a8e7ba9f73e8 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -36,30 +36,13 @@ subdir-ccflags-y :=
36 36
37include scripts/Kbuild.include 37include scripts/Kbuild.include
38 38
39# For backward compatibility check that these variables do not change
40save-cflags := $(CFLAGS)
41
42# The filename Kbuild has precedence over Makefile 39# The filename Kbuild has precedence over Makefile
43kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 40kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
44kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) 41kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
45include $(kbuild-file) 42include $(kbuild-file)
46 43
47# If the save-* variables changed error out
48ifeq ($(KBUILD_NOPEDANTIC),)
49 ifneq ("$(save-cflags)","$(CFLAGS)")
50 $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
51 endif
52endif
53
54include scripts/Makefile.lib 44include scripts/Makefile.lib
55 45
56ifdef host-progs
57ifneq ($(hostprogs-y),$(host-progs))
58$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!)
59hostprogs-y += $(host-progs)
60endif
61endif
62
63# Do not include host rules unless needed 46# Do not include host rules unless needed
64ifneq ($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),) 47ifneq ($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),)
65include scripts/Makefile.host 48include scripts/Makefile.host
@@ -73,11 +56,11 @@ endif
73 56
74ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) 57ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
75lib-target := $(obj)/lib.a 58lib-target := $(obj)/lib.a
76obj-y += $(obj)/lib-ksyms.o 59real-obj-y += $(obj)/lib-ksyms.o
77endif 60endif
78 61
79ifneq ($(strip $(obj-y) $(need-builtin)),) 62ifneq ($(strip $(real-obj-y) $(need-builtin)),)
80builtin-target := $(obj)/built-in.o 63builtin-target := $(obj)/built-in.a
81endif 64endif
82 65
83modorder-target := $(obj)/modules.order 66modorder-target := $(obj)/modules.order
@@ -90,21 +73,19 @@ __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
90 @: 73 @:
91 74
92# Linus' kernel sanity checking tool 75# Linus' kernel sanity checking tool
93ifneq ($(KBUILD_CHECKSRC),0) 76ifeq ($(KBUILD_CHECKSRC),1)
94 ifeq ($(KBUILD_CHECKSRC),2) 77 quiet_cmd_checksrc = CHECK $<
95 quiet_cmd_force_checksrc = CHECK $< 78 cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
96 cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ; 79else ifeq ($(KBUILD_CHECKSRC),2)
97 else 80 quiet_cmd_force_checksrc = CHECK $<
98 quiet_cmd_checksrc = CHECK $< 81 cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
99 cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
100 endif
101endif 82endif
102 83
103ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) 84ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),)
104 cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< ; 85 cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< ;
105endif 86endif
106 87
107# Do section mismatch analysis for each module/built-in.o 88# Do section mismatch analysis for each module/built-in.a
108ifdef CONFIG_DEBUG_SECTION_MISMATCH 89ifdef CONFIG_DEBUG_SECTION_MISMATCH
109 cmd_secanalysis = ; scripts/mod/modpost $@ 90 cmd_secanalysis = ; scripts/mod/modpost $@
110endif 91endif
@@ -119,29 +100,17 @@ modkern_cflags = \
119 $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL)) 100 $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
120quiet_modtag := $(empty) $(empty) 101quiet_modtag := $(empty) $(empty)
121 102
122$(real-objs-m) : part-of-module := y 103$(real-obj-m) : part-of-module := y
123$(real-objs-m:.o=.i) : part-of-module := y 104$(real-obj-m:.o=.i) : part-of-module := y
124$(real-objs-m:.o=.s) : part-of-module := y 105$(real-obj-m:.o=.s) : part-of-module := y
125$(real-objs-m:.o=.lst): part-of-module := y 106$(real-obj-m:.o=.lst): part-of-module := y
126 107
127$(real-objs-m) : quiet_modtag := [M] 108$(real-obj-m) : quiet_modtag := [M]
128$(real-objs-m:.o=.i) : quiet_modtag := [M] 109$(real-obj-m:.o=.i) : quiet_modtag := [M]
129$(real-objs-m:.o=.s) : quiet_modtag := [M] 110$(real-obj-m:.o=.s) : quiet_modtag := [M]
130$(real-objs-m:.o=.lst): quiet_modtag := [M] 111$(real-obj-m:.o=.lst): quiet_modtag := [M]
131 112
132$(obj-m) : quiet_modtag := [M] 113$(obj-m) : quiet_modtag := [M]
133
134# Default for not multi-part modules
135modname = $(basetarget)
136
137$(multi-objs-m) : modname = $(modname-multi)
138$(multi-objs-m:.o=.i) : modname = $(modname-multi)
139$(multi-objs-m:.o=.s) : modname = $(modname-multi)
140$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
141$(multi-objs-y) : modname = $(modname-multi)
142$(multi-objs-y:.o=.i) : modname = $(modname-multi)
143$(multi-objs-y:.o=.s) : modname = $(modname-multi)
144$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
145 114
146quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ 115quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
147cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< 116cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $<
@@ -159,7 +128,6 @@ $(obj)/%.i: $(src)/%.c FORCE
159cmd_gensymtypes_c = \ 128cmd_gensymtypes_c = \
160 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ 129 $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
161 $(GENKSYMS) $(if $(1), -T $(2)) \ 130 $(GENKSYMS) $(if $(1), -T $(2)) \
162 $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \
163 $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ 131 $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
164 $(if $(KBUILD_PRESERVE),-p) \ 132 $(if $(KBUILD_PRESERVE),-p) \
165 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) 133 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
@@ -210,7 +178,7 @@ cmd_modversions_c = \
210 $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ 178 $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
211 > $(@D)/.tmp_$(@F:.o=.ver); \ 179 > $(@D)/.tmp_$(@F:.o=.ver); \
212 \ 180 \
213 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ 181 $(LD) $(KBUILD_LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
214 -T $(@D)/.tmp_$(@F:.o=.ver); \ 182 -T $(@D)/.tmp_$(@F:.o=.ver); \
215 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ 183 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
216 else \ 184 else \
@@ -219,6 +187,8 @@ cmd_modversions_c = \
219endif 187endif
220 188
221ifdef CONFIG_FTRACE_MCOUNT_RECORD 189ifdef CONFIG_FTRACE_MCOUNT_RECORD
190ifndef CC_USING_RECORD_MCOUNT
191# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
222ifdef BUILD_C_RECORDMCOUNT 192ifdef BUILD_C_RECORDMCOUNT
223ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") 193ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
224 RECORDMCOUNT_FLAGS = -w 194 RECORDMCOUNT_FLAGS = -w
@@ -237,8 +207,8 @@ else
237sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ 207sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
238 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ 208 "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
239 "$(if $(CONFIG_64BIT),64,32)" \ 209 "$(if $(CONFIG_64BIT),64,32)" \
240 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \ 210 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \
241 "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ 211 "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \
242 "$(if $(part-of-module),1,0)" "$(@)"; 212 "$(if $(part-of-module),1,0)" "$(@)";
243recordmcount_source := $(srctree)/scripts/recordmcount.pl 213recordmcount_source := $(srctree)/scripts/recordmcount.pl
244endif # BUILD_C_RECORDMCOUNT 214endif # BUILD_C_RECORDMCOUNT
@@ -247,6 +217,7 @@ cmd_record_mcount = \
247 "$(CC_FLAGS_FTRACE)" ]; then \ 217 "$(CC_FLAGS_FTRACE)" ]; then \
248 $(sub_cmd_record_mcount) \ 218 $(sub_cmd_record_mcount) \
249 fi; 219 fi;
220endif # CC_USING_RECORD_MCOUNT
250endif # CONFIG_FTRACE_MCOUNT_RECORD 221endif # CONFIG_FTRACE_MCOUNT_RECORD
251 222
252ifdef CONFIG_STACK_VALIDATION 223ifdef CONFIG_STACK_VALIDATION
@@ -263,8 +234,6 @@ objtool_args += --no-fp
263endif 234endif
264ifdef CONFIG_GCOV_KERNEL 235ifdef CONFIG_GCOV_KERNEL
265objtool_args += --no-unreachable 236objtool_args += --no-unreachable
266else
267objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable)
268endif 237endif
269ifdef CONFIG_RETPOLINE 238ifdef CONFIG_RETPOLINE
270ifneq ($(RETPOLINE_CFLAGS),) 239ifneq ($(RETPOLINE_CFLAGS),)
@@ -314,7 +283,7 @@ endef
314 283
315# List module undefined symbols (or empty line if not enabled) 284# List module undefined symbols (or empty line if not enabled)
316ifdef CONFIG_TRIM_UNUSED_KSYMS 285ifdef CONFIG_TRIM_UNUSED_KSYMS
317cmd_undef_syms = $(NM) $@ | sed -n 's/^ \+U //p' | xargs echo 286cmd_undef_syms = $(NM) $@ | sed -n 's/^ *U //p' | xargs echo
318else 287else
319cmd_undef_syms = echo 288cmd_undef_syms = echo
320endif 289endif
@@ -345,8 +314,8 @@ $(obj)/%.lst: $(src)/%.c FORCE
345 314
346modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) 315modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
347 316
348$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) 317$(real-obj-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
349$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) 318$(real-obj-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
350 319
351# .S file exports must have their C prototypes defined in asm/asm-prototypes.h 320# .S file exports must have their C prototypes defined in asm/asm-prototypes.h
352# or a file that it includes, in order to get versioned symbols. We build a 321# or a file that it includes, in order to get versioned symbols. We build a
@@ -367,7 +336,6 @@ cmd_gensymtypes_S = \
367 sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ) | \ 336 sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ) | \
368 $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ 337 $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \
369 $(GENKSYMS) $(if $(1), -T $(2)) \ 338 $(GENKSYMS) $(if $(1), -T $(2)) \
370 $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \
371 $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ 339 $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
372 $(if $(KBUILD_PRESERVE),-p) \ 340 $(if $(KBUILD_PRESERVE),-p) \
373 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) 341 -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
@@ -412,7 +380,7 @@ cmd_modversions_S = \
412 $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ 380 $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
413 > $(@D)/.tmp_$(@F:.o=.ver); \ 381 > $(@D)/.tmp_$(@F:.o=.ver); \
414 \ 382 \
415 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ 383 $(LD) $(KBUILD_LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
416 -T $(@D)/.tmp_$(@F:.o=.ver); \ 384 -T $(@D)/.tmp_$(@F:.o=.ver); \
417 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ 385 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
418 else \ 386 else \
@@ -424,7 +392,7 @@ endif
424$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE 392$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
425 $(call if_changed_rule,as_o_S) 393 $(call if_changed_rule,as_o_S)
426 394
427targets += $(real-objs-y) $(real-objs-m) $(lib-y) 395targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y)
428targets += $(extra-y) $(MAKECMDGOALS) $(always) 396targets += $(extra-y) $(MAKECMDGOALS) $(always)
429 397
430# Linker scripts preprocessor (.lds.S -> .lds) 398# Linker scripts preprocessor (.lds.S -> .lds)
@@ -442,9 +410,7 @@ quiet_cmd_asn1_compiler = ASN.1 $@
442 cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \ 410 cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
443 $(subst .h,.c,$@) $(subst .c,.h,$@) 411 $(subst .h,.c,$@) $(subst .c,.h,$@)
444 412
445.PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h 413$(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
446
447$(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
448 $(call cmd,asn1_compiler) 414 $(call cmd,asn1_compiler)
449 415
450# Build the compiled-in targets 416# Build the compiled-in targets
@@ -458,24 +424,16 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ;
458# 424#
459ifdef builtin-target 425ifdef builtin-target
460 426
461ifdef CONFIG_THIN_ARCHIVES 427# built-in.a archives are made with no symbol table or index which
462 cmd_make_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) 428# makes them small and fast, but unable to be used by the linker.
463 cmd_make_empty_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) 429# scripts/link-vmlinux.sh builds an aggregate built-in.a with a symbol
464 quiet_cmd_link_o_target = AR $@ 430# table and index.
465else 431quiet_cmd_ar_builtin = AR $@
466 cmd_make_builtin = $(LD) $(ld_flags) -r -o 432 cmd_ar_builtin = rm -f $@; \
467 cmd_make_empty_builtin = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) 433 $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(filter $(real-obj-y), $^)
468 quiet_cmd_link_o_target = LD $@
469endif
470
471# If the list of objects to link is empty, just create an empty built-in.o
472cmd_link_o_target = $(if $(strip $(obj-y)),\
473 $(cmd_make_builtin) $@ $(filter $(obj-y), $^) \
474 $(cmd_secanalysis),\
475 $(cmd_make_empty_builtin) $@)
476 434
477$(builtin-target): $(obj-y) FORCE 435$(builtin-target): $(real-obj-y) FORCE
478 $(call if_changed,link_o_target) 436 $(call if_changed,ar_builtin)
479 437
480targets += $(builtin-target) 438targets += $(builtin-target)
481endif # builtin-target 439endif # builtin-target
@@ -499,11 +457,8 @@ $(modorder-target): $(subdir-ym) FORCE
499ifdef lib-target 457ifdef lib-target
500quiet_cmd_link_l_target = AR $@ 458quiet_cmd_link_l_target = AR $@
501 459
502ifdef CONFIG_THIN_ARCHIVES 460# lib target archives do get a symbol table and index
503 cmd_link_l_target = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(lib-y) 461cmd_link_l_target = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(lib-y)
504else
505 cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y)
506endif
507 462
508$(lib-target): $(lib-y) FORCE 463$(lib-target): $(lib-y) FORCE
509 $(call if_changed,link_l_target) 464 $(call if_changed,link_l_target)
@@ -512,15 +467,10 @@ targets += $(lib-target)
512 467
513dummy-object = $(obj)/.lib_exports.o 468dummy-object = $(obj)/.lib_exports.o
514ksyms-lds = $(dot-target).lds 469ksyms-lds = $(dot-target).lds
515ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
516ref_prefix = EXTERN(_
517else
518ref_prefix = EXTERN(
519endif
520 470
521quiet_cmd_export_list = EXPORTS $@ 471quiet_cmd_export_list = EXPORTS $@
522cmd_export_list = $(OBJDUMP) -h $< | \ 472cmd_export_list = $(OBJDUMP) -h $< | \
523 sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/$(ref_prefix)\1)/p' >$(ksyms-lds);\ 473 sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/EXTERN(\1)/p' >$(ksyms-lds);\
524 rm -f $(dummy-object);\ 474 rm -f $(dummy-object);\
525 echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\ 475 echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\
526 $(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\ 476 $(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\
@@ -533,48 +483,33 @@ targets += $(obj)/lib-ksyms.o
533 483
534endif 484endif
535 485
536#
537# Rule to link composite objects
538#
539# Composite objects are specified in kbuild makefile as follows:
540# <composite-object>-objs := <list of .o files>
541# or
542# <composite-object>-y := <list of .o files>
543# or
544# <composite-object>-m := <list of .o files>
545# The -m syntax only works if <composite object> is a module
546link_multi_deps = \
547$(filter $(addprefix $(obj)/, \
548$($(subst $(obj)/,,$(@:.o=-objs))) \
549$($(subst $(obj)/,,$(@:.o=-y))) \
550$($(subst $(obj)/,,$(@:.o=-m)))), $^)
551
552cmd_link_multi-link = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis)
553
554ifdef CONFIG_THIN_ARCHIVES
555 quiet_cmd_link_multi-y = AR $@
556 cmd_link_multi-y = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(link_multi_deps)
557else
558 quiet_cmd_link_multi-y = LD $@
559 cmd_link_multi-y = $(cmd_link_multi-link)
560endif
561
562quiet_cmd_link_multi-m = LD [M] $@ 486quiet_cmd_link_multi-m = LD [M] $@
563cmd_link_multi-m = $(cmd_link_multi-link) 487cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) $(cmd_secanalysis)
564
565$(multi-used-y): FORCE
566 $(call if_changed,link_multi-y)
567$(call multi_depend, $(multi-used-y), .o, -objs -y)
568 488
569$(multi-used-m): FORCE 489$(multi-used-m): FORCE
570 $(call if_changed,link_multi-m) 490 $(call if_changed,link_multi-m)
571 @{ echo $(@:.o=.ko); echo $(link_multi_deps); \ 491 @{ echo $(@:.o=.ko); echo $(filter %.o,$^); \
572 $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) 492 $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
573$(call multi_depend, $(multi-used-m), .o, -objs -y -m) 493$(call multi_depend, $(multi-used-m), .o, -objs -y -m)
574 494
575targets += $(multi-used-y) $(multi-used-m) 495targets += $(multi-used-m)
576targets := $(filter-out $(PHONY), $(targets)) 496targets := $(filter-out $(PHONY), $(targets))
577 497
498# Add intermediate targets:
499# When building objects with specific suffix patterns, add intermediate
500# targets that the final targets are derived from.
501intermediate_targets = $(foreach sfx, $(2), \
502 $(patsubst %$(strip $(1)),%$(sfx), \
503 $(filter %$(strip $(1)), $(targets))))
504# %.asn1.o <- %.asn1.[ch] <- %.asn1
505# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts
506# %.lex.o <- %.lex.c <- %.l
507# %.tab.o <- %.tab.[ch] <- %.y
508targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \
509 $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \
510 $(call intermediate_targets, .lex.o, .lex.c) \
511 $(call intermediate_targets, .tab.o, .tab.c .tab.h)
512
578# Descending 513# Descending
579# --------------------------------------------------------------------------- 514# ---------------------------------------------------------------------------
580 515
@@ -611,7 +546,8 @@ $(shell mkdir -p $(obj-dirs))
611endif 546endif
612endif 547endif
613 548
614# Declare the contents of the .PHONY variable as phony. We keep that 549# Some files contained in $(targets) are intermediate artifacts.
615# information in a variable se we can use it in if_changed and friends. 550# We never want them to be removed automatically.
551.SECONDARY: $(targets)
616 552
617.PHONY: $(PHONY) 553.PHONY: $(PHONY)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 808d09f27ad4..0b80e3207b20 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -38,7 +38,6 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
38 38
39__clean-files := $(extra-y) $(extra-m) $(extra-) \ 39__clean-files := $(extra-y) $(extra-m) $(extra-) \
40 $(always) $(targets) $(clean-files) \ 40 $(always) $(targets) $(clean-files) \
41 $(host-progs) \
42 $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \ 41 $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
43 $(hostlibs-y) $(hostlibs-m) $(hostlibs-) \ 42 $(hostlibs-y) $(hostlibs-m) $(hostlibs-) \
44 $(hostcxxlibs-y) $(hostcxxlibs-m) 43 $(hostcxxlibs-y) $(hostcxxlibs-m)
@@ -88,7 +87,4 @@ PHONY += $(subdir-ymn)
88$(subdir-ymn): 87$(subdir-ymn):
89 $(Q)$(MAKE) $(clean)=$@ 88 $(Q)$(MAKE) $(clean)=$@
90 89
91# Declare the contents of the .PHONY variable as phony. We keep that
92# information in a variable se we can use it in if_changed and friends.
93
94.PHONY: $(PHONY) 90.PHONY: $(PHONY)
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index 8d5357053f86..768306add591 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -29,6 +29,7 @@ warning-1 += $(call cc-option, -Wmissing-include-dirs)
29warning-1 += $(call cc-option, -Wunused-but-set-variable) 29warning-1 += $(call cc-option, -Wunused-but-set-variable)
30warning-1 += $(call cc-option, -Wunused-const-variable) 30warning-1 += $(call cc-option, -Wunused-const-variable)
31warning-1 += $(call cc-option, -Wpacked-not-aligned) 31warning-1 += $(call cc-option, -Wpacked-not-aligned)
32warning-1 += $(call cc-option, -Wstringop-truncation)
32warning-1 += $(call cc-disable-warning, missing-field-initializers) 33warning-1 += $(call cc-disable-warning, missing-field-initializers)
33warning-1 += $(call cc-disable-warning, sign-compare) 34warning-1 += $(call cc-disable-warning, sign-compare)
34 35
@@ -52,7 +53,6 @@ warning-3 += -Wpointer-arith
52warning-3 += -Wredundant-decls 53warning-3 += -Wredundant-decls
53warning-3 += -Wswitch-default 54warning-3 += -Wswitch-default
54warning-3 += $(call cc-option, -Wpacked-bitfield-compat) 55warning-3 += $(call cc-option, -Wpacked-bitfield-compat)
55warning-3 += $(call cc-option, -Wvla)
56 56
57warning := $(warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) 57warning := $(warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
58warning += $(warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) 58warning += $(warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
@@ -65,7 +65,7 @@ endif
65KBUILD_CFLAGS += $(warning) 65KBUILD_CFLAGS += $(warning)
66else 66else
67 67
68ifeq ($(cc-name),clang) 68ifdef CONFIG_CC_IS_CLANG
69KBUILD_CFLAGS += $(call cc-disable-warning, initializer-overrides) 69KBUILD_CFLAGS += $(call cc-disable-warning, initializer-overrides)
70KBUILD_CFLAGS += $(call cc-disable-warning, unused-value) 70KBUILD_CFLAGS += $(call cc-disable-warning, unused-value)
71KBUILD_CFLAGS += $(call cc-disable-warning, format) 71KBUILD_CFLAGS += $(call cc-disable-warning, format)
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index b2a95af7df18..46c5c6809806 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -1,84 +1,58 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2ifdef CONFIG_GCC_PLUGINS
3 __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
4 PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
5
6 SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
7
8 gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so
9
10 gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so
11 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += -DLATENT_ENTROPY_PLUGIN
12 ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
13 DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable
14 endif
15
16 ifdef CONFIG_GCC_PLUGIN_SANCOV
17 ifeq ($(CFLAGS_KCOV),)
18 # It is needed because of the gcc-plugin.sh and gcc version checks.
19 gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so
20
21 ifneq ($(PLUGINCC),)
22 CFLAGS_KCOV := $(SANCOV_PLUGIN)
23 else
24 $(warning warning: cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler)
25 endif
26 endif
27 endif
28
29 gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so
30 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose
31 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all
32 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN
33 2
34 gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so 3gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so
35 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN
36 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode
37 4
38 GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) 5gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so
39 6gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \
40 export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR 7 += -DLATENT_ENTROPY_PLUGIN
41 export SANCOV_PLUGIN DISABLE_LATENT_ENTROPY_PLUGIN 8ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
9 DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable
10endif
11export DISABLE_LATENT_ENTROPY_PLUGIN
12
13gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so
14
15gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so
16gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) \
17 += -fplugin-arg-structleak_plugin-verbose
18gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \
19 += -fplugin-arg-structleak_plugin-byref-all
20gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \
21 += -DSTRUCTLEAK_PLUGIN
22
23gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
24gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \
25 += -DRANDSTRUCT_PLUGIN
26gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \
27 += -fplugin-arg-randomize_layout_plugin-performance-mode
28
29gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so
30gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
31 += -DSTACKLEAK_PLUGIN
32gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
33 += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE)
34ifdef CONFIG_GCC_PLUGIN_STACKLEAK
35 DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable
36endif
37export DISABLE_STACKLEAK_PLUGIN
42 38
43 ifneq ($(PLUGINCC),) 39# All the plugin CFLAGS are collected here in case a build target needs to
44 # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication. 40# filter them out of the KBUILD_CFLAGS.
45 GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS)) 41GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
46 endif 42# The sancov_plugin.so is included via CFLAGS_KCOV, so it is removed here.
43GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS))
44export GCC_PLUGINS_CFLAGS
47 45
48 KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) 46# Add the flags to the build!
49 GCC_PLUGIN := $(gcc-plugin-y) 47KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
50 GCC_PLUGIN_SUBDIR := $(gcc-plugin-subdir-y)
51endif
52 48
53# If plugins aren't supported, abort the build before hard-to-read compiler 49# All enabled GCC plugins are collected here for building below.
54# errors start getting spewed by the main build. 50GCC_PLUGIN := $(gcc-plugin-y)
55PHONY += gcc-plugins-check 51export GCC_PLUGIN
56gcc-plugins-check: FORCE
57ifdef CONFIG_GCC_PLUGINS
58 ifeq ($(PLUGINCC),)
59 ifneq ($(GCC_PLUGINS_CFLAGS),)
60 # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing
61 # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 have
62 # issues with 64-bit targets.
63 ifeq ($(ARCH),powerpc)
64 ifeq ($(call cc-ifversion, -le, 0501, y), y)
65 @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1
66 endif
67 endif
68 ifeq ($(call cc-ifversion, -ge, 0405, y), y)
69 $(Q)$(srctree)/scripts/gcc-plugin.sh --show-error "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" || true
70 @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc installation does not support plugins, perhaps the necessary headers are missing?" >&2 && exit 1
71 else
72 @echo "Cannot use CONFIG_GCC_PLUGINS: your gcc version does not support plugins, you should upgrade it to at least gcc 4.5" >&2 && exit 1
73 endif
74 endif
75 endif
76endif
77 @:
78 52
79# Actually do the build, if requested. 53# Actually do the build, if requested.
80PHONY += gcc-plugins 54PHONY += gcc-plugins
81gcc-plugins: scripts_basic gcc-plugins-check 55gcc-plugins: scripts_basic
82ifdef CONFIG_GCC_PLUGINS 56ifdef CONFIG_GCC_PLUGINS
83 $(Q)$(MAKE) $(build)=scripts/gcc-plugins 57 $(Q)$(MAKE) $(build)=scripts/gcc-plugins
84endif 58endif
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index e6dc6ae2d7c4..0393f75db4d4 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -62,9 +62,9 @@ host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs))
62##### 62#####
63# Handle options to gcc. Support building with separate output directory 63# Handle options to gcc. Support building with separate output directory
64 64
65_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ 65_hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
66 $(HOSTCFLAGS_$(basetarget).o) 66 $(HOSTCFLAGS_$(basetarget).o)
67_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ 67_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
68 $(HOSTCXXFLAGS_$(basetarget).o) 68 $(HOSTCXXFLAGS_$(basetarget).o)
69 69
70ifeq ($(KBUILD_SRC),) 70ifeq ($(KBUILD_SRC),)
@@ -84,17 +84,17 @@ hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags)
84# Create executable from a single .c file 84# Create executable from a single .c file
85# host-csingle -> Executable 85# host-csingle -> Executable
86quiet_cmd_host-csingle = HOSTCC $@ 86quiet_cmd_host-csingle = HOSTCC $@
87 cmd_host-csingle = $(HOSTCC) $(hostc_flags) -o $@ $< \ 87 cmd_host-csingle = $(HOSTCC) $(hostc_flags) $(KBUILD_HOSTLDFLAGS) -o $@ $< \
88 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) 88 $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
89$(host-csingle): $(obj)/%: $(src)/%.c FORCE 89$(host-csingle): $(obj)/%: $(src)/%.c FORCE
90 $(call if_changed_dep,host-csingle) 90 $(call if_changed_dep,host-csingle)
91 91
92# Link an executable based on list of .o files, all plain c 92# Link an executable based on list of .o files, all plain c
93# host-cmulti -> executable 93# host-cmulti -> executable
94quiet_cmd_host-cmulti = HOSTLD $@ 94quiet_cmd_host-cmulti = HOSTLD $@
95 cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \ 95 cmd_host-cmulti = $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ \
96 $(addprefix $(obj)/,$($(@F)-objs)) \ 96 $(addprefix $(obj)/,$($(@F)-objs)) \
97 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) 97 $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
98$(host-cmulti): FORCE 98$(host-cmulti): FORCE
99 $(call if_changed,host-cmulti) 99 $(call if_changed,host-cmulti)
100$(call multi_depend, $(host-cmulti), , -objs) 100$(call multi_depend, $(host-cmulti), , -objs)
@@ -109,10 +109,10 @@ $(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE
109# Link an executable based on list of .o files, a mixture of .c and .cc 109# Link an executable based on list of .o files, a mixture of .c and .cc
110# host-cxxmulti -> executable 110# host-cxxmulti -> executable
111quiet_cmd_host-cxxmulti = HOSTLD $@ 111quiet_cmd_host-cxxmulti = HOSTLD $@
112 cmd_host-cxxmulti = $(HOSTCXX) $(HOSTLDFLAGS) -o $@ \ 112 cmd_host-cxxmulti = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -o $@ \
113 $(foreach o,objs cxxobjs,\ 113 $(foreach o,objs cxxobjs,\
114 $(addprefix $(obj)/,$($(@F)-$(o)))) \ 114 $(addprefix $(obj)/,$($(@F)-$(o)))) \
115 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) 115 $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
116$(host-cxxmulti): FORCE 116$(host-cxxmulti): FORCE
117 $(call if_changed,host-cxxmulti) 117 $(call if_changed,host-cxxmulti)
118$(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs) 118$(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs)
@@ -143,9 +143,9 @@ $(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
143# Link a shared library, based on position independent .o files 143# Link a shared library, based on position independent .o files
144# *.o -> .so shared library (host-cshlib) 144# *.o -> .so shared library (host-cshlib)
145quiet_cmd_host-cshlib = HOSTLLD -shared $@ 145quiet_cmd_host-cshlib = HOSTLLD -shared $@
146 cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \ 146 cmd_host-cshlib = $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \
147 $(addprefix $(obj)/,$($(@F:.so=-objs))) \ 147 $(addprefix $(obj)/,$($(@F:.so=-objs))) \
148 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) 148 $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
149$(host-cshlib): FORCE 149$(host-cshlib): FORCE
150 $(call if_changed,host-cshlib) 150 $(call if_changed,host-cshlib)
151$(call multi_depend, $(host-cshlib), .so, -objs) 151$(call multi_depend, $(host-cshlib), .so, -objs)
@@ -153,9 +153,9 @@ $(call multi_depend, $(host-cshlib), .so, -objs)
153# Link a shared library, based on position independent .o files 153# Link a shared library, based on position independent .o files
154# *.o -> .so shared library (host-cxxshlib) 154# *.o -> .so shared library (host-cxxshlib)
155quiet_cmd_host-cxxshlib = HOSTLLD -shared $@ 155quiet_cmd_host-cxxshlib = HOSTLLD -shared $@
156 cmd_host-cxxshlib = $(HOSTCXX) $(HOSTLDFLAGS) -shared -o $@ \ 156 cmd_host-cxxshlib = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \
157 $(addprefix $(obj)/,$($(@F:.so=-objs))) \ 157 $(addprefix $(obj)/,$($(@F:.so=-objs))) \
158 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) 158 $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
159$(host-cxxshlib): FORCE 159$(host-cxxshlib): FORCE
160 $(call if_changed,host-cxxshlib) 160 $(call if_changed,host-cxxshlib)
161$(call multi_depend, $(host-cxxshlib), .so, -objs) 161$(call multi_depend, $(host-cxxshlib), .so, -objs)
diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov
index 5cc72037e423..3d61c4bfcbee 100644
--- a/scripts/Makefile.kcov
+++ b/scripts/Makefile.kcov
@@ -1,7 +1,9 @@
1ifdef CONFIG_KCOV 1ifdef CONFIG_KCOV
2CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) 2
3ifeq ($(CONFIG_KCOV_ENABLE_COMPARISONS),y) 3kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc
4CFLAGS_KCOV += $(call cc-option,-fsanitize-coverage=trace-cmp,) 4kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp
5endif 5kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
6
7export CFLAGS_KCOV := $(kcov-flags-y)
6 8
7endif 9endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index a6f538b31ad6..8fe4468f9bda 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -27,7 +27,7 @@ modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko
27 27
28# Handle objects in subdirs 28# Handle objects in subdirs
29# --------------------------------------------------------------------------- 29# ---------------------------------------------------------------------------
30# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o 30# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a
31# and add the directory to the list of dirs to descend into: $(subdir-y) 31# and add the directory to the list of dirs to descend into: $(subdir-y)
32# o if we encounter foo/ in $(obj-m), remove it from $(obj-m) 32# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
33# and add the directory to the list of dirs to descend into: $(subdir-m) 33# and add the directory to the list of dirs to descend into: $(subdir-m)
@@ -35,7 +35,7 @@ __subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
35subdir-y += $(__subdir-y) 35subdir-y += $(__subdir-y)
36__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) 36__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
37subdir-m += $(__subdir-m) 37subdir-m += $(__subdir-m)
38obj-y := $(patsubst %/, %/built-in.o, $(obj-y)) 38obj-y := $(patsubst %/, %/built-in.a, $(obj-y))
39obj-m := $(filter-out %/, $(obj-m)) 39obj-m := $(filter-out %/, $(obj-m))
40 40
41# Subdirectories we need to descend into 41# Subdirectories we need to descend into
@@ -47,18 +47,14 @@ multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m
47multi-used := $(multi-used-y) $(multi-used-m) 47multi-used := $(multi-used-y) $(multi-used-m)
48single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) 48single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
49 49
50# Build list of the parts of our composite objects, our composite
51# objects depend on those (obviously)
52multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
53multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
54
55# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to 50# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
56# tell kbuild to descend 51# tell kbuild to descend
57subdir-obj-y := $(filter %/built-in.o, $(obj-y)) 52subdir-obj-y := $(filter %/built-in.a, $(obj-y))
58 53
59# Replace multi-part objects by their individual parts, look at local dir only 54# Replace multi-part objects by their individual parts,
60real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) 55# including built-in.a from subdirectories
61real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) 56real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
57real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m)))
62 58
63# DTB 59# DTB
64# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built 60# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
@@ -71,29 +67,29 @@ extra-y := $(addprefix $(obj)/,$(extra-y))
71always := $(addprefix $(obj)/,$(always)) 67always := $(addprefix $(obj)/,$(always))
72targets := $(addprefix $(obj)/,$(targets)) 68targets := $(addprefix $(obj)/,$(targets))
73modorder := $(addprefix $(obj)/,$(modorder)) 69modorder := $(addprefix $(obj)/,$(modorder))
74obj-y := $(addprefix $(obj)/,$(obj-y))
75obj-m := $(addprefix $(obj)/,$(obj-m)) 70obj-m := $(addprefix $(obj)/,$(obj-m))
76lib-y := $(addprefix $(obj)/,$(lib-y)) 71lib-y := $(addprefix $(obj)/,$(lib-y))
77subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) 72subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
78real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) 73real-obj-y := $(addprefix $(obj)/,$(real-obj-y))
79real-objs-m := $(addprefix $(obj)/,$(real-objs-m)) 74real-obj-m := $(addprefix $(obj)/,$(real-obj-m))
80single-used-m := $(addprefix $(obj)/,$(single-used-m)) 75single-used-m := $(addprefix $(obj)/,$(single-used-m))
81multi-used-y := $(addprefix $(obj)/,$(multi-used-y))
82multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) 76multi-used-m := $(addprefix $(obj)/,$(multi-used-m))
83multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y))
84multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m))
85subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) 77subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
86 78
79# Finds the multi-part object the current object will be linked into.
80# If the object belongs to two or more multi-part objects, all of them are
81# concatenated with a colon separator.
82modname-multi = $(subst $(space),:,$(sort $(foreach m,$(multi-used),\
83 $(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=)))))
84
85modname = $(if $(modname-multi),$(modname-multi),$(basetarget))
86
87# These flags are needed for modversions and compiling, so we define them here 87# These flags are needed for modversions and compiling, so we define them here
88# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will 88# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will
89# end up in (or would, if it gets compiled in) 89# end up in (or would, if it gets compiled in)
90# Note: Files that end up in two or more modules are compiled without the
91# KBUILD_MODNAME definition. The reason is that any made-up name would
92# differ in different configs.
93name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote) 90name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote)
94basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) 91basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
95modname_flags = $(if $(filter 1,$(words $(modname))),\ 92modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname))
96 -DKBUILD_MODNAME=$(call name-fix,$(modname)))
97 93
98orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ 94orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
99 $(ccflags-y) $(CFLAGS_$(basetarget).o) 95 $(ccflags-y) $(CFLAGS_$(basetarget).o)
@@ -156,6 +152,7 @@ __cpp_flags = $(call flags,_cpp_flags)
156endif 152endif
157 153
158c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 154c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
155 -include $(srctree)/include/linux/compiler_types.h \
159 $(__c_flags) $(modkern_cflags) \ 156 $(__c_flags) $(modkern_cflags) \
160 $(basename_flags) $(modname_flags) 157 $(basename_flags) $(modname_flags)
161 158
@@ -165,7 +162,7 @@ a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
165cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 162cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
166 $(__cpp_flags) 163 $(__cpp_flags)
167 164
168ld_flags = $(LDFLAGS) $(ldflags-y) 165ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
169 166
170DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes 167DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes
171 168
@@ -173,10 +170,6 @@ dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \
173 $(addprefix -I,$(DTC_INCLUDE)) \ 170 $(addprefix -I,$(DTC_INCLUDE)) \
174 -undef -D__DTS__ 171 -undef -D__DTS__
175 172
176# Finds the multi-part object the current object will be linked into
177modname-multi = $(sort $(foreach m,$(multi-used),\
178 $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
179
180# Useful for describing the dependency of composite objects 173# Useful for describing the dependency of composite objects
181# Usage: 174# Usage:
182# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) 175# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
@@ -191,14 +184,7 @@ endef
191quiet_cmd_flex = LEX $@ 184quiet_cmd_flex = LEX $@
192 cmd_flex = $(LEX) -o$@ -L $< 185 cmd_flex = $(LEX) -o$@ -L $<
193 186
194ifdef REGENERATE_PARSERS 187$(obj)/%.lex.c: $(src)/%.l FORCE
195.PRECIOUS: $(src)/%.lex.c_shipped
196$(src)/%.lex.c_shipped: $(src)/%.l
197 $(call cmd,flex)
198endif
199
200.PRECIOUS: $(obj)/%.lex.c
201$(filter %.lex.c,$(targets)): $(obj)/%.lex.c: $(src)/%.l FORCE
202 $(call if_changed,flex) 188 $(call if_changed,flex)
203 189
204# YACC 190# YACC
@@ -206,27 +192,13 @@ $(filter %.lex.c,$(targets)): $(obj)/%.lex.c: $(src)/%.l FORCE
206quiet_cmd_bison = YACC $@ 192quiet_cmd_bison = YACC $@
207 cmd_bison = $(YACC) -o$@ -t -l $< 193 cmd_bison = $(YACC) -o$@ -t -l $<
208 194
209ifdef REGENERATE_PARSERS 195$(obj)/%.tab.c: $(src)/%.y FORCE
210.PRECIOUS: $(src)/%.tab.c_shipped
211$(src)/%.tab.c_shipped: $(src)/%.y
212 $(call cmd,bison)
213endif
214
215.PRECIOUS: $(obj)/%.tab.c
216$(filter %.tab.c,$(targets)): $(obj)/%.tab.c: $(src)/%.y FORCE
217 $(call if_changed,bison) 196 $(call if_changed,bison)
218 197
219quiet_cmd_bison_h = YACC $@ 198quiet_cmd_bison_h = YACC $@
220 cmd_bison_h = bison -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $< 199 cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l $<
221
222ifdef REGENERATE_PARSERS
223.PRECIOUS: $(src)/%.tab.h_shipped
224$(src)/%.tab.h_shipped: $(src)/%.y
225 $(call cmd,bison_h)
226endif
227 200
228.PRECIOUS: $(obj)/%.tab.h 201$(obj)/%.tab.h: $(src)/%.y FORCE
229$(filter %.tab.h,$(targets)): $(obj)/%.tab.h: $(src)/%.y FORCE
230 $(call if_changed,bison_h) 202 $(call if_changed,bison_h)
231 203
232# Shipped files 204# Shipped files
@@ -253,8 +225,7 @@ $(obj)/%: $(src)/%_shipped
253# --------------------------------------------------------------------------- 225# ---------------------------------------------------------------------------
254 226
255quiet_cmd_ld = LD $@ 227quiet_cmd_ld = LD $@
256cmd_ld = $(LD) $(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \ 228cmd_ld = $(LD) $(ld_flags) $(filter-out FORCE,$^) -o $@
257 $(filter-out FORCE,$^) -o $@
258 229
259# Objcopy 230# Objcopy
260# --------------------------------------------------------------------------- 231# ---------------------------------------------------------------------------
@@ -276,10 +247,12 @@ DTC ?= $(objtree)/scripts/dtc/dtc
276# Disable noisy checks by default 247# Disable noisy checks by default
277ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) 248ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),)
278DTC_FLAGS += -Wno-unit_address_vs_reg \ 249DTC_FLAGS += -Wno-unit_address_vs_reg \
279 -Wno-simple_bus_reg \
280 -Wno-unit_address_format \ 250 -Wno-unit_address_format \
281 -Wno-pci_bridge \ 251 -Wno-avoid_unnecessary_addr_size \
282 -Wno-pci_device_bus_num \ 252 -Wno-alias_paths \
253 -Wno-graph_child_address \
254 -Wno-graph_port \
255 -Wno-unique_unit_address \
283 -Wno-pci_device_reg 256 -Wno-pci_device_reg
284endif 257endif
285 258
@@ -305,18 +278,18 @@ cmd_dt_S_dtb= \
305 echo '.balign STRUCT_ALIGNMENT'; \ 278 echo '.balign STRUCT_ALIGNMENT'; \
306) > $@ 279) > $@
307 280
308$(obj)/%.dtb.S: $(obj)/%.dtb 281$(obj)/%.dtb.S: $(obj)/%.dtb FORCE
309 $(call cmd,dt_S_dtb) 282 $(call if_changed,dt_S_dtb)
310 283
311quiet_cmd_dtc = DTC $@ 284quiet_cmd_dtc = DTC $@
312cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ 285cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
313 $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ 286 $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
314 $(DTC) -O dtb -o $@ -b 0 \ 287 $(DTC) -O dtb -o $@ -b 0 \
315 $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ 288 $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
316 -d $(depfile).dtc.tmp $(dtc-tmp) ; \ 289 -d $(depfile).dtc.tmp $(dtc-tmp) ; \
317 cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) 290 cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
318 291
319$(obj)/%.dtb: $(src)/%.dts FORCE 292$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
320 $(call if_changed_dep,dtc) 293 $(call if_changed_dep,dtc)
321 294
322dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) 295dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
@@ -329,7 +302,7 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
329size_append = printf $(shell \ 302size_append = printf $(shell \
330dec_size=0; \ 303dec_size=0; \
331for F in $1; do \ 304for F in $1; do \
332 fsize=$$(stat -c "%s" $$F); \ 305 fsize=$$($(CONFIG_SHELL) $(srctree)/scripts/file-size.sh $$F); \
333 dec_size=$$(expr $$dec_size + $$fsize); \ 306 dec_size=$$(expr $$dec_size + $$fsize); \
334done; \ 307done; \
335printf "%08x\n" $$dec_size | \ 308printf "%08x\n" $$dec_size | \
@@ -442,7 +415,7 @@ define filechk_offsets
442 echo " * This file was generated by Kbuild"; \ 415 echo " * This file was generated by Kbuild"; \
443 echo " */"; \ 416 echo " */"; \
444 echo ""; \ 417 echo ""; \
445 sed -ne $(sed-offsets); \ 418 sed -ne $(sed-offsets) < $<; \
446 echo ""; \ 419 echo ""; \
447 echo "#endif" ) 420 echo "#endif" )
448endef 421endef
diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin
index a763b4775d06..a072a4267746 100644
--- a/scripts/Makefile.modbuiltin
+++ b/scripts/Makefile.modbuiltin
@@ -8,10 +8,10 @@ src := $(obj)
8PHONY := __modbuiltin 8PHONY := __modbuiltin
9__modbuiltin: 9__modbuiltin:
10 10
11-include include/config/auto.conf 11include include/config/auto.conf
12# tristate.conf sets tristate variables to uppercase 'Y' or 'M' 12# tristate.conf sets tristate variables to uppercase 'Y' or 'M'
13# That way, we get the list of built-in modules in obj-Y 13# That way, we get the list of built-in modules in obj-Y
14-include include/config/tristate.conf 14include include/config/tristate.conf
15 15
16include scripts/Kbuild.include 16include scripts/Kbuild.include
17 17
@@ -54,8 +54,4 @@ PHONY += $(subdir-ym)
54$(subdir-ym): 54$(subdir-ym):
55 $(Q)$(MAKE) $(modbuiltin)=$@ 55 $(Q)$(MAKE) $(modbuiltin)=$@
56 56
57
58# Declare the contents of the .PHONY variable as phony. We keep that
59# information in a variable se we can use it in if_changed and friends.
60
61.PHONY: $(PHONY) 57.PHONY: $(PHONY)
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 51ca0244fc8a..ff5ca9817a85 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -35,8 +35,4 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
35$(modules): 35$(modules):
36 $(call cmd,modules_install,$(MODLIB)/$(modinst_dir)) 36 $(call cmd,modules_install,$(MODLIB)/$(modinst_dir))
37 37
38
39# Declare the contents of the .PHONY variable as phony. We keep that
40# information in a variable so we can use it in if_changed and friends.
41
42.PHONY: $(PHONY) 38.PHONY: $(PHONY)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index df4174405feb..7d4af0d0accb 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -120,7 +120,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
120# Step 6), final link of the modules with optional arch pass after final link 120# Step 6), final link of the modules with optional arch pass after final link
121quiet_cmd_ld_ko_o = LD [M] $@ 121quiet_cmd_ld_ko_o = LD [M] $@
122 cmd_ld_ko_o = \ 122 cmd_ld_ko_o = \
123 $(LD) -r $(LDFLAGS) \ 123 $(LD) -r $(KBUILD_LDFLAGS) \
124 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ 124 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
125 -o $@ $(filter-out FORCE,$^) ; \ 125 -o $@ $(filter-out FORCE,$^) ; \
126 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) 126 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
@@ -149,8 +149,4 @@ ifneq ($(cmd_files),)
149 include $(cmd_files) 149 include $(cmd_files)
150endif 150endif
151 151
152
153# Declare the contents of the .PHONY variable as phony. We keep that
154# information in a variable se we can use it in if_changed and friends.
155
156.PHONY: $(PHONY) 152.PHONY: $(PHONY)
diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign
index 171483bc0538..da56aa78d245 100644
--- a/scripts/Makefile.modsign
+++ b/scripts/Makefile.modsign
@@ -27,7 +27,4 @@ modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
27$(modules): 27$(modules):
28 $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir)) 28 $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir))
29 29
30# Declare the contents of the .PHONY variable as phony. We keep that
31# information in a variable se we can use it in if_changed and friends.
32
33.PHONY: $(PHONY) 30.PHONY: $(PHONY)
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index b593b36ccff8..38b2b4818e8e 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -14,10 +14,6 @@ ifdef CONFIG_UBSAN_ALIGNMENT
14 CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment) 14 CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment)
15endif 15endif
16 16
17ifdef CONFIG_UBSAN_NULL
18 CFLAGS_UBSAN += $(call cc-option, -fsanitize=null)
19endif
20
21 # -fsanitize=* options makes GCC less smart than usual and 17 # -fsanitize=* options makes GCC less smart than usual and
22 # increase number of 'maybe-uninitialized false-positives 18 # increase number of 'maybe-uninitialized false-positives
23 CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized) 19 CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized)
diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh
index d67830e6e360..6e6d63957da3 100755
--- a/scripts/adjust_autoksyms.sh
+++ b/scripts/adjust_autoksyms.sh
@@ -48,9 +48,6 @@ case "${KCONFIG_CONFIG}" in
48 . "./${KCONFIG_CONFIG}" 48 . "./${KCONFIG_CONFIG}"
49esac 49esac
50 50
51# In case it doesn't exist yet...
52if [ -e "$cur_ksyms_file" ]; then touch "$cur_ksyms_file"; fi
53
54# Generate a new ksym list file with symbols needed by the current 51# Generate a new ksym list file with symbols needed by the current
55# set of modules. 52# set of modules.
56cat > "$new_ksyms_file" << EOT 53cat > "$new_ksyms_file" << EOT
@@ -60,11 +57,10 @@ cat > "$new_ksyms_file" << EOT
60 57
61EOT 58EOT
62[ "$(ls -A "$MODVERDIR")" ] && 59[ "$(ls -A "$MODVERDIR")" ] &&
63sed -ns -e '3{s/ /\n/g;/^$/!p;}' "$MODVERDIR"/*.mod | sort -u | 60for mod in "$MODVERDIR"/*.mod; do
61 sed -n -e '3{s/ /\n/g;/^$/!p;}' "$mod"
62done | sort -u |
64while read sym; do 63while read sym; do
65 if [ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]; then
66 sym="${sym#_}"
67 fi
68 echo "#define __KSYM_${sym} 1" 64 echo "#define __KSYM_${sym} 1"
69done >> "$new_ksyms_file" 65done >> "$new_ksyms_file"
70 66
@@ -81,7 +77,7 @@ sort "$cur_ksyms_file" "$new_ksyms_file" | uniq -u |
81sed -n 's/^#define __KSYM_\(.*\) 1/\1/p' | tr "A-Z_" "a-z/" | 77sed -n 's/^#define __KSYM_\(.*\) 1/\1/p' | tr "A-Z_" "a-z/" |
82while read sympath; do 78while read sympath; do
83 if [ -z "$sympath" ]; then continue; fi 79 if [ -z "$sympath" ]; then continue; fi
84 depfile="include/config/ksym/${sympath}.h" 80 depfile="include/ksym/${sympath}.h"
85 mkdir -p "$(dirname "$depfile")" 81 mkdir -p "$(dirname "$depfile")"
86 touch "$depfile" 82 touch "$depfile"
87 # Filesystems with coarse time precision may create timestamps 83 # Filesystems with coarse time precision may create timestamps
diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c
index c1b7ef3e24c1..1b28787028d3 100644
--- a/scripts/asn1_compiler.c
+++ b/scripts/asn1_compiler.c
@@ -413,7 +413,7 @@ static void tokenise(char *buffer, char *end)
413 413
414 /* Handle string tokens */ 414 /* Handle string tokens */
415 if (isalpha(*p)) { 415 if (isalpha(*p)) {
416 const char **dir, *start = p; 416 const char **dir;
417 417
418 /* Can be a directive, type name or element 418 /* Can be a directive, type name or element
419 * name. Find the end of the name. 419 * name. Find the end of the name.
@@ -1319,7 +1319,7 @@ static void render(FILE *out, FILE *hdr)
1319 fprintf(out, " * ASN.1 parser for %s\n", grammar_name); 1319 fprintf(out, " * ASN.1 parser for %s\n", grammar_name);
1320 fprintf(out, " */\n"); 1320 fprintf(out, " */\n");
1321 fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n"); 1321 fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n");
1322 fprintf(out, "#include \"%s-asn1.h\"\n", grammar_name); 1322 fprintf(out, "#include \"%s.asn1.h\"\n", grammar_name);
1323 fprintf(out, "\n"); 1323 fprintf(out, "\n");
1324 if (ferror(out)) { 1324 if (ferror(out)) {
1325 perror(outputname); 1325 perror(outputname);
diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore
index 9528ec9e5adc..a776371a3502 100644
--- a/scripts/basic/.gitignore
+++ b/scripts/basic/.gitignore
@@ -1,2 +1 @@
1fixdep fixdep
2bin2c
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 0372b33febe5..af49b446f17d 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,6 @@
9# fixdep: Used to generate dependency information during build process 9# fixdep: Used to generate dependency information during build process
10 10
11hostprogs-y := fixdep 11hostprogs-y := fixdep
12hostprogs-$(CONFIG_BUILD_BIN2C) += bin2c
13always := $(hostprogs-y) 12always := $(hostprogs-y)
14 13
15# fixdep is needed to compile other host programs 14# fixdep is needed to compile other host programs
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 449b68c4c90c..850966f3d602 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -113,18 +113,20 @@ static void usage(void)
113/* 113/*
114 * Print out a dependency path from a symbol name 114 * Print out a dependency path from a symbol name
115 */ 115 */
116static void print_config(const char *m, int slen) 116static void print_dep(const char *m, int slen, const char *dir)
117{ 117{
118 int c, i; 118 int c, prev_c = '/', i;
119 119
120 printf(" $(wildcard include/config/"); 120 printf(" $(wildcard %s/", dir);
121 for (i = 0; i < slen; i++) { 121 for (i = 0; i < slen; i++) {
122 c = m[i]; 122 c = m[i];
123 if (c == '_') 123 if (c == '_')
124 c = '/'; 124 c = '/';
125 else 125 else
126 c = tolower(c); 126 c = tolower(c);
127 putchar(c); 127 if (c != '/' || prev_c != '/')
128 putchar(c);
129 prev_c = c;
128 } 130 }
129 printf(".h) \\\n"); 131 printf(".h) \\\n");
130} 132}
@@ -140,7 +142,7 @@ static void do_extra_deps(void)
140 fprintf(stderr, "fixdep: bad data on stdin\n"); 142 fprintf(stderr, "fixdep: bad data on stdin\n");
141 exit(1); 143 exit(1);
142 } 144 }
143 print_config(buf, len - 1); 145 print_dep(buf, len - 1, "include/ksym");
144 } 146 }
145} 147}
146 148
@@ -208,7 +210,7 @@ static void use_config(const char *m, int slen)
208 return; 210 return;
209 211
210 define_config(m, slen, hash); 212 define_config(m, slen, hash);
211 print_config(m, slen); 213 print_dep(m, slen, "include/config");
212} 214}
213 215
214/* test if s ends in sub */ 216/* test if s ends in sub */
diff --git a/scripts/basic/bin2c.c b/scripts/bin2c.c
index c3d7eef3ad06..c3d7eef3ad06 100644
--- a/scripts/basic/bin2c.c
+++ b/scripts/bin2c.c
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index d84a5674e95e..a923f05edb36 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -30,8 +30,8 @@ def getsizes(file, format):
30 if type in format: 30 if type in format:
31 # strip generated symbols 31 # strip generated symbols
32 if name.startswith("__mod_"): continue 32 if name.startswith("__mod_"): continue
33 if name.startswith("SyS_"): continue 33 if name.startswith("__se_sys"): continue
34 if name.startswith("compat_SyS_"): continue 34 if name.startswith("__se_compat_sys"): continue
35 if name == "linux_banner": continue 35 if name == "linux_banner": continue
36 # statics and some other optimizations adds random .NUMBER 36 # statics and some other optimizations adds random .NUMBER
37 name = re_NUMBER.sub('', name) 37 name = re_NUMBER.sub('', name)
diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py
new file mode 100755
index 000000000000..5010a4d5bfba
--- /dev/null
+++ b/scripts/bpf_helpers_doc.py
@@ -0,0 +1,421 @@
1#!/usr/bin/python3
2# SPDX-License-Identifier: GPL-2.0-only
3#
4# Copyright (C) 2018 Netronome Systems, Inc.
5
6# In case user attempts to run with Python 2.
7from __future__ import print_function
8
9import argparse
10import re
11import sys, os
12
13class NoHelperFound(BaseException):
14 pass
15
16class ParsingError(BaseException):
17 def __init__(self, line='<line not provided>', reader=None):
18 if reader:
19 BaseException.__init__(self,
20 'Error at file offset %d, parsing line: %s' %
21 (reader.tell(), line))
22 else:
23 BaseException.__init__(self, 'Error parsing line: %s' % line)
24
25class Helper(object):
26 """
27 An object representing the description of an eBPF helper function.
28 @proto: function prototype of the helper function
29 @desc: textual description of the helper function
30 @ret: description of the return value of the helper function
31 """
32 def __init__(self, proto='', desc='', ret=''):
33 self.proto = proto
34 self.desc = desc
35 self.ret = ret
36
37 def proto_break_down(self):
38 """
39 Break down helper function protocol into smaller chunks: return type,
40 name, distincts arguments.
41 """
42 arg_re = re.compile('((const )?(struct )?(\w+|...))( (\**)(\w+))?$')
43 res = {}
44 proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$')
45
46 capture = proto_re.match(self.proto)
47 res['ret_type'] = capture.group(1)
48 res['ret_star'] = capture.group(2)
49 res['name'] = capture.group(3)
50 res['args'] = []
51
52 args = capture.group(4).split(', ')
53 for a in args:
54 capture = arg_re.match(a)
55 res['args'].append({
56 'type' : capture.group(1),
57 'star' : capture.group(6),
58 'name' : capture.group(7)
59 })
60
61 return res
62
63class HeaderParser(object):
64 """
65 An object used to parse a file in order to extract the documentation of a
66 list of eBPF helper functions. All the helpers that can be retrieved are
67 stored as Helper object, in the self.helpers() array.
68 @filename: name of file to parse, usually include/uapi/linux/bpf.h in the
69 kernel tree
70 """
71 def __init__(self, filename):
72 self.reader = open(filename, 'r')
73 self.line = ''
74 self.helpers = []
75
76 def parse_helper(self):
77 proto = self.parse_proto()
78 desc = self.parse_desc()
79 ret = self.parse_ret()
80 return Helper(proto=proto, desc=desc, ret=ret)
81
82 def parse_proto(self):
83 # Argument can be of shape:
84 # - "void"
85 # - "type name"
86 # - "type *name"
87 # - Same as above, with "const" and/or "struct" in front of type
88 # - "..." (undefined number of arguments, for bpf_trace_printk())
89 # There is at least one term ("void"), and at most five arguments.
90 p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$')
91 capture = p.match(self.line)
92 if not capture:
93 raise NoHelperFound
94 self.line = self.reader.readline()
95 return capture.group(1)
96
97 def parse_desc(self):
98 p = re.compile(' \* ?(?:\t| {5,8})Description$')
99 capture = p.match(self.line)
100 if not capture:
101 # Helper can have empty description and we might be parsing another
102 # attribute: return but do not consume.
103 return ''
104 # Description can be several lines, some of them possibly empty, and it
105 # stops when another subsection title is met.
106 desc = ''
107 while True:
108 self.line = self.reader.readline()
109 if self.line == ' *\n':
110 desc += '\n'
111 else:
112 p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
113 capture = p.match(self.line)
114 if capture:
115 desc += capture.group(1) + '\n'
116 else:
117 break
118 return desc
119
120 def parse_ret(self):
121 p = re.compile(' \* ?(?:\t| {5,8})Return$')
122 capture = p.match(self.line)
123 if not capture:
124 # Helper can have empty retval and we might be parsing another
125 # attribute: return but do not consume.
126 return ''
127 # Return value description can be several lines, some of them possibly
128 # empty, and it stops when another subsection title is met.
129 ret = ''
130 while True:
131 self.line = self.reader.readline()
132 if self.line == ' *\n':
133 ret += '\n'
134 else:
135 p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
136 capture = p.match(self.line)
137 if capture:
138 ret += capture.group(1) + '\n'
139 else:
140 break
141 return ret
142
143 def run(self):
144 # Advance to start of helper function descriptions.
145 offset = self.reader.read().find('* Start of BPF helper function descriptions:')
146 if offset == -1:
147 raise Exception('Could not find start of eBPF helper descriptions list')
148 self.reader.seek(offset)
149 self.reader.readline()
150 self.reader.readline()
151 self.line = self.reader.readline()
152
153 while True:
154 try:
155 helper = self.parse_helper()
156 self.helpers.append(helper)
157 except NoHelperFound:
158 break
159
160 self.reader.close()
161 print('Parsed description of %d helper function(s)' % len(self.helpers),
162 file=sys.stderr)
163
164###############################################################################
165
166class Printer(object):
167 """
168 A generic class for printers. Printers should be created with an array of
169 Helper objects, and implement a way to print them in the desired fashion.
170 @helpers: array of Helper objects to print to standard output
171 """
172 def __init__(self, helpers):
173 self.helpers = helpers
174
175 def print_header(self):
176 pass
177
178 def print_footer(self):
179 pass
180
181 def print_one(self, helper):
182 pass
183
184 def print_all(self):
185 self.print_header()
186 for helper in self.helpers:
187 self.print_one(helper)
188 self.print_footer()
189
190class PrinterRST(Printer):
191 """
192 A printer for dumping collected information about helpers as a ReStructured
193 Text page compatible with the rst2man program, which can be used to
194 generate a manual page for the helpers.
195 @helpers: array of Helper objects to print to standard output
196 """
197 def print_header(self):
198 header = '''\
199.. Copyright (C) All BPF authors and contributors from 2014 to present.
200.. See git log include/uapi/linux/bpf.h in kernel tree for details.
201..
202.. %%%LICENSE_START(VERBATIM)
203.. Permission is granted to make and distribute verbatim copies of this
204.. manual provided the copyright notice and this permission notice are
205.. preserved on all copies.
206..
207.. Permission is granted to copy and distribute modified versions of this
208.. manual under the conditions for verbatim copying, provided that the
209.. entire resulting derived work is distributed under the terms of a
210.. permission notice identical to this one.
211..
212.. Since the Linux kernel and libraries are constantly changing, this
213.. manual page may be incorrect or out-of-date. The author(s) assume no
214.. responsibility for errors or omissions, or for damages resulting from
215.. the use of the information contained herein. The author(s) may not
216.. have taken the same level of care in the production of this manual,
217.. which is licensed free of charge, as they might when working
218.. professionally.
219..
220.. Formatted or processed versions of this manual, if unaccompanied by
221.. the source, must acknowledge the copyright and authors of this work.
222.. %%%LICENSE_END
223..
224.. Please do not edit this file. It was generated from the documentation
225.. located in file include/uapi/linux/bpf.h of the Linux kernel sources
226.. (helpers description), and from scripts/bpf_helpers_doc.py in the same
227.. repository (header and footer).
228
229===========
230BPF-HELPERS
231===========
232-------------------------------------------------------------------------------
233list of eBPF helper functions
234-------------------------------------------------------------------------------
235
236:Manual section: 7
237
238DESCRIPTION
239===========
240
241The extended Berkeley Packet Filter (eBPF) subsystem consists in programs
242written in a pseudo-assembly language, then attached to one of the several
243kernel hooks and run in reaction of specific events. This framework differs
244from the older, "classic" BPF (or "cBPF") in several aspects, one of them being
245the ability to call special functions (or "helpers") from within a program.
246These functions are restricted to a white-list of helpers defined in the
247kernel.
248
249These helpers are used by eBPF programs to interact with the system, or with
250the context in which they work. For instance, they can be used to print
251debugging messages, to get the time since the system was booted, to interact
252with eBPF maps, or to manipulate network packets. Since there are several eBPF
253program types, and that they do not run in the same context, each program type
254can only call a subset of those helpers.
255
256Due to eBPF conventions, a helper can not have more than five arguments.
257
258Internally, eBPF programs call directly into the compiled helper functions
259without requiring any foreign-function interface. As a result, calling helpers
260introduces no overhead, thus offering excellent performance.
261
262This document is an attempt to list and document the helpers available to eBPF
263developers. They are sorted by chronological order (the oldest helpers in the
264kernel at the top).
265
266HELPERS
267=======
268'''
269 print(header)
270
271 def print_footer(self):
272 footer = '''
273EXAMPLES
274========
275
276Example usage for most of the eBPF helpers listed in this manual page are
277available within the Linux kernel sources, at the following locations:
278
279* *samples/bpf/*
280* *tools/testing/selftests/bpf/*
281
282LICENSE
283=======
284
285eBPF programs can have an associated license, passed along with the bytecode
286instructions to the kernel when the programs are loaded. The format for that
287string is identical to the one in use for kernel modules (Dual licenses, such
288as "Dual BSD/GPL", may be used). Some helper functions are only accessible to
289programs that are compatible with the GNU Privacy License (GPL).
290
291In order to use such helpers, the eBPF program must be loaded with the correct
292license string passed (via **attr**) to the **bpf**\ () system call, and this
293generally translates into the C source code of the program containing a line
294similar to the following:
295
296::
297
298 char ____license[] __attribute__((section("license"), used)) = "GPL";
299
300IMPLEMENTATION
301==============
302
303This manual page is an effort to document the existing eBPF helper functions.
304But as of this writing, the BPF sub-system is under heavy development. New eBPF
305program or map types are added, along with new helper functions. Some helpers
306are occasionally made available for additional program types. So in spite of
307the efforts of the community, this page might not be up-to-date. If you want to
308check by yourself what helper functions exist in your kernel, or what types of
309programs they can support, here are some files among the kernel tree that you
310may be interested in:
311
312* *include/uapi/linux/bpf.h* is the main BPF header. It contains the full list
313 of all helper functions, as well as many other BPF definitions including most
314 of the flags, structs or constants used by the helpers.
315* *net/core/filter.c* contains the definition of most network-related helper
316 functions, and the list of program types from which they can be used.
317* *kernel/trace/bpf_trace.c* is the equivalent for most tracing program-related
318 helpers.
319* *kernel/bpf/verifier.c* contains the functions used to check that valid types
320 of eBPF maps are used with a given helper function.
321* *kernel/bpf/* directory contains other files in which additional helpers are
322 defined (for cgroups, sockmaps, etc.).
323
324Compatibility between helper functions and program types can generally be found
325in the files where helper functions are defined. Look for the **struct
326bpf_func_proto** objects and for functions returning them: these functions
327contain a list of helpers that a given program type can call. Note that the
328**default:** label of the **switch ... case** used to filter helpers can call
329other functions, themselves allowing access to additional helpers. The
330requirement for GPL license is also in those **struct bpf_func_proto**.
331
332Compatibility between helper functions and map types can be found in the
333**check_map_func_compatibility**\ () function in file *kernel/bpf/verifier.c*.
334
335Helper functions that invalidate the checks on **data** and **data_end**
336pointers for network processing are listed in function
337**bpf_helper_changes_pkt_data**\ () in file *net/core/filter.c*.
338
339SEE ALSO
340========
341
342**bpf**\ (2),
343**cgroups**\ (7),
344**ip**\ (8),
345**perf_event_open**\ (2),
346**sendmsg**\ (2),
347**socket**\ (7),
348**tc-bpf**\ (8)'''
349 print(footer)
350
351 def print_proto(self, helper):
352 """
353 Format function protocol with bold and italics markers. This makes RST
354 file less readable, but gives nice results in the manual page.
355 """
356 proto = helper.proto_break_down()
357
358 print('**%s %s%s(' % (proto['ret_type'],
359 proto['ret_star'].replace('*', '\\*'),
360 proto['name']),
361 end='')
362
363 comma = ''
364 for a in proto['args']:
365 one_arg = '{}{}'.format(comma, a['type'])
366 if a['name']:
367 if a['star']:
368 one_arg += ' {}**\ '.format(a['star'].replace('*', '\\*'))
369 else:
370 one_arg += '** '
371 one_arg += '*{}*\\ **'.format(a['name'])
372 comma = ', '
373 print(one_arg, end='')
374
375 print(')**')
376
377 def print_one(self, helper):
378 self.print_proto(helper)
379
380 if (helper.desc):
381 print('\tDescription')
382 # Do not strip all newline characters: formatted code at the end of
383 # a section must be followed by a blank line.
384 for line in re.sub('\n$', '', helper.desc, count=1).split('\n'):
385 print('{}{}'.format('\t\t' if line else '', line))
386
387 if (helper.ret):
388 print('\tReturn')
389 for line in helper.ret.rstrip().split('\n'):
390 print('{}{}'.format('\t\t' if line else '', line))
391
392 print('')
393
394###############################################################################
395
396# If script is launched from scripts/ from kernel tree and can access
397# ../include/uapi/linux/bpf.h, use it as a default name for the file to parse,
398# otherwise the --filename argument will be required from the command line.
399script = os.path.abspath(sys.argv[0])
400linuxRoot = os.path.dirname(os.path.dirname(script))
401bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h')
402
403argParser = argparse.ArgumentParser(description="""
404Parse eBPF header file and generate documentation for eBPF helper functions.
405The RST-formatted output produced can be turned into a manual page with the
406rst2man utility.
407""")
408if (os.path.isfile(bpfh)):
409 argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h',
410 default=bpfh)
411else:
412 argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h')
413args = argParser.parse_args()
414
415# Parse file.
416headerParser = HeaderParser(args.filename)
417headerParser.run()
418
419# Print formatted output to standard output.
420printer = PrinterRST(headerParser.helpers)
421printer.print_all()
diff --git a/scripts/cc-can-link.sh b/scripts/cc-can-link.sh
new file mode 100755
index 000000000000..6efcead31989
--- /dev/null
+++ b/scripts/cc-can-link.sh
@@ -0,0 +1,11 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4cat << "END" | $@ -x c - -o /dev/null >/dev/null 2>&1
5#include <stdio.h>
6int main(void)
7{
8 printf("");
9 return 0;
10}
11END
diff --git a/scripts/check_00index.sh b/scripts/check_00index.sh
deleted file mode 100755
index aa47f5926c80..000000000000
--- a/scripts/check_00index.sh
+++ /dev/null
@@ -1,67 +0,0 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4cd Documentation/
5
6# Check entries that should be removed
7
8obsolete=""
9for i in $(tail -n +12 00-INDEX |grep -E '^[a-zA-Z0-9]+'); do
10 if [ ! -e $i ]; then
11 obsolete="$obsolete $i"
12 fi
13done
14
15# Check directory entries that should be added
16search=""
17dir=""
18for i in $(find . -maxdepth 1 -type d); do
19 if [ "$i" != "." ]; then
20 new=$(echo $i|perl -ne 's,./(.*),$1/,; print $_')
21 search="$search $new"
22 fi
23done
24
25for i in $search; do
26 if [ "$(grep -P "^$i" 00-INDEX)" == "" ]; then
27 dir="$dir $i"
28 fi
29done
30
31# Check file entries that should be added
32search=""
33file=""
34for i in $(find . -maxdepth 1 -type f); do
35 if [ "$i" != "./.gitignore" ]; then
36 new=$(echo $i|perl -ne 's,./(.*),$1,; print $_')
37 search="$search $new"
38 fi
39done
40
41for i in $search; do
42 if [ "$(grep -P "^$i\$" 00-INDEX)" == "" ]; then
43 file="$file $i"
44 fi
45done
46
47# Output its findings
48
49echo -e "Documentation/00-INDEX check results:\n"
50
51if [ "$obsolete" != "" ]; then
52 echo -e "- Should remove those entries:\n\t$obsolete\n"
53else
54 echo -e "- No obsolete entries\n"
55fi
56
57if [ "$dir" != "" ]; then
58 echo -e "- Should document those directories:\n\t$dir\n"
59else
60 echo -e "- No new directories to add\n"
61fi
62
63if [ "$file" != "" ]; then
64 echo -e "- Should document those files:\n\t$file"
65else
66 echo "- No new files to add"
67fi
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3d4040322ae1..c883ec55654f 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,9 +1,11 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2# SPDX-License-Identifier: GPL-2.0
3#
2# (c) 2001, Dave Jones. (the file handling bit) 4# (c) 2001, Dave Jones. (the file handling bit)
3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 5# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 6# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5# (c) 2008-2010 Andy Whitcroft <apw@canonical.com> 7# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
6# Licensed under the terms of the GNU GPL License version 2 8# (c) 2010-2018 Joe Perches <joe@perches.com>
7 9
8use strict; 10use strict;
9use warnings; 11use warnings;
@@ -11,6 +13,7 @@ use POSIX;
11use File::Basename; 13use File::Basename;
12use Cwd 'abs_path'; 14use Cwd 'abs_path';
13use Term::ANSIColor qw(:constants); 15use Term::ANSIColor qw(:constants);
16use Encode qw(decode encode);
14 17
15my $P = $0; 18my $P = $0;
16my $D = dirname(abs_path($P)); 19my $D = dirname(abs_path($P));
@@ -238,11 +241,11 @@ $check_orig = $check;
238 241
239my $exit = 0; 242my $exit = 0;
240 243
244my $perl_version_ok = 1;
241if ($^V && $^V lt $minimum_perl_version) { 245if ($^V && $^V lt $minimum_perl_version) {
246 $perl_version_ok = 0;
242 printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 247 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
243 if (!$ignore_perl_version) { 248 exit(1) if (!$ignore_perl_version);
244 exit(1);
245 }
246} 249}
247 250
248#if no filenames are given, push '-' to read patch from stdin 251#if no filenames are given, push '-' to read patch from stdin
@@ -344,9 +347,10 @@ our $Sparse = qr{
344 __force| 347 __force|
345 __iomem| 348 __iomem|
346 __must_check| 349 __must_check|
347 __init_refok|
348 __kprobes| 350 __kprobes|
349 __ref| 351 __ref|
352 __refconst|
353 __refdata|
350 __rcu| 354 __rcu|
351 __private 355 __private
352 }x; 356 }x;
@@ -376,6 +380,7 @@ our $Attribute = qr{
376 __noclone| 380 __noclone|
377 __deprecated| 381 __deprecated|
378 __read_mostly| 382 __read_mostly|
383 __ro_after_init|
379 __kprobes| 384 __kprobes|
380 $InitAttribute| 385 $InitAttribute|
381 ____cacheline_aligned| 386 ____cacheline_aligned|
@@ -791,7 +796,8 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
791our $declaration_macros = qr{(?x: 796our $declaration_macros = qr{(?x:
792 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 797 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
793 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 798 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
794 (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( 799 (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
800 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
795)}; 801)};
796 802
797sub deparenthesize { 803sub deparenthesize {
@@ -844,6 +850,17 @@ sub is_maintained_obsolete {
844 return $status =~ /obsolete/i; 850 return $status =~ /obsolete/i;
845} 851}
846 852
853sub is_SPDX_License_valid {
854 my ($license) = @_;
855
856 return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
857
858 my $root_path = abs_path($root);
859 my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
860 return 0 if ($status ne "");
861 return 1;
862}
863
847my $camelcase_seeded = 0; 864my $camelcase_seeded = 0;
848sub seed_camelcase_includes { 865sub seed_camelcase_includes {
849 return if ($camelcase_seeded); 866 return if ($camelcase_seeded);
@@ -1023,11 +1040,11 @@ if (!$quiet) {
1023 hash_show_words(\%use_type, "Used"); 1040 hash_show_words(\%use_type, "Used");
1024 hash_show_words(\%ignore_type, "Ignored"); 1041 hash_show_words(\%ignore_type, "Ignored");
1025 1042
1026 if ($^V lt 5.10.0) { 1043 if (!$perl_version_ok) {
1027 print << "EOM" 1044 print << "EOM"
1028 1045
1029NOTE: perl $^V is not modern enough to detect all possible issues. 1046NOTE: perl $^V is not modern enough to detect all possible issues.
1030 An upgrade to at least perl v5.10.0 is suggested. 1047 An upgrade to at least perl $minimum_perl_version is suggested.
1031EOM 1048EOM
1032 } 1049 }
1033 if ($exit) { 1050 if ($exit) {
@@ -1075,7 +1092,7 @@ sub parse_email {
1075 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 1092 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1076 $address = $1; 1093 $address = $1;
1077 $comment = $2 if defined $2; 1094 $comment = $2 if defined $2;
1078 $formatted_email =~ s/$address.*$//; 1095 $formatted_email =~ s/\Q$address\E.*$//;
1079 $name = $formatted_email; 1096 $name = $formatted_email;
1080 $name = trim($name); 1097 $name = trim($name);
1081 $name =~ s/^\"|\"$//g; 1098 $name =~ s/^\"|\"$//g;
@@ -1217,7 +1234,7 @@ sub sanitise_line {
1217 for ($off = 1; $off < length($line); $off++) { 1234 for ($off = 1; $off < length($line); $off++) {
1218 $c = substr($line, $off, 1); 1235 $c = substr($line, $off, 1);
1219 1236
1220 # Comments we are wacking completly including the begin 1237 # Comments we are whacking completely including the begin
1221 # and end, all to $;. 1238 # and end, all to $;.
1222 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1239 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1223 $sanitise_quote = '*/'; 1240 $sanitise_quote = '*/';
@@ -1297,6 +1314,7 @@ sub sanitise_line {
1297sub get_quoted_string { 1314sub get_quoted_string {
1298 my ($line, $rawline) = @_; 1315 my ($line, $rawline) = @_;
1299 1316
1317 return "" if (!defined($line) || !defined($rawline));
1300 return "" if ($line !~ m/($String)/g); 1318 return "" if ($line !~ m/($String)/g);
1301 return substr($rawline, $-[0], $+[0] - $-[0]); 1319 return substr($rawline, $-[0], $+[0] - $-[0]);
1302} 1320}
@@ -1644,6 +1662,28 @@ sub raw_line {
1644 return $line; 1662 return $line;
1645} 1663}
1646 1664
1665sub get_stat_real {
1666 my ($linenr, $lc) = @_;
1667
1668 my $stat_real = raw_line($linenr, 0);
1669 for (my $count = $linenr + 1; $count <= $lc; $count++) {
1670 $stat_real = $stat_real . "\n" . raw_line($count, 0);
1671 }
1672
1673 return $stat_real;
1674}
1675
1676sub get_stat_here {
1677 my ($linenr, $cnt, $here) = @_;
1678
1679 my $herectx = $here . "\n";
1680 for (my $n = 0; $n < $cnt; $n++) {
1681 $herectx .= raw_line($linenr, $n) . "\n";
1682 }
1683
1684 return $herectx;
1685}
1686
1647sub cat_vet { 1687sub cat_vet {
1648 my ($vet) = @_; 1688 my ($vet) = @_;
1649 my ($res, $coded); 1689 my ($res, $coded);
@@ -2209,10 +2249,14 @@ sub process {
2209 2249
2210 our $clean = 1; 2250 our $clean = 1;
2211 my $signoff = 0; 2251 my $signoff = 0;
2252 my $author = '';
2253 my $authorsignoff = 0;
2212 my $is_patch = 0; 2254 my $is_patch = 0;
2255 my $is_binding_patch = -1;
2213 my $in_header_lines = $file ? 0 : 1; 2256 my $in_header_lines = $file ? 0 : 1;
2214 my $in_commit_log = 0; #Scanning lines before patch 2257 my $in_commit_log = 0; #Scanning lines before patch
2215 my $has_commit_log = 0; #Encountered lines before patch 2258 my $has_commit_log = 0; #Encountered lines before patch
2259 my $commit_log_lines = 0; #Number of commit log lines
2216 my $commit_log_possible_stack_dump = 0; 2260 my $commit_log_possible_stack_dump = 0;
2217 my $commit_log_long_line = 0; 2261 my $commit_log_long_line = 0;
2218 my $commit_log_has_diff = 0; 2262 my $commit_log_has_diff = 0;
@@ -2257,6 +2301,8 @@ sub process {
2257 2301
2258 my $camelcase_file_seeded = 0; 2302 my $camelcase_file_seeded = 0;
2259 2303
2304 my $checklicenseline = 1;
2305
2260 sanitise_line_reset(); 2306 sanitise_line_reset();
2261 my $line; 2307 my $line;
2262 foreach my $rawline (@rawlines) { 2308 foreach my $rawline (@rawlines) {
@@ -2349,6 +2395,14 @@ sub process {
2349 2395
2350 my $rawline = $rawlines[$linenr - 1]; 2396 my $rawline = $rawlines[$linenr - 1];
2351 2397
2398# check if it's a mode change, rename or start of a patch
2399 if (!$in_commit_log &&
2400 ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2401 ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2402 $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2403 $is_patch = 1;
2404 }
2405
2352#extract the line range in the file after the patch is applied 2406#extract the line range in the file after the patch is applied
2353 if (!$in_commit_log && 2407 if (!$in_commit_log &&
2354 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 2408 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
@@ -2448,6 +2502,20 @@ sub process {
2448 } else { 2502 } else {
2449 $check = $check_orig; 2503 $check = $check_orig;
2450 } 2504 }
2505 $checklicenseline = 1;
2506
2507 if ($realfile !~ /^MAINTAINERS/) {
2508 my $last_binding_patch = $is_binding_patch;
2509
2510 $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2511
2512 if (($last_binding_patch != -1) &&
2513 ($last_binding_patch ^ $is_binding_patch)) {
2514 WARN("DT_SPLIT_BINDING_PATCH",
2515 "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2516 }
2517 }
2518
2451 next; 2519 next;
2452 } 2520 }
2453 2521
@@ -2459,6 +2527,18 @@ sub process {
2459 2527
2460 $cnt_lines++ if ($realcnt != 0); 2528 $cnt_lines++ if ($realcnt != 0);
2461 2529
2530# Verify the existence of a commit log if appropriate
2531# 2 is used because a $signature is counted in $commit_log_lines
2532 if ($in_commit_log) {
2533 if ($line !~ /^\s*$/) {
2534 $commit_log_lines++; #could be a $signature
2535 }
2536 } elsif ($has_commit_log && $commit_log_lines < 2) {
2537 WARN("COMMIT_MESSAGE",
2538 "Missing commit description - Add an appropriate one\n");
2539 $commit_log_lines = 2; #warn only once
2540 }
2541
2462# Check if the commit log has what seems like a diff which can confuse patch 2542# Check if the commit log has what seems like a diff which can confuse patch
2463 if ($in_commit_log && !$commit_log_has_diff && 2543 if ($in_commit_log && !$commit_log_has_diff &&
2464 (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 2544 (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
@@ -2480,10 +2560,24 @@ sub process {
2480 } 2560 }
2481 } 2561 }
2482 2562
2563# Check the patch for a From:
2564 if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2565 $author = $1;
2566 $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2567 $author =~ s/"//g;
2568 }
2569
2483# Check the patch for a signoff: 2570# Check the patch for a signoff:
2484 if ($line =~ /^\s*signed-off-by:/i) { 2571 if ($line =~ /^\s*signed-off-by:/i) {
2485 $signoff++; 2572 $signoff++;
2486 $in_commit_log = 0; 2573 $in_commit_log = 0;
2574 if ($author ne '') {
2575 my $l = $line;
2576 $l =~ s/"//g;
2577 if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
2578 $authorsignoff = 1;
2579 }
2580 }
2487 } 2581 }
2488 2582
2489# Check if MAINTAINERS is being updated. If so, there's probably no need to 2583# Check if MAINTAINERS is being updated. If so, there's probably no need to
@@ -2569,12 +2663,6 @@ sub process {
2569 "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2663 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2570 } 2664 }
2571 2665
2572# Check for old stable address
2573 if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
2574 ERROR("STABLE_ADDRESS",
2575 "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
2576 }
2577
2578# Check for unwanted Gerrit info 2666# Check for unwanted Gerrit info
2579 if ($in_commit_log && $line =~ /^\s*change-id:/i) { 2667 if ($in_commit_log && $line =~ /^\s*change-id:/i) {
2580 ERROR("GERRIT_CHANGE_ID", 2668 ERROR("GERRIT_CHANGE_ID",
@@ -2797,7 +2885,10 @@ sub process {
2797# Only applies when adding the entry originally, after that we do not have 2885# Only applies when adding the entry originally, after that we do not have
2798# sufficient context to determine whether it is indeed long enough. 2886# sufficient context to determine whether it is indeed long enough.
2799 if ($realfile =~ /Kconfig/ && 2887 if ($realfile =~ /Kconfig/ &&
2800 $line =~ /^\+\s*config\s+/) { 2888 # 'choice' is usually the last thing on the line (though
2889 # Kconfig supports named choices), so use a word boundary
2890 # (\b) rather than a whitespace character (\s)
2891 $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
2801 my $length = 0; 2892 my $length = 0;
2802 my $cnt = $realcnt; 2893 my $cnt = $realcnt;
2803 my $ln = $linenr + 1; 2894 my $ln = $linenr + 1;
@@ -2812,9 +2903,13 @@ sub process {
2812 next if ($f =~ /^-/); 2903 next if ($f =~ /^-/);
2813 last if (!$file && $f =~ /^\@\@/); 2904 last if (!$file && $f =~ /^\@\@/);
2814 2905
2815 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { 2906 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
2816 $is_start = 1; 2907 $is_start = 1;
2817 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 2908 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
2909 if ($lines[$ln - 1] =~ "---help---") {
2910 WARN("CONFIG_DESCRIPTION",
2911 "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
2912 }
2818 $length = -1; 2913 $length = -1;
2819 } 2914 }
2820 2915
@@ -2822,7 +2917,13 @@ sub process {
2822 $f =~ s/#.*//; 2917 $f =~ s/#.*//;
2823 $f =~ s/^\s+//; 2918 $f =~ s/^\s+//;
2824 next if ($f =~ /^$/); 2919 next if ($f =~ /^$/);
2825 if ($f =~ /^\s*config\s/) { 2920
2921 # This only checks context lines in the patch
2922 # and so hopefully shouldn't trigger false
2923 # positives, even though some of these are
2924 # common words in help texts
2925 if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
2926 if|endif|menu|endmenu|source)\b/x) {
2826 $is_end = 1; 2927 $is_end = 1;
2827 last; 2928 last;
2828 } 2929 }
@@ -2898,6 +2999,36 @@ sub process {
2898 } 2999 }
2899 } 3000 }
2900 3001
3002# check for using SPDX license tag at beginning of files
3003 if ($realline == $checklicenseline) {
3004 if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3005 $checklicenseline = 2;
3006 } elsif ($rawline =~ /^\+/) {
3007 my $comment = "";
3008 if ($realfile =~ /\.(h|s|S)$/) {
3009 $comment = '/*';
3010 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
3011 $comment = '//';
3012 } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
3013 $comment = '#';
3014 } elsif ($realfile =~ /\.rst$/) {
3015 $comment = '..';
3016 }
3017
3018 if ($comment !~ /^$/ &&
3019 $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) {
3020 WARN("SPDX_LICENSE_TAG",
3021 "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
3022 } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
3023 my $spdx_license = $1;
3024 if (!is_SPDX_License_valid($spdx_license)) {
3025 WARN("SPDX_LICENSE_TAG",
3026 "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3027 }
3028 }
3029 }
3030 }
3031
2901# check we are in a valid source file if not then ignore this hunk 3032# check we are in a valid source file if not then ignore this hunk
2902 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 3033 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
2903 3034
@@ -2969,20 +3100,6 @@ sub process {
2969 "adding a line without newline at end of file\n" . $herecurr); 3100 "adding a line without newline at end of file\n" . $herecurr);
2970 } 3101 }
2971 3102
2972# Blackfin: use hi/lo macros
2973 if ($realfile =~ m@arch/blackfin/.*\.S$@) {
2974 if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
2975 my $herevet = "$here\n" . cat_vet($line) . "\n";
2976 ERROR("LO_MACRO",
2977 "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
2978 }
2979 if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
2980 my $herevet = "$here\n" . cat_vet($line) . "\n";
2981 ERROR("HI_MACRO",
2982 "use the HI() macro, not (... >> 16)\n" . $herevet);
2983 }
2984 }
2985
2986# check we are in a valid source file C or perl if not then ignore this hunk 3103# check we are in a valid source file C or perl if not then ignore this hunk
2987 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 3104 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
2988 3105
@@ -3012,6 +3129,12 @@ sub process {
3012 } 3129 }
3013 } 3130 }
3014 3131
3132# check for assignments on the start of a line
3133 if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3134 CHK("ASSIGNMENT_CONTINUATIONS",
3135 "Assignment operator '$1' should be on the previous line\n" . $hereprev);
3136 }
3137
3015# check for && or || at the start of a line 3138# check for && or || at the start of a line
3016 if ($rawline =~ /^\+\s*(&&|\|\|)/) { 3139 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3017 CHK("LOGICAL_CONTINUATIONS", 3140 CHK("LOGICAL_CONTINUATIONS",
@@ -3019,7 +3142,7 @@ sub process {
3019 } 3142 }
3020 3143
3021# check indentation starts on a tab stop 3144# check indentation starts on a tab stop
3022 if ($^V && $^V ge 5.10.0 && 3145 if ($perl_version_ok &&
3023 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3146 $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3024 my $indent = length($1); 3147 my $indent = length($1);
3025 if ($indent % 8) { 3148 if ($indent % 8) {
@@ -3032,7 +3155,7 @@ sub process {
3032 } 3155 }
3033 3156
3034# check multi-line statement indentation matches previous line 3157# check multi-line statement indentation matches previous line
3035 if ($^V && $^V ge 5.10.0 && 3158 if ($perl_version_ok &&
3036 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3159 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3037 $prevline =~ /^\+(\t*)(.*)$/; 3160 $prevline =~ /^\+(\t*)(.*)$/;
3038 my $oldindent = $1; 3161 my $oldindent = $1;
@@ -3189,7 +3312,7 @@ sub process {
3189 # known declaration macros 3312 # known declaration macros
3190 $sline =~ /^\+\s+$declaration_macros/ || 3313 $sline =~ /^\+\s+$declaration_macros/ ||
3191 # start of struct or union or enum 3314 # start of struct or union or enum
3192 $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 3315 $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
3193 # start or end of block or continuation of declaration 3316 # start or end of block or continuation of declaration
3194 $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 3317 $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
3195 # bitfield continuation 3318 # bitfield continuation
@@ -3269,18 +3392,6 @@ sub process {
3269 "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3392 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3270 } 3393 }
3271 3394
3272# Blackfin: don't use __builtin_bfin_[cs]sync
3273 if ($line =~ /__builtin_bfin_csync/) {
3274 my $herevet = "$here\n" . cat_vet($line) . "\n";
3275 ERROR("CSYNC",
3276 "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
3277 }
3278 if ($line =~ /__builtin_bfin_ssync/) {
3279 my $herevet = "$here\n" . cat_vet($line) . "\n";
3280 ERROR("SSYNC",
3281 "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
3282 }
3283
3284# check for old HOTPLUG __dev<foo> section markings 3395# check for old HOTPLUG __dev<foo> section markings
3285 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 3396 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
3286 WARN("HOTPLUG_SECTION", 3397 WARN("HOTPLUG_SECTION",
@@ -3733,6 +3844,26 @@ sub process {
3733 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 3844 "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
3734 } 3845 }
3735 3846
3847# check for unnecessary <signed> int declarations of short/long/long long
3848 while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
3849 my $type = trim($1);
3850 next if ($type !~ /\bint\b/);
3851 next if ($type !~ /\b(?:short|long\s+long|long)\b/);
3852 my $new_type = $type;
3853 $new_type =~ s/\b\s*int\s*\b/ /;
3854 $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
3855 $new_type =~ s/^const\s+//;
3856 $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
3857 $new_type = "const $new_type" if ($type =~ /^const\b/);
3858 $new_type =~ s/\s+/ /g;
3859 $new_type = trim($new_type);
3860 if (WARN("UNNECESSARY_INT",
3861 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
3862 $fix) {
3863 $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
3864 }
3865 }
3866
3736# check for static const char * arrays. 3867# check for static const char * arrays.
3737 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3868 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3738 WARN("STATIC_CONST_CHAR_ARRAY", 3869 WARN("STATIC_CONST_CHAR_ARRAY",
@@ -3919,7 +4050,7 @@ sub process {
3919 4050
3920# function brace can't be on same line, except for #defines of do while, 4051# function brace can't be on same line, except for #defines of do while,
3921# or if closed on same line 4052# or if closed on same line
3922 if ($^V && $^V ge 5.10.0 && 4053 if ($perl_version_ok &&
3923 $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 4054 $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
3924 $sline !~ /\#\s*define\b.*do\s*\{/ && 4055 $sline !~ /\#\s*define\b.*do\s*\{/ &&
3925 $sline !~ /}/) { 4056 $sline !~ /}/) {
@@ -4045,7 +4176,7 @@ sub process {
4045 my ($where, $prefix) = ($-[1], $1); 4176 my ($where, $prefix) = ($-[1], $1);
4046 if ($prefix !~ /$Type\s+$/ && 4177 if ($prefix !~ /$Type\s+$/ &&
4047 ($where != 0 || $prefix !~ /^.\s+$/) && 4178 ($where != 0 || $prefix !~ /^.\s+$/) &&
4048 $prefix !~ /[{,]\s+$/) { 4179 $prefix !~ /[{,:]\s+$/) {
4049 if (ERROR("BRACKET_SPACE", 4180 if (ERROR("BRACKET_SPACE",
4050 "space prohibited before open square bracket '['\n" . $herecurr) && 4181 "space prohibited before open square bracket '['\n" . $herecurr) &&
4051 $fix) { 4182 $fix) {
@@ -4435,11 +4566,11 @@ sub process {
4435 4566
4436#need space before brace following if, while, etc 4567#need space before brace following if, while, etc
4437 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 4568 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
4438 $line =~ /do\{/) { 4569 $line =~ /\b(?:else|do)\{/) {
4439 if (ERROR("SPACING", 4570 if (ERROR("SPACING",
4440 "space required before the open brace '{'\n" . $herecurr) && 4571 "space required before the open brace '{'\n" . $herecurr) &&
4441 $fix) { 4572 $fix) {
4442 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; 4573 $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
4443 } 4574 }
4444 } 4575 }
4445 4576
@@ -4530,7 +4661,7 @@ sub process {
4530# check for unnecessary parentheses around comparisons in if uses 4661# check for unnecessary parentheses around comparisons in if uses
4531# when !drivers/staging or command-line uses --strict 4662# when !drivers/staging or command-line uses --strict
4532 if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 4663 if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
4533 $^V && $^V ge 5.10.0 && defined($stat) && 4664 $perl_version_ok && defined($stat) &&
4534 $stat =~ /(^.\s*if\s*($balanced_parens))/) { 4665 $stat =~ /(^.\s*if\s*($balanced_parens))/) {
4535 my $if_stat = $1; 4666 my $if_stat = $1;
4536 my $test = substr($2, 1, -1); 4667 my $test = substr($2, 1, -1);
@@ -4567,7 +4698,7 @@ sub process {
4567# return is not a function 4698# return is not a function
4568 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4699 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4569 my $spacing = $1; 4700 my $spacing = $1;
4570 if ($^V && $^V ge 5.10.0 && 4701 if ($perl_version_ok &&
4571 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 4702 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
4572 my $value = $1; 4703 my $value = $1;
4573 $value = deparenthesize($value); 4704 $value = deparenthesize($value);
@@ -4594,7 +4725,7 @@ sub process {
4594 } 4725 }
4595 4726
4596# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4727# if statements using unnecessary parentheses - ie: if ((foo == bar))
4597 if ($^V && $^V ge 5.10.0 && 4728 if ($perl_version_ok &&
4598 $line =~ /\bif\s*((?:\(\s*){2,})/) { 4729 $line =~ /\bif\s*((?:\(\s*){2,})/) {
4599 my $openparens = $1; 4730 my $openparens = $1;
4600 my $count = $openparens =~ tr@\(@\(@; 4731 my $count = $openparens =~ tr@\(@\(@;
@@ -4611,7 +4742,7 @@ sub process {
4611# avoid cases like "foo + BAR < baz" 4742# avoid cases like "foo + BAR < baz"
4612# only fix matches surrounded by parentheses to avoid incorrect 4743# only fix matches surrounded by parentheses to avoid incorrect
4613# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 4744# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
4614 if ($^V && $^V ge 5.10.0 && 4745 if ($perl_version_ok &&
4615 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4746 $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4616 my $lead = $1; 4747 my $lead = $1;
4617 my $const = $2; 4748 my $const = $2;
@@ -4803,17 +4934,6 @@ sub process {
4803 while ($line =~ m{($Constant|$Lval)}g) { 4934 while ($line =~ m{($Constant|$Lval)}g) {
4804 my $var = $1; 4935 my $var = $1;
4805 4936
4806#gcc binary extension
4807 if ($var =~ /^$Binary$/) {
4808 if (WARN("GCC_BINARY_CONSTANT",
4809 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4810 $fix) {
4811 my $hexval = sprintf("0x%x", oct($var));
4812 $fixed[$fixlinenr] =~
4813 s/\b$var\b/$hexval/;
4814 }
4815 }
4816
4817#CamelCase 4937#CamelCase
4818 if ($var !~ /^$Constant$/ && 4938 if ($var !~ /^$Constant$/ &&
4819 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 4939 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
@@ -4901,6 +5021,7 @@ sub process {
4901 if (defined $define_args && $define_args ne "") { 5021 if (defined $define_args && $define_args ne "") {
4902 $define_args = substr($define_args, 1, length($define_args) - 2); 5022 $define_args = substr($define_args, 1, length($define_args) - 2);
4903 $define_args =~ s/\s*//g; 5023 $define_args =~ s/\s*//g;
5024 $define_args =~ s/\\\+?//g;
4904 @def_args = split(",", $define_args); 5025 @def_args = split(",", $define_args);
4905 } 5026 }
4906 5027
@@ -4941,12 +5062,8 @@ sub process {
4941 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5062 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
4942 5063
4943 $ctx =~ s/\n*$//; 5064 $ctx =~ s/\n*$//;
4944 my $herectx = $here . "\n";
4945 my $stmt_cnt = statement_rawlines($ctx); 5065 my $stmt_cnt = statement_rawlines($ctx);
4946 5066 my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
4947 for (my $n = 0; $n < $stmt_cnt; $n++) {
4948 $herectx .= raw_line($linenr, $n) . "\n";
4949 }
4950 5067
4951 if ($dstat ne '' && 5068 if ($dstat ne '' &&
4952 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5069 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
@@ -5001,7 +5118,7 @@ sub process {
5001 $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 5118 $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
5002 $tmp_stmt =~ s/\#+\s*$arg\b//g; 5119 $tmp_stmt =~ s/\#+\s*$arg\b//g;
5003 $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5120 $tmp_stmt =~ s/\b$arg\s*\#\#//g;
5004 my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g; 5121 my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5005 if ($use_cnt > 1) { 5122 if ($use_cnt > 1) {
5006 CHK("MACRO_ARG_REUSE", 5123 CHK("MACRO_ARG_REUSE",
5007 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5124 "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
@@ -5018,12 +5135,9 @@ sub process {
5018# check for macros with flow control, but without ## concatenation 5135# check for macros with flow control, but without ## concatenation
5019# ## concatenation is commonly a macro that defines a function so ignore those 5136# ## concatenation is commonly a macro that defines a function so ignore those
5020 if ($has_flow_statement && !$has_arg_concat) { 5137 if ($has_flow_statement && !$has_arg_concat) {
5021 my $herectx = $here . "\n";
5022 my $cnt = statement_rawlines($ctx); 5138 my $cnt = statement_rawlines($ctx);
5139 my $herectx = get_stat_here($linenr, $cnt, $here);
5023 5140
5024 for (my $n = 0; $n < $cnt; $n++) {
5025 $herectx .= raw_line($linenr, $n) . "\n";
5026 }
5027 WARN("MACRO_WITH_FLOW_CONTROL", 5141 WARN("MACRO_WITH_FLOW_CONTROL",
5028 "Macros with flow control statements should be avoided\n" . "$herectx"); 5142 "Macros with flow control statements should be avoided\n" . "$herectx");
5029 } 5143 }
@@ -5043,7 +5157,7 @@ sub process {
5043# do {} while (0) macro tests: 5157# do {} while (0) macro tests:
5044# single-statement macros do not need to be enclosed in do while (0) loop, 5158# single-statement macros do not need to be enclosed in do while (0) loop,
5045# macro should not end with a semicolon 5159# macro should not end with a semicolon
5046 if ($^V && $^V ge 5.10.0 && 5160 if ($perl_version_ok &&
5047 $realfile !~ m@/vmlinux.lds.h$@ && 5161 $realfile !~ m@/vmlinux.lds.h$@ &&
5048 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5162 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5049 my $ln = $linenr; 5163 my $ln = $linenr;
@@ -5063,11 +5177,7 @@ sub process {
5063 5177
5064 $ctx =~ s/\n*$//; 5178 $ctx =~ s/\n*$//;
5065 my $cnt = statement_rawlines($ctx); 5179 my $cnt = statement_rawlines($ctx);
5066 my $herectx = $here . "\n"; 5180 my $herectx = get_stat_here($linenr, $cnt, $here);
5067
5068 for (my $n = 0; $n < $cnt; $n++) {
5069 $herectx .= raw_line($linenr, $n) . "\n";
5070 }
5071 5181
5072 if (($stmts =~ tr/;/;/) == 1 && 5182 if (($stmts =~ tr/;/;/) == 1 &&
5073 $stmts !~ /^\s*(if|while|for|switch)\b/) { 5183 $stmts !~ /^\s*(if|while|for|switch)\b/) {
@@ -5081,27 +5191,13 @@ sub process {
5081 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5191 } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5082 $ctx =~ s/\n*$//; 5192 $ctx =~ s/\n*$//;
5083 my $cnt = statement_rawlines($ctx); 5193 my $cnt = statement_rawlines($ctx);
5084 my $herectx = $here . "\n"; 5194 my $herectx = get_stat_here($linenr, $cnt, $here);
5085
5086 for (my $n = 0; $n < $cnt; $n++) {
5087 $herectx .= raw_line($linenr, $n) . "\n";
5088 }
5089 5195
5090 WARN("TRAILING_SEMICOLON", 5196 WARN("TRAILING_SEMICOLON",
5091 "macros should not use a trailing semicolon\n" . "$herectx"); 5197 "macros should not use a trailing semicolon\n" . "$herectx");
5092 } 5198 }
5093 } 5199 }
5094 5200
5095# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
5096# all assignments may have only one of the following with an assignment:
5097# .
5098# ALIGN(...)
5099# VMLINUX_SYMBOL(...)
5100 if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
5101 WARN("MISSING_VMLINUX_SYMBOL",
5102 "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
5103 }
5104
5105# check for redundant bracing round if etc 5201# check for redundant bracing round if etc
5106 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 5202 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5107 my ($level, $endln, @chunks) = 5203 my ($level, $endln, @chunks) =
@@ -5208,12 +5304,8 @@ sub process {
5208 } 5304 }
5209 } 5305 }
5210 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5306 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5211 my $herectx = $here . "\n";
5212 my $cnt = statement_rawlines($block); 5307 my $cnt = statement_rawlines($block);
5213 5308 my $herectx = get_stat_here($linenr, $cnt, $here);
5214 for (my $n = 0; $n < $cnt; $n++) {
5215 $herectx .= raw_line($linenr, $n) . "\n";
5216 }
5217 5309
5218 WARN("BRACES", 5310 WARN("BRACES",
5219 "braces {} are not necessary for single statement blocks\n" . $herectx); 5311 "braces {} are not necessary for single statement blocks\n" . $herectx);
@@ -5311,15 +5403,28 @@ sub process {
5311 } 5403 }
5312 5404
5313# concatenated string without spaces between elements 5405# concatenated string without spaces between elements
5314 if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { 5406 if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5315 CHK("CONCATENATED_STRING", 5407 if (CHK("CONCATENATED_STRING",
5316 "Concatenated strings should use spaces between elements\n" . $herecurr); 5408 "Concatenated strings should use spaces between elements\n" . $herecurr) &&
5409 $fix) {
5410 while ($line =~ /($String)/g) {
5411 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
5412 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
5413 $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
5414 }
5415 }
5317 } 5416 }
5318 5417
5319# uncoalesced string fragments 5418# uncoalesced string fragments
5320 if ($line =~ /$String\s*"/) { 5419 if ($line =~ /$String\s*"/) {
5321 WARN("STRING_FRAGMENTS", 5420 if (WARN("STRING_FRAGMENTS",
5322 "Consecutive strings are generally better as a single string\n" . $herecurr); 5421 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
5422 $fix) {
5423 while ($line =~ /($String)(?=\s*")/g) {
5424 my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
5425 $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
5426 }
5427 }
5323 } 5428 }
5324 5429
5325# check for non-standard and hex prefixed decimal printf formats 5430# check for non-standard and hex prefixed decimal printf formats
@@ -5355,9 +5460,14 @@ sub process {
5355 5460
5356# warn about #if 0 5461# warn about #if 0
5357 if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5462 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5358 CHK("REDUNDANT_CODE", 5463 WARN("IF_0",
5359 "if this code is redundant consider removing it\n" . 5464 "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
5360 $herecurr); 5465 }
5466
5467# warn about #if 1
5468 if ($line =~ /^.\s*\#\s*if\s+1\b/) {
5469 WARN("IF_1",
5470 "Consider removing the #if 1 and its #endif\n" . $herecurr);
5361 } 5471 }
5362 5472
5363# check for needless "if (<foo>) fn(<foo>)" uses 5473# check for needless "if (<foo>) fn(<foo>)" uses
@@ -5428,7 +5538,7 @@ sub process {
5428 } 5538 }
5429 5539
5430# check for mask then right shift without a parentheses 5540# check for mask then right shift without a parentheses
5431 if ($^V && $^V ge 5.10.0 && 5541 if ($perl_version_ok &&
5432 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5542 $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5433 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5543 $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5434 WARN("MASK_THEN_SHIFT", 5544 WARN("MASK_THEN_SHIFT",
@@ -5436,7 +5546,7 @@ sub process {
5436 } 5546 }
5437 5547
5438# check for pointer comparisons to NULL 5548# check for pointer comparisons to NULL
5439 if ($^V && $^V ge 5.10.0) { 5549 if ($perl_version_ok) {
5440 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5550 while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5441 my $val = $1; 5551 my $val = $1;
5442 my $equal = "!"; 5552 my $equal = "!";
@@ -5708,7 +5818,7 @@ sub process {
5708 } 5818 }
5709 5819
5710# Check for __attribute__ weak, or __weak declarations (may have link issues) 5820# Check for __attribute__ weak, or __weak declarations (may have link issues)
5711 if ($^V && $^V ge 5.10.0 && 5821 if ($perl_version_ok &&
5712 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5822 $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5713 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5823 ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5714 $line =~ /\b__weak\b/)) { 5824 $line =~ /\b__weak\b/)) {
@@ -5789,41 +5899,55 @@ sub process {
5789 } 5899 }
5790 } 5900 }
5791 5901
5792 # check for vsprintf extension %p<foo> misuses 5902# check for vsprintf extension %p<foo> misuses
5793 if ($^V && $^V ge 5.10.0 && 5903 if ($perl_version_ok &&
5794 defined $stat && 5904 defined $stat &&
5795 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 5905 $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
5796 $1 !~ /^_*volatile_*$/) { 5906 $1 !~ /^_*volatile_*$/) {
5797 my $bad_extension = ""; 5907 my $stat_real;
5908
5798 my $lc = $stat =~ tr@\n@@; 5909 my $lc = $stat =~ tr@\n@@;
5799 $lc = $lc + $linenr; 5910 $lc = $lc + $linenr;
5800 for (my $count = $linenr; $count <= $lc; $count++) { 5911 for (my $count = $linenr; $count <= $lc; $count++) {
5912 my $specifier;
5913 my $extension;
5914 my $bad_specifier = "";
5801 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 5915 my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
5802 $fmt =~ s/%%//g; 5916 $fmt =~ s/%%//g;
5803 if ($fmt =~ /(\%[\*\d\.]*p(?![\WSsBKRraEhMmIiUDdgVCbGNOx]).)/) { 5917
5804 $bad_extension = $1; 5918 while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
5805 last; 5919 $specifier = $1;
5806 } 5920 $extension = $2;
5807 } 5921 if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) {
5808 if ($bad_extension ne "") { 5922 $bad_specifier = $specifier;
5809 my $stat_real = raw_line($linenr, 0); 5923 last;
5810 my $ext_type = "Invalid"; 5924 }
5811 my $use = ""; 5925 if ($extension eq "x" && !defined($stat_real)) {
5812 for (my $count = $linenr + 1; $count <= $lc; $count++) { 5926 if (!defined($stat_real)) {
5813 $stat_real = $stat_real . "\n" . raw_line($count, 0); 5927 $stat_real = get_stat_real($linenr, $lc);
5928 }
5929 WARN("VSPRINTF_SPECIFIER_PX",
5930 "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");
5931 }
5814 } 5932 }
5815 if ($bad_extension =~ /p[Ff]/) { 5933 if ($bad_specifier ne "") {
5816 $ext_type = "Deprecated"; 5934 my $stat_real = get_stat_real($linenr, $lc);
5817 $use = " - use %pS instead"; 5935 my $ext_type = "Invalid";
5818 $use =~ s/pS/ps/ if ($bad_extension =~ /pf/); 5936 my $use = "";
5937 if ($bad_specifier =~ /p[Ff]/) {
5938 $ext_type = "Deprecated";
5939 $use = " - use %pS instead";
5940 $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
5941 }
5942
5943 WARN("VSPRINTF_POINTER_EXTENSION",
5944 "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
5819 } 5945 }
5820 WARN("VSPRINTF_POINTER_EXTENSION",
5821 "$ext_type vsprintf pointer extension '$bad_extension'$use\n" . "$here\n$stat_real\n");
5822 } 5946 }
5823 } 5947 }
5824 5948
5825# Check for misused memsets 5949# Check for misused memsets
5826 if ($^V && $^V ge 5.10.0 && 5950 if ($perl_version_ok &&
5827 defined $stat && 5951 defined $stat &&
5828 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5952 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
5829 5953
@@ -5841,7 +5965,7 @@ sub process {
5841 } 5965 }
5842 5966
5843# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 5967# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
5844# if ($^V && $^V ge 5.10.0 && 5968# if ($perl_version_ok &&
5845# defined $stat && 5969# defined $stat &&
5846# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5970# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5847# if (WARN("PREFER_ETHER_ADDR_COPY", 5971# if (WARN("PREFER_ETHER_ADDR_COPY",
@@ -5852,7 +5976,7 @@ sub process {
5852# } 5976# }
5853 5977
5854# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 5978# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
5855# if ($^V && $^V ge 5.10.0 && 5979# if ($perl_version_ok &&
5856# defined $stat && 5980# defined $stat &&
5857# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5981# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5858# WARN("PREFER_ETHER_ADDR_EQUAL", 5982# WARN("PREFER_ETHER_ADDR_EQUAL",
@@ -5861,7 +5985,7 @@ sub process {
5861 5985
5862# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 5986# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
5863# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 5987# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
5864# if ($^V && $^V ge 5.10.0 && 5988# if ($perl_version_ok &&
5865# defined $stat && 5989# defined $stat &&
5866# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5990# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5867# 5991#
@@ -5883,7 +6007,7 @@ sub process {
5883# } 6007# }
5884 6008
5885# typecasts on min/max could be min_t/max_t 6009# typecasts on min/max could be min_t/max_t
5886 if ($^V && $^V ge 5.10.0 && 6010 if ($perl_version_ok &&
5887 defined $stat && 6011 defined $stat &&
5888 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6012 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5889 if (defined $2 || defined $7) { 6013 if (defined $2 || defined $7) {
@@ -5907,7 +6031,7 @@ sub process {
5907 } 6031 }
5908 6032
5909# check usleep_range arguments 6033# check usleep_range arguments
5910 if ($^V && $^V ge 5.10.0 && 6034 if ($perl_version_ok &&
5911 defined $stat && 6035 defined $stat &&
5912 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 6036 $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
5913 my $min = $1; 6037 my $min = $1;
@@ -5923,7 +6047,7 @@ sub process {
5923 } 6047 }
5924 6048
5925# check for naked sscanf 6049# check for naked sscanf
5926 if ($^V && $^V ge 5.10.0 && 6050 if ($perl_version_ok &&
5927 defined $stat && 6051 defined $stat &&
5928 $line =~ /\bsscanf\b/ && 6052 $line =~ /\bsscanf\b/ &&
5929 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6053 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
@@ -5931,24 +6055,18 @@ sub process {
5931 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6055 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5932 my $lc = $stat =~ tr@\n@@; 6056 my $lc = $stat =~ tr@\n@@;
5933 $lc = $lc + $linenr; 6057 $lc = $lc + $linenr;
5934 my $stat_real = raw_line($linenr, 0); 6058 my $stat_real = get_stat_real($linenr, $lc);
5935 for (my $count = $linenr + 1; $count <= $lc; $count++) {
5936 $stat_real = $stat_real . "\n" . raw_line($count, 0);
5937 }
5938 WARN("NAKED_SSCANF", 6059 WARN("NAKED_SSCANF",
5939 "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6060 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5940 } 6061 }
5941 6062
5942# check for simple sscanf that should be kstrto<foo> 6063# check for simple sscanf that should be kstrto<foo>
5943 if ($^V && $^V ge 5.10.0 && 6064 if ($perl_version_ok &&
5944 defined $stat && 6065 defined $stat &&
5945 $line =~ /\bsscanf\b/) { 6066 $line =~ /\bsscanf\b/) {
5946 my $lc = $stat =~ tr@\n@@; 6067 my $lc = $stat =~ tr@\n@@;
5947 $lc = $lc + $linenr; 6068 $lc = $lc + $linenr;
5948 my $stat_real = raw_line($linenr, 0); 6069 my $stat_real = get_stat_real($linenr, $lc);
5949 for (my $count = $linenr + 1; $count <= $lc; $count++) {
5950 $stat_real = $stat_real . "\n" . raw_line($count, 0);
5951 }
5952 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6070 if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5953 my $format = $6; 6071 my $format = $6;
5954 my $count = $format =~ tr@%@%@; 6072 my $count = $format =~ tr@%@%@;
@@ -6015,7 +6133,7 @@ sub process {
6015 } 6133 }
6016 6134
6017# check for function definitions 6135# check for function definitions
6018 if ($^V && $^V ge 5.10.0 && 6136 if ($perl_version_ok &&
6019 defined $stat && 6137 defined $stat &&
6020 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6138 $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6021 $context_function = $1; 6139 $context_function = $1;
@@ -6055,14 +6173,14 @@ sub process {
6055 6173
6056# alloc style 6174# alloc style
6057# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 6175# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
6058 if ($^V && $^V ge 5.10.0 && 6176 if ($perl_version_ok &&
6059 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6177 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6060 CHK("ALLOC_SIZEOF_STRUCT", 6178 CHK("ALLOC_SIZEOF_STRUCT",
6061 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6179 "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6062 } 6180 }
6063 6181
6064# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 6182# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
6065 if ($^V && $^V ge 5.10.0 && 6183 if ($perl_version_ok &&
6066 defined $stat && 6184 defined $stat &&
6067 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 6185 $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
6068 my $oldfunc = $3; 6186 my $oldfunc = $3;
@@ -6078,12 +6196,9 @@ sub process {
6078 } 6196 }
6079 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 6197 if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6080 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 6198 !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
6081 my $ctx = '';
6082 my $herectx = $here . "\n";
6083 my $cnt = statement_rawlines($stat); 6199 my $cnt = statement_rawlines($stat);
6084 for (my $n = 0; $n < $cnt; $n++) { 6200 my $herectx = get_stat_here($linenr, $cnt, $here);
6085 $herectx .= raw_line($linenr, $n) . "\n"; 6201
6086 }
6087 if (WARN("ALLOC_WITH_MULTIPLY", 6202 if (WARN("ALLOC_WITH_MULTIPLY",
6088 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 6203 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
6089 $cnt == 1 && 6204 $cnt == 1 &&
@@ -6094,8 +6209,9 @@ sub process {
6094 } 6209 }
6095 6210
6096# check for krealloc arg reuse 6211# check for krealloc arg reuse
6097 if ($^V && $^V ge 5.10.0 && 6212 if ($perl_version_ok &&
6098 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 6213 $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
6214 $1 eq $3) {
6099 WARN("KREALLOC_ARG_REUSE", 6215 WARN("KREALLOC_ARG_REUSE",
6100 "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6216 "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6101 } 6217 }
@@ -6163,15 +6279,12 @@ sub process {
6163 } 6279 }
6164 6280
6165# check for switch/default statements without a break; 6281# check for switch/default statements without a break;
6166 if ($^V && $^V ge 5.10.0 && 6282 if ($perl_version_ok &&
6167 defined $stat && 6283 defined $stat &&
6168 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6284 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6169 my $ctx = '';
6170 my $herectx = $here . "\n";
6171 my $cnt = statement_rawlines($stat); 6285 my $cnt = statement_rawlines($stat);
6172 for (my $n = 0; $n < $cnt; $n++) { 6286 my $herectx = get_stat_here($linenr, $cnt, $here);
6173 $herectx .= raw_line($linenr, $n) . "\n"; 6287
6174 }
6175 WARN("DEFAULT_NO_BREAK", 6288 WARN("DEFAULT_NO_BREAK",
6176 "switch default: should use break\n" . $herectx); 6289 "switch default: should use break\n" . $herectx);
6177 } 6290 }
@@ -6224,6 +6337,19 @@ sub process {
6224 } 6337 }
6225 } 6338 }
6226 6339
6340# check for bool bitfields
6341 if ($sline =~ /^.\s+bool\s*$Ident\s*:\s*\d+\s*;/) {
6342 WARN("BOOL_BITFIELD",
6343 "Avoid using bool as bitfield. Prefer bool bitfields as unsigned int or u<8|16|32>\n" . $herecurr);
6344 }
6345
6346# check for bool use in .h files
6347 if ($realfile =~ /\.h$/ &&
6348 $sline =~ /^.\s+bool\s*$Ident\s*(?::\s*d+\s*)?;/) {
6349 CHK("BOOL_MEMBER",
6350 "Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384\n" . $herecurr);
6351 }
6352
6227# check for semaphores initialized locked 6353# check for semaphores initialized locked
6228 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6354 if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6229 WARN("CONSIDER_COMPLETION", 6355 WARN("CONSIDER_COMPLETION",
@@ -6270,7 +6396,7 @@ sub process {
6270 } 6396 }
6271 6397
6272# likely/unlikely comparisons similar to "(likely(foo) > 0)" 6398# likely/unlikely comparisons similar to "(likely(foo) > 0)"
6273 if ($^V && $^V ge 5.10.0 && 6399 if ($perl_version_ok &&
6274 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6400 $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6275 WARN("LIKELY_MISUSE", 6401 WARN("LIKELY_MISUSE",
6276 "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6402 "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
@@ -6313,7 +6439,7 @@ sub process {
6313# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 6439# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
6314# and whether or not function naming is typical and if 6440# and whether or not function naming is typical and if
6315# DEVICE_ATTR permissions uses are unusual too 6441# DEVICE_ATTR permissions uses are unusual too
6316 if ($^V && $^V ge 5.10.0 && 6442 if ($perl_version_ok &&
6317 defined $stat && 6443 defined $stat &&
6318 $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { 6444 $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
6319 my $var = $1; 6445 my $var = $1;
@@ -6373,7 +6499,7 @@ sub process {
6373# specific definition of not visible in sysfs. 6499# specific definition of not visible in sysfs.
6374# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 6500# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
6375# use the default permissions 6501# use the default permissions
6376 if ($^V && $^V ge 5.10.0 && 6502 if ($perl_version_ok &&
6377 defined $stat && 6503 defined $stat &&
6378 $line =~ /$mode_perms_search/) { 6504 $line =~ /$mode_perms_search/) {
6379 foreach my $entry (@mode_permission_funcs) { 6505 foreach my $entry (@mode_permission_funcs) {
@@ -6382,10 +6508,7 @@ sub process {
6382 6508
6383 my $lc = $stat =~ tr@\n@@; 6509 my $lc = $stat =~ tr@\n@@;
6384 $lc = $lc + $linenr; 6510 $lc = $lc + $linenr;
6385 my $stat_real = raw_line($linenr, 0); 6511 my $stat_real = get_stat_real($linenr, $lc);
6386 for (my $count = $linenr + 1; $count <= $lc; $count++) {
6387 $stat_real = $stat_real . "\n" . raw_line($count, 0);
6388 }
6389 6512
6390 my $skip_args = ""; 6513 my $skip_args = "";
6391 if ($arg_pos > 1) { 6514 if ($arg_pos > 1) {
@@ -6411,7 +6534,7 @@ sub process {
6411 } 6534 }
6412 6535
6413# check for uses of S_<PERMS> that could be octal for readability 6536# check for uses of S_<PERMS> that could be octal for readability
6414 if ($line =~ /\b($multi_mode_perms_string_search)\b/) { 6537 while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
6415 my $oval = $1; 6538 my $oval = $1;
6416 my $octal = perms_to_octal($oval); 6539 my $octal = perms_to_octal($oval);
6417 if (WARN("SYMBOLIC_PERMS", 6540 if (WARN("SYMBOLIC_PERMS",
@@ -6462,9 +6585,14 @@ sub process {
6462 ERROR("NOT_UNIFIED_DIFF", 6585 ERROR("NOT_UNIFIED_DIFF",
6463 "Does not appear to be a unified-diff format patch\n"); 6586 "Does not appear to be a unified-diff format patch\n");
6464 } 6587 }
6465 if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6588 if ($is_patch && $has_commit_log && $chk_signoff) {
6466 ERROR("MISSING_SIGN_OFF", 6589 if ($signoff == 0) {
6467 "Missing Signed-off-by: line(s)\n"); 6590 ERROR("MISSING_SIGN_OFF",
6591 "Missing Signed-off-by: line(s)\n");
6592 } elsif (!$authorsignoff) {
6593 WARN("NO_AUTHOR_SIGN_OFF",
6594 "Missing Signed-off-by: line by nominal patch author '$author'\n");
6595 }
6468 } 6596 }
6469 6597
6470 print report_dump(); 6598 print report_dump();
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index cb993801e4b2..8081b6cf67d2 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -15,6 +15,7 @@
15# M68k port by Geert Uytterhoeven and Andreas Schwab 15# M68k port by Geert Uytterhoeven and Andreas Schwab
16# AArch64, PARISC ports by Kyle McMartin 16# AArch64, PARISC ports by Kyle McMartin
17# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk> 17# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
18# ppc64le port by Breno Leitao <leitao@debian.org>
18# 19#
19# Usage: 20# Usage:
20# objdump -d vmlinux | scripts/checkstack.pl [arch] 21# objdump -d vmlinux | scripts/checkstack.pl [arch]
@@ -64,10 +65,6 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
64 # 2b6c: 4e56 fb70 linkw %fp,#-1168 65 # 2b6c: 4e56 fb70 linkw %fp,#-1168
65 # 1df770: defc ffe4 addaw #-28,%sp 66 # 1df770: defc ffe4 addaw #-28,%sp
66 $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o; 67 $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
67 } elsif ($arch eq 'metag') {
68 #400026fc: 40 00 00 82 ADD A0StP,A0StP,#0x8
69 $re = qr/.*ADD.*A0StP,A0StP,\#(0x$x{1,8})/o;
70 $funcre = qr/^$x* <[^\$](.*)>:$/;
71 } elsif ($arch eq 'mips64') { 68 } elsif ($arch eq 'mips64') {
72 #8800402c: 67bdfff0 daddiu sp,sp,-16 69 #8800402c: 67bdfff0 daddiu sp,sp,-16
73 $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o; 70 $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
@@ -82,13 +79,9 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
82 $re = qr/.*l\.addi.*r1,r1,-(([0-9]{2}|[3-9])[0-9]{2})/o; 79 $re = qr/.*l\.addi.*r1,r1,-(([0-9]{2}|[3-9])[0-9]{2})/o;
83 } elsif ($arch eq 'parisc' || $arch eq 'parisc64') { 80 } elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
84 $re = qr/.*ldo ($x{1,8})\(sp\),sp/o; 81 $re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
85 } elsif ($arch eq 'ppc') { 82 } elsif ($arch eq 'powerpc' || $arch =~ /^ppc(64)?(le)?$/ ) {
86 #c00029f4: 94 21 ff 30 stwu r1,-208(r1) 83 # powerpc : 94 21 ff 30 stwu r1,-208(r1)
87 $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o; 84 # ppc64(le) : 81 ff 21 f8 stdu r1,-128(r1)
88 } elsif ($arch eq 'ppc64') {
89 #XXX
90 $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
91 } elsif ($arch eq 'powerpc') {
92 $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o; 85 $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
93 } elsif ($arch =~ /^s390x?$/) { 86 } elsif ($arch =~ /^s390x?$/) {
94 # 11160: a7 fb ff 60 aghi %r15,-160 87 # 11160: a7 fb ff 60 aghi %r15,-160
@@ -102,9 +95,6 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
102 # pair for larger users. -- PFM. 95 # pair for larger users. -- PFM.
103 #a00048e0: d4fc40f0 addi.l r15,-240,r15 96 #a00048e0: d4fc40f0 addi.l r15,-240,r15
104 $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o; 97 $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
105 } elsif ($arch =~ /^blackfin$/) {
106 # 0: 00 e8 38 01 LINK 0x4e0;
107 $re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o;
108 } elsif ($arch eq 'sparc' || $arch eq 'sparc64') { 98 } elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
109 # f0019d10: 9d e3 bf 90 save %sp, -112, %sp 99 # f0019d10: 9d e3 bf 90 save %sp, -112, %sp
110 $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o; 100 $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
diff --git a/scripts/clang-version.sh b/scripts/clang-version.sh
new file mode 100755
index 000000000000..e65fbc3079d4
--- /dev/null
+++ b/scripts/clang-version.sh
@@ -0,0 +1,23 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3#
4# clang-version [-p] clang-command
5#
6# Prints the compiler version of `clang-command' in a canonical 4-digit form
7# such as `0500' for clang-5.0 etc.
8#
9# With the -p option, prints the patchlevel as well, for example `050001' for
10# clang-5.0.1 etc.
11#
12
13compiler="$*"
14
15if ! ( $compiler --version | grep -q clang) ; then
16 echo 0
17 exit 1
18fi
19
20MAJOR=$(echo __clang_major__ | $compiler -E -x c - | tail -n 1)
21MINOR=$(echo __clang_minor__ | $compiler -E -x c - | tail -n 1)
22PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1)
23printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 9fedca611b7f..e04d328210ac 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -128,9 +128,10 @@ run_cmd_parmap() {
128 fi 128 fi
129 echo $@ >>$DEBUG_FILE 129 echo $@ >>$DEBUG_FILE
130 $@ 2>>$DEBUG_FILE 130 $@ 2>>$DEBUG_FILE
131 if [[ $? -ne 0 ]]; then 131 err=$?
132 if [[ $err -ne 0 ]]; then
132 echo "coccicheck failed" 133 echo "coccicheck failed"
133 exit $? 134 exit $err
134 fi 135 fi
135} 136}
136 137
diff --git a/scripts/coccinelle/api/alloc/zalloc-simple.cocci b/scripts/coccinelle/api/alloc/zalloc-simple.cocci
index 92b20913055f..d819275b7fde 100644
--- a/scripts/coccinelle/api/alloc/zalloc-simple.cocci
+++ b/scripts/coccinelle/api/alloc/zalloc-simple.cocci
@@ -35,8 +35,7 @@ statement S;
35 35
36* x = (T)\(kmalloc(E1, ...)\|vmalloc(E1)\|dma_alloc_coherent(...,E1,...)\| 36* x = (T)\(kmalloc(E1, ...)\|vmalloc(E1)\|dma_alloc_coherent(...,E1,...)\|
37 kmalloc_node(E1, ...)\|kmem_cache_alloc(...)\|kmem_alloc(E1, ...)\| 37 kmalloc_node(E1, ...)\|kmem_cache_alloc(...)\|kmem_alloc(E1, ...)\|
38 devm_kmalloc(...,E1,...)\|kvmalloc(E1, ...)\|pci_alloc_consistent(...,E1,...)\| 38 devm_kmalloc(...,E1,...)\|kvmalloc(E1, ...)\|kvmalloc_node(E1,...)\);
39 kvmalloc_node(E1,...)\);
40 if ((x==NULL) || ...) S 39 if ((x==NULL) || ...) S
41* memset((T2)x,0,E1); 40* memset((T2)x,0,E1);
42 41
@@ -124,15 +123,6 @@ statement S;
124- x = (T)kvmalloc(E1,E2); 123- x = (T)kvmalloc(E1,E2);
125+ x = (T)kvzalloc(E1,E2); 124+ x = (T)kvzalloc(E1,E2);
126| 125|
127- x = pci_alloc_consistent(E2,E1,E3);
128+ x = pci_zalloc_consistent(E2,E1,E3);
129|
130- x = (T *)pci_alloc_consistent(E2,E1,E3);
131+ x = pci_zalloc_consistent(E2,E1,E3);
132|
133- x = (T)pci_alloc_consistent(E2,E1,E3);
134+ x = (T)pci_zalloc_consistent(E2,E1,E3);
135|
136- x = kvmalloc_node(E1,E2,E3); 126- x = kvmalloc_node(E1,E2,E3);
137+ x = kvzalloc_node(E1,E2,E3); 127+ x = kvzalloc_node(E1,E2,E3);
138| 128|
@@ -389,35 +379,6 @@ msg="WARNING: kvzalloc should be used for %s, instead of kvmalloc/memset" % (x)
389coccilib.report.print_report(p[0], msg) 379coccilib.report.print_report(p[0], msg)
390 380
391//----------------------------------------------------------------- 381//-----------------------------------------------------------------
392@r8 depends on org || report@
393type T, T2;
394expression x;
395expression E1,E2,E3;
396statement S;
397position p;
398@@
399
400 x = (T)pci_alloc_consistent@p(E2,E1,E3);
401 if ((x==NULL) || ...) S
402 memset((T2)x,0,E1);
403
404@script:python depends on org@
405p << r8.p;
406x << r8.x;
407@@
408
409msg="%s" % (x)
410msg_safe=msg.replace("[","@(").replace("]",")")
411coccilib.org.print_todo(p[0], msg_safe)
412
413@script:python depends on report@
414p << r8.p;
415x << r8.x;
416@@
417
418msg="WARNING: pci_zalloc_consistent should be used for %s, instead of pci_alloc_consistent/memset" % (x)
419coccilib.report.print_report(p[0], msg)
420//-----------------------------------------------------------------
421@r9 depends on org || report@ 382@r9 depends on org || report@
422type T, T2; 383type T, T2;
423expression x; 384expression x;
diff --git a/scripts/coccinelle/api/atomic_as_refcounter.cocci b/scripts/coccinelle/api/atomic_as_refcounter.cocci
new file mode 100644
index 000000000000..988120e0fd67
--- /dev/null
+++ b/scripts/coccinelle/api/atomic_as_refcounter.cocci
@@ -0,0 +1,129 @@
1// Check if refcount_t type and API should be used
2// instead of atomic_t type when dealing with refcounters
3//
4// Copyright (c) 2016-2017, Elena Reshetova, Intel Corporation
5//
6// Confidence: Moderate
7// URL: http://coccinelle.lip6.fr/
8// Options: --include-headers --very-quiet
9
10virtual report
11
12@r1 exists@
13identifier a, x;
14position p1, p2;
15identifier fname =~ ".*free.*";
16identifier fname2 =~ ".*destroy.*";
17identifier fname3 =~ ".*del.*";
18identifier fname4 =~ ".*queue_work.*";
19identifier fname5 =~ ".*schedule_work.*";
20identifier fname6 =~ ".*call_rcu.*";
21
22@@
23
24(
25 atomic_dec_and_test@p1(&(a)->x)
26|
27 atomic_dec_and_lock@p1(&(a)->x, ...)
28|
29 atomic_long_dec_and_lock@p1(&(a)->x, ...)
30|
31 atomic_long_dec_and_test@p1(&(a)->x)
32|
33 atomic64_dec_and_test@p1(&(a)->x)
34|
35 local_dec_and_test@p1(&(a)->x)
36)
37...
38(
39 fname@p2(a, ...);
40|
41 fname2@p2(...);
42|
43 fname3@p2(...);
44|
45 fname4@p2(...);
46|
47 fname5@p2(...);
48|
49 fname6@p2(...);
50)
51
52
53@script:python depends on report@
54p1 << r1.p1;
55p2 << r1.p2;
56@@
57msg = "atomic_dec_and_test variation before object free at line %s."
58coccilib.report.print_report(p1[0], msg % (p2[0].line))
59
60@r4 exists@
61identifier a, x, y;
62position p1, p2;
63identifier fname =~ ".*free.*";
64
65@@
66
67(
68 atomic_dec_and_test@p1(&(a)->x)
69|
70 atomic_dec_and_lock@p1(&(a)->x, ...)
71|
72 atomic_long_dec_and_lock@p1(&(a)->x, ...)
73|
74 atomic_long_dec_and_test@p1(&(a)->x)
75|
76 atomic64_dec_and_test@p1(&(a)->x)
77|
78 local_dec_and_test@p1(&(a)->x)
79)
80...
81y=a
82...
83fname@p2(y, ...);
84
85
86@script:python depends on report@
87p1 << r4.p1;
88p2 << r4.p2;
89@@
90msg = "atomic_dec_and_test variation before object free at line %s."
91coccilib.report.print_report(p1[0], msg % (p2[0].line))
92
93@r2 exists@
94identifier a, x;
95position p1;
96@@
97
98(
99atomic_add_unless(&(a)->x,-1,1)@p1
100|
101atomic_long_add_unless(&(a)->x,-1,1)@p1
102|
103atomic64_add_unless(&(a)->x,-1,1)@p1
104)
105
106@script:python depends on report@
107p1 << r2.p1;
108@@
109msg = "atomic_add_unless"
110coccilib.report.print_report(p1[0], msg)
111
112@r3 exists@
113identifier x;
114position p1;
115@@
116
117(
118x = atomic_add_return@p1(-1, ...);
119|
120x = atomic_long_add_return@p1(-1, ...);
121|
122x = atomic64_add_return@p1(-1, ...);
123)
124
125@script:python depends on report@
126p1 << r3.p1;
127@@
128msg = "x = atomic_add_return(-1, ...)"
129coccilib.report.print_report(p1[0], msg)
diff --git a/scripts/coccinelle/api/drm-get-put.cocci b/scripts/coccinelle/api/drm-get-put.cocci
index 91fceb8f1fa2..3a09c97ad87d 100644
--- a/scripts/coccinelle/api/drm-get-put.cocci
+++ b/scripts/coccinelle/api/drm-get-put.cocci
@@ -16,12 +16,6 @@ expression object;
16@@ 16@@
17 17
18( 18(
19- drm_mode_object_reference(object)
20+ drm_mode_object_get(object)
21|
22- drm_mode_object_unreference(object)
23+ drm_mode_object_put(object)
24|
25- drm_connector_reference(object) 19- drm_connector_reference(object)
26+ drm_connector_get(object) 20+ drm_connector_get(object)
27| 21|
@@ -46,12 +40,6 @@ expression object;
46- drm_gem_object_unreference_unlocked(object) 40- drm_gem_object_unreference_unlocked(object)
47+ drm_gem_object_put_unlocked(object) 41+ drm_gem_object_put_unlocked(object)
48| 42|
49- drm_property_reference_blob(object)
50+ drm_property_blob_get(object)
51|
52- drm_property_unreference_blob(object)
53+ drm_property_blob_put(object)
54|
55- drm_dev_unref(object) 43- drm_dev_unref(object)
56+ drm_dev_put(object) 44+ drm_dev_put(object)
57) 45)
@@ -62,10 +50,6 @@ position p;
62@@ 50@@
63 51
64( 52(
65drm_mode_object_unreference@p(object)
66|
67drm_mode_object_reference@p(object)
68|
69drm_connector_unreference@p(object) 53drm_connector_unreference@p(object)
70| 54|
71drm_connector_reference@p(object) 55drm_connector_reference@p(object)
@@ -82,10 +66,6 @@ __drm_gem_object_unreference(object)
82| 66|
83drm_gem_object_unreference_unlocked(object) 67drm_gem_object_unreference_unlocked(object)
84| 68|
85drm_property_unreference_blob@p(object)
86|
87drm_property_reference_blob@p(object)
88|
89drm_dev_unref@p(object) 69drm_dev_unref@p(object)
90) 70)
91 71
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci
index 47f649b0ea87..19c6ee5b986b 100644
--- a/scripts/coccinelle/locks/mini_lock.cocci
+++ b/scripts/coccinelle/locks/mini_lock.cocci
@@ -67,12 +67,14 @@ identifier lock,unlock;
67@@ 67@@
68 68
69*lock(E1@p,...); 69*lock(E1@p,...);
70<+... when != E1 70... when != E1
71 when any
71if (...) { 72if (...) {
72 ... when != E1 73 ... when != E1
73* return@r ...; 74* return@r ...;
74} 75}
75...+> 76... when != E1
77 when any
76*unlock@up(E1,...); 78*unlock@up(E1,...);
77 79
78@script:python depends on org@ 80@script:python depends on org@
diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci
index b16ccb7663a7..cbc6184e69ef 100644
--- a/scripts/coccinelle/null/deref_null.cocci
+++ b/scripts/coccinelle/null/deref_null.cocci
@@ -14,18 +14,10 @@ virtual context
14virtual org 14virtual org
15virtual report 15virtual report
16 16
17@ifm@
18expression *E;
19statement S1,S2;
20position p1;
21@@
22
23if@p1 ((E == NULL && ...) || ...) S1 else S2
24
25// The following two rules are separate, because both can match a single 17// The following two rules are separate, because both can match a single
26// expression in different ways 18// expression in different ways
27@pr1 expression@ 19@pr1 expression@
28expression *ifm.E; 20expression E;
29identifier f; 21identifier f;
30position p1; 22position p1;
31@@ 23@@
@@ -33,7 +25,7 @@ position p1;
33 (E != NULL && ...) ? <+...E->f@p1...+> : ... 25 (E != NULL && ...) ? <+...E->f@p1...+> : ...
34 26
35@pr2 expression@ 27@pr2 expression@
36expression *ifm.E; 28expression E;
37identifier f; 29identifier f;
38position p2; 30position p2;
39@@ 31@@
@@ -46,6 +38,14 @@ position p2;
46 sizeof(<+...E->f@p2...+>) 38 sizeof(<+...E->f@p2...+>)
47) 39)
48 40
41@ifm@
42expression *E;
43statement S1,S2;
44position p1;
45@@
46
47if@p1 ((E == NULL && ...) || ...) S1 else S2
48
49// For org and report modes 49// For org and report modes
50 50
51@r depends on !context && (org || report) exists@ 51@r depends on !context && (org || report) exists@
@@ -212,16 +212,8 @@ else S3
212// The following three rules are duplicates of ifm, pr1 and pr2 respectively. 212// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
213// It is need because the previous rule as already made a "change". 213// It is need because the previous rule as already made a "change".
214 214
215@ifm1 depends on context && !org && !report@
216expression *E;
217statement S1,S2;
218position p1;
219@@
220
221if@p1 ((E == NULL && ...) || ...) S1 else S2
222
223@pr11 depends on context && !org && !report expression@ 215@pr11 depends on context && !org && !report expression@
224expression *ifm1.E; 216expression E;
225identifier f; 217identifier f;
226position p1; 218position p1;
227@@ 219@@
@@ -229,7 +221,7 @@ position p1;
229 (E != NULL && ...) ? <+...E->f@p1...+> : ... 221 (E != NULL && ...) ? <+...E->f@p1...+> : ...
230 222
231@pr12 depends on context && !org && !report expression@ 223@pr12 depends on context && !org && !report expression@
232expression *ifm1.E; 224expression E;
233identifier f; 225identifier f;
234position p2; 226position p2;
235@@ 227@@
@@ -242,6 +234,14 @@ position p2;
242 sizeof(<+...E->f@p2...+>) 234 sizeof(<+...E->f@p2...+>)
243) 235)
244 236
237@ifm1 depends on context && !org && !report@
238expression *E;
239statement S1,S2;
240position p1;
241@@
242
243if@p1 ((E == NULL && ...) || ...) S1 else S2
244
245@depends on context && !org && !report exists@ 245@depends on context && !org && !report exists@
246expression subE <= ifm1.E; 246expression subE <= ifm1.E;
247expression *ifm1.E; 247expression *ifm1.E;
diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci
index 78d74c22ca12..7af2ce7eb9bf 100644
--- a/scripts/coccinelle/tests/doubletest.cocci
+++ b/scripts/coccinelle/tests/doubletest.cocci
@@ -1,6 +1,7 @@
1/// Find &&/|| operations that include the same argument more than once 1/// Find &&/|| operations that include the same argument more than once
2//# A common source of false positives is when the argument performs a side 2//# A common source of false positives is when the expression, or
3//# effect. 3//# another expresssion in the same && or || operation, performs a
4//# side effect.
4/// 5///
5// Confidence: Moderate 6// Confidence: Moderate
6// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 7// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
@@ -20,20 +21,37 @@ position p;
20@@ 21@@
21 22
22( 23(
23* E@p 24 E@p || ... || E
24 || ... || E
25| 25|
26* E@p 26 E@p && ... && E
27 && ... && E
28) 27)
29 28
30@script:python depends on org@ 29@bad@
30expression r.E,e1,e2,fn;
31position r.p;
32assignment operator op;
33@@
34
35(
36E@p
37&
38 <+... \(fn(...)\|e1 op e2\|e1++\|e1--\|++e1\|--e1\) ...+>
39)
40
41@depends on context && !bad@
42expression r.E;
43position r.p;
44@@
45
46*E@p
47
48@script:python depends on org && !bad@
31p << r.p; 49p << r.p;
32@@ 50@@
33 51
34cocci.print_main("duplicated argument to && or ||",p) 52cocci.print_main("duplicated argument to && or ||",p)
35 53
36@script:python depends on report@ 54@script:python depends on report && !bad@
37p << r.p; 55p << r.p;
38@@ 56@@
39 57
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index 9831cca31240..e083bcae343f 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -3,34 +3,22 @@
3# 3#
4# A depmod wrapper used by the toplevel Makefile 4# A depmod wrapper used by the toplevel Makefile
5 5
6if test $# -ne 3; then 6if test $# -ne 2; then
7 echo "Usage: $0 /sbin/depmod <kernelrelease> <symbolprefix>" >&2 7 echo "Usage: $0 /sbin/depmod <kernelrelease>" >&2
8 exit 1 8 exit 1
9fi 9fi
10DEPMOD=$1 10DEPMOD=$1
11KERNELRELEASE=$2 11KERNELRELEASE=$2
12SYMBOL_PREFIX=$3
13 12
14if ! test -r System.map -a -x "$DEPMOD"; then 13if ! test -r System.map ; then
14 echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2
15 exit 0 15 exit 0
16fi 16fi
17 17
18# older versions of depmod don't support -P <symbol-prefix> 18if [ -z $(command -v $DEPMOD) ]; then
19# support was added in module-init-tools 3.13 19 echo "Warning: 'make modules_install' requires $DEPMOD. Please install it." >&2
20if test -n "$SYMBOL_PREFIX"; then 20 echo "This is probably in the kmod package." >&2
21 release=$("$DEPMOD" --version) 21 exit 0
22 package=$(echo "$release" | cut -d' ' -f 1)
23 if test "$package" = "module-init-tools"; then
24 version=$(echo "$release" | cut -d' ' -f 2)
25 later=$(printf '%s\n' "$version" "3.13" | sort -V | tail -n 1)
26 if test "$later" != "$version"; then
27 # module-init-tools < 3.13, drop the symbol prefix
28 SYMBOL_PREFIX=""
29 fi
30 fi
31 if test -n "$SYMBOL_PREFIX"; then
32 SYMBOL_PREFIX="-P $SYMBOL_PREFIX"
33 fi
34fi 22fi
35 23
36# older versions of depmod require the version string to start with three 24# older versions of depmod require the version string to start with three
@@ -55,7 +43,7 @@ set -- -ae -F System.map
55if test -n "$INSTALL_MOD_PATH"; then 43if test -n "$INSTALL_MOD_PATH"; then
56 set -- "$@" -b "$INSTALL_MOD_PATH" 44 set -- "$@" -b "$INSTALL_MOD_PATH"
57fi 45fi
58"$DEPMOD" "$@" "$KERNELRELEASE" $SYMBOL_PREFIX 46"$DEPMOD" "$@" "$KERNELRELEASE"
59ret=$? 47ret=$?
60 48
61if $depmod_hack_needed; then 49if $depmod_hack_needed; then
diff --git a/scripts/documentation-file-ref-check b/scripts/documentation-file-ref-check
index bc1659900e89..ad9db6821824 100755
--- a/scripts/documentation-file-ref-check
+++ b/scripts/documentation-file-ref-check
@@ -1,15 +1,164 @@
1#!/bin/sh 1#!/usr/bin/env perl
2# SPDX-License-Identifier: GPL-2.0
3#
2# Treewide grep for references to files under Documentation, and report 4# Treewide grep for references to files under Documentation, and report
3# non-existing files in stderr. 5# non-existing files in stderr.
4 6
5for f in $(git ls-files); do 7use warnings;
6 for ref in $(grep -ho "Documentation/[A-Za-z0-9_.,~/*+-]*" "$f"); do 8use strict;
7 # presume trailing . and , are not part of the name 9use Getopt::Long qw(:config no_auto_abbrev);
8 ref=${ref%%[.,]} 10
9 11my $scriptname = $0;
10 # use ls to handle wildcards 12$scriptname =~ s,.*/([^/]+/),$1,;
11 if ! ls $ref >/dev/null 2>&1; then 13
12 echo "$f: $ref" >&2 14# Parse arguments
13 fi 15my $help = 0;
14 done 16my $fix = 0;
15done 17
18GetOptions(
19 'fix' => \$fix,
20 'h|help|usage' => \$help,
21);
22
23if ($help != 0) {
24 print "$scriptname [--help] [--fix]\n";
25 exit -1;
26}
27
28# Step 1: find broken references
29print "Finding broken references. This may take a while... " if ($fix);
30
31my %broken_ref;
32
33open IN, "git grep 'Documentation/'|"
34 or die "Failed to run git grep";
35while (<IN>) {
36 next if (!m/^([^:]+):(.*)/);
37
38 my $f = $1;
39 my $ln = $2;
40
41 # Makefiles and scripts contain nasty expressions to parse docs
42 next if ($f =~ m/Makefile/ || $f =~ m/\.sh$/);
43
44 # Skip this script
45 next if ($f eq $scriptname);
46
47 if ($ln =~ m,\b(\S*)(Documentation/[A-Za-z0-9\_\.\,\~/\*\[\]\?+-]*)(.*),) {
48 my $prefix = $1;
49 my $ref = $2;
50 my $base = $2;
51 my $extra = $3;
52
53 # some file references are like:
54 # /usr/src/linux/Documentation/DMA-{API,mapping}.txt
55 # For now, ignore them
56 next if ($extra =~ m/^{/);
57
58 # Remove footnotes at the end like:
59 # Documentation/devicetree/dt-object-internal.txt[1]
60 $ref =~ s/(txt|rst)\[\d+]$/$1/;
61
62 # Remove ending ']' without any '['
63 $ref =~ s/\].*// if (!($ref =~ m/\[/));
64
65 # Remove puntuation marks at the end
66 $ref =~ s/[\,\.]+$//;
67
68 my $fulref = "$prefix$ref";
69
70 $fulref =~ s/^(\<file|ref)://;
71 $fulref =~ s/^[\'\`]+//;
72 $fulref =~ s,^\$\(.*\)/,,;
73 $base =~ s,.*/,,;
74
75 # Remove URL false-positives
76 next if ($fulref =~ m/^http/);
77
78 # Remove sched-pelt false-positive
79 next if ($fulref =~ m,^Documentation/scheduler/sched-pelt$,);
80
81 # Discard some build examples from Documentation/target/tcm_mod_builder.txt
82 next if ($fulref =~ m,mnt/sdb/lio-core-2.6.git/Documentation/target,);
83
84 # Check if exists, evaluating wildcards
85 next if (grep -e, glob("$ref $fulref"));
86
87 # Accept relative Documentation patches for tools/
88 if ($f =~ m/tools/) {
89 my $path = $f;
90 $path =~ s,(.*)/.*,$1,;
91 next if (grep -e, glob("$path/$ref $path/$fulref"));
92 }
93
94 if ($fix) {
95 if (!($ref =~ m/(scripts|Kconfig|Kbuild)/)) {
96 $broken_ref{$ref}++;
97 }
98 } else {
99 print STDERR "$f: $fulref\n";
100 }
101 }
102}
103
104exit 0 if (!$fix);
105
106# Step 2: Seek for file name alternatives
107print "Auto-fixing broken references. Please double-check the results\n";
108
109foreach my $ref (keys %broken_ref) {
110 my $new =$ref;
111
112 # get just the basename
113 $new =~ s,.*/,,;
114
115 my $f="";
116
117 # usual reason for breakage: DT file moved around
118 if ($ref =~ /devicetree/) {
119 my $search = $new;
120 $search =~ s,^.*/,,;
121 $f = qx(find Documentation/devicetree/ -iname "*$search*") if ($search);
122 if (!$f) {
123 # Manufacturer name may have changed
124 $search =~ s/^.*,//;
125 $f = qx(find Documentation/devicetree/ -iname "*$search*") if ($search);
126 }
127 }
128
129 # usual reason for breakage: file renamed to .rst
130 if (!$f) {
131 $new =~ s/\.txt$/.rst/;
132 $f=qx(find . -iname $new) if ($new);
133 }
134
135 # usual reason for breakage: use dash or underline
136 if (!$f) {
137 $new =~ s/[-_]/[-_]/g;
138 $f=qx(find . -iname $new) if ($new);
139 }
140
141 # Wild guess: seek for the same name on another place
142 if (!$f) {
143 $f = qx(find . -iname $new) if ($new);
144 }
145
146 my @find = split /\s+/, $f;
147
148 if (!$f) {
149 print STDERR "ERROR: Didn't find a replacement for $ref\n";
150 } elsif (scalar(@find) > 1) {
151 print STDERR "WARNING: Won't auto-replace, as found multiple files close to $ref:\n";
152 foreach my $j (@find) {
153 $j =~ s,^./,,;
154 print STDERR " $j\n";
155 }
156 } else {
157 $f = $find[0];
158 $f =~ s,^./,,;
159 print "INFO: Replacing $ref to $f\n";
160 foreach my $j (qx(git grep -l $ref)) {
161 qx(sed "s\@$ref\@$f\@g" -i $j);
162 }
163 }
164}
diff --git a/scripts/dtc/.gitignore b/scripts/dtc/.gitignore
index cdabdc95a6e7..2e6e60d64ede 100644
--- a/scripts/dtc/.gitignore
+++ b/scripts/dtc/.gitignore
@@ -1,4 +1 @@
1dtc dtc
2dtc-lexer.lex.c
3dtc-parser.tab.c
4dtc-parser.tab.h
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 0dc922bb7aea..056d5da6c477 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -1,7 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2# scripts/dtc makefile 2# scripts/dtc makefile
3 3
4hostprogs-y := dtc 4hostprogs-$(CONFIG_DTC) := dtc
5always := $(hostprogs-y) 5always := $(hostprogs-y)
6 6
7dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ 7dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
@@ -9,24 +9,18 @@ dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
9dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o 9dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
10 10
11# Source files need to get at the userspace version of libfdt_env.h to compile 11# Source files need to get at the userspace version of libfdt_env.h to compile
12HOST_EXTRACFLAGS := -I$(src)/libfdt
12 13
13HOSTCFLAGS_DTC := -I$(src) -I$(src)/libfdt 14ifeq ($(wildcard /usr/include/yaml.h),)
15HOST_EXTRACFLAGS += -DNO_YAML
16else
17dtc-objs += yamltree.o
18HOSTLDLIBS_dtc := -lyaml
19endif
14 20
15HOSTCFLAGS_checks.o := $(HOSTCFLAGS_DTC) 21# Generated files need one more search path to include headers in source tree
16HOSTCFLAGS_data.o := $(HOSTCFLAGS_DTC) 22HOSTCFLAGS_dtc-lexer.lex.o := -I$(src)
17HOSTCFLAGS_dtc.o := $(HOSTCFLAGS_DTC) 23HOSTCFLAGS_dtc-parser.tab.o := -I$(src)
18HOSTCFLAGS_flattree.o := $(HOSTCFLAGS_DTC)
19HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
20HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC)
21HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
22HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
23HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
24
25HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
26HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
27 24
28# dependencies on generated files need to be listed explicitly 25# dependencies on generated files need to be listed explicitly
29$(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h 26$(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
30
31# generated files need to be cleaned explicitly
32clean-files := dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h
diff --git a/scripts/dtc/Makefile.dtc b/scripts/dtc/Makefile.dtc
index bece49b35535..d4375630a7f7 100644
--- a/scripts/dtc/Makefile.dtc
+++ b/scripts/dtc/Makefile.dtc
@@ -14,5 +14,9 @@ DTC_SRCS = \
14 treesource.c \ 14 treesource.c \
15 util.c 15 util.c
16 16
17ifneq ($(NO_YAML),1)
18DTC_SRCS += yamltree.c
19endif
20
17DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c 21DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
18DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o) 22DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index e66138449886..9c9b0c328af6 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -53,26 +53,28 @@ struct check {
53 struct check **prereq; 53 struct check **prereq;
54}; 54};
55 55
56#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...) \ 56#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \
57 static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \ 57 static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \
58 static struct check _nm = { \ 58 static struct check nm_ = { \
59 .name = #_nm, \ 59 .name = #nm_, \
60 .fn = (_fn), \ 60 .fn = (fn_), \
61 .data = (_d), \ 61 .data = (d_), \
62 .warn = (_w), \ 62 .warn = (w_), \
63 .error = (_e), \ 63 .error = (e_), \
64 .status = UNCHECKED, \ 64 .status = UNCHECKED, \
65 .num_prereqs = ARRAY_SIZE(_nm##_prereqs), \ 65 .num_prereqs = ARRAY_SIZE(nm_##_prereqs), \
66 .prereq = _nm##_prereqs, \ 66 .prereq = nm_##_prereqs, \
67 }; 67 };
68#define WARNING(_nm, _fn, _d, ...) \ 68#define WARNING(nm_, fn_, d_, ...) \
69 CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__) 69 CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__)
70#define ERROR(_nm, _fn, _d, ...) \ 70#define ERROR(nm_, fn_, d_, ...) \
71 CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__) 71 CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__)
72#define CHECK(_nm, _fn, _d, ...) \ 72#define CHECK(nm_, fn_, d_, ...) \
73 CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__) 73 CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__)
74 74
75static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, 75static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
76 struct node *node,
77 struct property *prop,
76 const char *fmt, ...) 78 const char *fmt, ...)
77{ 79{
78 va_list ap; 80 va_list ap;
@@ -83,19 +85,33 @@ static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
83 fprintf(stderr, "%s: %s (%s): ", 85 fprintf(stderr, "%s: %s (%s): ",
84 strcmp(dti->outname, "-") ? dti->outname : "<stdout>", 86 strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
85 (c->error) ? "ERROR" : "Warning", c->name); 87 (c->error) ? "ERROR" : "Warning", c->name);
88 if (node) {
89 fprintf(stderr, "%s", node->fullpath);
90 if (prop)
91 fprintf(stderr, ":%s", prop->name);
92 fputs(": ", stderr);
93 }
86 vfprintf(stderr, fmt, ap); 94 vfprintf(stderr, fmt, ap);
87 fprintf(stderr, "\n"); 95 fprintf(stderr, "\n");
88 } 96 }
89 va_end(ap); 97 va_end(ap);
90} 98}
91 99
92#define FAIL(c, dti, ...) \ 100#define FAIL(c, dti, node, ...) \
93 do { \ 101 do { \
94 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ 102 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
95 (c)->status = FAILED; \ 103 (c)->status = FAILED; \
96 check_msg((c), dti, __VA_ARGS__); \ 104 check_msg((c), dti, node, NULL, __VA_ARGS__); \
97 } while (0) 105 } while (0)
98 106
107#define FAIL_PROP(c, dti, node, prop, ...) \
108 do { \
109 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
110 (c)->status = FAILED; \
111 check_msg((c), dti, node, prop, __VA_ARGS__); \
112 } while (0)
113
114
99static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) 115static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
100{ 116{
101 struct node *child; 117 struct node *child;
@@ -126,7 +142,7 @@ static bool run_check(struct check *c, struct dt_info *dti)
126 error = error || run_check(prq, dti); 142 error = error || run_check(prq, dti);
127 if (prq->status != PASSED) { 143 if (prq->status != PASSED) {
128 c->status = PREREQ; 144 c->status = PREREQ;
129 check_msg(c, dti, "Failed prerequisite '%s'", 145 check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'",
130 c->prereq[i]->name); 146 c->prereq[i]->name);
131 } 147 }
132 } 148 }
@@ -156,7 +172,7 @@ out:
156static inline void check_always_fail(struct check *c, struct dt_info *dti, 172static inline void check_always_fail(struct check *c, struct dt_info *dti,
157 struct node *node) 173 struct node *node)
158{ 174{
159 FAIL(c, dti, "always_fail check"); 175 FAIL(c, dti, node, "always_fail check");
160} 176}
161CHECK(always_fail, check_always_fail, NULL); 177CHECK(always_fail, check_always_fail, NULL);
162 178
@@ -171,14 +187,42 @@ static void check_is_string(struct check *c, struct dt_info *dti,
171 return; /* Not present, assumed ok */ 187 return; /* Not present, assumed ok */
172 188
173 if (!data_is_one_string(prop->val)) 189 if (!data_is_one_string(prop->val))
174 FAIL(c, dti, "\"%s\" property in %s is not a string", 190 FAIL_PROP(c, dti, node, prop, "property is not a string");
175 propname, node->fullpath);
176} 191}
177#define WARNING_IF_NOT_STRING(nm, propname) \ 192#define WARNING_IF_NOT_STRING(nm, propname) \
178 WARNING(nm, check_is_string, (propname)) 193 WARNING(nm, check_is_string, (propname))
179#define ERROR_IF_NOT_STRING(nm, propname) \ 194#define ERROR_IF_NOT_STRING(nm, propname) \
180 ERROR(nm, check_is_string, (propname)) 195 ERROR(nm, check_is_string, (propname))
181 196
197static void check_is_string_list(struct check *c, struct dt_info *dti,
198 struct node *node)
199{
200 int rem, l;
201 struct property *prop;
202 char *propname = c->data;
203 char *str;
204
205 prop = get_property(node, propname);
206 if (!prop)
207 return; /* Not present, assumed ok */
208
209 str = prop->val.val;
210 rem = prop->val.len;
211 while (rem > 0) {
212 l = strnlen(str, rem);
213 if (l == rem) {
214 FAIL_PROP(c, dti, node, prop, "property is not a string list");
215 break;
216 }
217 rem -= l + 1;
218 str += l + 1;
219 }
220}
221#define WARNING_IF_NOT_STRING_LIST(nm, propname) \
222 WARNING(nm, check_is_string_list, (propname))
223#define ERROR_IF_NOT_STRING_LIST(nm, propname) \
224 ERROR(nm, check_is_string_list, (propname))
225
182static void check_is_cell(struct check *c, struct dt_info *dti, 226static void check_is_cell(struct check *c, struct dt_info *dti,
183 struct node *node) 227 struct node *node)
184{ 228{
@@ -190,8 +234,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti,
190 return; /* Not present, assumed ok */ 234 return; /* Not present, assumed ok */
191 235
192 if (prop->val.len != sizeof(cell_t)) 236 if (prop->val.len != sizeof(cell_t))
193 FAIL(c, dti, "\"%s\" property in %s is not a single cell", 237 FAIL_PROP(c, dti, node, prop, "property is not a single cell");
194 propname, node->fullpath);
195} 238}
196#define WARNING_IF_NOT_CELL(nm, propname) \ 239#define WARNING_IF_NOT_CELL(nm, propname) \
197 WARNING(nm, check_is_cell, (propname)) 240 WARNING(nm, check_is_cell, (propname))
@@ -212,8 +255,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
212 child2; 255 child2;
213 child2 = child2->next_sibling) 256 child2 = child2->next_sibling)
214 if (streq(child->name, child2->name)) 257 if (streq(child->name, child2->name))
215 FAIL(c, dti, "Duplicate node name %s", 258 FAIL(c, dti, child2, "Duplicate node name");
216 child->fullpath);
217} 259}
218ERROR(duplicate_node_names, check_duplicate_node_names, NULL); 260ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
219 261
@@ -227,8 +269,7 @@ static void check_duplicate_property_names(struct check *c, struct dt_info *dti,
227 if (prop2->deleted) 269 if (prop2->deleted)
228 continue; 270 continue;
229 if (streq(prop->name, prop2->name)) 271 if (streq(prop->name, prop2->name))
230 FAIL(c, dti, "Duplicate property name %s in %s", 272 FAIL_PROP(c, dti, node, prop, "Duplicate property name");
231 prop->name, node->fullpath);
232 } 273 }
233 } 274 }
234} 275}
@@ -246,8 +287,8 @@ static void check_node_name_chars(struct check *c, struct dt_info *dti,
246 int n = strspn(node->name, c->data); 287 int n = strspn(node->name, c->data);
247 288
248 if (n < strlen(node->name)) 289 if (n < strlen(node->name))
249 FAIL(c, dti, "Bad character '%c' in node %s", 290 FAIL(c, dti, node, "Bad character '%c' in node name",
250 node->name[n], node->fullpath); 291 node->name[n]);
251} 292}
252ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); 293ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
253 294
@@ -257,8 +298,8 @@ static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
257 int n = strspn(node->name, c->data); 298 int n = strspn(node->name, c->data);
258 299
259 if (n < node->basenamelen) 300 if (n < node->basenamelen)
260 FAIL(c, dti, "Character '%c' not recommended in node %s", 301 FAIL(c, dti, node, "Character '%c' not recommended in node name",
261 node->name[n], node->fullpath); 302 node->name[n]);
262} 303}
263CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); 304CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT);
264 305
@@ -266,8 +307,7 @@ static void check_node_name_format(struct check *c, struct dt_info *dti,
266 struct node *node) 307 struct node *node)
267{ 308{
268 if (strchr(get_unitname(node), '@')) 309 if (strchr(get_unitname(node), '@'))
269 FAIL(c, dti, "Node %s has multiple '@' characters in name", 310 FAIL(c, dti, node, "multiple '@' characters in node name");
270 node->fullpath);
271} 311}
272ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); 312ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
273 313
@@ -277,6 +317,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
277 const char *unitname = get_unitname(node); 317 const char *unitname = get_unitname(node);
278 struct property *prop = get_property(node, "reg"); 318 struct property *prop = get_property(node, "reg");
279 319
320 if (get_subnode(node, "__overlay__")) {
321 /* HACK: Overlay fragments are a special case */
322 return;
323 }
324
280 if (!prop) { 325 if (!prop) {
281 prop = get_property(node, "ranges"); 326 prop = get_property(node, "ranges");
282 if (prop && !prop->val.len) 327 if (prop && !prop->val.len)
@@ -285,12 +330,10 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
285 330
286 if (prop) { 331 if (prop) {
287 if (!unitname[0]) 332 if (!unitname[0])
288 FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name", 333 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
289 node->fullpath);
290 } else { 334 } else {
291 if (unitname[0]) 335 if (unitname[0])
292 FAIL(c, dti, "Node %s has a unit name, but no reg property", 336 FAIL(c, dti, node, "node has a unit name, but no reg property");
293 node->fullpath);
294 } 337 }
295} 338}
296WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); 339WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
@@ -304,8 +347,8 @@ static void check_property_name_chars(struct check *c, struct dt_info *dti,
304 int n = strspn(prop->name, c->data); 347 int n = strspn(prop->name, c->data);
305 348
306 if (n < strlen(prop->name)) 349 if (n < strlen(prop->name))
307 FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s", 350 FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name",
308 prop->name[n], prop->name, node->fullpath); 351 prop->name[n]);
309 } 352 }
310} 353}
311ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); 354ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
@@ -336,8 +379,8 @@ static void check_property_name_chars_strict(struct check *c,
336 n = strspn(name, c->data); 379 n = strspn(name, c->data);
337 } 380 }
338 if (n < strlen(name)) 381 if (n < strlen(name))
339 FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s", 382 FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name",
340 name[n], prop->name, node->fullpath); 383 name[n]);
341 } 384 }
342} 385}
343CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); 386CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT);
@@ -370,7 +413,7 @@ static void check_duplicate_label(struct check *c, struct dt_info *dti,
370 return; 413 return;
371 414
372 if ((othernode != node) || (otherprop != prop) || (othermark != mark)) 415 if ((othernode != node) || (otherprop != prop) || (othermark != mark))
373 FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT 416 FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT
374 " and " DESCLABEL_FMT, 417 " and " DESCLABEL_FMT,
375 label, DESCLABEL_ARGS(node, prop, mark), 418 label, DESCLABEL_ARGS(node, prop, mark),
376 DESCLABEL_ARGS(othernode, otherprop, othermark)); 419 DESCLABEL_ARGS(othernode, otherprop, othermark));
@@ -410,8 +453,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
410 return 0; 453 return 0;
411 454
412 if (prop->val.len != sizeof(cell_t)) { 455 if (prop->val.len != sizeof(cell_t)) {
413 FAIL(c, dti, "%s has bad length (%d) %s property", 456 FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property",
414 node->fullpath, prop->val.len, prop->name); 457 prop->val.len, prop->name);
415 return 0; 458 return 0;
416 } 459 }
417 460
@@ -422,8 +465,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
422 /* "Set this node's phandle equal to some 465 /* "Set this node's phandle equal to some
423 * other node's phandle". That's nonsensical 466 * other node's phandle". That's nonsensical
424 * by construction. */ { 467 * by construction. */ {
425 FAIL(c, dti, "%s in %s is a reference to another node", 468 FAIL(c, dti, node, "%s is a reference to another node",
426 prop->name, node->fullpath); 469 prop->name);
427 } 470 }
428 /* But setting this node's phandle equal to its own 471 /* But setting this node's phandle equal to its own
429 * phandle is allowed - that means allocate a unique 472 * phandle is allowed - that means allocate a unique
@@ -436,8 +479,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
436 phandle = propval_cell(prop); 479 phandle = propval_cell(prop);
437 480
438 if ((phandle == 0) || (phandle == -1)) { 481 if ((phandle == 0) || (phandle == -1)) {
439 FAIL(c, dti, "%s has bad value (0x%x) in %s property", 482 FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property",
440 node->fullpath, phandle, prop->name); 483 phandle, prop->name);
441 return 0; 484 return 0;
442 } 485 }
443 486
@@ -463,16 +506,16 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti,
463 return; 506 return;
464 507
465 if (linux_phandle && phandle && (phandle != linux_phandle)) 508 if (linux_phandle && phandle && (phandle != linux_phandle))
466 FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'" 509 FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'"
467 " properties", node->fullpath); 510 " properties");
468 511
469 if (linux_phandle && !phandle) 512 if (linux_phandle && !phandle)
470 phandle = linux_phandle; 513 phandle = linux_phandle;
471 514
472 other = get_node_by_phandle(root, phandle); 515 other = get_node_by_phandle(root, phandle);
473 if (other && (other != node)) { 516 if (other && (other != node)) {
474 FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)", 517 FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)",
475 node->fullpath, phandle, other->fullpath); 518 phandle, other->fullpath);
476 return; 519 return;
477 } 520 }
478 521
@@ -496,8 +539,8 @@ static void check_name_properties(struct check *c, struct dt_info *dti,
496 539
497 if ((prop->val.len != node->basenamelen+1) 540 if ((prop->val.len != node->basenamelen+1)
498 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { 541 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
499 FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead" 542 FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead"
500 " of base node name)", node->fullpath, prop->val.val); 543 " of base node name)", prop->val.val);
501 } else { 544 } else {
502 /* The name property is correct, and therefore redundant. 545 /* The name property is correct, and therefore redundant.
503 * Delete it */ 546 * Delete it */
@@ -531,7 +574,7 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
531 refnode = get_node_by_ref(dt, m->ref); 574 refnode = get_node_by_ref(dt, m->ref);
532 if (! refnode) { 575 if (! refnode) {
533 if (!(dti->dtsflags & DTSF_PLUGIN)) 576 if (!(dti->dtsflags & DTSF_PLUGIN))
534 FAIL(c, dti, "Reference to non-existent node or " 577 FAIL(c, dti, node, "Reference to non-existent node or "
535 "label \"%s\"\n", m->ref); 578 "label \"%s\"\n", m->ref);
536 else /* mark the entry as unresolved */ 579 else /* mark the entry as unresolved */
537 *((fdt32_t *)(prop->val.val + m->offset)) = 580 *((fdt32_t *)(prop->val.val + m->offset)) =
@@ -541,6 +584,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
541 584
542 phandle = get_node_phandle(dt, refnode); 585 phandle = get_node_phandle(dt, refnode);
543 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); 586 *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
587
588 reference_node(refnode);
544 } 589 }
545 } 590 }
546} 591}
@@ -563,7 +608,7 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
563 608
564 refnode = get_node_by_ref(dt, m->ref); 609 refnode = get_node_by_ref(dt, m->ref);
565 if (!refnode) { 610 if (!refnode) {
566 FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n", 611 FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n",
567 m->ref); 612 m->ref);
568 continue; 613 continue;
569 } 614 }
@@ -571,11 +616,21 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
571 path = refnode->fullpath; 616 path = refnode->fullpath;
572 prop->val = data_insert_at_marker(prop->val, m, path, 617 prop->val = data_insert_at_marker(prop->val, m, path,
573 strlen(path) + 1); 618 strlen(path) + 1);
619
620 reference_node(refnode);
574 } 621 }
575 } 622 }
576} 623}
577ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); 624ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
578 625
626static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti,
627 struct node *node)
628{
629 if (node->omit_if_unused && !node->is_referenced)
630 delete_node(node);
631}
632ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references);
633
579/* 634/*
580 * Semantic checks 635 * Semantic checks
581 */ 636 */
@@ -586,6 +641,45 @@ WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
586WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); 641WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
587WARNING_IF_NOT_STRING(model_is_string, "model"); 642WARNING_IF_NOT_STRING(model_is_string, "model");
588WARNING_IF_NOT_STRING(status_is_string, "status"); 643WARNING_IF_NOT_STRING(status_is_string, "status");
644WARNING_IF_NOT_STRING(label_is_string, "label");
645
646WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible");
647
648static void check_names_is_string_list(struct check *c, struct dt_info *dti,
649 struct node *node)
650{
651 struct property *prop;
652
653 for_each_property(node, prop) {
654 const char *s = strrchr(prop->name, '-');
655 if (!s || !streq(s, "-names"))
656 continue;
657
658 c->data = prop->name;
659 check_is_string_list(c, dti, node);
660 }
661}
662WARNING(names_is_string_list, check_names_is_string_list, NULL);
663
664static void check_alias_paths(struct check *c, struct dt_info *dti,
665 struct node *node)
666{
667 struct property *prop;
668
669 if (!streq(node->name, "aliases"))
670 return;
671
672 for_each_property(node, prop) {
673 if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) {
674 FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)",
675 prop->val.val);
676 continue;
677 }
678 if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name))
679 FAIL(c, dti, node, "aliases property name must include only lowercase and '-'");
680 }
681}
682WARNING(alias_paths, check_alias_paths, NULL);
589 683
590static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, 684static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
591 struct node *node) 685 struct node *node)
@@ -622,21 +716,21 @@ static void check_reg_format(struct check *c, struct dt_info *dti,
622 return; /* No "reg", that's fine */ 716 return; /* No "reg", that's fine */
623 717
624 if (!node->parent) { 718 if (!node->parent) {
625 FAIL(c, dti, "Root node has a \"reg\" property"); 719 FAIL(c, dti, node, "Root node has a \"reg\" property");
626 return; 720 return;
627 } 721 }
628 722
629 if (prop->val.len == 0) 723 if (prop->val.len == 0)
630 FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath); 724 FAIL_PROP(c, dti, node, prop, "property is empty");
631 725
632 addr_cells = node_addr_cells(node->parent); 726 addr_cells = node_addr_cells(node->parent);
633 size_cells = node_size_cells(node->parent); 727 size_cells = node_size_cells(node->parent);
634 entrylen = (addr_cells + size_cells) * sizeof(cell_t); 728 entrylen = (addr_cells + size_cells) * sizeof(cell_t);
635 729
636 if (!entrylen || (prop->val.len % entrylen) != 0) 730 if (!entrylen || (prop->val.len % entrylen) != 0)
637 FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) " 731 FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) "
638 "(#address-cells == %d, #size-cells == %d)", 732 "(#address-cells == %d, #size-cells == %d)",
639 node->fullpath, prop->val.len, addr_cells, size_cells); 733 prop->val.len, addr_cells, size_cells);
640} 734}
641WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); 735WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
642 736
@@ -651,7 +745,7 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
651 return; 745 return;
652 746
653 if (!node->parent) { 747 if (!node->parent) {
654 FAIL(c, dti, "Root node has a \"ranges\" property"); 748 FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property");
655 return; 749 return;
656 } 750 }
657 751
@@ -663,20 +757,20 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
663 757
664 if (prop->val.len == 0) { 758 if (prop->val.len == 0) {
665 if (p_addr_cells != c_addr_cells) 759 if (p_addr_cells != c_addr_cells)
666 FAIL(c, dti, "%s has empty \"ranges\" property but its " 760 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
667 "#address-cells (%d) differs from %s (%d)", 761 "#address-cells (%d) differs from %s (%d)",
668 node->fullpath, c_addr_cells, node->parent->fullpath, 762 c_addr_cells, node->parent->fullpath,
669 p_addr_cells); 763 p_addr_cells);
670 if (p_size_cells != c_size_cells) 764 if (p_size_cells != c_size_cells)
671 FAIL(c, dti, "%s has empty \"ranges\" property but its " 765 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
672 "#size-cells (%d) differs from %s (%d)", 766 "#size-cells (%d) differs from %s (%d)",
673 node->fullpath, c_size_cells, node->parent->fullpath, 767 c_size_cells, node->parent->fullpath,
674 p_size_cells); 768 p_size_cells);
675 } else if ((prop->val.len % entrylen) != 0) { 769 } else if ((prop->val.len % entrylen) != 0) {
676 FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) " 770 FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) "
677 "(parent #address-cells == %d, child #address-cells == %d, " 771 "(parent #address-cells == %d, child #address-cells == %d, "
678 "#size-cells == %d)", node->fullpath, prop->val.len, 772 "#size-cells == %d)", prop->val.len,
679 p_addr_cells, c_addr_cells, c_size_cells); 773 p_addr_cells, c_addr_cells, c_size_cells);
680 } 774 }
681} 775}
682WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); 776WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
@@ -696,41 +790,32 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *
696 790
697 node->bus = &pci_bus; 791 node->bus = &pci_bus;
698 792
699 if (!strneq(node->name, "pci", node->basenamelen) && 793 if (!strprefixeq(node->name, node->basenamelen, "pci") &&
700 !strneq(node->name, "pcie", node->basenamelen)) 794 !strprefixeq(node->name, node->basenamelen, "pcie"))
701 FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"", 795 FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\"");
702 node->fullpath);
703 796
704 prop = get_property(node, "ranges"); 797 prop = get_property(node, "ranges");
705 if (!prop) 798 if (!prop)
706 FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)", 799 FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)");
707 node->fullpath);
708 800
709 if (node_addr_cells(node) != 3) 801 if (node_addr_cells(node) != 3)
710 FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge", 802 FAIL(c, dti, node, "incorrect #address-cells for PCI bridge");
711 node->fullpath);
712 if (node_size_cells(node) != 2) 803 if (node_size_cells(node) != 2)
713 FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge", 804 FAIL(c, dti, node, "incorrect #size-cells for PCI bridge");
714 node->fullpath);
715 805
716 prop = get_property(node, "bus-range"); 806 prop = get_property(node, "bus-range");
717 if (!prop) { 807 if (!prop)
718 FAIL(c, dti, "Node %s missing bus-range for PCI bridge",
719 node->fullpath);
720 return; 808 return;
721 } 809
722 if (prop->val.len != (sizeof(cell_t) * 2)) { 810 if (prop->val.len != (sizeof(cell_t) * 2)) {
723 FAIL(c, dti, "Node %s bus-range must be 2 cells", 811 FAIL_PROP(c, dti, node, prop, "value must be 2 cells");
724 node->fullpath);
725 return; 812 return;
726 } 813 }
727 cells = (cell_t *)prop->val.val; 814 cells = (cell_t *)prop->val.val;
728 if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) 815 if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
729 FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell", 816 FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell");
730 node->fullpath);
731 if (fdt32_to_cpu(cells[1]) > 0xff) 817 if (fdt32_to_cpu(cells[1]) > 0xff)
732 FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256", 818 FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256");
733 node->fullpath);
734} 819}
735WARNING(pci_bridge, check_pci_bridge, NULL, 820WARNING(pci_bridge, check_pci_bridge, NULL,
736 &device_type_is_string, &addr_size_cells); 821 &device_type_is_string, &addr_size_cells);
@@ -760,8 +845,8 @@ static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struc
760 max_bus = fdt32_to_cpu(cells[0]); 845 max_bus = fdt32_to_cpu(cells[0]);
761 } 846 }
762 if ((bus_num < min_bus) || (bus_num > max_bus)) 847 if ((bus_num < min_bus) || (bus_num > max_bus))
763 FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)", 848 FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)",
764 node->fullpath, bus_num, min_bus, max_bus); 849 bus_num, min_bus, max_bus);
765} 850}
766WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge); 851WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);
767 852
@@ -778,25 +863,22 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no
778 863
779 prop = get_property(node, "reg"); 864 prop = get_property(node, "reg");
780 if (!prop) { 865 if (!prop) {
781 FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath); 866 FAIL(c, dti, node, "missing PCI reg property");
782 return; 867 return;
783 } 868 }
784 869
785 cells = (cell_t *)prop->val.val; 870 cells = (cell_t *)prop->val.val;
786 if (cells[1] || cells[2]) 871 if (cells[1] || cells[2])
787 FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0", 872 FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0");
788 node->fullpath);
789 873
790 reg = fdt32_to_cpu(cells[0]); 874 reg = fdt32_to_cpu(cells[0]);
791 dev = (reg & 0xf800) >> 11; 875 dev = (reg & 0xf800) >> 11;
792 func = (reg & 0x700) >> 8; 876 func = (reg & 0x700) >> 8;
793 877
794 if (reg & 0xff000000) 878 if (reg & 0xff000000)
795 FAIL(c, dti, "Node %s PCI reg address is not configuration space", 879 FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space");
796 node->fullpath);
797 if (reg & 0x000000ff) 880 if (reg & 0x000000ff)
798 FAIL(c, dti, "Node %s PCI reg config space address register number must be 0", 881 FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0");
799 node->fullpath);
800 882
801 if (func == 0) { 883 if (func == 0) {
802 snprintf(unit_addr, sizeof(unit_addr), "%x", dev); 884 snprintf(unit_addr, sizeof(unit_addr), "%x", dev);
@@ -808,8 +890,8 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no
808 if (streq(unitname, unit_addr)) 890 if (streq(unitname, unit_addr))
809 return; 891 return;
810 892
811 FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"", 893 FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"",
812 node->fullpath, unit_addr); 894 unit_addr);
813} 895}
814WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge); 896WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge);
815 897
@@ -828,7 +910,7 @@ static bool node_is_compatible(struct node *node, const char *compat)
828 910
829 for (str = prop->val.val, end = str + prop->val.len; str < end; 911 for (str = prop->val.val, end = str + prop->val.len; str < end;
830 str += strnlen(str, end - str) + 1) { 912 str += strnlen(str, end - str) + 1) {
831 if (strneq(str, compat, end - str)) 913 if (strprefixeq(str, end - str, compat))
832 return true; 914 return true;
833 } 915 }
834 return false; 916 return false;
@@ -865,7 +947,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
865 947
866 if (!cells) { 948 if (!cells) {
867 if (node->parent->parent && !(node->bus == &simple_bus)) 949 if (node->parent->parent && !(node->bus == &simple_bus))
868 FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath); 950 FAIL(c, dti, node, "missing or empty reg/ranges property");
869 return; 951 return;
870 } 952 }
871 953
@@ -875,11 +957,148 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
875 957
876 snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); 958 snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
877 if (!streq(unitname, unit_addr)) 959 if (!streq(unitname, unit_addr))
878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", 960 FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"",
879 node->fullpath, unit_addr); 961 unit_addr);
880} 962}
881WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge); 963WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
882 964
965static const struct bus_type i2c_bus = {
966 .name = "i2c-bus",
967};
968
969static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
970{
971 if (strprefixeq(node->name, node->basenamelen, "i2c-bus") ||
972 strprefixeq(node->name, node->basenamelen, "i2c-arb")) {
973 node->bus = &i2c_bus;
974 } else if (strprefixeq(node->name, node->basenamelen, "i2c")) {
975 struct node *child;
976 for_each_child(node, child) {
977 if (strprefixeq(child->name, node->basenamelen, "i2c-bus"))
978 return;
979 }
980 node->bus = &i2c_bus;
981 } else
982 return;
983
984 if (!node->children)
985 return;
986
987 if (node_addr_cells(node) != 1)
988 FAIL(c, dti, node, "incorrect #address-cells for I2C bus");
989 if (node_size_cells(node) != 0)
990 FAIL(c, dti, node, "incorrect #size-cells for I2C bus");
991
992}
993WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells);
994
995static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
996{
997 struct property *prop;
998 const char *unitname = get_unitname(node);
999 char unit_addr[17];
1000 uint32_t reg = 0;
1001 int len;
1002 cell_t *cells = NULL;
1003
1004 if (!node->parent || (node->parent->bus != &i2c_bus))
1005 return;
1006
1007 prop = get_property(node, "reg");
1008 if (prop)
1009 cells = (cell_t *)prop->val.val;
1010
1011 if (!cells) {
1012 FAIL(c, dti, node, "missing or empty reg property");
1013 return;
1014 }
1015
1016 reg = fdt32_to_cpu(*cells);
1017 snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
1018 if (!streq(unitname, unit_addr))
1019 FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
1020 unit_addr);
1021
1022 for (len = prop->val.len; len > 0; len -= 4) {
1023 reg = fdt32_to_cpu(*(cells++));
1024 if (reg > 0x3ff)
1025 FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
1026 reg);
1027
1028 }
1029}
1030WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
1031
1032static const struct bus_type spi_bus = {
1033 .name = "spi-bus",
1034};
1035
1036static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
1037{
1038
1039 if (strprefixeq(node->name, node->basenamelen, "spi")) {
1040 node->bus = &spi_bus;
1041 } else {
1042 /* Try to detect SPI buses which don't have proper node name */
1043 struct node *child;
1044
1045 if (node_addr_cells(node) != 1 || node_size_cells(node) != 0)
1046 return;
1047
1048 for_each_child(node, child) {
1049 struct property *prop;
1050 for_each_property(child, prop) {
1051 if (strprefixeq(prop->name, 4, "spi-")) {
1052 node->bus = &spi_bus;
1053 break;
1054 }
1055 }
1056 if (node->bus == &spi_bus)
1057 break;
1058 }
1059
1060 if (node->bus == &spi_bus && get_property(node, "reg"))
1061 FAIL(c, dti, node, "node name for SPI buses should be 'spi'");
1062 }
1063 if (node->bus != &spi_bus || !node->children)
1064 return;
1065
1066 if (node_addr_cells(node) != 1)
1067 FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
1068 if (node_size_cells(node) != 0)
1069 FAIL(c, dti, node, "incorrect #size-cells for SPI bus");
1070
1071}
1072WARNING(spi_bus_bridge, check_spi_bus_bridge, NULL, &addr_size_cells);
1073
1074static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
1075{
1076 struct property *prop;
1077 const char *unitname = get_unitname(node);
1078 char unit_addr[9];
1079 uint32_t reg = 0;
1080 cell_t *cells = NULL;
1081
1082 if (!node->parent || (node->parent->bus != &spi_bus))
1083 return;
1084
1085 prop = get_property(node, "reg");
1086 if (prop)
1087 cells = (cell_t *)prop->val.val;
1088
1089 if (!cells) {
1090 FAIL(c, dti, node, "missing or empty reg property");
1091 return;
1092 }
1093
1094 reg = fdt32_to_cpu(*cells);
1095 snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
1096 if (!streq(unitname, unit_addr))
1097 FAIL(c, dti, node, "SPI bus unit address format error, expected \"%s\"",
1098 unit_addr);
1099}
1100WARNING(spi_bus_reg, check_spi_bus_reg, NULL, &reg_format, &spi_bus_bridge);
1101
883static void check_unit_address_format(struct check *c, struct dt_info *dti, 1102static void check_unit_address_format(struct check *c, struct dt_info *dti,
884 struct node *node) 1103 struct node *node)
885{ 1104{
@@ -892,14 +1111,12 @@ static void check_unit_address_format(struct check *c, struct dt_info *dti,
892 return; 1111 return;
893 1112
894 if (!strncmp(unitname, "0x", 2)) { 1113 if (!strncmp(unitname, "0x", 2)) {
895 FAIL(c, dti, "Node %s unit name should not have leading \"0x\"", 1114 FAIL(c, dti, node, "unit name should not have leading \"0x\"");
896 node->fullpath);
897 /* skip over 0x for next test */ 1115 /* skip over 0x for next test */
898 unitname += 2; 1116 unitname += 2;
899 } 1117 }
900 if (unitname[0] == '0' && isxdigit(unitname[1])) 1118 if (unitname[0] == '0' && isxdigit(unitname[1]))
901 FAIL(c, dti, "Node %s unit name should not have leading 0s", 1119 FAIL(c, dti, node, "unit name should not have leading 0s");
902 node->fullpath);
903} 1120}
904WARNING(unit_address_format, check_unit_address_format, NULL, 1121WARNING(unit_address_format, check_unit_address_format, NULL,
905 &node_name_format, &pci_bridge, &simple_bus_bridge); 1122 &node_name_format, &pci_bridge, &simple_bus_bridge);
@@ -922,16 +1139,68 @@ static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti,
922 return; 1139 return;
923 1140
924 if (node->parent->addr_cells == -1) 1141 if (node->parent->addr_cells == -1)
925 FAIL(c, dti, "Relying on default #address-cells value for %s", 1142 FAIL(c, dti, node, "Relying on default #address-cells value");
926 node->fullpath);
927 1143
928 if (node->parent->size_cells == -1) 1144 if (node->parent->size_cells == -1)
929 FAIL(c, dti, "Relying on default #size-cells value for %s", 1145 FAIL(c, dti, node, "Relying on default #size-cells value");
930 node->fullpath);
931} 1146}
932WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, 1147WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
933 &addr_size_cells); 1148 &addr_size_cells);
934 1149
1150static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti,
1151 struct node *node)
1152{
1153 struct property *prop;
1154 struct node *child;
1155 bool has_reg = false;
1156
1157 if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)
1158 return;
1159
1160 if (get_property(node, "ranges") || !node->children)
1161 return;
1162
1163 for_each_child(node, child) {
1164 prop = get_property(child, "reg");
1165 if (prop)
1166 has_reg = true;
1167 }
1168
1169 if (!has_reg)
1170 FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property");
1171}
1172WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
1173
1174static void check_unique_unit_address(struct check *c, struct dt_info *dti,
1175 struct node *node)
1176{
1177 struct node *childa;
1178
1179 if (node->addr_cells < 0 || node->size_cells < 0)
1180 return;
1181
1182 if (!node->children)
1183 return;
1184
1185 for_each_child(node, childa) {
1186 struct node *childb;
1187 const char *addr_a = get_unitname(childa);
1188
1189 if (!strlen(addr_a))
1190 continue;
1191
1192 for_each_child(node, childb) {
1193 const char *addr_b = get_unitname(childb);
1194 if (childa == childb)
1195 break;
1196
1197 if (streq(addr_a, addr_b))
1198 FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath);
1199 }
1200 }
1201}
1202WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size);
1203
935static void check_obsolete_chosen_interrupt_controller(struct check *c, 1204static void check_obsolete_chosen_interrupt_controller(struct check *c,
936 struct dt_info *dti, 1205 struct dt_info *dti,
937 struct node *node) 1206 struct node *node)
@@ -950,12 +1219,61 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
950 1219
951 prop = get_property(chosen, "interrupt-controller"); 1220 prop = get_property(chosen, "interrupt-controller");
952 if (prop) 1221 if (prop)
953 FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" " 1222 FAIL_PROP(c, dti, node, prop,
954 "property"); 1223 "/chosen has obsolete \"interrupt-controller\" property");
955} 1224}
956WARNING(obsolete_chosen_interrupt_controller, 1225WARNING(obsolete_chosen_interrupt_controller,
957 check_obsolete_chosen_interrupt_controller, NULL); 1226 check_obsolete_chosen_interrupt_controller, NULL);
958 1227
1228static void check_chosen_node_is_root(struct check *c, struct dt_info *dti,
1229 struct node *node)
1230{
1231 if (!streq(node->name, "chosen"))
1232 return;
1233
1234 if (node->parent != dti->dt)
1235 FAIL(c, dti, node, "chosen node must be at root node");
1236}
1237WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL);
1238
1239static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti,
1240 struct node *node)
1241{
1242 struct property *prop;
1243
1244 if (!streq(node->name, "chosen"))
1245 return;
1246
1247 prop = get_property(node, "bootargs");
1248 if (!prop)
1249 return;
1250
1251 c->data = prop->name;
1252 check_is_string(c, dti, node);
1253}
1254WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL);
1255
1256static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti,
1257 struct node *node)
1258{
1259 struct property *prop;
1260
1261 if (!streq(node->name, "chosen"))
1262 return;
1263
1264 prop = get_property(node, "stdout-path");
1265 if (!prop) {
1266 prop = get_property(node, "linux,stdout-path");
1267 if (!prop)
1268 return;
1269 FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead");
1270 }
1271
1272 c->data = prop->name;
1273 check_is_string(c, dti, node);
1274}
1275WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL);
1276
959struct provider { 1277struct provider {
960 const char *prop_name; 1278 const char *prop_name;
961 const char *cell_name; 1279 const char *cell_name;
@@ -972,8 +1290,9 @@ static void check_property_phandle_args(struct check *c,
972 int cell, cellsize = 0; 1290 int cell, cellsize = 0;
973 1291
974 if (prop->val.len % sizeof(cell_t)) { 1292 if (prop->val.len % sizeof(cell_t)) {
975 FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s", 1293 FAIL_PROP(c, dti, node, prop,
976 prop->name, prop->val.len, sizeof(cell_t), node->fullpath); 1294 "property size (%d) is invalid, expected multiple of %zu",
1295 prop->val.len, sizeof(cell_t));
977 return; 1296 return;
978 } 1297 }
979 1298
@@ -1004,14 +1323,16 @@ static void check_property_phandle_args(struct check *c,
1004 break; 1323 break;
1005 } 1324 }
1006 if (!m) 1325 if (!m)
1007 FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s", 1326 FAIL_PROP(c, dti, node, prop,
1008 prop->name, cell, node->fullpath); 1327 "cell %d is not a phandle reference",
1328 cell);
1009 } 1329 }
1010 1330
1011 provider_node = get_node_by_phandle(root, phandle); 1331 provider_node = get_node_by_phandle(root, phandle);
1012 if (!provider_node) { 1332 if (!provider_node) {
1013 FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)", 1333 FAIL_PROP(c, dti, node, prop,
1014 node->fullpath, prop->name, cell); 1334 "Could not get phandle node for (cell %d)",
1335 cell);
1015 break; 1336 break;
1016 } 1337 }
1017 1338
@@ -1021,16 +1342,17 @@ static void check_property_phandle_args(struct check *c,
1021 } else if (provider->optional) { 1342 } else if (provider->optional) {
1022 cellsize = 0; 1343 cellsize = 0;
1023 } else { 1344 } else {
1024 FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])", 1345 FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])",
1025 provider->cell_name, 1346 provider->cell_name,
1026 provider_node->fullpath, 1347 provider_node->fullpath,
1027 node->fullpath, prop->name, cell); 1348 prop->name, cell);
1028 break; 1349 break;
1029 } 1350 }
1030 1351
1031 if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { 1352 if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
1032 FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s", 1353 FAIL_PROP(c, dti, node, prop,
1033 prop->name, prop->val.len, cellsize, node->fullpath); 1354 "property size (%d) too small for cell size %d",
1355 prop->val.len, cellsize);
1034 } 1356 }
1035 } 1357 }
1036} 1358}
@@ -1066,7 +1388,7 @@ WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
1066WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); 1388WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
1067WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); 1389WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
1068WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); 1390WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
1069WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells"); 1391WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells");
1070WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); 1392WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
1071 1393
1072static bool prop_is_gpio(struct property *prop) 1394static bool prop_is_gpio(struct property *prop)
@@ -1132,8 +1454,8 @@ static void check_deprecated_gpio_property(struct check *c,
1132 if (!streq(str, "gpio")) 1454 if (!streq(str, "gpio"))
1133 continue; 1455 continue;
1134 1456
1135 FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s", 1457 FAIL_PROP(c, dti, node, prop,
1136 node->fullpath, prop->name); 1458 "'[*-]gpio' is deprecated, use '[*-]gpios' instead");
1137 } 1459 }
1138 1460
1139} 1461}
@@ -1167,9 +1489,8 @@ static void check_interrupts_property(struct check *c,
1167 return; 1489 return;
1168 1490
1169 if (irq_prop->val.len % sizeof(cell_t)) 1491 if (irq_prop->val.len % sizeof(cell_t))
1170 FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s", 1492 FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu",
1171 irq_prop->name, irq_prop->val.len, sizeof(cell_t), 1493 irq_prop->val.len, sizeof(cell_t));
1172 node->fullpath);
1173 1494
1174 while (parent && !prop) { 1495 while (parent && !prop) {
1175 if (parent != node && node_is_interrupt_provider(parent)) { 1496 if (parent != node && node_is_interrupt_provider(parent)) {
@@ -1187,14 +1508,12 @@ static void check_interrupts_property(struct check *c,
1187 1508
1188 irq_node = get_node_by_phandle(root, phandle); 1509 irq_node = get_node_by_phandle(root, phandle);
1189 if (!irq_node) { 1510 if (!irq_node) {
1190 FAIL(c, dti, "Bad interrupt-parent phandle for %s", 1511 FAIL_PROP(c, dti, parent, prop, "Bad phandle");
1191 node->fullpath);
1192 return; 1512 return;
1193 } 1513 }
1194 if (!node_is_interrupt_provider(irq_node)) 1514 if (!node_is_interrupt_provider(irq_node))
1195 FAIL(c, dti, 1515 FAIL(c, dti, irq_node,
1196 "Missing interrupt-controller or interrupt-map property in %s", 1516 "Missing interrupt-controller or interrupt-map property");
1197 irq_node->fullpath);
1198 1517
1199 break; 1518 break;
1200 } 1519 }
@@ -1203,27 +1522,171 @@ static void check_interrupts_property(struct check *c,
1203 } 1522 }
1204 1523
1205 if (!irq_node) { 1524 if (!irq_node) {
1206 FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath); 1525 FAIL(c, dti, node, "Missing interrupt-parent");
1207 return; 1526 return;
1208 } 1527 }
1209 1528
1210 prop = get_property(irq_node, "#interrupt-cells"); 1529 prop = get_property(irq_node, "#interrupt-cells");
1211 if (!prop) { 1530 if (!prop) {
1212 FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s", 1531 FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent");
1213 irq_node->fullpath);
1214 return; 1532 return;
1215 } 1533 }
1216 1534
1217 irq_cells = propval_cell(prop); 1535 irq_cells = propval_cell(prop);
1218 if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { 1536 if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
1219 FAIL(c, dti, 1537 FAIL_PROP(c, dti, node, prop,
1220 "interrupts size is (%d), expected multiple of %d in %s", 1538 "size is (%d), expected multiple of %d",
1221 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)), 1539 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)));
1222 node->fullpath);
1223 } 1540 }
1224} 1541}
1225WARNING(interrupts_property, check_interrupts_property, &phandle_references); 1542WARNING(interrupts_property, check_interrupts_property, &phandle_references);
1226 1543
1544static const struct bus_type graph_port_bus = {
1545 .name = "graph-port",
1546};
1547
1548static const struct bus_type graph_ports_bus = {
1549 .name = "graph-ports",
1550};
1551
1552static void check_graph_nodes(struct check *c, struct dt_info *dti,
1553 struct node *node)
1554{
1555 struct node *child;
1556
1557 for_each_child(node, child) {
1558 if (!(strprefixeq(child->name, child->basenamelen, "endpoint") ||
1559 get_property(child, "remote-endpoint")))
1560 continue;
1561
1562 node->bus = &graph_port_bus;
1563
1564 /* The parent of 'port' nodes can be either 'ports' or a device */
1565 if (!node->parent->bus &&
1566 (streq(node->parent->name, "ports") || get_property(node, "reg")))
1567 node->parent->bus = &graph_ports_bus;
1568
1569 break;
1570 }
1571
1572}
1573WARNING(graph_nodes, check_graph_nodes, NULL);
1574
1575static void check_graph_child_address(struct check *c, struct dt_info *dti,
1576 struct node *node)
1577{
1578 int cnt = 0;
1579 struct node *child;
1580
1581 if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
1582 return;
1583
1584 for_each_child(node, child) {
1585 struct property *prop = get_property(child, "reg");
1586
1587 /* No error if we have any non-zero unit address */
1588 if (prop && propval_cell(prop) != 0)
1589 return;
1590
1591 cnt++;
1592 }
1593
1594 if (cnt == 1 && node->addr_cells != -1)
1595 FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
1596 node->children->name);
1597}
1598WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes);
1599
1600static void check_graph_reg(struct check *c, struct dt_info *dti,
1601 struct node *node)
1602{
1603 char unit_addr[9];
1604 const char *unitname = get_unitname(node);
1605 struct property *prop;
1606
1607 prop = get_property(node, "reg");
1608 if (!prop || !unitname)
1609 return;
1610
1611 if (!(prop->val.val && prop->val.len == sizeof(cell_t))) {
1612 FAIL(c, dti, node, "graph node malformed 'reg' property");
1613 return;
1614 }
1615
1616 snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop));
1617 if (!streq(unitname, unit_addr))
1618 FAIL(c, dti, node, "graph node unit address error, expected \"%s\"",
1619 unit_addr);
1620
1621 if (node->parent->addr_cells != 1)
1622 FAIL_PROP(c, dti, node, get_property(node, "#address-cells"),
1623 "graph node '#address-cells' is %d, must be 1",
1624 node->parent->addr_cells);
1625 if (node->parent->size_cells != 0)
1626 FAIL_PROP(c, dti, node, get_property(node, "#size-cells"),
1627 "graph node '#size-cells' is %d, must be 0",
1628 node->parent->size_cells);
1629}
1630
1631static void check_graph_port(struct check *c, struct dt_info *dti,
1632 struct node *node)
1633{
1634 if (node->bus != &graph_port_bus)
1635 return;
1636
1637 if (!strprefixeq(node->name, node->basenamelen, "port"))
1638 FAIL(c, dti, node, "graph port node name should be 'port'");
1639
1640 check_graph_reg(c, dti, node);
1641}
1642WARNING(graph_port, check_graph_port, NULL, &graph_nodes);
1643
1644static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
1645 struct node *endpoint)
1646{
1647 int phandle;
1648 struct node *node;
1649 struct property *prop;
1650
1651 prop = get_property(endpoint, "remote-endpoint");
1652 if (!prop)
1653 return NULL;
1654
1655 phandle = propval_cell(prop);
1656 /* Give up if this is an overlay with external references */
1657 if (phandle == 0 || phandle == -1)
1658 return NULL;
1659
1660 node = get_node_by_phandle(dti->dt, phandle);
1661 if (!node)
1662 FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid");
1663
1664 return node;
1665}
1666
1667static void check_graph_endpoint(struct check *c, struct dt_info *dti,
1668 struct node *node)
1669{
1670 struct node *remote_node;
1671
1672 if (!node->parent || node->parent->bus != &graph_port_bus)
1673 return;
1674
1675 if (!strprefixeq(node->name, node->basenamelen, "endpoint"))
1676 FAIL(c, dti, node, "graph endpont node name should be 'endpoint'");
1677
1678 check_graph_reg(c, dti, node);
1679
1680 remote_node = get_remote_endpoint(c, dti, node);
1681 if (!remote_node)
1682 return;
1683
1684 if (get_remote_endpoint(c, dti, remote_node) != node)
1685 FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional",
1686 remote_node->fullpath);
1687}
1688WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes);
1689
1227static struct check *check_table[] = { 1690static struct check *check_table[] = {
1228 &duplicate_node_names, &duplicate_property_names, 1691 &duplicate_node_names, &duplicate_property_names,
1229 &node_name_chars, &node_name_format, &property_name_chars, 1692 &node_name_chars, &node_name_format, &property_name_chars,
@@ -1233,9 +1696,13 @@ static struct check *check_table[] = {
1233 1696
1234 &explicit_phandles, 1697 &explicit_phandles,
1235 &phandle_references, &path_references, 1698 &phandle_references, &path_references,
1699 &omit_unused_nodes,
1236 1700
1237 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, 1701 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
1238 &device_type_is_string, &model_is_string, &status_is_string, 1702 &device_type_is_string, &model_is_string, &status_is_string,
1703 &label_is_string,
1704
1705 &compatible_is_string_list, &names_is_string_list,
1239 1706
1240 &property_name_chars_strict, 1707 &property_name_chars_strict,
1241 &node_name_chars_strict, 1708 &node_name_chars_strict,
@@ -1252,8 +1719,17 @@ static struct check *check_table[] = {
1252 &simple_bus_bridge, 1719 &simple_bus_bridge,
1253 &simple_bus_reg, 1720 &simple_bus_reg,
1254 1721
1722 &i2c_bus_bridge,
1723 &i2c_bus_reg,
1724
1725 &spi_bus_bridge,
1726 &spi_bus_reg,
1727
1255 &avoid_default_addr_size, 1728 &avoid_default_addr_size,
1729 &avoid_unnecessary_addr_size,
1730 &unique_unit_address,
1256 &obsolete_chosen_interrupt_controller, 1731 &obsolete_chosen_interrupt_controller,
1732 &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
1257 1733
1258 &clocks_property, 1734 &clocks_property,
1259 &cooling_device_property, 1735 &cooling_device_property,
@@ -1269,13 +1745,17 @@ static struct check *check_table[] = {
1269 &power_domains_property, 1745 &power_domains_property,
1270 &pwms_property, 1746 &pwms_property,
1271 &resets_property, 1747 &resets_property,
1272 &sound_dais_property, 1748 &sound_dai_property,
1273 &thermal_sensors_property, 1749 &thermal_sensors_property,
1274 1750
1275 &deprecated_gpio_property, 1751 &deprecated_gpio_property,
1276 &gpios_property, 1752 &gpios_property,
1277 &interrupts_property, 1753 &interrupts_property,
1278 1754
1755 &alias_paths,
1756
1757 &graph_nodes, &graph_child_address, &graph_port, &graph_endpoint,
1758
1279 &always_fail, 1759 &always_fail,
1280}; 1760};
1281 1761
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index aa37a16c8891..4a204145cc7b 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -74,7 +74,8 @@ struct data data_copy_escape_string(const char *s, int len)
74 struct data d; 74 struct data d;
75 char *q; 75 char *q;
76 76
77 d = data_grow_for(empty_data, len + 1); 77 d = data_add_marker(empty_data, TYPE_STRING, NULL);
78 d = data_grow_for(d, len + 1);
78 79
79 q = d.val; 80 q = d.val;
80 while (i < len) { 81 while (i < len) {
@@ -94,6 +95,7 @@ struct data data_copy_file(FILE *f, size_t maxlen)
94{ 95{
95 struct data d = empty_data; 96 struct data d = empty_data;
96 97
98 d = data_add_marker(d, TYPE_NONE, NULL);
97 while (!feof(f) && (d.len < maxlen)) { 99 while (!feof(f) && (d.len < maxlen)) {
98 size_t chunksize, ret; 100 size_t chunksize, ret;
99 101
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index fd825ebba69c..615b7ec6588f 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
153 return DT_DEL_NODE; 153 return DT_DEL_NODE;
154 } 154 }
155 155
156<*>"/omit-if-no-ref/" {
157 DPRINT("Keyword: /omit-if-no-ref/\n");
158 DPRINT("<PROPNODENAME>\n");
159 BEGIN(PROPNODENAME);
160 return DT_OMIT_NO_REF;
161 }
162
156<*>{LABEL}: { 163<*>{LABEL}: {
157 DPRINT("Label: %s\n", yytext); 164 DPRINT("Label: %s\n", yytext);
158 yylval.labelref = xstrdup(yytext); 165 yylval.labelref = xstrdup(yytext);
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
deleted file mode 100644
index 011bb9632ff2..000000000000
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ /dev/null
@@ -1,2259 +0,0 @@
1#line 2 "dtc-lexer.lex.c"
2
3#line 4 "dtc-lexer.lex.c"
4
5#define YY_INT_ALIGNED short int
6
7/* A lexical scanner generated by flex */
8
9#define FLEX_SCANNER
10#define YY_FLEX_MAJOR_VERSION 2
11#define YY_FLEX_MINOR_VERSION 6
12#define YY_FLEX_SUBMINOR_VERSION 1
13#if YY_FLEX_SUBMINOR_VERSION > 0
14#define FLEX_BETA
15#endif
16
17/* First, we deal with platform-specific or compiler-specific issues. */
18
19/* begin standard C headers. */
20#include <stdio.h>
21#include <string.h>
22#include <errno.h>
23#include <stdlib.h>
24
25/* end standard C headers. */
26
27/* flex integer type definitions */
28
29#ifndef FLEXINT_H
30#define FLEXINT_H
31
32/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
33
34#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
35
36/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
37 * if you want the limit (max/min) macros for int types.
38 */
39#ifndef __STDC_LIMIT_MACROS
40#define __STDC_LIMIT_MACROS 1
41#endif
42
43#include <inttypes.h>
44typedef int8_t flex_int8_t;
45typedef uint8_t flex_uint8_t;
46typedef int16_t flex_int16_t;
47typedef uint16_t flex_uint16_t;
48typedef int32_t flex_int32_t;
49typedef uint32_t flex_uint32_t;
50#else
51typedef signed char flex_int8_t;
52typedef short int flex_int16_t;
53typedef int flex_int32_t;
54typedef unsigned char flex_uint8_t;
55typedef unsigned short int flex_uint16_t;
56typedef unsigned int flex_uint32_t;
57
58/* Limits of integral types. */
59#ifndef INT8_MIN
60#define INT8_MIN (-128)
61#endif
62#ifndef INT16_MIN
63#define INT16_MIN (-32767-1)
64#endif
65#ifndef INT32_MIN
66#define INT32_MIN (-2147483647-1)
67#endif
68#ifndef INT8_MAX
69#define INT8_MAX (127)
70#endif
71#ifndef INT16_MAX
72#define INT16_MAX (32767)
73#endif
74#ifndef INT32_MAX
75#define INT32_MAX (2147483647)
76#endif
77#ifndef UINT8_MAX
78#define UINT8_MAX (255U)
79#endif
80#ifndef UINT16_MAX
81#define UINT16_MAX (65535U)
82#endif
83#ifndef UINT32_MAX
84#define UINT32_MAX (4294967295U)
85#endif
86
87#endif /* ! C99 */
88
89#endif /* ! FLEXINT_H */
90
91/* TODO: this is always defined, so inline it */
92#define yyconst const
93
94#if defined(__GNUC__) && __GNUC__ >= 3
95#define yynoreturn __attribute__((__noreturn__))
96#else
97#define yynoreturn
98#endif
99
100/* Returned upon end-of-file. */
101#define YY_NULL 0
102
103/* Promotes a possibly negative, possibly signed char to an unsigned
104 * integer for use as an array index. If the signed char is negative,
105 * we want to instead treat it as an 8-bit unsigned char, hence the
106 * double cast.
107 */
108#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
109
110/* Enter a start condition. This macro really ought to take a parameter,
111 * but we do it the disgusting crufty way forced on us by the ()-less
112 * definition of BEGIN.
113 */
114#define BEGIN (yy_start) = 1 + 2 *
115
116/* Translate the current start state into a value that can be later handed
117 * to BEGIN to return to the state. The YYSTATE alias is for lex
118 * compatibility.
119 */
120#define YY_START (((yy_start) - 1) / 2)
121#define YYSTATE YY_START
122
123/* Action number for EOF rule of a given start state. */
124#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
125
126/* Special action meaning "start processing a new file". */
127#define YY_NEW_FILE yyrestart(yyin )
128
129#define YY_END_OF_BUFFER_CHAR 0
130
131/* Size of default input buffer. */
132#ifndef YY_BUF_SIZE
133#ifdef __ia64__
134/* On IA-64, the buffer size is 16k, not 8k.
135 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
136 * Ditto for the __ia64__ case accordingly.
137 */
138#define YY_BUF_SIZE 32768
139#else
140#define YY_BUF_SIZE 16384
141#endif /* __ia64__ */
142#endif
143
144/* The state buf must be large enough to hold one state per character in the main buffer.
145 */
146#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
147
148#ifndef YY_TYPEDEF_YY_BUFFER_STATE
149#define YY_TYPEDEF_YY_BUFFER_STATE
150typedef struct yy_buffer_state *YY_BUFFER_STATE;
151#endif
152
153#ifndef YY_TYPEDEF_YY_SIZE_T
154#define YY_TYPEDEF_YY_SIZE_T
155typedef size_t yy_size_t;
156#endif
157
158extern int yyleng;
159
160extern FILE *yyin, *yyout;
161
162#define EOB_ACT_CONTINUE_SCAN 0
163#define EOB_ACT_END_OF_FILE 1
164#define EOB_ACT_LAST_MATCH 2
165
166 #define YY_LESS_LINENO(n)
167 #define YY_LINENO_REWIND_TO(ptr)
168
169/* Return all but the first "n" matched characters back to the input stream. */
170#define yyless(n) \
171 do \
172 { \
173 /* Undo effects of setting up yytext. */ \
174 int yyless_macro_arg = (n); \
175 YY_LESS_LINENO(yyless_macro_arg);\
176 *yy_cp = (yy_hold_char); \
177 YY_RESTORE_YY_MORE_OFFSET \
178 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
179 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
180 } \
181 while ( 0 )
182
183#define unput(c) yyunput( c, (yytext_ptr) )
184
185#ifndef YY_STRUCT_YY_BUFFER_STATE
186#define YY_STRUCT_YY_BUFFER_STATE
187struct yy_buffer_state
188 {
189 FILE *yy_input_file;
190
191 char *yy_ch_buf; /* input buffer */
192 char *yy_buf_pos; /* current position in input buffer */
193
194 /* Size of input buffer in bytes, not including room for EOB
195 * characters.
196 */
197 int yy_buf_size;
198
199 /* Number of characters read into yy_ch_buf, not including EOB
200 * characters.
201 */
202 int yy_n_chars;
203
204 /* Whether we "own" the buffer - i.e., we know we created it,
205 * and can realloc() it to grow it, and should free() it to
206 * delete it.
207 */
208 int yy_is_our_buffer;
209
210 /* Whether this is an "interactive" input source; if so, and
211 * if we're using stdio for input, then we want to use getc()
212 * instead of fread(), to make sure we stop fetching input after
213 * each newline.
214 */
215 int yy_is_interactive;
216
217 /* Whether we're considered to be at the beginning of a line.
218 * If so, '^' rules will be active on the next match, otherwise
219 * not.
220 */
221 int yy_at_bol;
222
223 int yy_bs_lineno; /**< The line count. */
224 int yy_bs_column; /**< The column count. */
225
226 /* Whether to try to fill the input buffer when we reach the
227 * end of it.
228 */
229 int yy_fill_buffer;
230
231 int yy_buffer_status;
232
233#define YY_BUFFER_NEW 0
234#define YY_BUFFER_NORMAL 1
235 /* When an EOF's been seen but there's still some text to process
236 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
237 * shouldn't try reading from the input source any more. We might
238 * still have a bunch of tokens to match, though, because of
239 * possible backing-up.
240 *
241 * When we actually see the EOF, we change the status to "new"
242 * (via yyrestart()), so that the user can continue scanning by
243 * just pointing yyin at a new input file.
244 */
245#define YY_BUFFER_EOF_PENDING 2
246
247 };
248#endif /* !YY_STRUCT_YY_BUFFER_STATE */
249
250/* Stack of input buffers. */
251static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
252static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
253static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
254
255/* We provide macros for accessing buffer states in case in the
256 * future we want to put the buffer states in a more general
257 * "scanner state".
258 *
259 * Returns the top of the stack, or NULL.
260 */
261#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
262 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
263 : NULL)
264
265/* Same as previous macro, but useful when we know that the buffer stack is not
266 * NULL or when we need an lvalue. For internal use only.
267 */
268#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
269
270/* yy_hold_char holds the character lost when yytext is formed. */
271static char yy_hold_char;
272static int yy_n_chars; /* number of characters read into yy_ch_buf */
273int yyleng;
274
275/* Points to current character in buffer. */
276static char *yy_c_buf_p = NULL;
277static int yy_init = 0; /* whether we need to initialize */
278static int yy_start = 0; /* start state number */
279
280/* Flag which is used to allow yywrap()'s to do buffer switches
281 * instead of setting up a fresh yyin. A bit of a hack ...
282 */
283static int yy_did_buffer_switch_on_eof;
284
285void yyrestart (FILE *input_file );
286void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
287YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
288void yy_delete_buffer (YY_BUFFER_STATE b );
289void yy_flush_buffer (YY_BUFFER_STATE b );
290void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
291void yypop_buffer_state (void );
292
293static void yyensure_buffer_stack (void );
294static void yy_load_buffer_state (void );
295static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
296
297#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
298
299YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
300YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
301YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
302
303void *yyalloc (yy_size_t );
304void *yyrealloc (void *,yy_size_t );
305void yyfree (void * );
306
307#define yy_new_buffer yy_create_buffer
308
309#define yy_set_interactive(is_interactive) \
310 { \
311 if ( ! YY_CURRENT_BUFFER ){ \
312 yyensure_buffer_stack (); \
313 YY_CURRENT_BUFFER_LVALUE = \
314 yy_create_buffer(yyin,YY_BUF_SIZE ); \
315 } \
316 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
317 }
318
319#define yy_set_bol(at_bol) \
320 { \
321 if ( ! YY_CURRENT_BUFFER ){\
322 yyensure_buffer_stack (); \
323 YY_CURRENT_BUFFER_LVALUE = \
324 yy_create_buffer(yyin,YY_BUF_SIZE ); \
325 } \
326 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
327 }
328
329#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
330
331/* Begin user sect3 */
332
333#define yywrap() (/*CONSTCOND*/1)
334#define YY_SKIP_YYWRAP
335
336typedef unsigned char YY_CHAR;
337
338FILE *yyin = NULL, *yyout = NULL;
339
340typedef int yy_state_type;
341
342extern int yylineno;
343
344int yylineno = 1;
345
346extern char *yytext;
347#ifdef yytext_ptr
348#undef yytext_ptr
349#endif
350#define yytext_ptr yytext
351
352static yy_state_type yy_get_previous_state (void );
353static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
354static int yy_get_next_buffer (void );
355static void yynoreturn yy_fatal_error (yyconst char* msg );
356
357/* Done after the current pattern has been matched and before the
358 * corresponding action - sets up yytext.
359 */
360#define YY_DO_BEFORE_ACTION \
361 (yytext_ptr) = yy_bp; \
362 yyleng = (int) (yy_cp - yy_bp); \
363 (yy_hold_char) = *yy_cp; \
364 *yy_cp = '\0'; \
365 (yy_c_buf_p) = yy_cp;
366
367#define YY_NUM_RULES 31
368#define YY_END_OF_BUFFER 32
369/* This struct is not used in this scanner,
370 but its presence is necessary. */
371struct yy_trans_info
372 {
373 flex_int32_t yy_verify;
374 flex_int32_t yy_nxt;
375 };
376static yyconst flex_int16_t yy_accept[166] =
377 { 0,
378 0, 0, 0, 0, 0, 0, 0, 0, 32, 30,
379 19, 19, 30, 30, 30, 30, 30, 30, 30, 30,
380 30, 30, 30, 30, 30, 30, 16, 17, 17, 30,
381 17, 11, 11, 19, 27, 0, 3, 0, 28, 13,
382 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
383 0, 22, 24, 26, 25, 23, 0, 10, 29, 0,
384 0, 0, 15, 15, 17, 17, 17, 11, 11, 11,
385 0, 13, 0, 12, 0, 0, 0, 21, 0, 0,
386 0, 0, 0, 0, 0, 0, 0, 17, 11, 11,
387 11, 0, 14, 20, 0, 0, 0, 0, 0, 0,
388
389 0, 0, 0, 0, 17, 0, 0, 0, 0, 0,
390 0, 0, 0, 0, 0, 17, 7, 0, 0, 0,
391 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 4, 18, 0, 0, 5, 2,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 0, 0, 1, 0, 0, 0, 0, 6, 9, 0,
395 0, 0, 0, 8, 0
396 } ;
397
398static yyconst YY_CHAR yy_ec[256] =
399 { 0,
400 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
401 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
402 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
403 1, 2, 5, 6, 7, 1, 1, 8, 9, 1,
404 1, 10, 11, 11, 12, 11, 13, 14, 15, 16,
405 16, 16, 16, 16, 16, 16, 16, 17, 1, 18,
406 19, 20, 11, 11, 21, 21, 21, 21, 21, 21,
407 22, 22, 22, 22, 22, 23, 22, 22, 22, 22,
408 22, 22, 22, 22, 24, 22, 22, 25, 22, 22,
409 1, 26, 27, 1, 22, 1, 21, 28, 29, 30,
410
411 31, 21, 32, 22, 33, 22, 22, 34, 35, 36,
412 37, 38, 22, 39, 40, 41, 42, 43, 22, 25,
413 44, 22, 45, 46, 47, 1, 1, 1, 1, 1,
414 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
415 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
416 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
417 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
418 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
419 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
420 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
421
422 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
423 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
424 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
425 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
426 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
427 1, 1, 1, 1, 1
428 } ;
429
430static yyconst YY_CHAR yy_meta[48] =
431 { 0,
432 1, 1, 1, 1, 1, 1, 2, 3, 1, 2,
433 2, 2, 4, 5, 5, 5, 6, 1, 1, 1,
434 7, 8, 8, 8, 8, 1, 1, 7, 7, 7,
435 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
436 8, 8, 8, 8, 3, 1, 4
437 } ;
438
439static yyconst flex_uint16_t yy_base[180] =
440 { 0,
441 0, 393, 35, 392, 66, 391, 38, 107, 397, 401,
442 55, 113, 377, 112, 111, 111, 114, 42, 376, 106,
443 377, 347, 126, 120, 0, 147, 401, 0, 124, 0,
444 137, 158, 170, 163, 401, 153, 401, 389, 401, 0,
445 378, 120, 401, 131, 380, 386, 355, 139, 351, 355,
446 351, 401, 401, 401, 401, 401, 367, 401, 401, 185,
447 350, 346, 401, 364, 0, 185, 347, 189, 356, 355,
448 0, 0, 330, 180, 366, 141, 372, 361, 332, 338,
449 331, 341, 334, 326, 205, 331, 337, 329, 401, 341,
450 167, 316, 401, 349, 348, 320, 328, 346, 180, 318,
451
452 324, 209, 324, 320, 322, 342, 338, 309, 306, 315,
453 305, 315, 312, 192, 342, 341, 401, 293, 306, 282,
454 268, 252, 255, 203, 285, 282, 272, 268, 252, 233,
455 232, 239, 208, 107, 401, 401, 238, 211, 401, 211,
456 212, 208, 228, 203, 215, 207, 233, 222, 212, 211,
457 203, 227, 401, 237, 225, 204, 185, 401, 401, 149,
458 128, 88, 42, 401, 401, 253, 259, 267, 271, 275,
459 281, 288, 292, 300, 308, 312, 318, 326, 334
460 } ;
461
462static yyconst flex_int16_t yy_def[180] =
463 { 0,
464 165, 1, 1, 3, 165, 5, 1, 1, 165, 165,
465 165, 165, 165, 166, 167, 168, 165, 165, 165, 165,
466 169, 165, 165, 165, 170, 169, 165, 171, 172, 171,
467 171, 165, 165, 165, 165, 166, 165, 166, 165, 173,
468 165, 168, 165, 168, 174, 175, 165, 165, 165, 165,
469 165, 165, 165, 165, 165, 165, 169, 165, 165, 165,
470 165, 165, 165, 169, 171, 172, 171, 165, 165, 165,
471 176, 173, 177, 168, 174, 174, 175, 165, 165, 165,
472 165, 165, 165, 165, 165, 165, 165, 171, 165, 165,
473 176, 177, 165, 165, 165, 165, 165, 165, 165, 165,
474
475 165, 165, 165, 165, 171, 165, 165, 165, 165, 165,
476 165, 165, 165, 178, 165, 171, 165, 165, 165, 165,
477 165, 165, 165, 178, 165, 178, 165, 165, 165, 165,
478 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
479 165, 165, 165, 165, 165, 165, 165, 179, 165, 165,
480 165, 179, 165, 179, 165, 165, 165, 165, 165, 165,
481 165, 165, 165, 165, 0, 165, 165, 165, 165, 165,
482 165, 165, 165, 165, 165, 165, 165, 165, 165
483 } ;
484
485static yyconst flex_uint16_t yy_nxt[449] =
486 { 0,
487 10, 11, 12, 11, 13, 14, 10, 15, 16, 10,
488 10, 10, 17, 10, 10, 10, 10, 18, 19, 20,
489 21, 21, 21, 21, 21, 10, 10, 21, 21, 21,
490 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
491 21, 21, 21, 21, 10, 22, 10, 24, 25, 25,
492 25, 32, 33, 33, 164, 26, 34, 34, 34, 52,
493 53, 27, 26, 26, 26, 26, 10, 11, 12, 11,
494 13, 14, 28, 15, 16, 28, 28, 28, 24, 28,
495 28, 28, 10, 18, 19, 20, 29, 29, 29, 29,
496 29, 30, 10, 29, 29, 29, 29, 29, 29, 29,
497
498 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
499 10, 22, 10, 23, 34, 34, 34, 37, 39, 43,
500 32, 33, 33, 45, 55, 56, 46, 60, 43, 45,
501 65, 163, 46, 65, 65, 65, 44, 38, 60, 74,
502 58, 47, 141, 48, 142, 44, 49, 47, 50, 48,
503 76, 51, 62, 94, 50, 41, 44, 51, 37, 61,
504 64, 64, 64, 58, 34, 34, 34, 64, 162, 80,
505 67, 68, 68, 68, 64, 64, 64, 64, 38, 81,
506 69, 70, 71, 68, 68, 68, 60, 161, 43, 69,
507 70, 65, 69, 70, 65, 65, 65, 125, 85, 85,
508
509 85, 58, 68, 68, 68, 44, 102, 110, 125, 133,
510 102, 69, 70, 111, 114, 160, 159, 126, 85, 85,
511 85, 140, 140, 140, 140, 140, 140, 153, 126, 147,
512 147, 147, 153, 148, 147, 147, 147, 158, 148, 165,
513 157, 156, 155, 151, 150, 149, 146, 154, 145, 144,
514 143, 139, 154, 36, 36, 36, 36, 36, 36, 36,
515 36, 40, 138, 137, 136, 40, 40, 42, 42, 42,
516 42, 42, 42, 42, 42, 57, 57, 57, 57, 63,
517 135, 63, 65, 134, 165, 65, 133, 65, 65, 66,
518 132, 131, 66, 66, 66, 66, 72, 130, 72, 72,
519
520 75, 75, 75, 75, 75, 75, 75, 75, 77, 77,
521 77, 77, 77, 77, 77, 77, 91, 129, 91, 92,
522 128, 92, 92, 127, 92, 92, 124, 124, 124, 124,
523 124, 124, 124, 124, 152, 152, 152, 152, 152, 152,
524 152, 152, 60, 60, 123, 122, 121, 120, 119, 118,
525 117, 45, 116, 111, 115, 113, 112, 109, 108, 107,
526 46, 106, 93, 89, 105, 104, 103, 101, 100, 99,
527 98, 97, 96, 95, 78, 76, 93, 90, 89, 88,
528 58, 87, 86, 58, 84, 83, 82, 79, 78, 76,
529 73, 165, 59, 58, 54, 35, 165, 31, 23, 23,
530
531 9, 165, 165, 165, 165, 165, 165, 165, 165, 165,
532 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
533 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
534 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
535 165, 165, 165, 165, 165, 165, 165, 165
536 } ;
537
538static yyconst flex_int16_t yy_chk[449] =
539 { 0,
540 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
541 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
542 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
543 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
544 1, 1, 1, 1, 1, 1, 1, 3, 3, 3,
545 3, 7, 7, 7, 163, 3, 11, 11, 11, 18,
546 18, 3, 3, 3, 3, 3, 5, 5, 5, 5,
547 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
548 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
549 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
550
551 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
552 5, 5, 5, 8, 12, 12, 12, 14, 15, 16,
553 8, 8, 8, 17, 20, 20, 17, 23, 42, 24,
554 29, 162, 24, 29, 29, 29, 16, 14, 31, 44,
555 29, 17, 134, 17, 134, 42, 17, 24, 17, 24,
556 76, 17, 24, 76, 24, 15, 44, 24, 36, 23,
557 26, 26, 26, 26, 34, 34, 34, 26, 161, 48,
558 31, 32, 32, 32, 26, 26, 26, 26, 36, 48,
559 32, 32, 32, 33, 33, 33, 60, 160, 74, 91,
560 91, 66, 33, 33, 66, 66, 66, 114, 60, 60,
561
562 60, 66, 68, 68, 68, 74, 85, 99, 124, 133,
563 102, 68, 68, 99, 102, 157, 156, 114, 85, 85,
564 85, 133, 133, 133, 140, 140, 140, 148, 124, 143,
565 143, 143, 152, 143, 147, 147, 147, 155, 147, 154,
566 151, 150, 149, 146, 145, 144, 142, 148, 141, 138,
567 137, 132, 152, 166, 166, 166, 166, 166, 166, 166,
568 166, 167, 131, 130, 129, 167, 167, 168, 168, 168,
569 168, 168, 168, 168, 168, 169, 169, 169, 169, 170,
570 128, 170, 171, 127, 126, 171, 125, 171, 171, 172,
571 123, 122, 172, 172, 172, 172, 173, 121, 173, 173,
572
573 174, 174, 174, 174, 174, 174, 174, 174, 175, 175,
574 175, 175, 175, 175, 175, 175, 176, 120, 176, 177,
575 119, 177, 177, 118, 177, 177, 178, 178, 178, 178,
576 178, 178, 178, 178, 179, 179, 179, 179, 179, 179,
577 179, 179, 116, 115, 113, 112, 111, 110, 109, 108,
578 107, 106, 105, 104, 103, 101, 100, 98, 97, 96,
579 95, 94, 92, 90, 88, 87, 86, 84, 83, 82,
580 81, 80, 79, 78, 77, 75, 73, 70, 69, 67,
581 64, 62, 61, 57, 51, 50, 49, 47, 46, 45,
582 41, 38, 22, 21, 19, 13, 9, 6, 4, 2,
583
584 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
585 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
586 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
587 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
588 165, 165, 165, 165, 165, 165, 165, 165
589 } ;
590
591static yy_state_type yy_last_accepting_state;
592static char *yy_last_accepting_cpos;
593
594extern int yy_flex_debug;
595int yy_flex_debug = 0;
596
597/* The intent behind this definition is that it'll catch
598 * any uses of REJECT which flex missed.
599 */
600#define REJECT reject_used_but_not_detected
601#define yymore() yymore_used_but_not_detected
602#define YY_MORE_ADJ 0
603#define YY_RESTORE_YY_MORE_OFFSET
604char *yytext;
605#line 1 "dtc-lexer.l"
606/*
607 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
608 *
609 *
610 * This program is free software; you can redistribute it and/or
611 * modify it under the terms of the GNU General Public License as
612 * published by the Free Software Foundation; either version 2 of the
613 * License, or (at your option) any later version.
614 *
615 * This program is distributed in the hope that it will be useful,
616 * but WITHOUT ANY WARRANTY; without even the implied warranty of
617 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
618 * General Public License for more details.
619 *
620 * You should have received a copy of the GNU General Public License
621 * along with this program; if not, write to the Free Software
622 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
623 * USA
624 */
625#define YY_NO_INPUT 1
626
627
628
629#line 37 "dtc-lexer.l"
630#include "dtc.h"
631#include "srcpos.h"
632#include "dtc-parser.tab.h"
633
634YYLTYPE yylloc;
635extern bool treesource_error;
636
637/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
638#define YY_USER_ACTION \
639 { \
640 srcpos_update(&yylloc, yytext, yyleng); \
641 }
642
643/*#define LEXDEBUG 1*/
644
645#ifdef LEXDEBUG
646#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
647#else
648#define DPRINT(fmt, ...) do { } while (0)
649#endif
650
651static int dts_version = 1;
652
653#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
654 BEGIN(V1); \
655
656static void push_input_file(const char *filename);
657static bool pop_input_file(void);
658static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
659
660#line 661 "dtc-lexer.lex.c"
661
662#define INITIAL 0
663#define BYTESTRING 1
664#define PROPNODENAME 2
665#define V1 3
666
667#ifndef YY_NO_UNISTD_H
668/* Special case for "unistd.h", since it is non-ANSI. We include it way
669 * down here because we want the user's section 1 to have been scanned first.
670 * The user has a chance to override it with an option.
671 */
672#include <unistd.h>
673#endif
674
675#ifndef YY_EXTRA_TYPE
676#define YY_EXTRA_TYPE void *
677#endif
678
679static int yy_init_globals (void );
680
681/* Accessor methods to globals.
682 These are made visible to non-reentrant scanners for convenience. */
683
684int yylex_destroy (void );
685
686int yyget_debug (void );
687
688void yyset_debug (int debug_flag );
689
690YY_EXTRA_TYPE yyget_extra (void );
691
692void yyset_extra (YY_EXTRA_TYPE user_defined );
693
694FILE *yyget_in (void );
695
696void yyset_in (FILE * _in_str );
697
698FILE *yyget_out (void );
699
700void yyset_out (FILE * _out_str );
701
702 int yyget_leng (void );
703
704char *yyget_text (void );
705
706int yyget_lineno (void );
707
708void yyset_lineno (int _line_number );
709
710/* Macros after this point can all be overridden by user definitions in
711 * section 1.
712 */
713
714#ifndef YY_SKIP_YYWRAP
715#ifdef __cplusplus
716extern "C" int yywrap (void );
717#else
718extern int yywrap (void );
719#endif
720#endif
721
722#ifndef YY_NO_UNPUT
723
724#endif
725
726#ifndef yytext_ptr
727static void yy_flex_strncpy (char *,yyconst char *,int );
728#endif
729
730#ifdef YY_NEED_STRLEN
731static int yy_flex_strlen (yyconst char * );
732#endif
733
734#ifndef YY_NO_INPUT
735
736#ifdef __cplusplus
737static int yyinput (void );
738#else
739static int input (void );
740#endif
741
742#endif
743
744/* Amount of stuff to slurp up with each read. */
745#ifndef YY_READ_BUF_SIZE
746#ifdef __ia64__
747/* On IA-64, the buffer size is 16k, not 8k */
748#define YY_READ_BUF_SIZE 16384
749#else
750#define YY_READ_BUF_SIZE 8192
751#endif /* __ia64__ */
752#endif
753
754/* Copy whatever the last rule matched to the standard output. */
755#ifndef ECHO
756/* This used to be an fputs(), but since the string might contain NUL's,
757 * we now use fwrite().
758 */
759#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
760#endif
761
762/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
763 * is returned in "result".
764 */
765#ifndef YY_INPUT
766#define YY_INPUT(buf,result,max_size) \
767 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
768 { \
769 int c = '*'; \
770 size_t n; \
771 for ( n = 0; n < max_size && \
772 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
773 buf[n] = (char) c; \
774 if ( c == '\n' ) \
775 buf[n++] = (char) c; \
776 if ( c == EOF && ferror( yyin ) ) \
777 YY_FATAL_ERROR( "input in flex scanner failed" ); \
778 result = n; \
779 } \
780 else \
781 { \
782 errno=0; \
783 while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
784 { \
785 if( errno != EINTR) \
786 { \
787 YY_FATAL_ERROR( "input in flex scanner failed" ); \
788 break; \
789 } \
790 errno=0; \
791 clearerr(yyin); \
792 } \
793 }\
794\
795
796#endif
797
798/* No semi-colon after return; correct usage is to write "yyterminate();" -
799 * we don't want an extra ';' after the "return" because that will cause
800 * some compilers to complain about unreachable statements.
801 */
802#ifndef yyterminate
803#define yyterminate() return YY_NULL
804#endif
805
806/* Number of entries by which start-condition stack grows. */
807#ifndef YY_START_STACK_INCR
808#define YY_START_STACK_INCR 25
809#endif
810
811/* Report a fatal error. */
812#ifndef YY_FATAL_ERROR
813#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
814#endif
815
816/* end tables serialization structures and prototypes */
817
818/* Default declaration of generated scanner - a define so the user can
819 * easily add parameters.
820 */
821#ifndef YY_DECL
822#define YY_DECL_IS_OURS 1
823
824extern int yylex (void);
825
826#define YY_DECL int yylex (void)
827#endif /* !YY_DECL */
828
829/* Code executed at the beginning of each rule, after yytext and yyleng
830 * have been set up.
831 */
832#ifndef YY_USER_ACTION
833#define YY_USER_ACTION
834#endif
835
836/* Code executed at the end of each rule. */
837#ifndef YY_BREAK
838#define YY_BREAK /*LINTED*/break;
839#endif
840
841#define YY_RULE_SETUP \
842 if ( yyleng > 0 ) \
843 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
844 (yytext[yyleng - 1] == '\n'); \
845 YY_USER_ACTION
846
847/** The main scanner function which does all the work.
848 */
849YY_DECL
850{
851 yy_state_type yy_current_state;
852 char *yy_cp, *yy_bp;
853 int yy_act;
854
855 if ( !(yy_init) )
856 {
857 (yy_init) = 1;
858
859#ifdef YY_USER_INIT
860 YY_USER_INIT;
861#endif
862
863 if ( ! (yy_start) )
864 (yy_start) = 1; /* first start state */
865
866 if ( ! yyin )
867 yyin = stdin;
868
869 if ( ! yyout )
870 yyout = stdout;
871
872 if ( ! YY_CURRENT_BUFFER ) {
873 yyensure_buffer_stack ();
874 YY_CURRENT_BUFFER_LVALUE =
875 yy_create_buffer(yyin,YY_BUF_SIZE );
876 }
877
878 yy_load_buffer_state( );
879 }
880
881 {
882#line 69 "dtc-lexer.l"
883
884#line 885 "dtc-lexer.lex.c"
885
886 while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
887 {
888 yy_cp = (yy_c_buf_p);
889
890 /* Support of yytext. */
891 *yy_cp = (yy_hold_char);
892
893 /* yy_bp points to the position in yy_ch_buf of the start of
894 * the current run.
895 */
896 yy_bp = yy_cp;
897
898 yy_current_state = (yy_start);
899 yy_current_state += YY_AT_BOL();
900yy_match:
901 do
902 {
903 YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
904 if ( yy_accept[yy_current_state] )
905 {
906 (yy_last_accepting_state) = yy_current_state;
907 (yy_last_accepting_cpos) = yy_cp;
908 }
909 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
910 {
911 yy_current_state = (int) yy_def[yy_current_state];
912 if ( yy_current_state >= 166 )
913 yy_c = yy_meta[(unsigned int) yy_c];
914 }
915 yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
916 ++yy_cp;
917 }
918 while ( yy_current_state != 165 );
919 yy_cp = (yy_last_accepting_cpos);
920 yy_current_state = (yy_last_accepting_state);
921
922yy_find_action:
923 yy_act = yy_accept[yy_current_state];
924
925 YY_DO_BEFORE_ACTION;
926
927do_action: /* This label is used only to access EOF actions. */
928
929 switch ( yy_act )
930 { /* beginning of action switch */
931 case 0: /* must back up */
932 /* undo the effects of YY_DO_BEFORE_ACTION */
933 *yy_cp = (yy_hold_char);
934 yy_cp = (yy_last_accepting_cpos);
935 yy_current_state = (yy_last_accepting_state);
936 goto yy_find_action;
937
938case 1:
939/* rule 1 can match eol */
940YY_RULE_SETUP
941#line 70 "dtc-lexer.l"
942{
943 char *name = strchr(yytext, '\"') + 1;
944 yytext[yyleng-1] = '\0';
945 push_input_file(name);
946 }
947 YY_BREAK
948case 2:
949/* rule 2 can match eol */
950YY_RULE_SETUP
951#line 76 "dtc-lexer.l"
952{
953 char *line, *fnstart, *fnend;
954 struct data fn;
955 /* skip text before line # */
956 line = yytext;
957 while (!isdigit((unsigned char)*line))
958 line++;
959
960 /* regexp ensures that first and list "
961 * in the whole yytext are those at
962 * beginning and end of the filename string */
963 fnstart = memchr(yytext, '"', yyleng);
964 for (fnend = yytext + yyleng - 1;
965 *fnend != '"'; fnend--)
966 ;
967 assert(fnstart && fnend && (fnend > fnstart));
968
969 fn = data_copy_escape_string(fnstart + 1,
970 fnend - fnstart - 1);
971
972 /* Don't allow nuls in filenames */
973 if (memchr(fn.val, '\0', fn.len - 1))
974 lexical_error("nul in line number directive");
975
976 /* -1 since #line is the number of the next line */
977 srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
978 data_free(fn);
979 }
980 YY_BREAK
981case YY_STATE_EOF(INITIAL):
982case YY_STATE_EOF(BYTESTRING):
983case YY_STATE_EOF(PROPNODENAME):
984case YY_STATE_EOF(V1):
985#line 105 "dtc-lexer.l"
986{
987 if (!pop_input_file()) {
988 yyterminate();
989 }
990 }
991 YY_BREAK
992case 3:
993/* rule 3 can match eol */
994YY_RULE_SETUP
995#line 111 "dtc-lexer.l"
996{
997 DPRINT("String: %s\n", yytext);
998 yylval.data = data_copy_escape_string(yytext+1,
999 yyleng-2);
1000 return DT_STRING;
1001 }
1002 YY_BREAK
1003case 4:
1004YY_RULE_SETUP
1005#line 118 "dtc-lexer.l"
1006{
1007 DPRINT("Keyword: /dts-v1/\n");
1008 dts_version = 1;
1009 BEGIN_DEFAULT();
1010 return DT_V1;
1011 }
1012 YY_BREAK
1013case 5:
1014YY_RULE_SETUP
1015#line 125 "dtc-lexer.l"
1016{
1017 DPRINT("Keyword: /plugin/\n");
1018 return DT_PLUGIN;
1019 }
1020 YY_BREAK
1021case 6:
1022YY_RULE_SETUP
1023#line 130 "dtc-lexer.l"
1024{
1025 DPRINT("Keyword: /memreserve/\n");
1026 BEGIN_DEFAULT();
1027 return DT_MEMRESERVE;
1028 }
1029 YY_BREAK
1030case 7:
1031YY_RULE_SETUP
1032#line 136 "dtc-lexer.l"
1033{
1034 DPRINT("Keyword: /bits/\n");
1035 BEGIN_DEFAULT();
1036 return DT_BITS;
1037 }
1038 YY_BREAK
1039case 8:
1040YY_RULE_SETUP
1041#line 142 "dtc-lexer.l"
1042{
1043 DPRINT("Keyword: /delete-property/\n");
1044 DPRINT("<PROPNODENAME>\n");
1045 BEGIN(PROPNODENAME);
1046 return DT_DEL_PROP;
1047 }
1048 YY_BREAK
1049case 9:
1050YY_RULE_SETUP
1051#line 149 "dtc-lexer.l"
1052{
1053 DPRINT("Keyword: /delete-node/\n");
1054 DPRINT("<PROPNODENAME>\n");
1055 BEGIN(PROPNODENAME);
1056 return DT_DEL_NODE;
1057 }
1058 YY_BREAK
1059case 10:
1060YY_RULE_SETUP
1061#line 156 "dtc-lexer.l"
1062{
1063 DPRINT("Label: %s\n", yytext);
1064 yylval.labelref = xstrdup(yytext);
1065 yylval.labelref[yyleng-1] = '\0';
1066 return DT_LABEL;
1067 }
1068 YY_BREAK
1069case 11:
1070YY_RULE_SETUP
1071#line 163 "dtc-lexer.l"
1072{
1073 char *e;
1074 DPRINT("Integer Literal: '%s'\n", yytext);
1075
1076 errno = 0;
1077 yylval.integer = strtoull(yytext, &e, 0);
1078
1079 if (*e && e[strspn(e, "UL")]) {
1080 lexical_error("Bad integer literal '%s'",
1081 yytext);
1082 }
1083
1084 if (errno == ERANGE)
1085 lexical_error("Integer literal '%s' out of range",
1086 yytext);
1087 else
1088 /* ERANGE is the only strtoull error triggerable
1089 * by strings matching the pattern */
1090 assert(errno == 0);
1091 return DT_LITERAL;
1092 }
1093 YY_BREAK
1094case 12:
1095/* rule 12 can match eol */
1096YY_RULE_SETUP
1097#line 185 "dtc-lexer.l"
1098{
1099 struct data d;
1100 DPRINT("Character literal: %s\n", yytext);
1101
1102 d = data_copy_escape_string(yytext+1, yyleng-2);
1103 if (d.len == 1) {
1104 lexical_error("Empty character literal");
1105 yylval.integer = 0;
1106 } else {
1107 yylval.integer = (unsigned char)d.val[0];
1108
1109 if (d.len > 2)
1110 lexical_error("Character literal has %d"
1111 " characters instead of 1",
1112 d.len - 1);
1113 }
1114
1115 data_free(d);
1116 return DT_CHAR_LITERAL;
1117 }
1118 YY_BREAK
1119case 13:
1120YY_RULE_SETUP
1121#line 206 "dtc-lexer.l"
1122{ /* label reference */
1123 DPRINT("Ref: %s\n", yytext+1);
1124 yylval.labelref = xstrdup(yytext+1);
1125 return DT_REF;
1126 }
1127 YY_BREAK
1128case 14:
1129YY_RULE_SETUP
1130#line 212 "dtc-lexer.l"
1131{ /* new-style path reference */
1132 yytext[yyleng-1] = '\0';
1133 DPRINT("Ref: %s\n", yytext+2);
1134 yylval.labelref = xstrdup(yytext+2);
1135 return DT_REF;
1136 }
1137 YY_BREAK
1138case 15:
1139YY_RULE_SETUP
1140#line 219 "dtc-lexer.l"
1141{
1142 yylval.byte = strtol(yytext, NULL, 16);
1143 DPRINT("Byte: %02x\n", (int)yylval.byte);
1144 return DT_BYTE;
1145 }
1146 YY_BREAK
1147case 16:
1148YY_RULE_SETUP
1149#line 225 "dtc-lexer.l"
1150{
1151 DPRINT("/BYTESTRING\n");
1152 BEGIN_DEFAULT();
1153 return ']';
1154 }
1155 YY_BREAK
1156case 17:
1157YY_RULE_SETUP
1158#line 231 "dtc-lexer.l"
1159{
1160 DPRINT("PropNodeName: %s\n", yytext);
1161 yylval.propnodename = xstrdup((yytext[0] == '\\') ?
1162 yytext + 1 : yytext);
1163 BEGIN_DEFAULT();
1164 return DT_PROPNODENAME;
1165 }
1166 YY_BREAK
1167case 18:
1168YY_RULE_SETUP
1169#line 239 "dtc-lexer.l"
1170{
1171 DPRINT("Binary Include\n");
1172 return DT_INCBIN;
1173 }
1174 YY_BREAK
1175case 19:
1176/* rule 19 can match eol */
1177YY_RULE_SETUP
1178#line 244 "dtc-lexer.l"
1179/* eat whitespace */
1180 YY_BREAK
1181case 20:
1182/* rule 20 can match eol */
1183YY_RULE_SETUP
1184#line 245 "dtc-lexer.l"
1185/* eat C-style comments */
1186 YY_BREAK
1187case 21:
1188/* rule 21 can match eol */
1189YY_RULE_SETUP
1190#line 246 "dtc-lexer.l"
1191/* eat C++-style comments */
1192 YY_BREAK
1193case 22:
1194YY_RULE_SETUP
1195#line 248 "dtc-lexer.l"
1196{ return DT_LSHIFT; };
1197 YY_BREAK
1198case 23:
1199YY_RULE_SETUP
1200#line 249 "dtc-lexer.l"
1201{ return DT_RSHIFT; };
1202 YY_BREAK
1203case 24:
1204YY_RULE_SETUP
1205#line 250 "dtc-lexer.l"
1206{ return DT_LE; };
1207 YY_BREAK
1208case 25:
1209YY_RULE_SETUP
1210#line 251 "dtc-lexer.l"
1211{ return DT_GE; };
1212 YY_BREAK
1213case 26:
1214YY_RULE_SETUP
1215#line 252 "dtc-lexer.l"
1216{ return DT_EQ; };
1217 YY_BREAK
1218case 27:
1219YY_RULE_SETUP
1220#line 253 "dtc-lexer.l"
1221{ return DT_NE; };
1222 YY_BREAK
1223case 28:
1224YY_RULE_SETUP
1225#line 254 "dtc-lexer.l"
1226{ return DT_AND; };
1227 YY_BREAK
1228case 29:
1229YY_RULE_SETUP
1230#line 255 "dtc-lexer.l"
1231{ return DT_OR; };
1232 YY_BREAK
1233case 30:
1234YY_RULE_SETUP
1235#line 257 "dtc-lexer.l"
1236{
1237 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
1238 (unsigned)yytext[0]);
1239 if (yytext[0] == '[') {
1240 DPRINT("<BYTESTRING>\n");
1241 BEGIN(BYTESTRING);
1242 }
1243 if ((yytext[0] == '{')
1244 || (yytext[0] == ';')) {
1245 DPRINT("<PROPNODENAME>\n");
1246 BEGIN(PROPNODENAME);
1247 }
1248 return yytext[0];
1249 }
1250 YY_BREAK
1251case 31:
1252YY_RULE_SETUP
1253#line 272 "dtc-lexer.l"
1254ECHO;
1255 YY_BREAK
1256#line 1257 "dtc-lexer.lex.c"
1257
1258 case YY_END_OF_BUFFER:
1259 {
1260 /* Amount of text matched not including the EOB char. */
1261 int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
1262
1263 /* Undo the effects of YY_DO_BEFORE_ACTION. */
1264 *yy_cp = (yy_hold_char);
1265 YY_RESTORE_YY_MORE_OFFSET
1266
1267 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
1268 {
1269 /* We're scanning a new file or input source. It's
1270 * possible that this happened because the user
1271 * just pointed yyin at a new source and called
1272 * yylex(). If so, then we have to assure
1273 * consistency between YY_CURRENT_BUFFER and our
1274 * globals. Here is the right place to do so, because
1275 * this is the first action (other than possibly a
1276 * back-up) that will match for the new input source.
1277 */
1278 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1279 YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
1280 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
1281 }
1282
1283 /* Note that here we test for yy_c_buf_p "<=" to the position
1284 * of the first EOB in the buffer, since yy_c_buf_p will
1285 * already have been incremented past the NUL character
1286 * (since all states make transitions on EOB to the
1287 * end-of-buffer state). Contrast this with the test
1288 * in input().
1289 */
1290 if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1291 { /* This was really a NUL. */
1292 yy_state_type yy_next_state;
1293
1294 (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
1295
1296 yy_current_state = yy_get_previous_state( );
1297
1298 /* Okay, we're now positioned to make the NUL
1299 * transition. We couldn't have
1300 * yy_get_previous_state() go ahead and do it
1301 * for us because it doesn't know how to deal
1302 * with the possibility of jamming (and we don't
1303 * want to build jamming into it because then it
1304 * will run more slowly).
1305 */
1306
1307 yy_next_state = yy_try_NUL_trans( yy_current_state );
1308
1309 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1310
1311 if ( yy_next_state )
1312 {
1313 /* Consume the NUL. */
1314 yy_cp = ++(yy_c_buf_p);
1315 yy_current_state = yy_next_state;
1316 goto yy_match;
1317 }
1318
1319 else
1320 {
1321 yy_cp = (yy_last_accepting_cpos);
1322 yy_current_state = (yy_last_accepting_state);
1323 goto yy_find_action;
1324 }
1325 }
1326
1327 else switch ( yy_get_next_buffer( ) )
1328 {
1329 case EOB_ACT_END_OF_FILE:
1330 {
1331 (yy_did_buffer_switch_on_eof) = 0;
1332
1333 if ( yywrap( ) )
1334 {
1335 /* Note: because we've taken care in
1336 * yy_get_next_buffer() to have set up
1337 * yytext, we can now set up
1338 * yy_c_buf_p so that if some total
1339 * hoser (like flex itself) wants to
1340 * call the scanner after we return the
1341 * YY_NULL, it'll still work - another
1342 * YY_NULL will get returned.
1343 */
1344 (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
1345
1346 yy_act = YY_STATE_EOF(YY_START);
1347 goto do_action;
1348 }
1349
1350 else
1351 {
1352 if ( ! (yy_did_buffer_switch_on_eof) )
1353 YY_NEW_FILE;
1354 }
1355 break;
1356 }
1357
1358 case EOB_ACT_CONTINUE_SCAN:
1359 (yy_c_buf_p) =
1360 (yytext_ptr) + yy_amount_of_matched_text;
1361
1362 yy_current_state = yy_get_previous_state( );
1363
1364 yy_cp = (yy_c_buf_p);
1365 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1366 goto yy_match;
1367
1368 case EOB_ACT_LAST_MATCH:
1369 (yy_c_buf_p) =
1370 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
1371
1372 yy_current_state = yy_get_previous_state( );
1373
1374 yy_cp = (yy_c_buf_p);
1375 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1376 goto yy_find_action;
1377 }
1378 break;
1379 }
1380
1381 default:
1382 YY_FATAL_ERROR(
1383 "fatal flex scanner internal error--no action found" );
1384 } /* end of action switch */
1385 } /* end of scanning one token */
1386 } /* end of user's declarations */
1387} /* end of yylex */
1388
1389/* yy_get_next_buffer - try to read in a new buffer
1390 *
1391 * Returns a code representing an action:
1392 * EOB_ACT_LAST_MATCH -
1393 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
1394 * EOB_ACT_END_OF_FILE - end of file
1395 */
1396static int yy_get_next_buffer (void)
1397{
1398 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1399 char *source = (yytext_ptr);
1400 int number_to_move, i;
1401 int ret_val;
1402
1403 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
1404 YY_FATAL_ERROR(
1405 "fatal flex scanner internal error--end of buffer missed" );
1406
1407 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
1408 { /* Don't try to fill the buffer, so this is an EOF. */
1409 if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
1410 {
1411 /* We matched a single character, the EOB, so
1412 * treat this as a final EOF.
1413 */
1414 return EOB_ACT_END_OF_FILE;
1415 }
1416
1417 else
1418 {
1419 /* We matched some text prior to the EOB, first
1420 * process it.
1421 */
1422 return EOB_ACT_LAST_MATCH;
1423 }
1424 }
1425
1426 /* Try to read more data. */
1427
1428 /* First move last chars to start of buffer. */
1429 number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
1430
1431 for ( i = 0; i < number_to_move; ++i )
1432 *(dest++) = *(source++);
1433
1434 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1435 /* don't do the read, it's not guaranteed to return an EOF,
1436 * just force an EOF
1437 */
1438 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
1439
1440 else
1441 {
1442 int num_to_read =
1443 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1444
1445 while ( num_to_read <= 0 )
1446 { /* Not enough room in the buffer - grow it. */
1447
1448 /* just a shorter name for the current buffer */
1449 YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
1450
1451 int yy_c_buf_p_offset =
1452 (int) ((yy_c_buf_p) - b->yy_ch_buf);
1453
1454 if ( b->yy_is_our_buffer )
1455 {
1456 int new_size = b->yy_buf_size * 2;
1457
1458 if ( new_size <= 0 )
1459 b->yy_buf_size += b->yy_buf_size / 8;
1460 else
1461 b->yy_buf_size *= 2;
1462
1463 b->yy_ch_buf = (char *)
1464 /* Include room in for 2 EOB chars. */
1465 yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
1466 }
1467 else
1468 /* Can't grow it, we don't own it. */
1469 b->yy_ch_buf = NULL;
1470
1471 if ( ! b->yy_ch_buf )
1472 YY_FATAL_ERROR(
1473 "fatal error - scanner input buffer overflow" );
1474
1475 (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
1476
1477 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
1478 number_to_move - 1;
1479
1480 }
1481
1482 if ( num_to_read > YY_READ_BUF_SIZE )
1483 num_to_read = YY_READ_BUF_SIZE;
1484
1485 /* Read in more data. */
1486 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1487 (yy_n_chars), num_to_read );
1488
1489 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1490 }
1491
1492 if ( (yy_n_chars) == 0 )
1493 {
1494 if ( number_to_move == YY_MORE_ADJ )
1495 {
1496 ret_val = EOB_ACT_END_OF_FILE;
1497 yyrestart(yyin );
1498 }
1499
1500 else
1501 {
1502 ret_val = EOB_ACT_LAST_MATCH;
1503 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
1504 YY_BUFFER_EOF_PENDING;
1505 }
1506 }
1507
1508 else
1509 ret_val = EOB_ACT_CONTINUE_SCAN;
1510
1511 if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
1512 /* Extend the array by 50%, plus the number we really need. */
1513 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
1514 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
1515 if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1516 YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
1517 }
1518
1519 (yy_n_chars) += number_to_move;
1520 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1521 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
1522
1523 (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
1524
1525 return ret_val;
1526}
1527
1528/* yy_get_previous_state - get the state just before the EOB char was reached */
1529
1530 static yy_state_type yy_get_previous_state (void)
1531{
1532 yy_state_type yy_current_state;
1533 char *yy_cp;
1534
1535 yy_current_state = (yy_start);
1536 yy_current_state += YY_AT_BOL();
1537
1538 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1539 {
1540 YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1541 if ( yy_accept[yy_current_state] )
1542 {
1543 (yy_last_accepting_state) = yy_current_state;
1544 (yy_last_accepting_cpos) = yy_cp;
1545 }
1546 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1547 {
1548 yy_current_state = (int) yy_def[yy_current_state];
1549 if ( yy_current_state >= 166 )
1550 yy_c = yy_meta[(unsigned int) yy_c];
1551 }
1552 yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
1553 }
1554
1555 return yy_current_state;
1556}
1557
1558/* yy_try_NUL_trans - try to make a transition on the NUL character
1559 *
1560 * synopsis
1561 * next_state = yy_try_NUL_trans( current_state );
1562 */
1563 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
1564{
1565 int yy_is_jam;
1566 char *yy_cp = (yy_c_buf_p);
1567
1568 YY_CHAR yy_c = 1;
1569 if ( yy_accept[yy_current_state] )
1570 {
1571 (yy_last_accepting_state) = yy_current_state;
1572 (yy_last_accepting_cpos) = yy_cp;
1573 }
1574 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1575 {
1576 yy_current_state = (int) yy_def[yy_current_state];
1577 if ( yy_current_state >= 166 )
1578 yy_c = yy_meta[(unsigned int) yy_c];
1579 }
1580 yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
1581 yy_is_jam = (yy_current_state == 165);
1582
1583 return yy_is_jam ? 0 : yy_current_state;
1584}
1585
1586#ifndef YY_NO_UNPUT
1587
1588#endif
1589
1590#ifndef YY_NO_INPUT
1591#ifdef __cplusplus
1592 static int yyinput (void)
1593#else
1594 static int input (void)
1595#endif
1596
1597{
1598 int c;
1599
1600 *(yy_c_buf_p) = (yy_hold_char);
1601
1602 if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
1603 {
1604 /* yy_c_buf_p now points to the character we want to return.
1605 * If this occurs *before* the EOB characters, then it's a
1606 * valid NUL; if not, then we've hit the end of the buffer.
1607 */
1608 if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1609 /* This was really a NUL. */
1610 *(yy_c_buf_p) = '\0';
1611
1612 else
1613 { /* need more input */
1614 int offset = (yy_c_buf_p) - (yytext_ptr);
1615 ++(yy_c_buf_p);
1616
1617 switch ( yy_get_next_buffer( ) )
1618 {
1619 case EOB_ACT_LAST_MATCH:
1620 /* This happens because yy_g_n_b()
1621 * sees that we've accumulated a
1622 * token and flags that we need to
1623 * try matching the token before
1624 * proceeding. But for input(),
1625 * there's no matching to consider.
1626 * So convert the EOB_ACT_LAST_MATCH
1627 * to EOB_ACT_END_OF_FILE.
1628 */
1629
1630 /* Reset buffer status. */
1631 yyrestart(yyin );
1632
1633 /*FALLTHROUGH*/
1634
1635 case EOB_ACT_END_OF_FILE:
1636 {
1637 if ( yywrap( ) )
1638 return 0;
1639
1640 if ( ! (yy_did_buffer_switch_on_eof) )
1641 YY_NEW_FILE;
1642#ifdef __cplusplus
1643 return yyinput();
1644#else
1645 return input();
1646#endif
1647 }
1648
1649 case EOB_ACT_CONTINUE_SCAN:
1650 (yy_c_buf_p) = (yytext_ptr) + offset;
1651 break;
1652 }
1653 }
1654 }
1655
1656 c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
1657 *(yy_c_buf_p) = '\0'; /* preserve yytext */
1658 (yy_hold_char) = *++(yy_c_buf_p);
1659
1660 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
1661
1662 return c;
1663}
1664#endif /* ifndef YY_NO_INPUT */
1665
1666/** Immediately switch to a different input stream.
1667 * @param input_file A readable stream.
1668 *
1669 * @note This function does not reset the start condition to @c INITIAL .
1670 */
1671 void yyrestart (FILE * input_file )
1672{
1673
1674 if ( ! YY_CURRENT_BUFFER ){
1675 yyensure_buffer_stack ();
1676 YY_CURRENT_BUFFER_LVALUE =
1677 yy_create_buffer(yyin,YY_BUF_SIZE );
1678 }
1679
1680 yy_init_buffer(YY_CURRENT_BUFFER,input_file );
1681 yy_load_buffer_state( );
1682}
1683
1684/** Switch to a different input buffer.
1685 * @param new_buffer The new input buffer.
1686 *
1687 */
1688 void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
1689{
1690
1691 /* TODO. We should be able to replace this entire function body
1692 * with
1693 * yypop_buffer_state();
1694 * yypush_buffer_state(new_buffer);
1695 */
1696 yyensure_buffer_stack ();
1697 if ( YY_CURRENT_BUFFER == new_buffer )
1698 return;
1699
1700 if ( YY_CURRENT_BUFFER )
1701 {
1702 /* Flush out information for old buffer. */
1703 *(yy_c_buf_p) = (yy_hold_char);
1704 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1705 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1706 }
1707
1708 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1709 yy_load_buffer_state( );
1710
1711 /* We don't actually know whether we did this switch during
1712 * EOF (yywrap()) processing, but the only time this flag
1713 * is looked at is after yywrap() is called, so it's safe
1714 * to go ahead and always set it.
1715 */
1716 (yy_did_buffer_switch_on_eof) = 1;
1717}
1718
1719static void yy_load_buffer_state (void)
1720{
1721 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1722 (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
1723 yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
1724 (yy_hold_char) = *(yy_c_buf_p);
1725}
1726
1727/** Allocate and initialize an input buffer state.
1728 * @param file A readable stream.
1729 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1730 *
1731 * @return the allocated buffer state.
1732 */
1733 YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
1734{
1735 YY_BUFFER_STATE b;
1736
1737 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1738 if ( ! b )
1739 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1740
1741 b->yy_buf_size = (yy_size_t)size;
1742
1743 /* yy_ch_buf has to be 2 characters longer than the size given because
1744 * we need to put in 2 end-of-buffer characters.
1745 */
1746 b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
1747 if ( ! b->yy_ch_buf )
1748 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1749
1750 b->yy_is_our_buffer = 1;
1751
1752 yy_init_buffer(b,file );
1753
1754 return b;
1755}
1756
1757/** Destroy the buffer.
1758 * @param b a buffer created with yy_create_buffer()
1759 *
1760 */
1761 void yy_delete_buffer (YY_BUFFER_STATE b )
1762{
1763
1764 if ( ! b )
1765 return;
1766
1767 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
1768 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
1769
1770 if ( b->yy_is_our_buffer )
1771 yyfree((void *) b->yy_ch_buf );
1772
1773 yyfree((void *) b );
1774}
1775
1776/* Initializes or reinitializes a buffer.
1777 * This function is sometimes called more than once on the same buffer,
1778 * such as during a yyrestart() or at EOF.
1779 */
1780 static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
1781
1782{
1783 int oerrno = errno;
1784
1785 yy_flush_buffer(b );
1786
1787 b->yy_input_file = file;
1788 b->yy_fill_buffer = 1;
1789
1790 /* If b is the current buffer, then yy_init_buffer was _probably_
1791 * called from yyrestart() or through yy_get_next_buffer.
1792 * In that case, we don't want to reset the lineno or column.
1793 */
1794 if (b != YY_CURRENT_BUFFER){
1795 b->yy_bs_lineno = 1;
1796 b->yy_bs_column = 0;
1797 }
1798
1799 b->yy_is_interactive = 0;
1800
1801 errno = oerrno;
1802}
1803
1804/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1805 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1806 *
1807 */
1808 void yy_flush_buffer (YY_BUFFER_STATE b )
1809{
1810 if ( ! b )
1811 return;
1812
1813 b->yy_n_chars = 0;
1814
1815 /* We always need two end-of-buffer characters. The first causes
1816 * a transition to the end-of-buffer state. The second causes
1817 * a jam in that state.
1818 */
1819 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1820 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1821
1822 b->yy_buf_pos = &b->yy_ch_buf[0];
1823
1824 b->yy_at_bol = 1;
1825 b->yy_buffer_status = YY_BUFFER_NEW;
1826
1827 if ( b == YY_CURRENT_BUFFER )
1828 yy_load_buffer_state( );
1829}
1830
1831/** Pushes the new state onto the stack. The new state becomes
1832 * the current state. This function will allocate the stack
1833 * if necessary.
1834 * @param new_buffer The new state.
1835 *
1836 */
1837void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
1838{
1839 if (new_buffer == NULL)
1840 return;
1841
1842 yyensure_buffer_stack();
1843
1844 /* This block is copied from yy_switch_to_buffer. */
1845 if ( YY_CURRENT_BUFFER )
1846 {
1847 /* Flush out information for old buffer. */
1848 *(yy_c_buf_p) = (yy_hold_char);
1849 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1850 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1851 }
1852
1853 /* Only push if top exists. Otherwise, replace top. */
1854 if (YY_CURRENT_BUFFER)
1855 (yy_buffer_stack_top)++;
1856 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1857
1858 /* copied from yy_switch_to_buffer. */
1859 yy_load_buffer_state( );
1860 (yy_did_buffer_switch_on_eof) = 1;
1861}
1862
1863/** Removes and deletes the top of the stack, if present.
1864 * The next element becomes the new top.
1865 *
1866 */
1867void yypop_buffer_state (void)
1868{
1869 if (!YY_CURRENT_BUFFER)
1870 return;
1871
1872 yy_delete_buffer(YY_CURRENT_BUFFER );
1873 YY_CURRENT_BUFFER_LVALUE = NULL;
1874 if ((yy_buffer_stack_top) > 0)
1875 --(yy_buffer_stack_top);
1876
1877 if (YY_CURRENT_BUFFER) {
1878 yy_load_buffer_state( );
1879 (yy_did_buffer_switch_on_eof) = 1;
1880 }
1881}
1882
1883/* Allocates the stack if it does not exist.
1884 * Guarantees space for at least one push.
1885 */
1886static void yyensure_buffer_stack (void)
1887{
1888 int num_to_alloc;
1889
1890 if (!(yy_buffer_stack)) {
1891
1892 /* First allocation is just for 2 elements, since we don't know if this
1893 * scanner will even need a stack. We use 2 instead of 1 to avoid an
1894 * immediate realloc on the next call.
1895 */
1896 num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
1897 (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
1898 (num_to_alloc * sizeof(struct yy_buffer_state*)
1899 );
1900 if ( ! (yy_buffer_stack) )
1901 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1902
1903 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1904
1905 (yy_buffer_stack_max) = num_to_alloc;
1906 (yy_buffer_stack_top) = 0;
1907 return;
1908 }
1909
1910 if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
1911
1912 /* Increase the buffer to prepare for a possible push. */
1913 yy_size_t grow_size = 8 /* arbitrary grow size */;
1914
1915 num_to_alloc = (yy_buffer_stack_max) + grow_size;
1916 (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
1917 ((yy_buffer_stack),
1918 num_to_alloc * sizeof(struct yy_buffer_state*)
1919 );
1920 if ( ! (yy_buffer_stack) )
1921 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1922
1923 /* zero only the new slots.*/
1924 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
1925 (yy_buffer_stack_max) = num_to_alloc;
1926 }
1927}
1928
1929/** Setup the input buffer state to scan directly from a user-specified character buffer.
1930 * @param base the character buffer
1931 * @param size the size in bytes of the character buffer
1932 *
1933 * @return the newly allocated buffer state object.
1934 */
1935YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
1936{
1937 YY_BUFFER_STATE b;
1938
1939 if ( size < 2 ||
1940 base[size-2] != YY_END_OF_BUFFER_CHAR ||
1941 base[size-1] != YY_END_OF_BUFFER_CHAR )
1942 /* They forgot to leave room for the EOB's. */
1943 return NULL;
1944
1945 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1946 if ( ! b )
1947 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
1948
1949 b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
1950 b->yy_buf_pos = b->yy_ch_buf = base;
1951 b->yy_is_our_buffer = 0;
1952 b->yy_input_file = NULL;
1953 b->yy_n_chars = b->yy_buf_size;
1954 b->yy_is_interactive = 0;
1955 b->yy_at_bol = 1;
1956 b->yy_fill_buffer = 0;
1957 b->yy_buffer_status = YY_BUFFER_NEW;
1958
1959 yy_switch_to_buffer(b );
1960
1961 return b;
1962}
1963
1964/** Setup the input buffer state to scan a string. The next call to yylex() will
1965 * scan from a @e copy of @a str.
1966 * @param yystr a NUL-terminated string to scan
1967 *
1968 * @return the newly allocated buffer state object.
1969 * @note If you want to scan bytes that may contain NUL values, then use
1970 * yy_scan_bytes() instead.
1971 */
1972YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1973{
1974
1975 return yy_scan_bytes(yystr,(int) strlen(yystr) );
1976}
1977
1978/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1979 * scan from a @e copy of @a bytes.
1980 * @param yybytes the byte buffer to scan
1981 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
1982 *
1983 * @return the newly allocated buffer state object.
1984 */
1985YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
1986{
1987 YY_BUFFER_STATE b;
1988 char *buf;
1989 yy_size_t n;
1990 int i;
1991
1992 /* Get memory for full buffer, including space for trailing EOB's. */
1993 n = (yy_size_t) (_yybytes_len + 2);
1994 buf = (char *) yyalloc(n );
1995 if ( ! buf )
1996 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
1997
1998 for ( i = 0; i < _yybytes_len; ++i )
1999 buf[i] = yybytes[i];
2000
2001 buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
2002
2003 b = yy_scan_buffer(buf,n );
2004 if ( ! b )
2005 YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
2006
2007 /* It's okay to grow etc. this buffer, and we should throw it
2008 * away when we're done.
2009 */
2010 b->yy_is_our_buffer = 1;
2011
2012 return b;
2013}
2014
2015#ifndef YY_EXIT_FAILURE
2016#define YY_EXIT_FAILURE 2
2017#endif
2018
2019static void yynoreturn yy_fatal_error (yyconst char* msg )
2020{
2021 (void) fprintf( stderr, "%s\n", msg );
2022 exit( YY_EXIT_FAILURE );
2023}
2024
2025/* Redefine yyless() so it works in section 3 code. */
2026
2027#undef yyless
2028#define yyless(n) \
2029 do \
2030 { \
2031 /* Undo effects of setting up yytext. */ \
2032 int yyless_macro_arg = (n); \
2033 YY_LESS_LINENO(yyless_macro_arg);\
2034 yytext[yyleng] = (yy_hold_char); \
2035 (yy_c_buf_p) = yytext + yyless_macro_arg; \
2036 (yy_hold_char) = *(yy_c_buf_p); \
2037 *(yy_c_buf_p) = '\0'; \
2038 yyleng = yyless_macro_arg; \
2039 } \
2040 while ( 0 )
2041
2042/* Accessor methods (get/set functions) to struct members. */
2043
2044/** Get the current line number.
2045 *
2046 */
2047int yyget_lineno (void)
2048{
2049
2050 return yylineno;
2051}
2052
2053/** Get the input stream.
2054 *
2055 */
2056FILE *yyget_in (void)
2057{
2058 return yyin;
2059}
2060
2061/** Get the output stream.
2062 *
2063 */
2064FILE *yyget_out (void)
2065{
2066 return yyout;
2067}
2068
2069/** Get the length of the current token.
2070 *
2071 */
2072int yyget_leng (void)
2073{
2074 return yyleng;
2075}
2076
2077/** Get the current token.
2078 *
2079 */
2080
2081char *yyget_text (void)
2082{
2083 return yytext;
2084}
2085
2086/** Set the current line number.
2087 * @param _line_number line number
2088 *
2089 */
2090void yyset_lineno (int _line_number )
2091{
2092
2093 yylineno = _line_number;
2094}
2095
2096/** Set the input stream. This does not discard the current
2097 * input buffer.
2098 * @param _in_str A readable stream.
2099 *
2100 * @see yy_switch_to_buffer
2101 */
2102void yyset_in (FILE * _in_str )
2103{
2104 yyin = _in_str ;
2105}
2106
2107void yyset_out (FILE * _out_str )
2108{
2109 yyout = _out_str ;
2110}
2111
2112int yyget_debug (void)
2113{
2114 return yy_flex_debug;
2115}
2116
2117void yyset_debug (int _bdebug )
2118{
2119 yy_flex_debug = _bdebug ;
2120}
2121
2122static int yy_init_globals (void)
2123{
2124 /* Initialization is the same as for the non-reentrant scanner.
2125 * This function is called from yylex_destroy(), so don't allocate here.
2126 */
2127
2128 (yy_buffer_stack) = NULL;
2129 (yy_buffer_stack_top) = 0;
2130 (yy_buffer_stack_max) = 0;
2131 (yy_c_buf_p) = NULL;
2132 (yy_init) = 0;
2133 (yy_start) = 0;
2134
2135/* Defined in main.c */
2136#ifdef YY_STDINIT
2137 yyin = stdin;
2138 yyout = stdout;
2139#else
2140 yyin = NULL;
2141 yyout = NULL;
2142#endif
2143
2144 /* For future reference: Set errno on error, since we are called by
2145 * yylex_init()
2146 */
2147 return 0;
2148}
2149
2150/* yylex_destroy is for both reentrant and non-reentrant scanners. */
2151int yylex_destroy (void)
2152{
2153
2154 /* Pop the buffer stack, destroying each element. */
2155 while(YY_CURRENT_BUFFER){
2156 yy_delete_buffer(YY_CURRENT_BUFFER );
2157 YY_CURRENT_BUFFER_LVALUE = NULL;
2158 yypop_buffer_state();
2159 }
2160
2161 /* Destroy the stack itself. */
2162 yyfree((yy_buffer_stack) );
2163 (yy_buffer_stack) = NULL;
2164
2165 /* Reset the globals. This is important in a non-reentrant scanner so the next time
2166 * yylex() is called, initialization will occur. */
2167 yy_init_globals( );
2168
2169 return 0;
2170}
2171
2172/*
2173 * Internal utility routines.
2174 */
2175
2176#ifndef yytext_ptr
2177static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
2178{
2179
2180 int i;
2181 for ( i = 0; i < n; ++i )
2182 s1[i] = s2[i];
2183}
2184#endif
2185
2186#ifdef YY_NEED_STRLEN
2187static int yy_flex_strlen (yyconst char * s )
2188{
2189 int n;
2190 for ( n = 0; s[n]; ++n )
2191 ;
2192
2193 return n;
2194}
2195#endif
2196
2197void *yyalloc (yy_size_t size )
2198{
2199 return malloc(size);
2200}
2201
2202void *yyrealloc (void * ptr, yy_size_t size )
2203{
2204
2205 /* The cast to (char *) in the following accommodates both
2206 * implementations that use char* generic pointers, and those
2207 * that use void* generic pointers. It works with the latter
2208 * because both ANSI C and C++ allow castless assignment from
2209 * any pointer type to void*, and deal with argument conversions
2210 * as though doing an assignment.
2211 */
2212 return realloc(ptr, size);
2213}
2214
2215void yyfree (void * ptr )
2216{
2217 free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
2218}
2219
2220#define YYTABLES_NAME "yytables"
2221
2222#line 272 "dtc-lexer.l"
2223
2224
2225
2226static void push_input_file(const char *filename)
2227{
2228 assert(filename);
2229
2230 srcfile_push(filename);
2231
2232 yyin = current_srcfile->f;
2233
2234 yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
2235}
2236
2237
2238static bool pop_input_file(void)
2239{
2240 if (srcfile_pop() == 0)
2241 return false;
2242
2243 yypop_buffer_state();
2244 yyin = current_srcfile->f;
2245
2246 return true;
2247}
2248
2249static void lexical_error(const char *fmt, ...)
2250{
2251 va_list ap;
2252
2253 va_start(ap, fmt);
2254 srcpos_verror(&yylloc, "Lexical error", fmt, ap);
2255 va_end(ap);
2256
2257 treesource_error = true;
2258}
2259
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
deleted file mode 100644
index aea514fa6928..000000000000
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ /dev/null
@@ -1,2321 +0,0 @@
1/* A Bison parser, made by GNU Bison 3.0.4. */
2
3/* Bison implementation for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33/* C LALR(1) parser skeleton written by Richard Stallman, by
34 simplifying the original so-called "semantic" parser. */
35
36/* All symbols defined below should begin with yy or YY, to avoid
37 infringing on user name space. This should be done even for local
38 variables, as they might otherwise be expanded by user macros.
39 There are some unavoidable exceptions within include files to
40 define necessary library symbols; they are noted "INFRINGES ON
41 USER NAME SPACE" below. */
42
43/* Identify Bison output. */
44#define YYBISON 1
45
46/* Bison version. */
47#define YYBISON_VERSION "3.0.4"
48
49/* Skeleton name. */
50#define YYSKELETON_NAME "yacc.c"
51
52/* Pure parsers. */
53#define YYPURE 0
54
55/* Push parsers. */
56#define YYPUSH 0
57
58/* Pull parsers. */
59#define YYPULL 1
60
61
62
63
64/* Copy the first part of user declarations. */
65#line 20 "dtc-parser.y" /* yacc.c:339 */
66
67#include <stdio.h>
68#include <inttypes.h>
69
70#include "dtc.h"
71#include "srcpos.h"
72
73extern int yylex(void);
74extern void yyerror(char const *s);
75#define ERROR(loc, ...) \
76 do { \
77 srcpos_error((loc), "Error", __VA_ARGS__); \
78 treesource_error = true; \
79 } while (0)
80
81extern struct dt_info *parser_output;
82extern bool treesource_error;
83
84#line 85 "dtc-parser.tab.c" /* yacc.c:339 */
85
86# ifndef YY_NULLPTR
87# if defined __cplusplus && 201103L <= __cplusplus
88# define YY_NULLPTR nullptr
89# else
90# define YY_NULLPTR 0
91# endif
92# endif
93
94/* Enabling verbose error messages. */
95#ifdef YYERROR_VERBOSE
96# undef YYERROR_VERBOSE
97# define YYERROR_VERBOSE 1
98#else
99# define YYERROR_VERBOSE 0
100#endif
101
102/* In a future release of Bison, this section will be replaced
103 by #include "dtc-parser.tab.h". */
104#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
105# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
106/* Debug traces. */
107#ifndef YYDEBUG
108# define YYDEBUG 0
109#endif
110#if YYDEBUG
111extern int yydebug;
112#endif
113
114/* Token type. */
115#ifndef YYTOKENTYPE
116# define YYTOKENTYPE
117 enum yytokentype
118 {
119 DT_V1 = 258,
120 DT_PLUGIN = 259,
121 DT_MEMRESERVE = 260,
122 DT_LSHIFT = 261,
123 DT_RSHIFT = 262,
124 DT_LE = 263,
125 DT_GE = 264,
126 DT_EQ = 265,
127 DT_NE = 266,
128 DT_AND = 267,
129 DT_OR = 268,
130 DT_BITS = 269,
131 DT_DEL_PROP = 270,
132 DT_DEL_NODE = 271,
133 DT_PROPNODENAME = 272,
134 DT_LITERAL = 273,
135 DT_CHAR_LITERAL = 274,
136 DT_BYTE = 275,
137 DT_STRING = 276,
138 DT_LABEL = 277,
139 DT_REF = 278,
140 DT_INCBIN = 279
141 };
142#endif
143
144/* Value type. */
145#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
146
147union YYSTYPE
148{
149#line 39 "dtc-parser.y" /* yacc.c:355 */
150
151 char *propnodename;
152 char *labelref;
153 uint8_t byte;
154 struct data data;
155
156 struct {
157 struct data data;
158 int bits;
159 } array;
160
161 struct property *prop;
162 struct property *proplist;
163 struct node *node;
164 struct node *nodelist;
165 struct reserve_info *re;
166 uint64_t integer;
167 unsigned int flags;
168
169#line 170 "dtc-parser.tab.c" /* yacc.c:355 */
170};
171
172typedef union YYSTYPE YYSTYPE;
173# define YYSTYPE_IS_TRIVIAL 1
174# define YYSTYPE_IS_DECLARED 1
175#endif
176
177/* Location type. */
178#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
179typedef struct YYLTYPE YYLTYPE;
180struct YYLTYPE
181{
182 int first_line;
183 int first_column;
184 int last_line;
185 int last_column;
186};
187# define YYLTYPE_IS_DECLARED 1
188# define YYLTYPE_IS_TRIVIAL 1
189#endif
190
191
192extern YYSTYPE yylval;
193extern YYLTYPE yylloc;
194int yyparse (void);
195
196#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */
197
198/* Copy the second part of user declarations. */
199
200#line 201 "dtc-parser.tab.c" /* yacc.c:358 */
201
202#ifdef short
203# undef short
204#endif
205
206#ifdef YYTYPE_UINT8
207typedef YYTYPE_UINT8 yytype_uint8;
208#else
209typedef unsigned char yytype_uint8;
210#endif
211
212#ifdef YYTYPE_INT8
213typedef YYTYPE_INT8 yytype_int8;
214#else
215typedef signed char yytype_int8;
216#endif
217
218#ifdef YYTYPE_UINT16
219typedef YYTYPE_UINT16 yytype_uint16;
220#else
221typedef unsigned short int yytype_uint16;
222#endif
223
224#ifdef YYTYPE_INT16
225typedef YYTYPE_INT16 yytype_int16;
226#else
227typedef short int yytype_int16;
228#endif
229
230#ifndef YYSIZE_T
231# ifdef __SIZE_TYPE__
232# define YYSIZE_T __SIZE_TYPE__
233# elif defined size_t
234# define YYSIZE_T size_t
235# elif ! defined YYSIZE_T
236# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
237# define YYSIZE_T size_t
238# else
239# define YYSIZE_T unsigned int
240# endif
241#endif
242
243#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
244
245#ifndef YY_
246# if defined YYENABLE_NLS && YYENABLE_NLS
247# if ENABLE_NLS
248# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
249# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
250# endif
251# endif
252# ifndef YY_
253# define YY_(Msgid) Msgid
254# endif
255#endif
256
257#ifndef YY_ATTRIBUTE
258# if (defined __GNUC__ \
259 && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
260 || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
261# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
262# else
263# define YY_ATTRIBUTE(Spec) /* empty */
264# endif
265#endif
266
267#ifndef YY_ATTRIBUTE_PURE
268# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
269#endif
270
271#ifndef YY_ATTRIBUTE_UNUSED
272# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
273#endif
274
275#if !defined _Noreturn \
276 && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
277# if defined _MSC_VER && 1200 <= _MSC_VER
278# define _Noreturn __declspec (noreturn)
279# else
280# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
281# endif
282#endif
283
284/* Suppress unused-variable warnings by "using" E. */
285#if ! defined lint || defined __GNUC__
286# define YYUSE(E) ((void) (E))
287#else
288# define YYUSE(E) /* empty */
289#endif
290
291#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
292/* Suppress an incorrect diagnostic about yylval being uninitialized. */
293# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
294 _Pragma ("GCC diagnostic push") \
295 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
296 _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
297# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
298 _Pragma ("GCC diagnostic pop")
299#else
300# define YY_INITIAL_VALUE(Value) Value
301#endif
302#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
303# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
304# define YY_IGNORE_MAYBE_UNINITIALIZED_END
305#endif
306#ifndef YY_INITIAL_VALUE
307# define YY_INITIAL_VALUE(Value) /* Nothing. */
308#endif
309
310
311#if ! defined yyoverflow || YYERROR_VERBOSE
312
313/* The parser invokes alloca or malloc; define the necessary symbols. */
314
315# ifdef YYSTACK_USE_ALLOCA
316# if YYSTACK_USE_ALLOCA
317# ifdef __GNUC__
318# define YYSTACK_ALLOC __builtin_alloca
319# elif defined __BUILTIN_VA_ARG_INCR
320# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
321# elif defined _AIX
322# define YYSTACK_ALLOC __alloca
323# elif defined _MSC_VER
324# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
325# define alloca _alloca
326# else
327# define YYSTACK_ALLOC alloca
328# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
329# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
330 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
331# ifndef EXIT_SUCCESS
332# define EXIT_SUCCESS 0
333# endif
334# endif
335# endif
336# endif
337# endif
338
339# ifdef YYSTACK_ALLOC
340 /* Pacify GCC's 'empty if-body' warning. */
341# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
342# ifndef YYSTACK_ALLOC_MAXIMUM
343 /* The OS might guarantee only one guard page at the bottom of the stack,
344 and a page size can be as small as 4096 bytes. So we cannot safely
345 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
346 to allow for a few compiler-allocated temporary stack slots. */
347# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
348# endif
349# else
350# define YYSTACK_ALLOC YYMALLOC
351# define YYSTACK_FREE YYFREE
352# ifndef YYSTACK_ALLOC_MAXIMUM
353# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
354# endif
355# if (defined __cplusplus && ! defined EXIT_SUCCESS \
356 && ! ((defined YYMALLOC || defined malloc) \
357 && (defined YYFREE || defined free)))
358# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
359# ifndef EXIT_SUCCESS
360# define EXIT_SUCCESS 0
361# endif
362# endif
363# ifndef YYMALLOC
364# define YYMALLOC malloc
365# if ! defined malloc && ! defined EXIT_SUCCESS
366void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
367# endif
368# endif
369# ifndef YYFREE
370# define YYFREE free
371# if ! defined free && ! defined EXIT_SUCCESS
372void free (void *); /* INFRINGES ON USER NAME SPACE */
373# endif
374# endif
375# endif
376#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
377
378
379#if (! defined yyoverflow \
380 && (! defined __cplusplus \
381 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
382 && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
383
384/* A type that is properly aligned for any stack member. */
385union yyalloc
386{
387 yytype_int16 yyss_alloc;
388 YYSTYPE yyvs_alloc;
389 YYLTYPE yyls_alloc;
390};
391
392/* The size of the maximum gap between one aligned stack and the next. */
393# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
394
395/* The size of an array large to enough to hold all stacks, each with
396 N elements. */
397# define YYSTACK_BYTES(N) \
398 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
399 + 2 * YYSTACK_GAP_MAXIMUM)
400
401# define YYCOPY_NEEDED 1
402
403/* Relocate STACK from its old location to the new one. The
404 local variables YYSIZE and YYSTACKSIZE give the old and new number of
405 elements in the stack, and YYPTR gives the new location of the
406 stack. Advance YYPTR to a properly aligned location for the next
407 stack. */
408# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
409 do \
410 { \
411 YYSIZE_T yynewbytes; \
412 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
413 Stack = &yyptr->Stack_alloc; \
414 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
415 yyptr += yynewbytes / sizeof (*yyptr); \
416 } \
417 while (0)
418
419#endif
420
421#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
422/* Copy COUNT objects from SRC to DST. The source and destination do
423 not overlap. */
424# ifndef YYCOPY
425# if defined __GNUC__ && 1 < __GNUC__
426# define YYCOPY(Dst, Src, Count) \
427 __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
428# else
429# define YYCOPY(Dst, Src, Count) \
430 do \
431 { \
432 YYSIZE_T yyi; \
433 for (yyi = 0; yyi < (Count); yyi++) \
434 (Dst)[yyi] = (Src)[yyi]; \
435 } \
436 while (0)
437# endif
438# endif
439#endif /* !YYCOPY_NEEDED */
440
441/* YYFINAL -- State number of the termination state. */
442#define YYFINAL 6
443/* YYLAST -- Last index in YYTABLE. */
444#define YYLAST 138
445
446/* YYNTOKENS -- Number of terminals. */
447#define YYNTOKENS 48
448/* YYNNTS -- Number of nonterminals. */
449#define YYNNTS 30
450/* YYNRULES -- Number of rules. */
451#define YYNRULES 85
452/* YYNSTATES -- Number of states. */
453#define YYNSTATES 149
454
455/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
456 by yylex, with out-of-bounds checking. */
457#define YYUNDEFTOK 2
458#define YYMAXUTOK 279
459
460#define YYTRANSLATE(YYX) \
461 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
462
463/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
464 as returned by yylex, without out-of-bounds checking. */
465static const yytype_uint8 yytranslate[] =
466{
467 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
468 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
469 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
470 2, 2, 2, 47, 2, 2, 2, 45, 41, 2,
471 33, 35, 44, 42, 34, 43, 2, 26, 2, 2,
472 2, 2, 2, 2, 2, 2, 2, 2, 38, 25,
473 36, 29, 30, 37, 2, 2, 2, 2, 2, 2,
474 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
475 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
476 2, 31, 2, 32, 40, 2, 2, 2, 2, 2,
477 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
478 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
479 2, 2, 2, 27, 39, 28, 46, 2, 2, 2,
480 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
481 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
482 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
483 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
484 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
485 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
486 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
487 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
488 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
489 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
490 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
491 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
492 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
493 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
494 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
495};
496
497#if YYDEBUG
498 /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
499static const yytype_uint16 yyrline[] =
500{
501 0, 109, 109, 117, 121, 128, 129, 139, 142, 149,
502 153, 161, 165, 170, 181, 200, 213, 220, 228, 231,
503 238, 242, 246, 250, 258, 262, 266, 270, 274, 290,
504 300, 308, 311, 315, 322, 338, 343, 362, 376, 383,
505 384, 385, 392, 396, 397, 401, 402, 406, 407, 411,
506 412, 416, 417, 421, 422, 426, 427, 428, 432, 433,
507 434, 435, 436, 440, 441, 442, 446, 447, 448, 452,
508 453, 462, 471, 475, 476, 477, 478, 483, 486, 490,
509 498, 501, 505, 513, 517, 521
510};
511#endif
512
513#if YYDEBUG || YYERROR_VERBOSE || 0
514/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
515 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
516static const char *const yytname[] =
517{
518 "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE",
519 "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND",
520 "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME",
521 "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL",
522 "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
523 "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
524 "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
525 "header", "headers", "memreserves", "memreserve", "devicetree",
526 "nodedef", "proplist", "propdef", "propdata", "propdataprefix",
527 "arrayprefix", "integer_prim", "integer_expr", "integer_trinary",
528 "integer_or", "integer_and", "integer_bitor", "integer_bitxor",
529 "integer_bitand", "integer_eq", "integer_rela", "integer_shift",
530 "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes",
531 "subnode", YY_NULLPTR
532};
533#endif
534
535# ifdef YYPRINT
536/* YYTOKNUM[NUM] -- (External) token number corresponding to the
537 (internal) symbol number NUM (which must be that of a token). */
538static const yytype_uint16 yytoknum[] =
539{
540 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
541 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
542 275, 276, 277, 278, 279, 59, 47, 123, 125, 61,
543 62, 91, 93, 40, 44, 41, 60, 63, 58, 124,
544 94, 38, 43, 45, 42, 37, 126, 33
545};
546# endif
547
548#define YYPACT_NINF -44
549
550#define yypact_value_is_default(Yystate) \
551 (!!((Yystate) == (-44)))
552
553#define YYTABLE_NINF -1
554
555#define yytable_value_is_error(Yytable_value) \
556 0
557
558 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
559 STATE-NUM. */
560static const yytype_int8 yypact[] =
561{
562 14, 27, 61, 14, 8, 18, -44, -44, 37, 8,
563 40, 8, 64, -44, -44, -12, 37, -44, 50, 52,
564 -44, -44, -12, -12, -12, -44, 51, -44, -4, 78,
565 53, 54, 55, 17, 2, 30, 38, -3, -44, 66,
566 -44, -44, 70, 72, 50, 50, -44, -44, -44, -44,
567 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
568 -12, -12, -12, -12, -12, -12, -12, -12, -12, -44,
569 3, 73, 50, -44, -44, 78, 59, 53, 54, 55,
570 17, 2, 2, 30, 30, 30, 30, 38, 38, -3,
571 -3, -44, -44, -44, 82, 83, 44, 3, -44, 74,
572 3, -44, -44, -12, 76, 79, -44, -44, -44, -44,
573 -44, 80, -44, -44, -44, -44, -44, -10, 36, -44,
574 -44, -44, -44, 85, -44, -44, -44, 75, -44, -44,
575 21, 71, 88, -6, -44, -44, -44, -44, -44, 11,
576 -44, -44, -44, 37, -44, 77, 37, 81, -44
577};
578
579 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
580 Performed when YYTABLE does not specify something else to do. Zero
581 means the default is an error. */
582static const yytype_uint8 yydefact[] =
583{
584 0, 0, 0, 5, 7, 3, 1, 6, 0, 0,
585 16, 7, 0, 39, 40, 0, 0, 10, 0, 2,
586 8, 4, 0, 0, 0, 73, 0, 42, 43, 45,
587 47, 49, 51, 53, 55, 58, 65, 68, 72, 0,
588 18, 11, 0, 0, 0, 0, 74, 75, 76, 41,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
591 80, 0, 0, 14, 12, 46, 0, 48, 50, 52,
592 54, 56, 57, 61, 62, 60, 59, 63, 64, 66,
593 67, 70, 69, 71, 0, 0, 0, 0, 19, 0,
594 80, 15, 13, 0, 0, 0, 21, 31, 83, 23,
595 85, 0, 82, 81, 44, 22, 84, 0, 0, 17,
596 30, 20, 32, 0, 24, 33, 27, 0, 77, 35,
597 0, 0, 0, 0, 38, 37, 25, 36, 34, 0,
598 78, 79, 26, 0, 29, 0, 0, 0, 28
599};
600
601 /* YYPGOTO[NTERM-NUM]. */
602static const yytype_int8 yypgoto[] =
603{
604 -44, -44, -44, 103, 99, 104, -44, -43, -44, -21,
605 -44, -44, -44, -8, 63, 9, -44, 65, 67, 68,
606 69, 62, 26, 4, 22, 23, -19, -44, 20, 28
607};
608
609 /* YYDEFGOTO[NTERM-NUM]. */
610static const yytype_int16 yydefgoto[] =
611{
612 -1, 2, 3, 4, 10, 11, 19, 41, 70, 98,
613 117, 118, 130, 25, 26, 27, 28, 29, 30, 31,
614 32, 33, 34, 35, 36, 37, 38, 133, 99, 100
615};
616
617 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
618 positive, shift that token. If negative, reduce the rule whose
619 number is the opposite. If YYTABLE_NINF, syntax error. */
620static const yytype_uint8 yytable[] =
621{
622 16, 73, 74, 46, 47, 48, 13, 14, 39, 50,
623 58, 59, 120, 8, 140, 121, 141, 1, 94, 95,
624 96, 15, 12, 66, 122, 97, 142, 56, 57, 102,
625 9, 22, 60, 51, 23, 24, 62, 63, 61, 13,
626 14, 67, 68, 134, 135, 143, 144, 91, 92, 93,
627 123, 136, 5, 108, 15, 13, 14, 124, 125, 126,
628 127, 6, 83, 84, 85, 86, 18, 128, 42, 106,
629 15, 40, 129, 107, 43, 44, 109, 40, 45, 112,
630 64, 65, 81, 82, 87, 88, 49, 89, 90, 21,
631 52, 69, 53, 71, 54, 72, 55, 103, 101, 104,
632 105, 115, 111, 131, 116, 119, 7, 138, 132, 139,
633 20, 146, 114, 17, 76, 75, 148, 80, 0, 77,
634 113, 78, 137, 79, 0, 110, 0, 0, 0, 0,
635 0, 0, 0, 0, 0, 145, 0, 0, 147
636};
637
638static const yytype_int16 yycheck[] =
639{
640 8, 44, 45, 22, 23, 24, 18, 19, 16, 13,
641 8, 9, 22, 5, 20, 25, 22, 3, 15, 16,
642 17, 33, 4, 26, 34, 22, 32, 10, 11, 72,
643 22, 43, 30, 37, 46, 47, 6, 7, 36, 18,
644 19, 44, 45, 22, 23, 34, 35, 66, 67, 68,
645 14, 30, 25, 96, 33, 18, 19, 21, 22, 23,
646 24, 0, 58, 59, 60, 61, 26, 31, 16, 25,
647 33, 27, 36, 29, 22, 23, 97, 27, 26, 100,
648 42, 43, 56, 57, 62, 63, 35, 64, 65, 25,
649 12, 25, 39, 23, 40, 23, 41, 38, 25, 17,
650 17, 25, 28, 18, 25, 25, 3, 36, 33, 21,
651 11, 34, 103, 9, 51, 50, 35, 55, -1, 52,
652 100, 53, 130, 54, -1, 97, -1, -1, -1, -1,
653 -1, -1, -1, -1, -1, 143, -1, -1, 146
654};
655
656 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
657 symbol of state STATE-NUM. */
658static const yytype_uint8 yystos[] =
659{
660 0, 3, 49, 50, 51, 25, 0, 51, 5, 22,
661 52, 53, 4, 18, 19, 33, 61, 53, 26, 54,
662 52, 25, 43, 46, 47, 61, 62, 63, 64, 65,
663 66, 67, 68, 69, 70, 71, 72, 73, 74, 61,
664 27, 55, 16, 22, 23, 26, 74, 74, 74, 35,
665 13, 37, 12, 39, 40, 41, 10, 11, 8, 9,
666 30, 36, 6, 7, 42, 43, 26, 44, 45, 25,
667 56, 23, 23, 55, 55, 65, 62, 66, 67, 68,
668 69, 70, 70, 71, 71, 71, 71, 72, 72, 73,
669 73, 74, 74, 74, 15, 16, 17, 22, 57, 76,
670 77, 25, 55, 38, 17, 17, 25, 29, 55, 57,
671 77, 28, 57, 76, 63, 25, 25, 58, 59, 25,
672 22, 25, 34, 14, 21, 22, 23, 24, 31, 36,
673 60, 18, 33, 75, 22, 23, 30, 61, 36, 21,
674 20, 22, 32, 34, 35, 61, 34, 61, 35
675};
676
677 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
678static const yytype_uint8 yyr1[] =
679{
680 0, 48, 49, 50, 50, 51, 51, 52, 52, 53,
681 53, 54, 54, 54, 54, 54, 54, 55, 56, 56,
682 57, 57, 57, 57, 58, 58, 58, 58, 58, 58,
683 58, 59, 59, 59, 60, 60, 60, 60, 60, 61,
684 61, 61, 62, 63, 63, 64, 64, 65, 65, 66,
685 66, 67, 67, 68, 68, 69, 69, 69, 70, 70,
686 70, 70, 70, 71, 71, 71, 72, 72, 72, 73,
687 73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
688 76, 76, 76, 77, 77, 77
689};
690
691 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
692static const yytype_uint8 yyr2[] =
693{
694 0, 2, 3, 2, 4, 1, 2, 0, 2, 4,
695 2, 2, 3, 4, 3, 4, 0, 5, 0, 2,
696 4, 2, 3, 2, 2, 3, 4, 2, 9, 5,
697 2, 0, 2, 2, 3, 1, 2, 2, 2, 1,
698 1, 3, 1, 1, 5, 1, 3, 1, 3, 1,
699 3, 1, 3, 1, 3, 1, 3, 3, 1, 3,
700 3, 3, 3, 3, 3, 1, 3, 3, 1, 3,
701 3, 3, 1, 1, 2, 2, 2, 0, 2, 2,
702 0, 2, 2, 2, 3, 2
703};
704
705
706#define yyerrok (yyerrstatus = 0)
707#define yyclearin (yychar = YYEMPTY)
708#define YYEMPTY (-2)
709#define YYEOF 0
710
711#define YYACCEPT goto yyacceptlab
712#define YYABORT goto yyabortlab
713#define YYERROR goto yyerrorlab
714
715
716#define YYRECOVERING() (!!yyerrstatus)
717
718#define YYBACKUP(Token, Value) \
719do \
720 if (yychar == YYEMPTY) \
721 { \
722 yychar = (Token); \
723 yylval = (Value); \
724 YYPOPSTACK (yylen); \
725 yystate = *yyssp; \
726 goto yybackup; \
727 } \
728 else \
729 { \
730 yyerror (YY_("syntax error: cannot back up")); \
731 YYERROR; \
732 } \
733while (0)
734
735/* Error token number */
736#define YYTERROR 1
737#define YYERRCODE 256
738
739
740/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
741 If N is 0, then set CURRENT to the empty location which ends
742 the previous symbol: RHS[0] (always defined). */
743
744#ifndef YYLLOC_DEFAULT
745# define YYLLOC_DEFAULT(Current, Rhs, N) \
746 do \
747 if (N) \
748 { \
749 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
750 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
751 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
752 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
753 } \
754 else \
755 { \
756 (Current).first_line = (Current).last_line = \
757 YYRHSLOC (Rhs, 0).last_line; \
758 (Current).first_column = (Current).last_column = \
759 YYRHSLOC (Rhs, 0).last_column; \
760 } \
761 while (0)
762#endif
763
764#define YYRHSLOC(Rhs, K) ((Rhs)[K])
765
766
767/* Enable debugging if requested. */
768#if YYDEBUG
769
770# ifndef YYFPRINTF
771# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
772# define YYFPRINTF fprintf
773# endif
774
775# define YYDPRINTF(Args) \
776do { \
777 if (yydebug) \
778 YYFPRINTF Args; \
779} while (0)
780
781
782/* YY_LOCATION_PRINT -- Print the location on the stream.
783 This macro was not mandated originally: define only if we know
784 we won't break user code: when these are the locations we know. */
785
786#ifndef YY_LOCATION_PRINT
787# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
788
789/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
790
791YY_ATTRIBUTE_UNUSED
792static unsigned
793yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
794{
795 unsigned res = 0;
796 int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
797 if (0 <= yylocp->first_line)
798 {
799 res += YYFPRINTF (yyo, "%d", yylocp->first_line);
800 if (0 <= yylocp->first_column)
801 res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
802 }
803 if (0 <= yylocp->last_line)
804 {
805 if (yylocp->first_line < yylocp->last_line)
806 {
807 res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
808 if (0 <= end_col)
809 res += YYFPRINTF (yyo, ".%d", end_col);
810 }
811 else if (0 <= end_col && yylocp->first_column < end_col)
812 res += YYFPRINTF (yyo, "-%d", end_col);
813 }
814 return res;
815 }
816
817# define YY_LOCATION_PRINT(File, Loc) \
818 yy_location_print_ (File, &(Loc))
819
820# else
821# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
822# endif
823#endif
824
825
826# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
827do { \
828 if (yydebug) \
829 { \
830 YYFPRINTF (stderr, "%s ", Title); \
831 yy_symbol_print (stderr, \
832 Type, Value, Location); \
833 YYFPRINTF (stderr, "\n"); \
834 } \
835} while (0)
836
837
838/*----------------------------------------.
839| Print this symbol's value on YYOUTPUT. |
840`----------------------------------------*/
841
842static void
843yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
844{
845 FILE *yyo = yyoutput;
846 YYUSE (yyo);
847 YYUSE (yylocationp);
848 if (!yyvaluep)
849 return;
850# ifdef YYPRINT
851 if (yytype < YYNTOKENS)
852 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
853# endif
854 YYUSE (yytype);
855}
856
857
858/*--------------------------------.
859| Print this symbol on YYOUTPUT. |
860`--------------------------------*/
861
862static void
863yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
864{
865 YYFPRINTF (yyoutput, "%s %s (",
866 yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
867
868 YY_LOCATION_PRINT (yyoutput, *yylocationp);
869 YYFPRINTF (yyoutput, ": ");
870 yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
871 YYFPRINTF (yyoutput, ")");
872}
873
874/*------------------------------------------------------------------.
875| yy_stack_print -- Print the state stack from its BOTTOM up to its |
876| TOP (included). |
877`------------------------------------------------------------------*/
878
879static void
880yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
881{
882 YYFPRINTF (stderr, "Stack now");
883 for (; yybottom <= yytop; yybottom++)
884 {
885 int yybot = *yybottom;
886 YYFPRINTF (stderr, " %d", yybot);
887 }
888 YYFPRINTF (stderr, "\n");
889}
890
891# define YY_STACK_PRINT(Bottom, Top) \
892do { \
893 if (yydebug) \
894 yy_stack_print ((Bottom), (Top)); \
895} while (0)
896
897
898/*------------------------------------------------.
899| Report that the YYRULE is going to be reduced. |
900`------------------------------------------------*/
901
902static void
903yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
904{
905 unsigned long int yylno = yyrline[yyrule];
906 int yynrhs = yyr2[yyrule];
907 int yyi;
908 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
909 yyrule - 1, yylno);
910 /* The symbols being reduced. */
911 for (yyi = 0; yyi < yynrhs; yyi++)
912 {
913 YYFPRINTF (stderr, " $%d = ", yyi + 1);
914 yy_symbol_print (stderr,
915 yystos[yyssp[yyi + 1 - yynrhs]],
916 &(yyvsp[(yyi + 1) - (yynrhs)])
917 , &(yylsp[(yyi + 1) - (yynrhs)]) );
918 YYFPRINTF (stderr, "\n");
919 }
920}
921
922# define YY_REDUCE_PRINT(Rule) \
923do { \
924 if (yydebug) \
925 yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \
926} while (0)
927
928/* Nonzero means print parse trace. It is left uninitialized so that
929 multiple parsers can coexist. */
930int yydebug;
931#else /* !YYDEBUG */
932# define YYDPRINTF(Args)
933# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
934# define YY_STACK_PRINT(Bottom, Top)
935# define YY_REDUCE_PRINT(Rule)
936#endif /* !YYDEBUG */
937
938
939/* YYINITDEPTH -- initial size of the parser's stacks. */
940#ifndef YYINITDEPTH
941# define YYINITDEPTH 200
942#endif
943
944/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
945 if the built-in stack extension method is used).
946
947 Do not make this value too large; the results are undefined if
948 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
949 evaluated with infinite-precision integer arithmetic. */
950
951#ifndef YYMAXDEPTH
952# define YYMAXDEPTH 10000
953#endif
954
955
956#if YYERROR_VERBOSE
957
958# ifndef yystrlen
959# if defined __GLIBC__ && defined _STRING_H
960# define yystrlen strlen
961# else
962/* Return the length of YYSTR. */
963static YYSIZE_T
964yystrlen (const char *yystr)
965{
966 YYSIZE_T yylen;
967 for (yylen = 0; yystr[yylen]; yylen++)
968 continue;
969 return yylen;
970}
971# endif
972# endif
973
974# ifndef yystpcpy
975# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
976# define yystpcpy stpcpy
977# else
978/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
979 YYDEST. */
980static char *
981yystpcpy (char *yydest, const char *yysrc)
982{
983 char *yyd = yydest;
984 const char *yys = yysrc;
985
986 while ((*yyd++ = *yys++) != '\0')
987 continue;
988
989 return yyd - 1;
990}
991# endif
992# endif
993
994# ifndef yytnamerr
995/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
996 quotes and backslashes, so that it's suitable for yyerror. The
997 heuristic is that double-quoting is unnecessary unless the string
998 contains an apostrophe, a comma, or backslash (other than
999 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1000 null, do not copy; instead, return the length of what the result
1001 would have been. */
1002static YYSIZE_T
1003yytnamerr (char *yyres, const char *yystr)
1004{
1005 if (*yystr == '"')
1006 {
1007 YYSIZE_T yyn = 0;
1008 char const *yyp = yystr;
1009
1010 for (;;)
1011 switch (*++yyp)
1012 {
1013 case '\'':
1014 case ',':
1015 goto do_not_strip_quotes;
1016
1017 case '\\':
1018 if (*++yyp != '\\')
1019 goto do_not_strip_quotes;
1020 /* Fall through. */
1021 default:
1022 if (yyres)
1023 yyres[yyn] = *yyp;
1024 yyn++;
1025 break;
1026
1027 case '"':
1028 if (yyres)
1029 yyres[yyn] = '\0';
1030 return yyn;
1031 }
1032 do_not_strip_quotes: ;
1033 }
1034
1035 if (! yyres)
1036 return yystrlen (yystr);
1037
1038 return yystpcpy (yyres, yystr) - yyres;
1039}
1040# endif
1041
1042/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1043 about the unexpected token YYTOKEN for the state stack whose top is
1044 YYSSP.
1045
1046 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
1047 not large enough to hold the message. In that case, also set
1048 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
1049 required number of bytes is too large to store. */
1050static int
1051yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1052 yytype_int16 *yyssp, int yytoken)
1053{
1054 YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
1055 YYSIZE_T yysize = yysize0;
1056 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1057 /* Internationalized format string. */
1058 const char *yyformat = YY_NULLPTR;
1059 /* Arguments of yyformat. */
1060 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1061 /* Number of reported tokens (one for the "unexpected", one per
1062 "expected"). */
1063 int yycount = 0;
1064
1065 /* There are many possibilities here to consider:
1066 - If this state is a consistent state with a default action, then
1067 the only way this function was invoked is if the default action
1068 is an error action. In that case, don't check for expected
1069 tokens because there are none.
1070 - The only way there can be no lookahead present (in yychar) is if
1071 this state is a consistent state with a default action. Thus,
1072 detecting the absence of a lookahead is sufficient to determine
1073 that there is no unexpected or expected token to report. In that
1074 case, just report a simple "syntax error".
1075 - Don't assume there isn't a lookahead just because this state is a
1076 consistent state with a default action. There might have been a
1077 previous inconsistent state, consistent state with a non-default
1078 action, or user semantic action that manipulated yychar.
1079 - Of course, the expected token list depends on states to have
1080 correct lookahead information, and it depends on the parser not
1081 to perform extra reductions after fetching a lookahead from the
1082 scanner and before detecting a syntax error. Thus, state merging
1083 (from LALR or IELR) and default reductions corrupt the expected
1084 token list. However, the list is correct for canonical LR with
1085 one exception: it will still contain any token that will not be
1086 accepted due to an error action in a later state.
1087 */
1088 if (yytoken != YYEMPTY)
1089 {
1090 int yyn = yypact[*yyssp];
1091 yyarg[yycount++] = yytname[yytoken];
1092 if (!yypact_value_is_default (yyn))
1093 {
1094 /* Start YYX at -YYN if negative to avoid negative indexes in
1095 YYCHECK. In other words, skip the first -YYN actions for
1096 this state because they are default actions. */
1097 int yyxbegin = yyn < 0 ? -yyn : 0;
1098 /* Stay within bounds of both yycheck and yytname. */
1099 int yychecklim = YYLAST - yyn + 1;
1100 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1101 int yyx;
1102
1103 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1104 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1105 && !yytable_value_is_error (yytable[yyx + yyn]))
1106 {
1107 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1108 {
1109 yycount = 1;
1110 yysize = yysize0;
1111 break;
1112 }
1113 yyarg[yycount++] = yytname[yyx];
1114 {
1115 YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
1116 if (! (yysize <= yysize1
1117 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1118 return 2;
1119 yysize = yysize1;
1120 }
1121 }
1122 }
1123 }
1124
1125 switch (yycount)
1126 {
1127# define YYCASE_(N, S) \
1128 case N: \
1129 yyformat = S; \
1130 break
1131 YYCASE_(0, YY_("syntax error"));
1132 YYCASE_(1, YY_("syntax error, unexpected %s"));
1133 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1134 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1135 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1136 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1137# undef YYCASE_
1138 }
1139
1140 {
1141 YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1142 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1143 return 2;
1144 yysize = yysize1;
1145 }
1146
1147 if (*yymsg_alloc < yysize)
1148 {
1149 *yymsg_alloc = 2 * yysize;
1150 if (! (yysize <= *yymsg_alloc
1151 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1152 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1153 return 1;
1154 }
1155
1156 /* Avoid sprintf, as that infringes on the user's name space.
1157 Don't have undefined behavior even if the translation
1158 produced a string with the wrong number of "%s"s. */
1159 {
1160 char *yyp = *yymsg;
1161 int yyi = 0;
1162 while ((*yyp = *yyformat) != '\0')
1163 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1164 {
1165 yyp += yytnamerr (yyp, yyarg[yyi++]);
1166 yyformat += 2;
1167 }
1168 else
1169 {
1170 yyp++;
1171 yyformat++;
1172 }
1173 }
1174 return 0;
1175}
1176#endif /* YYERROR_VERBOSE */
1177
1178/*-----------------------------------------------.
1179| Release the memory associated to this symbol. |
1180`-----------------------------------------------*/
1181
1182static void
1183yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
1184{
1185 YYUSE (yyvaluep);
1186 YYUSE (yylocationp);
1187 if (!yymsg)
1188 yymsg = "Deleting";
1189 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1190
1191 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1192 YYUSE (yytype);
1193 YY_IGNORE_MAYBE_UNINITIALIZED_END
1194}
1195
1196
1197
1198
1199/* The lookahead symbol. */
1200int yychar;
1201
1202/* The semantic value of the lookahead symbol. */
1203YYSTYPE yylval;
1204/* Location data for the lookahead symbol. */
1205YYLTYPE yylloc
1206# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
1207 = { 1, 1, 1, 1 }
1208# endif
1209;
1210/* Number of syntax errors so far. */
1211int yynerrs;
1212
1213
1214/*----------.
1215| yyparse. |
1216`----------*/
1217
1218int
1219yyparse (void)
1220{
1221 int yystate;
1222 /* Number of tokens to shift before error messages enabled. */
1223 int yyerrstatus;
1224
1225 /* The stacks and their tools:
1226 'yyss': related to states.
1227 'yyvs': related to semantic values.
1228 'yyls': related to locations.
1229
1230 Refer to the stacks through separate pointers, to allow yyoverflow
1231 to reallocate them elsewhere. */
1232
1233 /* The state stack. */
1234 yytype_int16 yyssa[YYINITDEPTH];
1235 yytype_int16 *yyss;
1236 yytype_int16 *yyssp;
1237
1238 /* The semantic value stack. */
1239 YYSTYPE yyvsa[YYINITDEPTH];
1240 YYSTYPE *yyvs;
1241 YYSTYPE *yyvsp;
1242
1243 /* The location stack. */
1244 YYLTYPE yylsa[YYINITDEPTH];
1245 YYLTYPE *yyls;
1246 YYLTYPE *yylsp;
1247
1248 /* The locations where the error started and ended. */
1249 YYLTYPE yyerror_range[3];
1250
1251 YYSIZE_T yystacksize;
1252
1253 int yyn;
1254 int yyresult;
1255 /* Lookahead token as an internal (translated) token number. */
1256 int yytoken = 0;
1257 /* The variables used to return semantic value and location from the
1258 action routines. */
1259 YYSTYPE yyval;
1260 YYLTYPE yyloc;
1261
1262#if YYERROR_VERBOSE
1263 /* Buffer for error messages, and its allocated size. */
1264 char yymsgbuf[128];
1265 char *yymsg = yymsgbuf;
1266 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1267#endif
1268
1269#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
1270
1271 /* The number of symbols on the RHS of the reduced rule.
1272 Keep to zero when no symbol should be popped. */
1273 int yylen = 0;
1274
1275 yyssp = yyss = yyssa;
1276 yyvsp = yyvs = yyvsa;
1277 yylsp = yyls = yylsa;
1278 yystacksize = YYINITDEPTH;
1279
1280 YYDPRINTF ((stderr, "Starting parse\n"));
1281
1282 yystate = 0;
1283 yyerrstatus = 0;
1284 yynerrs = 0;
1285 yychar = YYEMPTY; /* Cause a token to be read. */
1286 yylsp[0] = yylloc;
1287 goto yysetstate;
1288
1289/*------------------------------------------------------------.
1290| yynewstate -- Push a new state, which is found in yystate. |
1291`------------------------------------------------------------*/
1292 yynewstate:
1293 /* In all cases, when you get here, the value and location stacks
1294 have just been pushed. So pushing a state here evens the stacks. */
1295 yyssp++;
1296
1297 yysetstate:
1298 *yyssp = yystate;
1299
1300 if (yyss + yystacksize - 1 <= yyssp)
1301 {
1302 /* Get the current used size of the three stacks, in elements. */
1303 YYSIZE_T yysize = yyssp - yyss + 1;
1304
1305#ifdef yyoverflow
1306 {
1307 /* Give user a chance to reallocate the stack. Use copies of
1308 these so that the &'s don't force the real ones into
1309 memory. */
1310 YYSTYPE *yyvs1 = yyvs;
1311 yytype_int16 *yyss1 = yyss;
1312 YYLTYPE *yyls1 = yyls;
1313
1314 /* Each stack pointer address is followed by the size of the
1315 data in use in that stack, in bytes. This used to be a
1316 conditional around just the two extra args, but that might
1317 be undefined if yyoverflow is a macro. */
1318 yyoverflow (YY_("memory exhausted"),
1319 &yyss1, yysize * sizeof (*yyssp),
1320 &yyvs1, yysize * sizeof (*yyvsp),
1321 &yyls1, yysize * sizeof (*yylsp),
1322 &yystacksize);
1323
1324 yyls = yyls1;
1325 yyss = yyss1;
1326 yyvs = yyvs1;
1327 }
1328#else /* no yyoverflow */
1329# ifndef YYSTACK_RELOCATE
1330 goto yyexhaustedlab;
1331# else
1332 /* Extend the stack our own way. */
1333 if (YYMAXDEPTH <= yystacksize)
1334 goto yyexhaustedlab;
1335 yystacksize *= 2;
1336 if (YYMAXDEPTH < yystacksize)
1337 yystacksize = YYMAXDEPTH;
1338
1339 {
1340 yytype_int16 *yyss1 = yyss;
1341 union yyalloc *yyptr =
1342 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1343 if (! yyptr)
1344 goto yyexhaustedlab;
1345 YYSTACK_RELOCATE (yyss_alloc, yyss);
1346 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1347 YYSTACK_RELOCATE (yyls_alloc, yyls);
1348# undef YYSTACK_RELOCATE
1349 if (yyss1 != yyssa)
1350 YYSTACK_FREE (yyss1);
1351 }
1352# endif
1353#endif /* no yyoverflow */
1354
1355 yyssp = yyss + yysize - 1;
1356 yyvsp = yyvs + yysize - 1;
1357 yylsp = yyls + yysize - 1;
1358
1359 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1360 (unsigned long int) yystacksize));
1361
1362 if (yyss + yystacksize - 1 <= yyssp)
1363 YYABORT;
1364 }
1365
1366 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1367
1368 if (yystate == YYFINAL)
1369 YYACCEPT;
1370
1371 goto yybackup;
1372
1373/*-----------.
1374| yybackup. |
1375`-----------*/
1376yybackup:
1377
1378 /* Do appropriate processing given the current state. Read a
1379 lookahead token if we need one and don't already have one. */
1380
1381 /* First try to decide what to do without reference to lookahead token. */
1382 yyn = yypact[yystate];
1383 if (yypact_value_is_default (yyn))
1384 goto yydefault;
1385
1386 /* Not known => get a lookahead token if don't already have one. */
1387
1388 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1389 if (yychar == YYEMPTY)
1390 {
1391 YYDPRINTF ((stderr, "Reading a token: "));
1392 yychar = yylex ();
1393 }
1394
1395 if (yychar <= YYEOF)
1396 {
1397 yychar = yytoken = YYEOF;
1398 YYDPRINTF ((stderr, "Now at end of input.\n"));
1399 }
1400 else
1401 {
1402 yytoken = YYTRANSLATE (yychar);
1403 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1404 }
1405
1406 /* If the proper action on seeing token YYTOKEN is to reduce or to
1407 detect an error, take that action. */
1408 yyn += yytoken;
1409 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1410 goto yydefault;
1411 yyn = yytable[yyn];
1412 if (yyn <= 0)
1413 {
1414 if (yytable_value_is_error (yyn))
1415 goto yyerrlab;
1416 yyn = -yyn;
1417 goto yyreduce;
1418 }
1419
1420 /* Count tokens shifted since error; after three, turn off error
1421 status. */
1422 if (yyerrstatus)
1423 yyerrstatus--;
1424
1425 /* Shift the lookahead token. */
1426 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1427
1428 /* Discard the shifted token. */
1429 yychar = YYEMPTY;
1430
1431 yystate = yyn;
1432 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1433 *++yyvsp = yylval;
1434 YY_IGNORE_MAYBE_UNINITIALIZED_END
1435 *++yylsp = yylloc;
1436 goto yynewstate;
1437
1438
1439/*-----------------------------------------------------------.
1440| yydefault -- do the default action for the current state. |
1441`-----------------------------------------------------------*/
1442yydefault:
1443 yyn = yydefact[yystate];
1444 if (yyn == 0)
1445 goto yyerrlab;
1446 goto yyreduce;
1447
1448
1449/*-----------------------------.
1450| yyreduce -- Do a reduction. |
1451`-----------------------------*/
1452yyreduce:
1453 /* yyn is the number of a rule to reduce with. */
1454 yylen = yyr2[yyn];
1455
1456 /* If YYLEN is nonzero, implement the default value of the action:
1457 '$$ = $1'.
1458
1459 Otherwise, the following line sets YYVAL to garbage.
1460 This behavior is undocumented and Bison
1461 users should not rely upon it. Assigning to YYVAL
1462 unconditionally makes the parser a bit smaller, and it avoids a
1463 GCC warning that YYVAL may be used uninitialized. */
1464 yyval = yyvsp[1-yylen];
1465
1466 /* Default location. */
1467 YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
1468 YY_REDUCE_PRINT (yyn);
1469 switch (yyn)
1470 {
1471 case 2:
1472#line 110 "dtc-parser.y" /* yacc.c:1646 */
1473 {
1474 parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
1475 guess_boot_cpuid((yyvsp[0].node)));
1476 }
1477#line 1478 "dtc-parser.tab.c" /* yacc.c:1646 */
1478 break;
1479
1480 case 3:
1481#line 118 "dtc-parser.y" /* yacc.c:1646 */
1482 {
1483 (yyval.flags) = DTSF_V1;
1484 }
1485#line 1486 "dtc-parser.tab.c" /* yacc.c:1646 */
1486 break;
1487
1488 case 4:
1489#line 122 "dtc-parser.y" /* yacc.c:1646 */
1490 {
1491 (yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
1492 }
1493#line 1494 "dtc-parser.tab.c" /* yacc.c:1646 */
1494 break;
1495
1496 case 6:
1497#line 130 "dtc-parser.y" /* yacc.c:1646 */
1498 {
1499 if ((yyvsp[0].flags) != (yyvsp[-1].flags))
1500 ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
1501 (yyval.flags) = (yyvsp[-1].flags);
1502 }
1503#line 1504 "dtc-parser.tab.c" /* yacc.c:1646 */
1504 break;
1505
1506 case 7:
1507#line 139 "dtc-parser.y" /* yacc.c:1646 */
1508 {
1509 (yyval.re) = NULL;
1510 }
1511#line 1512 "dtc-parser.tab.c" /* yacc.c:1646 */
1512 break;
1513
1514 case 8:
1515#line 143 "dtc-parser.y" /* yacc.c:1646 */
1516 {
1517 (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
1518 }
1519#line 1520 "dtc-parser.tab.c" /* yacc.c:1646 */
1520 break;
1521
1522 case 9:
1523#line 150 "dtc-parser.y" /* yacc.c:1646 */
1524 {
1525 (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
1526 }
1527#line 1528 "dtc-parser.tab.c" /* yacc.c:1646 */
1528 break;
1529
1530 case 10:
1531#line 154 "dtc-parser.y" /* yacc.c:1646 */
1532 {
1533 add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
1534 (yyval.re) = (yyvsp[0].re);
1535 }
1536#line 1537 "dtc-parser.tab.c" /* yacc.c:1646 */
1537 break;
1538
1539 case 11:
1540#line 162 "dtc-parser.y" /* yacc.c:1646 */
1541 {
1542 (yyval.node) = name_node((yyvsp[0].node), "");
1543 }
1544#line 1545 "dtc-parser.tab.c" /* yacc.c:1646 */
1545 break;
1546
1547 case 12:
1548#line 166 "dtc-parser.y" /* yacc.c:1646 */
1549 {
1550 (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
1551 }
1552#line 1553 "dtc-parser.tab.c" /* yacc.c:1646 */
1553 break;
1554
1555 case 13:
1556#line 171 "dtc-parser.y" /* yacc.c:1646 */
1557 {
1558 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
1559
1560 if (target) {
1561 add_label(&target->labels, (yyvsp[-2].labelref));
1562 merge_nodes(target, (yyvsp[0].node));
1563 } else
1564 ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
1565 (yyval.node) = (yyvsp[-3].node);
1566 }
1567#line 1568 "dtc-parser.tab.c" /* yacc.c:1646 */
1568 break;
1569
1570 case 14:
1571#line 182 "dtc-parser.y" /* yacc.c:1646 */
1572 {
1573 struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
1574
1575 if (target) {
1576 merge_nodes(target, (yyvsp[0].node));
1577 } else {
1578 /*
1579 * We rely on the rule being always:
1580 * versioninfo plugindecl memreserves devicetree
1581 * so $-1 is what we want (plugindecl)
1582 */
1583 if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
1584 add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
1585 else
1586 ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
1587 }
1588 (yyval.node) = (yyvsp[-2].node);
1589 }
1590#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */
1591 break;
1592
1593 case 15:
1594#line 201 "dtc-parser.y" /* yacc.c:1646 */
1595 {
1596 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
1597
1598 if (target)
1599 delete_node(target);
1600 else
1601 ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
1602
1603
1604 (yyval.node) = (yyvsp[-3].node);
1605 }
1606#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */
1607 break;
1608
1609 case 16:
1610#line 213 "dtc-parser.y" /* yacc.c:1646 */
1611 {
1612 /* build empty node */
1613 (yyval.node) = name_node(build_node(NULL, NULL), "");
1614 }
1615#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */
1616 break;
1617
1618 case 17:
1619#line 221 "dtc-parser.y" /* yacc.c:1646 */
1620 {
1621 (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
1622 }
1623#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */
1624 break;
1625
1626 case 18:
1627#line 228 "dtc-parser.y" /* yacc.c:1646 */
1628 {
1629 (yyval.proplist) = NULL;
1630 }
1631#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */
1632 break;
1633
1634 case 19:
1635#line 232 "dtc-parser.y" /* yacc.c:1646 */
1636 {
1637 (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
1638 }
1639#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */
1640 break;
1641
1642 case 20:
1643#line 239 "dtc-parser.y" /* yacc.c:1646 */
1644 {
1645 (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
1646 }
1647#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */
1648 break;
1649
1650 case 21:
1651#line 243 "dtc-parser.y" /* yacc.c:1646 */
1652 {
1653 (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
1654 }
1655#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */
1656 break;
1657
1658 case 22:
1659#line 247 "dtc-parser.y" /* yacc.c:1646 */
1660 {
1661 (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
1662 }
1663#line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */
1664 break;
1665
1666 case 23:
1667#line 251 "dtc-parser.y" /* yacc.c:1646 */
1668 {
1669 add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
1670 (yyval.prop) = (yyvsp[0].prop);
1671 }
1672#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */
1673 break;
1674
1675 case 24:
1676#line 259 "dtc-parser.y" /* yacc.c:1646 */
1677 {
1678 (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
1679 }
1680#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */
1681 break;
1682
1683 case 25:
1684#line 263 "dtc-parser.y" /* yacc.c:1646 */
1685 {
1686 (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
1687 }
1688#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
1689 break;
1690
1691 case 26:
1692#line 267 "dtc-parser.y" /* yacc.c:1646 */
1693 {
1694 (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
1695 }
1696#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
1697 break;
1698
1699 case 27:
1700#line 271 "dtc-parser.y" /* yacc.c:1646 */
1701 {
1702 (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
1703 }
1704#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
1705 break;
1706
1707 case 28:
1708#line 275 "dtc-parser.y" /* yacc.c:1646 */
1709 {
1710 FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
1711 struct data d;
1712
1713 if ((yyvsp[-3].integer) != 0)
1714 if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0)
1715 die("Couldn't seek to offset %llu in \"%s\": %s",
1716 (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val,
1717 strerror(errno));
1718
1719 d = data_copy_file(f, (yyvsp[-1].integer));
1720
1721 (yyval.data) = data_merge((yyvsp[-8].data), d);
1722 fclose(f);
1723 }
1724#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
1725 break;
1726
1727 case 29:
1728#line 291 "dtc-parser.y" /* yacc.c:1646 */
1729 {
1730 FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
1731 struct data d = empty_data;
1732
1733 d = data_copy_file(f, -1);
1734
1735 (yyval.data) = data_merge((yyvsp[-4].data), d);
1736 fclose(f);
1737 }
1738#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */
1739 break;
1740
1741 case 30:
1742#line 301 "dtc-parser.y" /* yacc.c:1646 */
1743 {
1744 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
1745 }
1746#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */
1747 break;
1748
1749 case 31:
1750#line 308 "dtc-parser.y" /* yacc.c:1646 */
1751 {
1752 (yyval.data) = empty_data;
1753 }
1754#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */
1755 break;
1756
1757 case 32:
1758#line 312 "dtc-parser.y" /* yacc.c:1646 */
1759 {
1760 (yyval.data) = (yyvsp[-1].data);
1761 }
1762#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */
1763 break;
1764
1765 case 33:
1766#line 316 "dtc-parser.y" /* yacc.c:1646 */
1767 {
1768 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
1769 }
1770#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
1771 break;
1772
1773 case 34:
1774#line 323 "dtc-parser.y" /* yacc.c:1646 */
1775 {
1776 unsigned long long bits;
1777
1778 bits = (yyvsp[-1].integer);
1779
1780 if ((bits != 8) && (bits != 16) &&
1781 (bits != 32) && (bits != 64)) {
1782 ERROR(&(yylsp[-1]), "Array elements must be"
1783 " 8, 16, 32 or 64-bits");
1784 bits = 32;
1785 }
1786
1787 (yyval.array).data = empty_data;
1788 (yyval.array).bits = bits;
1789 }
1790#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
1791 break;
1792
1793 case 35:
1794#line 339 "dtc-parser.y" /* yacc.c:1646 */
1795 {
1796 (yyval.array).data = empty_data;
1797 (yyval.array).bits = 32;
1798 }
1799#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */
1800 break;
1801
1802 case 36:
1803#line 344 "dtc-parser.y" /* yacc.c:1646 */
1804 {
1805 if ((yyvsp[-1].array).bits < 64) {
1806 uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
1807 /*
1808 * Bits above mask must either be all zero
1809 * (positive within range of mask) or all one
1810 * (negative and sign-extended). The second
1811 * condition is true if when we set all bits
1812 * within the mask to one (i.e. | in the
1813 * mask), all bits are one.
1814 */
1815 if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL))
1816 ERROR(&(yylsp[0]), "Value out of range for"
1817 " %d-bit array element", (yyvsp[-1].array).bits);
1818 }
1819
1820 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
1821 }
1822#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
1823 break;
1824
1825 case 37:
1826#line 363 "dtc-parser.y" /* yacc.c:1646 */
1827 {
1828 uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
1829
1830 if ((yyvsp[-1].array).bits == 32)
1831 (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data,
1832 REF_PHANDLE,
1833 (yyvsp[0].labelref));
1834 else
1835 ERROR(&(yylsp[0]), "References are only allowed in "
1836 "arrays with 32-bit elements.");
1837
1838 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
1839 }
1840#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */
1841 break;
1842
1843 case 38:
1844#line 377 "dtc-parser.y" /* yacc.c:1646 */
1845 {
1846 (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
1847 }
1848#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
1849 break;
1850
1851 case 41:
1852#line 386 "dtc-parser.y" /* yacc.c:1646 */
1853 {
1854 (yyval.integer) = (yyvsp[-1].integer);
1855 }
1856#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
1857 break;
1858
1859 case 44:
1860#line 397 "dtc-parser.y" /* yacc.c:1646 */
1861 { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
1862#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
1863 break;
1864
1865 case 46:
1866#line 402 "dtc-parser.y" /* yacc.c:1646 */
1867 { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
1868#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
1869 break;
1870
1871 case 48:
1872#line 407 "dtc-parser.y" /* yacc.c:1646 */
1873 { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
1874#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
1875 break;
1876
1877 case 50:
1878#line 412 "dtc-parser.y" /* yacc.c:1646 */
1879 { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
1880#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
1881 break;
1882
1883 case 52:
1884#line 417 "dtc-parser.y" /* yacc.c:1646 */
1885 { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
1886#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
1887 break;
1888
1889 case 54:
1890#line 422 "dtc-parser.y" /* yacc.c:1646 */
1891 { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
1892#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
1893 break;
1894
1895 case 56:
1896#line 427 "dtc-parser.y" /* yacc.c:1646 */
1897 { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
1898#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
1899 break;
1900
1901 case 57:
1902#line 428 "dtc-parser.y" /* yacc.c:1646 */
1903 { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
1904#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
1905 break;
1906
1907 case 59:
1908#line 433 "dtc-parser.y" /* yacc.c:1646 */
1909 { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
1910#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
1911 break;
1912
1913 case 60:
1914#line 434 "dtc-parser.y" /* yacc.c:1646 */
1915 { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
1916#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
1917 break;
1918
1919 case 61:
1920#line 435 "dtc-parser.y" /* yacc.c:1646 */
1921 { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
1922#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
1923 break;
1924
1925 case 62:
1926#line 436 "dtc-parser.y" /* yacc.c:1646 */
1927 { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
1928#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
1929 break;
1930
1931 case 63:
1932#line 440 "dtc-parser.y" /* yacc.c:1646 */
1933 { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
1934#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
1935 break;
1936
1937 case 64:
1938#line 441 "dtc-parser.y" /* yacc.c:1646 */
1939 { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
1940#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
1941 break;
1942
1943 case 66:
1944#line 446 "dtc-parser.y" /* yacc.c:1646 */
1945 { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
1946#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
1947 break;
1948
1949 case 67:
1950#line 447 "dtc-parser.y" /* yacc.c:1646 */
1951 { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
1952#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
1953 break;
1954
1955 case 69:
1956#line 452 "dtc-parser.y" /* yacc.c:1646 */
1957 { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
1958#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */
1959 break;
1960
1961 case 70:
1962#line 454 "dtc-parser.y" /* yacc.c:1646 */
1963 {
1964 if ((yyvsp[0].integer) != 0) {
1965 (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
1966 } else {
1967 ERROR(&(yyloc), "Division by zero");
1968 (yyval.integer) = 0;
1969 }
1970 }
1971#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */
1972 break;
1973
1974 case 71:
1975#line 463 "dtc-parser.y" /* yacc.c:1646 */
1976 {
1977 if ((yyvsp[0].integer) != 0) {
1978 (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
1979 } else {
1980 ERROR(&(yyloc), "Division by zero");
1981 (yyval.integer) = 0;
1982 }
1983 }
1984#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
1985 break;
1986
1987 case 74:
1988#line 476 "dtc-parser.y" /* yacc.c:1646 */
1989 { (yyval.integer) = -(yyvsp[0].integer); }
1990#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
1991 break;
1992
1993 case 75:
1994#line 477 "dtc-parser.y" /* yacc.c:1646 */
1995 { (yyval.integer) = ~(yyvsp[0].integer); }
1996#line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */
1997 break;
1998
1999 case 76:
2000#line 478 "dtc-parser.y" /* yacc.c:1646 */
2001 { (yyval.integer) = !(yyvsp[0].integer); }
2002#line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */
2003 break;
2004
2005 case 77:
2006#line 483 "dtc-parser.y" /* yacc.c:1646 */
2007 {
2008 (yyval.data) = empty_data;
2009 }
2010#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */
2011 break;
2012
2013 case 78:
2014#line 487 "dtc-parser.y" /* yacc.c:1646 */
2015 {
2016 (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
2017 }
2018#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */
2019 break;
2020
2021 case 79:
2022#line 491 "dtc-parser.y" /* yacc.c:1646 */
2023 {
2024 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
2025 }
2026#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
2027 break;
2028
2029 case 80:
2030#line 498 "dtc-parser.y" /* yacc.c:1646 */
2031 {
2032 (yyval.nodelist) = NULL;
2033 }
2034#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */
2035 break;
2036
2037 case 81:
2038#line 502 "dtc-parser.y" /* yacc.c:1646 */
2039 {
2040 (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
2041 }
2042#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */
2043 break;
2044
2045 case 82:
2046#line 506 "dtc-parser.y" /* yacc.c:1646 */
2047 {
2048 ERROR(&(yylsp[0]), "Properties must precede subnodes");
2049 YYERROR;
2050 }
2051#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */
2052 break;
2053
2054 case 83:
2055#line 514 "dtc-parser.y" /* yacc.c:1646 */
2056 {
2057 (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
2058 }
2059#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */
2060 break;
2061
2062 case 84:
2063#line 518 "dtc-parser.y" /* yacc.c:1646 */
2064 {
2065 (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
2066 }
2067#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */
2068 break;
2069
2070 case 85:
2071#line 522 "dtc-parser.y" /* yacc.c:1646 */
2072 {
2073 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
2074 (yyval.node) = (yyvsp[0].node);
2075 }
2076#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */
2077 break;
2078
2079
2080#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */
2081 default: break;
2082 }
2083 /* User semantic actions sometimes alter yychar, and that requires
2084 that yytoken be updated with the new translation. We take the
2085 approach of translating immediately before every use of yytoken.
2086 One alternative is translating here after every semantic action,
2087 but that translation would be missed if the semantic action invokes
2088 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
2089 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
2090 incorrect destructor might then be invoked immediately. In the
2091 case of YYERROR or YYBACKUP, subsequent parser actions might lead
2092 to an incorrect destructor call or verbose syntax error message
2093 before the lookahead is translated. */
2094 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
2095
2096 YYPOPSTACK (yylen);
2097 yylen = 0;
2098 YY_STACK_PRINT (yyss, yyssp);
2099
2100 *++yyvsp = yyval;
2101 *++yylsp = yyloc;
2102
2103 /* Now 'shift' the result of the reduction. Determine what state
2104 that goes to, based on the state we popped back to and the rule
2105 number reduced by. */
2106
2107 yyn = yyr1[yyn];
2108
2109 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
2110 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2111 yystate = yytable[yystate];
2112 else
2113 yystate = yydefgoto[yyn - YYNTOKENS];
2114
2115 goto yynewstate;
2116
2117
2118/*--------------------------------------.
2119| yyerrlab -- here on detecting error. |
2120`--------------------------------------*/
2121yyerrlab:
2122 /* Make sure we have latest lookahead translation. See comments at
2123 user semantic actions for why this is necessary. */
2124 yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
2125
2126 /* If not already recovering from an error, report this error. */
2127 if (!yyerrstatus)
2128 {
2129 ++yynerrs;
2130#if ! YYERROR_VERBOSE
2131 yyerror (YY_("syntax error"));
2132#else
2133# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
2134 yyssp, yytoken)
2135 {
2136 char const *yymsgp = YY_("syntax error");
2137 int yysyntax_error_status;
2138 yysyntax_error_status = YYSYNTAX_ERROR;
2139 if (yysyntax_error_status == 0)
2140 yymsgp = yymsg;
2141 else if (yysyntax_error_status == 1)
2142 {
2143 if (yymsg != yymsgbuf)
2144 YYSTACK_FREE (yymsg);
2145 yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
2146 if (!yymsg)
2147 {
2148 yymsg = yymsgbuf;
2149 yymsg_alloc = sizeof yymsgbuf;
2150 yysyntax_error_status = 2;
2151 }
2152 else
2153 {
2154 yysyntax_error_status = YYSYNTAX_ERROR;
2155 yymsgp = yymsg;
2156 }
2157 }
2158 yyerror (yymsgp);
2159 if (yysyntax_error_status == 2)
2160 goto yyexhaustedlab;
2161 }
2162# undef YYSYNTAX_ERROR
2163#endif
2164 }
2165
2166 yyerror_range[1] = yylloc;
2167
2168 if (yyerrstatus == 3)
2169 {
2170 /* If just tried and failed to reuse lookahead token after an
2171 error, discard it. */
2172
2173 if (yychar <= YYEOF)
2174 {
2175 /* Return failure if at end of input. */
2176 if (yychar == YYEOF)
2177 YYABORT;
2178 }
2179 else
2180 {
2181 yydestruct ("Error: discarding",
2182 yytoken, &yylval, &yylloc);
2183 yychar = YYEMPTY;
2184 }
2185 }
2186
2187 /* Else will try to reuse lookahead token after shifting the error
2188 token. */
2189 goto yyerrlab1;
2190
2191
2192/*---------------------------------------------------.
2193| yyerrorlab -- error raised explicitly by YYERROR. |
2194`---------------------------------------------------*/
2195yyerrorlab:
2196
2197 /* Pacify compilers like GCC when the user code never invokes
2198 YYERROR and the label yyerrorlab therefore never appears in user
2199 code. */
2200 if (/*CONSTCOND*/ 0)
2201 goto yyerrorlab;
2202
2203 yyerror_range[1] = yylsp[1-yylen];
2204 /* Do not reclaim the symbols of the rule whose action triggered
2205 this YYERROR. */
2206 YYPOPSTACK (yylen);
2207 yylen = 0;
2208 YY_STACK_PRINT (yyss, yyssp);
2209 yystate = *yyssp;
2210 goto yyerrlab1;
2211
2212
2213/*-------------------------------------------------------------.
2214| yyerrlab1 -- common code for both syntax error and YYERROR. |
2215`-------------------------------------------------------------*/
2216yyerrlab1:
2217 yyerrstatus = 3; /* Each real token shifted decrements this. */
2218
2219 for (;;)
2220 {
2221 yyn = yypact[yystate];
2222 if (!yypact_value_is_default (yyn))
2223 {
2224 yyn += YYTERROR;
2225 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
2226 {
2227 yyn = yytable[yyn];
2228 if (0 < yyn)
2229 break;
2230 }
2231 }
2232
2233 /* Pop the current state because it cannot handle the error token. */
2234 if (yyssp == yyss)
2235 YYABORT;
2236
2237 yyerror_range[1] = *yylsp;
2238 yydestruct ("Error: popping",
2239 yystos[yystate], yyvsp, yylsp);
2240 YYPOPSTACK (1);
2241 yystate = *yyssp;
2242 YY_STACK_PRINT (yyss, yyssp);
2243 }
2244
2245 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
2246 *++yyvsp = yylval;
2247 YY_IGNORE_MAYBE_UNINITIALIZED_END
2248
2249 yyerror_range[2] = yylloc;
2250 /* Using YYLLOC is tempting, but would change the location of
2251 the lookahead. YYLOC is available though. */
2252 YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
2253 *++yylsp = yyloc;
2254
2255 /* Shift the error token. */
2256 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
2257
2258 yystate = yyn;
2259 goto yynewstate;
2260
2261
2262/*-------------------------------------.
2263| yyacceptlab -- YYACCEPT comes here. |
2264`-------------------------------------*/
2265yyacceptlab:
2266 yyresult = 0;
2267 goto yyreturn;
2268
2269/*-----------------------------------.
2270| yyabortlab -- YYABORT comes here. |
2271`-----------------------------------*/
2272yyabortlab:
2273 yyresult = 1;
2274 goto yyreturn;
2275
2276#if !defined yyoverflow || YYERROR_VERBOSE
2277/*-------------------------------------------------.
2278| yyexhaustedlab -- memory exhaustion comes here. |
2279`-------------------------------------------------*/
2280yyexhaustedlab:
2281 yyerror (YY_("memory exhausted"));
2282 yyresult = 2;
2283 /* Fall through. */
2284#endif
2285
2286yyreturn:
2287 if (yychar != YYEMPTY)
2288 {
2289 /* Make sure we have latest lookahead translation. See comments at
2290 user semantic actions for why this is necessary. */
2291 yytoken = YYTRANSLATE (yychar);
2292 yydestruct ("Cleanup: discarding lookahead",
2293 yytoken, &yylval, &yylloc);
2294 }
2295 /* Do not reclaim the symbols of the rule whose action triggered
2296 this YYABORT or YYACCEPT. */
2297 YYPOPSTACK (yylen);
2298 YY_STACK_PRINT (yyss, yyssp);
2299 while (yyssp != yyss)
2300 {
2301 yydestruct ("Cleanup: popping",
2302 yystos[*yyssp], yyvsp, yylsp);
2303 YYPOPSTACK (1);
2304 }
2305#ifndef yyoverflow
2306 if (yyss != yyssa)
2307 YYSTACK_FREE (yyss);
2308#endif
2309#if YYERROR_VERBOSE
2310 if (yymsg != yymsgbuf)
2311 YYSTACK_FREE (yymsg);
2312#endif
2313 return yyresult;
2314}
2315#line 528 "dtc-parser.y" /* yacc.c:1906 */
2316
2317
2318void yyerror(char const *s)
2319{
2320 ERROR(&yylloc, "%s", s);
2321}
diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
deleted file mode 100644
index 6aa512c1b337..000000000000
--- a/scripts/dtc/dtc-parser.tab.h_shipped
+++ /dev/null
@@ -1,125 +0,0 @@
1/* A Bison parser, made by GNU Bison 3.0.4. */
2
3/* Bison interface for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
34# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
35/* Debug traces. */
36#ifndef YYDEBUG
37# define YYDEBUG 0
38#endif
39#if YYDEBUG
40extern int yydebug;
41#endif
42
43/* Token type. */
44#ifndef YYTOKENTYPE
45# define YYTOKENTYPE
46 enum yytokentype
47 {
48 DT_V1 = 258,
49 DT_PLUGIN = 259,
50 DT_MEMRESERVE = 260,
51 DT_LSHIFT = 261,
52 DT_RSHIFT = 262,
53 DT_LE = 263,
54 DT_GE = 264,
55 DT_EQ = 265,
56 DT_NE = 266,
57 DT_AND = 267,
58 DT_OR = 268,
59 DT_BITS = 269,
60 DT_DEL_PROP = 270,
61 DT_DEL_NODE = 271,
62 DT_PROPNODENAME = 272,
63 DT_LITERAL = 273,
64 DT_CHAR_LITERAL = 274,
65 DT_BYTE = 275,
66 DT_STRING = 276,
67 DT_LABEL = 277,
68 DT_REF = 278,
69 DT_INCBIN = 279
70 };
71#endif
72
73/* Value type. */
74#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
75
76union YYSTYPE
77{
78#line 39 "dtc-parser.y" /* yacc.c:1909 */
79
80 char *propnodename;
81 char *labelref;
82 uint8_t byte;
83 struct data data;
84
85 struct {
86 struct data data;
87 int bits;
88 } array;
89
90 struct property *prop;
91 struct property *proplist;
92 struct node *node;
93 struct node *nodelist;
94 struct reserve_info *re;
95 uint64_t integer;
96 unsigned int flags;
97
98#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */
99};
100
101typedef union YYSTYPE YYSTYPE;
102# define YYSTYPE_IS_TRIVIAL 1
103# define YYSTYPE_IS_DECLARED 1
104#endif
105
106/* Location type. */
107#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
108typedef struct YYLTYPE YYLTYPE;
109struct YYLTYPE
110{
111 int first_line;
112 int first_column;
113 int last_line;
114 int last_column;
115};
116# define YYLTYPE_IS_DECLARED 1
117# define YYLTYPE_IS_TRIVIAL 1
118#endif
119
120
121extern YYSTYPE yylval;
122extern YYLTYPE yylloc;
123int yyparse (void);
124
125#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index affc81a8f9ab..dd70ebf386f4 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -63,6 +63,7 @@ extern bool treesource_error;
63%token DT_BITS 63%token DT_BITS
64%token DT_DEL_PROP 64%token DT_DEL_PROP
65%token DT_DEL_NODE 65%token DT_DEL_NODE
66%token DT_OMIT_NO_REF
66%token <propnodename> DT_PROPNODENAME 67%token <propnodename> DT_PROPNODENAME
67%token <integer> DT_LITERAL 68%token <integer> DT_LITERAL
68%token <integer> DT_CHAR_LITERAL 69%token <integer> DT_CHAR_LITERAL
@@ -166,7 +167,17 @@ devicetree:
166 { 167 {
167 $$ = merge_nodes($1, $3); 168 $$ = merge_nodes($1, $3);
168 } 169 }
169 170 | DT_REF nodedef
171 {
172 /*
173 * We rely on the rule being always:
174 * versioninfo plugindecl memreserves devicetree
175 * so $-1 is what we want (plugindecl)
176 */
177 if (!($<flags>-1 & DTSF_PLUGIN))
178 ERROR(&@2, "Label or path %s not found", $1);
179 $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1);
180 }
170 | devicetree DT_LABEL DT_REF nodedef 181 | devicetree DT_LABEL DT_REF nodedef
171 { 182 {
172 struct node *target = get_node_by_ref($1, $3); 183 struct node *target = get_node_by_ref($1, $3);
@@ -180,18 +191,18 @@ devicetree:
180 } 191 }
181 | devicetree DT_REF nodedef 192 | devicetree DT_REF nodedef
182 { 193 {
183 struct node *target = get_node_by_ref($1, $2); 194 /*
184 195 * We rely on the rule being always:
185 if (target) { 196 * versioninfo plugindecl memreserves devicetree
186 merge_nodes(target, $3); 197 * so $-1 is what we want (plugindecl)
198 */
199 if ($<flags>-1 & DTSF_PLUGIN) {
200 add_orphan_node($1, $3, $2);
187 } else { 201 } else {
188 /* 202 struct node *target = get_node_by_ref($1, $2);
189 * We rely on the rule being always: 203
190 * versioninfo plugindecl memreserves devicetree 204 if (target)
191 * so $-1 is what we want (plugindecl) 205 merge_nodes(target, $3);
192 */
193 if ($<flags>-1 & DTSF_PLUGIN)
194 add_orphan_node($1, $3, $2);
195 else 206 else
196 ERROR(&@2, "Label or path %s not found", $2); 207 ERROR(&@2, "Label or path %s not found", $2);
197 } 208 }
@@ -209,10 +220,17 @@ devicetree:
209 220
210 $$ = $1; 221 $$ = $1;
211 } 222 }
212 | /* empty */ 223 | devicetree DT_OMIT_NO_REF DT_REF ';'
213 { 224 {
214 /* build empty node */ 225 struct node *target = get_node_by_ref($1, $3);
215 $$ = name_node(build_node(NULL, NULL), ""); 226
227 if (target)
228 omit_node_if_unused(target);
229 else
230 ERROR(&@3, "Label or path %s not found", $3);
231
232
233 $$ = $1;
216 } 234 }
217 ; 235 ;
218 236
@@ -269,6 +287,7 @@ propdata:
269 } 287 }
270 | propdataprefix DT_REF 288 | propdataprefix DT_REF
271 { 289 {
290 $1 = data_add_marker($1, TYPE_STRING, $2);
272 $$ = data_add_marker($1, REF_PATH, $2); 291 $$ = data_add_marker($1, REF_PATH, $2);
273 } 292 }
274 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')' 293 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
@@ -322,22 +341,27 @@ arrayprefix:
322 DT_BITS DT_LITERAL '<' 341 DT_BITS DT_LITERAL '<'
323 { 342 {
324 unsigned long long bits; 343 unsigned long long bits;
344 enum markertype type = TYPE_UINT32;
325 345
326 bits = $2; 346 bits = $2;
327 347
328 if ((bits != 8) && (bits != 16) && 348 switch (bits) {
329 (bits != 32) && (bits != 64)) { 349 case 8: type = TYPE_UINT8; break;
350 case 16: type = TYPE_UINT16; break;
351 case 32: type = TYPE_UINT32; break;
352 case 64: type = TYPE_UINT64; break;
353 default:
330 ERROR(&@2, "Array elements must be" 354 ERROR(&@2, "Array elements must be"
331 " 8, 16, 32 or 64-bits"); 355 " 8, 16, 32 or 64-bits");
332 bits = 32; 356 bits = 32;
333 } 357 }
334 358
335 $$.data = empty_data; 359 $$.data = data_add_marker(empty_data, type, NULL);
336 $$.bits = bits; 360 $$.bits = bits;
337 } 361 }
338 | '<' 362 | '<'
339 { 363 {
340 $$.data = empty_data; 364 $$.data = data_add_marker(empty_data, TYPE_UINT32, NULL);
341 $$.bits = 32; 365 $$.bits = 32;
342 } 366 }
343 | arrayprefix integer_prim 367 | arrayprefix integer_prim
@@ -481,7 +505,7 @@ integer_unary:
481bytestring: 505bytestring:
482 /* empty */ 506 /* empty */
483 { 507 {
484 $$ = empty_data; 508 $$ = data_add_marker(empty_data, TYPE_UINT8, NULL);
485 } 509 }
486 | bytestring DT_BYTE 510 | bytestring DT_BYTE
487 { 511 {
@@ -518,6 +542,10 @@ subnode:
518 { 542 {
519 $$ = name_node(build_node_delete(), $2); 543 $$ = name_node(build_node_delete(), $2);
520 } 544 }
545 | DT_OMIT_NO_REF subnode
546 {
547 $$ = omit_node_if_unused($2);
548 }
521 | DT_LABEL subnode 549 | DT_LABEL subnode
522 { 550 {
523 add_label(&$2->labels, $1); 551 add_label(&$2->labels, $1);
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 5ed873c72ad1..64134aadb997 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -59,8 +59,6 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
59} 59}
60 60
61/* Usage related data. */ 61/* Usage related data. */
62#define FDT_VERSION(version) _FDT_VERSION(version)
63#define _FDT_VERSION(version) #version
64static const char usage_synopsis[] = "dtc [options] <input file>"; 62static const char usage_synopsis[] = "dtc [options] <input file>";
65static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; 63static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv";
66static struct option const usage_long_opts[] = { 64static struct option const usage_long_opts[] = {
@@ -97,8 +95,11 @@ static const char * const usage_opts_help[] = {
97 "\n\tOutput formats are:\n" 95 "\n\tOutput formats are:\n"
98 "\t\tdts - device tree source text\n" 96 "\t\tdts - device tree source text\n"
99 "\t\tdtb - device tree blob\n" 97 "\t\tdtb - device tree blob\n"
98#ifndef NO_YAML
99 "\t\tyaml - device tree encoded as YAML\n"
100#endif
100 "\t\tasm - assembler source", 101 "\t\tasm - assembler source",
101 "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", 102 "\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
102 "\n\tOutput dependency file", 103 "\n\tOutput dependency file",
103 "\n\tMake space for <number> reserve map entries (for dtb and asm output)", 104 "\n\tMake space for <number> reserve map entries (for dtb and asm output)",
104 "\n\tMake the blob at least <bytes> long (extra space)", 105 "\n\tMake the blob at least <bytes> long (extra space)",
@@ -130,6 +131,8 @@ static const char *guess_type_by_name(const char *fname, const char *fallback)
130 return fallback; 131 return fallback;
131 if (!strcasecmp(s, ".dts")) 132 if (!strcasecmp(s, ".dts"))
132 return "dts"; 133 return "dts";
134 if (!strcasecmp(s, ".yaml"))
135 return "yaml";
133 if (!strcasecmp(s, ".dtb")) 136 if (!strcasecmp(s, ".dtb"))
134 return "dtb"; 137 return "dtb";
135 return fallback; 138 return fallback;
@@ -319,13 +322,14 @@ int main(int argc, char *argv[])
319 dti->boot_cpuid_phys = cmdline_boot_cpuid; 322 dti->boot_cpuid_phys = cmdline_boot_cpuid;
320 323
321 fill_fullpaths(dti->dt, ""); 324 fill_fullpaths(dti->dt, "");
322 process_checks(force, dti);
323 325
324 /* on a plugin, generate by default */ 326 /* on a plugin, generate by default */
325 if (dti->dtsflags & DTSF_PLUGIN) { 327 if (dti->dtsflags & DTSF_PLUGIN) {
326 generate_fixups = 1; 328 generate_fixups = 1;
327 } 329 }
328 330
331 process_checks(force, dti);
332
329 if (auto_label_aliases) 333 if (auto_label_aliases)
330 generate_label_tree(dti, "aliases", false); 334 generate_label_tree(dti, "aliases", false);
331 335
@@ -351,6 +355,12 @@ int main(int argc, char *argv[])
351 355
352 if (streq(outform, "dts")) { 356 if (streq(outform, "dts")) {
353 dt_to_source(outf, dti); 357 dt_to_source(outf, dti);
358#ifndef NO_YAML
359 } else if (streq(outform, "yaml")) {
360 if (!streq(inform, "dts"))
361 die("YAML output format requires dts input format\n");
362 dt_to_yaml(outf, dti);
363#endif
354 } else if (streq(outform, "dtb")) { 364 } else if (streq(outform, "dtb")) {
355 dt_to_blob(outf, dti, outversion); 365 dt_to_blob(outf, dti, outversion);
356 } else if (streq(outform, "asm")) { 366 } else if (streq(outform, "asm")) {
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 35cf926cc14a..cbe541525c2c 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -1,5 +1,5 @@
1#ifndef _DTC_H 1#ifndef DTC_H
2#define _DTC_H 2#define DTC_H
3 3
4/* 4/*
5 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 5 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
@@ -67,16 +67,24 @@ typedef uint32_t cell_t;
67 67
68 68
69#define streq(a, b) (strcmp((a), (b)) == 0) 69#define streq(a, b) (strcmp((a), (b)) == 0)
70#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) 70#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)
71#define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0))
71 72
72#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 73#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
73 74
74/* Data blobs */ 75/* Data blobs */
75enum markertype { 76enum markertype {
77 TYPE_NONE,
76 REF_PHANDLE, 78 REF_PHANDLE,
77 REF_PATH, 79 REF_PATH,
78 LABEL, 80 LABEL,
81 TYPE_UINT8,
82 TYPE_UINT16,
83 TYPE_UINT32,
84 TYPE_UINT64,
85 TYPE_STRING,
79}; 86};
87extern const char *markername(enum markertype markertype);
80 88
81struct marker { 89struct marker {
82 enum markertype type; 90 enum markertype type;
@@ -100,6 +108,8 @@ struct data {
100 for_each_marker(m) \ 108 for_each_marker(m) \
101 if ((m)->type == (t)) 109 if ((m)->type == (t))
102 110
111size_t type_marker_length(struct marker *m);
112
103void data_free(struct data d); 113void data_free(struct data d);
104 114
105struct data data_grow_for(struct data d, int xlen); 115struct data data_grow_for(struct data d, int xlen);
@@ -167,6 +177,8 @@ struct node {
167 177
168 struct label *labels; 178 struct label *labels;
169 const struct bus_type *bus; 179 const struct bus_type *bus;
180
181 bool omit_if_unused, is_referenced;
170}; 182};
171 183
172#define for_each_label_withdel(l0, l) \ 184#define for_each_label_withdel(l0, l) \
@@ -201,9 +213,11 @@ struct property *reverse_properties(struct property *first);
201struct node *build_node(struct property *proplist, struct node *children); 213struct node *build_node(struct property *proplist, struct node *children);
202struct node *build_node_delete(void); 214struct node *build_node_delete(void);
203struct node *name_node(struct node *node, char *name); 215struct node *name_node(struct node *node, char *name);
216struct node *omit_node_if_unused(struct node *node);
217struct node *reference_node(struct node *node);
204struct node *chain_node(struct node *first, struct node *list); 218struct node *chain_node(struct node *first, struct node *list);
205struct node *merge_nodes(struct node *old_node, struct node *new_node); 219struct node *merge_nodes(struct node *old_node, struct node *new_node);
206void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); 220struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
207 221
208void add_property(struct node *node, struct property *prop); 222void add_property(struct node *node, struct property *prop);
209void delete_property_by_name(struct node *node, char *name); 223void delete_property_by_name(struct node *node, char *name);
@@ -285,8 +299,12 @@ struct dt_info *dt_from_blob(const char *fname);
285void dt_to_source(FILE *f, struct dt_info *dti); 299void dt_to_source(FILE *f, struct dt_info *dti);
286struct dt_info *dt_from_source(const char *f); 300struct dt_info *dt_from_source(const char *f);
287 301
302/* YAML source */
303
304void dt_to_yaml(FILE *f, struct dt_info *dti);
305
288/* FS trees */ 306/* FS trees */
289 307
290struct dt_info *dt_from_fs(const char *dirname); 308struct dt_info *dt_from_fs(const char *dirname);
291 309
292#endif /* _DTC_H */ 310#endif /* DTC_H */
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index fcf71541d8a7..851ea87dbc0f 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -393,7 +393,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int version)
393 padlen = 0; 393 padlen = 0;
394 if (quiet < 1) 394 if (quiet < 1)
395 fprintf(stderr, 395 fprintf(stderr,
396 "Warning: blob size %d >= minimum size %d\n", 396 "Warning: blob size %"PRIu32" >= minimum size %d\n",
397 fdt32_to_cpu(fdt.totalsize), minsize); 397 fdt32_to_cpu(fdt.totalsize), minsize);
398 } 398 }
399 } 399 }
@@ -731,7 +731,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
731 731
732 plen = strlen(ppath); 732 plen = strlen(ppath);
733 733
734 if (!strneq(ppath, cpath, plen)) 734 if (!strstarts(cpath, ppath))
735 die("Path \"%s\" is not valid as a child of \"%s\"\n", 735 die("Path \"%s\" is not valid as a child of \"%s\"\n",
736 cpath, ppath); 736 cpath, ppath);
737 737
diff --git a/scripts/dtc/include-prefixes/cris b/scripts/dtc/include-prefixes/cris
deleted file mode 120000
index 736d998ba506..000000000000
--- a/scripts/dtc/include-prefixes/cris
+++ /dev/null
@@ -1 +0,0 @@
1../../../arch/cris/boot/dts \ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/metag b/scripts/dtc/include-prefixes/metag
deleted file mode 120000
index 87a3c847db8f..000000000000
--- a/scripts/dtc/include-prefixes/metag
+++ /dev/null
@@ -1 +0,0 @@
1../../../arch/metag/boot/dts \ No newline at end of file
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 22286a1aaeaf..ae03b1112961 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -55,7 +55,12 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58int fdt_check_header(const void *fdt) 58/*
59 * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks
60 * that the given buffer contains what appears to be a flattened
61 * device tree with sane information in its header.
62 */
63int fdt_ro_probe_(const void *fdt)
59{ 64{
60 if (fdt_magic(fdt) == FDT_MAGIC) { 65 if (fdt_magic(fdt) == FDT_MAGIC) {
61 /* Complete tree */ 66 /* Complete tree */
@@ -74,6 +79,78 @@ int fdt_check_header(const void *fdt)
74 return 0; 79 return 0;
75} 80}
76 81
82static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)
83{
84 return (off >= hdrsize) && (off <= totalsize);
85}
86
87static int check_block_(uint32_t hdrsize, uint32_t totalsize,
88 uint32_t base, uint32_t size)
89{
90 if (!check_off_(hdrsize, totalsize, base))
91 return 0; /* block start out of bounds */
92 if ((base + size) < base)
93 return 0; /* overflow */
94 if (!check_off_(hdrsize, totalsize, base + size))
95 return 0; /* block end out of bounds */
96 return 1;
97}
98
99size_t fdt_header_size_(uint32_t version)
100{
101 if (version <= 1)
102 return FDT_V1_SIZE;
103 else if (version <= 2)
104 return FDT_V2_SIZE;
105 else if (version <= 3)
106 return FDT_V3_SIZE;
107 else if (version <= 16)
108 return FDT_V16_SIZE;
109 else
110 return FDT_V17_SIZE;
111}
112
113int fdt_check_header(const void *fdt)
114{
115 size_t hdrsize;
116
117 if (fdt_magic(fdt) != FDT_MAGIC)
118 return -FDT_ERR_BADMAGIC;
119 hdrsize = fdt_header_size(fdt);
120 if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
121 || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
122 return -FDT_ERR_BADVERSION;
123 if (fdt_version(fdt) < fdt_last_comp_version(fdt))
124 return -FDT_ERR_BADVERSION;
125
126 if ((fdt_totalsize(fdt) < hdrsize)
127 || (fdt_totalsize(fdt) > INT_MAX))
128 return -FDT_ERR_TRUNCATED;
129
130 /* Bounds check memrsv block */
131 if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
132 return -FDT_ERR_TRUNCATED;
133
134 /* Bounds check structure block */
135 if (fdt_version(fdt) < 17) {
136 if (!check_off_(hdrsize, fdt_totalsize(fdt),
137 fdt_off_dt_struct(fdt)))
138 return -FDT_ERR_TRUNCATED;
139 } else {
140 if (!check_block_(hdrsize, fdt_totalsize(fdt),
141 fdt_off_dt_struct(fdt),
142 fdt_size_dt_struct(fdt)))
143 return -FDT_ERR_TRUNCATED;
144 }
145
146 /* Bounds check strings block */
147 if (!check_block_(hdrsize, fdt_totalsize(fdt),
148 fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
149 return -FDT_ERR_TRUNCATED;
150
151 return 0;
152}
153
77const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) 154const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
78{ 155{
79 unsigned absoffset = offset + fdt_off_dt_struct(fdt); 156 unsigned absoffset = offset + fdt_off_dt_struct(fdt);
@@ -88,7 +165,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
88 || ((offset + len) > fdt_size_dt_struct(fdt))) 165 || ((offset + len) > fdt_size_dt_struct(fdt)))
89 return NULL; 166 return NULL;
90 167
91 return _fdt_offset_ptr(fdt, offset); 168 return fdt_offset_ptr_(fdt, offset);
92} 169}
93 170
94uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) 171uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
@@ -123,6 +200,9 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
123 /* skip-name offset, length and value */ 200 /* skip-name offset, length and value */
124 offset += sizeof(struct fdt_property) - FDT_TAGSIZE 201 offset += sizeof(struct fdt_property) - FDT_TAGSIZE
125 + fdt32_to_cpu(*lenp); 202 + fdt32_to_cpu(*lenp);
203 if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
204 ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
205 offset += 4;
126 break; 206 break;
127 207
128 case FDT_END: 208 case FDT_END:
@@ -141,7 +221,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
141 return tag; 221 return tag;
142} 222}
143 223
144int _fdt_check_node_offset(const void *fdt, int offset) 224int fdt_check_node_offset_(const void *fdt, int offset)
145{ 225{
146 if ((offset < 0) || (offset % FDT_TAGSIZE) 226 if ((offset < 0) || (offset % FDT_TAGSIZE)
147 || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) 227 || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
@@ -150,7 +230,7 @@ int _fdt_check_node_offset(const void *fdt, int offset)
150 return offset; 230 return offset;
151} 231}
152 232
153int _fdt_check_prop_offset(const void *fdt, int offset) 233int fdt_check_prop_offset_(const void *fdt, int offset)
154{ 234{
155 if ((offset < 0) || (offset % FDT_TAGSIZE) 235 if ((offset < 0) || (offset % FDT_TAGSIZE)
156 || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) 236 || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
@@ -165,7 +245,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
165 uint32_t tag; 245 uint32_t tag;
166 246
167 if (offset >= 0) 247 if (offset >= 0)
168 if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) 248 if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0)
169 return nextoffset; 249 return nextoffset;
170 250
171 do { 251 do {
@@ -227,7 +307,7 @@ int fdt_next_subnode(const void *fdt, int offset)
227 return offset; 307 return offset;
228} 308}
229 309
230const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) 310const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
231{ 311{
232 int len = strlen(s) + 1; 312 int len = strlen(s) + 1;
233 const char *last = strtab + tabsize - len; 313 const char *last = strtab + tabsize - len;
@@ -241,7 +321,7 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
241 321
242int fdt_move(const void *fdt, void *buf, int bufsize) 322int fdt_move(const void *fdt, void *buf, int bufsize)
243{ 323{
244 FDT_CHECK_HEADER(fdt); 324 FDT_RO_PROBE(fdt);
245 325
246 if (fdt_totalsize(fdt) > bufsize) 326 if (fdt_totalsize(fdt) > bufsize)
247 return -FDT_ERR_NOSPACE; 327 return -FDT_ERR_NOSPACE;
diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h
index 526aedb51556..74961f9026d1 100644
--- a/scripts/dtc/libfdt/fdt.h
+++ b/scripts/dtc/libfdt/fdt.h
@@ -1,5 +1,5 @@
1#ifndef _FDT_H 1#ifndef FDT_H
2#define _FDT_H 2#define FDT_H
3/* 3/*
4 * libfdt - Flat Device Tree manipulation 4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation. 5 * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -108,4 +108,4 @@ struct fdt_property {
108#define FDT_V16_SIZE FDT_V3_SIZE 108#define FDT_V16_SIZE FDT_V3_SIZE
109#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) 109#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))
110 110
111#endif /* _FDT_H */ 111#endif /* FDT_H */
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
index eff4dbcc729d..49537b578d03 100644
--- a/scripts/dtc/libfdt/fdt_addresses.c
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * libfdt - Flat Device Tree manipulation 2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au> 3 * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
4 * Copyright (C) 2018 embedded brains GmbH
4 * 5 *
5 * libfdt is dual licensed: you can use it either under the terms of 6 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option. 7 * the GPL, or the BSD license, at your option.
@@ -55,42 +56,32 @@
55 56
56#include "libfdt_internal.h" 57#include "libfdt_internal.h"
57 58
58int fdt_address_cells(const void *fdt, int nodeoffset) 59static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
59{ 60{
60 const fdt32_t *ac; 61 const fdt32_t *c;
61 int val; 62 int val;
62 int len; 63 int len;
63 64
64 ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len); 65 c = fdt_getprop(fdt, nodeoffset, name, &len);
65 if (!ac) 66 if (!c)
66 return 2; 67 return 2;
67 68
68 if (len != sizeof(*ac)) 69 if (len != sizeof(*c))
69 return -FDT_ERR_BADNCELLS; 70 return -FDT_ERR_BADNCELLS;
70 71
71 val = fdt32_to_cpu(*ac); 72 val = fdt32_to_cpu(*c);
72 if ((val <= 0) || (val > FDT_MAX_NCELLS)) 73 if ((val <= 0) || (val > FDT_MAX_NCELLS))
73 return -FDT_ERR_BADNCELLS; 74 return -FDT_ERR_BADNCELLS;
74 75
75 return val; 76 return val;
76} 77}
77 78
78int fdt_size_cells(const void *fdt, int nodeoffset) 79int fdt_address_cells(const void *fdt, int nodeoffset)
79{ 80{
80 const fdt32_t *sc; 81 return fdt_cells(fdt, nodeoffset, "#address-cells");
81 int val; 82}
82 int len;
83
84 sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
85 if (!sc)
86 return 2;
87
88 if (len != sizeof(*sc))
89 return -FDT_ERR_BADNCELLS;
90
91 val = fdt32_to_cpu(*sc);
92 if ((val < 0) || (val > FDT_MAX_NCELLS))
93 return -FDT_ERR_BADNCELLS;
94 83
95 return val; 84int fdt_size_cells(const void *fdt, int nodeoffset)
85{
86 return fdt_cells(fdt, nodeoffset, "#size-cells");
96} 87}
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
index bd81241e6658..5fdab6c6371d 100644
--- a/scripts/dtc/libfdt/fdt_overlay.c
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -1,3 +1,54 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2016 Free Electrons
4 * Copyright (C) 2016 NextThing Co.
5 *
6 * libfdt is dual licensed: you can use it either under the terms of
7 * the GPL, or the BSD license, at your option.
8 *
9 * a) This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
22 * MA 02110-1301 USA
23 *
24 * Alternatively,
25 *
26 * b) Redistribution and use in source and binary forms, with or
27 * without modification, are permitted provided that the following
28 * conditions are met:
29 *
30 * 1. Redistributions of source code must retain the above
31 * copyright notice, this list of conditions and the following
32 * disclaimer.
33 * 2. Redistributions in binary form must reproduce the above
34 * copyright notice, this list of conditions and the following
35 * disclaimer in the documentation and/or other materials
36 * provided with the distribution.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
39 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
40 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
41 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
43 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
49 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
50 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 */
1#include "libfdt_env.h" 52#include "libfdt_env.h"
2 53
3#include <fdt.h> 54#include <fdt.h>
@@ -646,7 +697,7 @@ static int get_path_len(const void *fdt, int nodeoffset)
646 int len = 0, namelen; 697 int len = 0, namelen;
647 const char *name; 698 const char *name;
648 699
649 FDT_CHECK_HEADER(fdt); 700 FDT_RO_PROBE(fdt);
650 701
651 for (;;) { 702 for (;;) {
652 name = fdt_get_name(fdt, nodeoffset, &namelen); 703 name = fdt_get_name(fdt, nodeoffset, &namelen);
@@ -815,8 +866,8 @@ int fdt_overlay_apply(void *fdt, void *fdto)
815 uint32_t delta = fdt_get_max_phandle(fdt); 866 uint32_t delta = fdt_get_max_phandle(fdt);
816 int ret; 867 int ret;
817 868
818 FDT_CHECK_HEADER(fdt); 869 FDT_RO_PROBE(fdt);
819 FDT_CHECK_HEADER(fdto); 870 FDT_RO_PROBE(fdto);
820 871
821 ret = overlay_adjust_local_phandles(fdto, delta); 872 ret = overlay_adjust_local_phandles(fdto, delta);
822 if (ret) 873 if (ret)
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 08de2cce674d..eafc14282892 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -55,12 +55,13 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58static int _fdt_nodename_eq(const void *fdt, int offset, 58static int fdt_nodename_eq_(const void *fdt, int offset,
59 const char *s, int len) 59 const char *s, int len)
60{ 60{
61 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); 61 int olen;
62 const char *p = fdt_get_name(fdt, offset, &olen);
62 63
63 if (!p) 64 if (!p || olen < len)
64 /* short match */ 65 /* short match */
65 return 0; 66 return 0;
66 67
@@ -75,17 +76,72 @@ static int _fdt_nodename_eq(const void *fdt, int offset,
75 return 0; 76 return 0;
76} 77}
77 78
79const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
80{
81 uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);
82 size_t len;
83 int err;
84 const char *s, *n;
85
86 err = fdt_ro_probe_(fdt);
87 if (err != 0)
88 goto fail;
89
90 err = -FDT_ERR_BADOFFSET;
91 if (absoffset >= fdt_totalsize(fdt))
92 goto fail;
93 len = fdt_totalsize(fdt) - absoffset;
94
95 if (fdt_magic(fdt) == FDT_MAGIC) {
96 if (stroffset < 0)
97 goto fail;
98 if (fdt_version(fdt) >= 17) {
99 if (stroffset >= fdt_size_dt_strings(fdt))
100 goto fail;
101 if ((fdt_size_dt_strings(fdt) - stroffset) < len)
102 len = fdt_size_dt_strings(fdt) - stroffset;
103 }
104 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
105 if ((stroffset >= 0)
106 || (stroffset < -fdt_size_dt_strings(fdt)))
107 goto fail;
108 if ((-stroffset) < len)
109 len = -stroffset;
110 } else {
111 err = -FDT_ERR_INTERNAL;
112 goto fail;
113 }
114
115 s = (const char *)fdt + absoffset;
116 n = memchr(s, '\0', len);
117 if (!n) {
118 /* missing terminating NULL */
119 err = -FDT_ERR_TRUNCATED;
120 goto fail;
121 }
122
123 if (lenp)
124 *lenp = n - s;
125 return s;
126
127fail:
128 if (lenp)
129 *lenp = err;
130 return NULL;
131}
132
78const char *fdt_string(const void *fdt, int stroffset) 133const char *fdt_string(const void *fdt, int stroffset)
79{ 134{
80 return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; 135 return fdt_get_string(fdt, stroffset, NULL);
81} 136}
82 137
83static int _fdt_string_eq(const void *fdt, int stroffset, 138static int fdt_string_eq_(const void *fdt, int stroffset,
84 const char *s, int len) 139 const char *s, int len)
85{ 140{
86 const char *p = fdt_string(fdt, stroffset); 141 int slen;
142 const char *p = fdt_get_string(fdt, stroffset, &slen);
87 143
88 return (strlen(p) == len) && (memcmp(p, s, len) == 0); 144 return p && (slen == len) && (memcmp(p, s, len) == 0);
89} 145}
90 146
91uint32_t fdt_get_max_phandle(const void *fdt) 147uint32_t fdt_get_max_phandle(const void *fdt)
@@ -114,24 +170,45 @@ uint32_t fdt_get_max_phandle(const void *fdt)
114 return 0; 170 return 0;
115} 171}
116 172
173static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
174{
175 int offset = n * sizeof(struct fdt_reserve_entry);
176 int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
177
178 if (absoffset < fdt_off_mem_rsvmap(fdt))
179 return NULL;
180 if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))
181 return NULL;
182 return fdt_mem_rsv_(fdt, n);
183}
184
117int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) 185int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
118{ 186{
119 FDT_CHECK_HEADER(fdt); 187 const struct fdt_reserve_entry *re;
120 *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); 188
121 *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); 189 FDT_RO_PROBE(fdt);
190 re = fdt_mem_rsv(fdt, n);
191 if (!re)
192 return -FDT_ERR_BADOFFSET;
193
194 *address = fdt64_ld(&re->address);
195 *size = fdt64_ld(&re->size);
122 return 0; 196 return 0;
123} 197}
124 198
125int fdt_num_mem_rsv(const void *fdt) 199int fdt_num_mem_rsv(const void *fdt)
126{ 200{
127 int i = 0; 201 int i;
202 const struct fdt_reserve_entry *re;
128 203
129 while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) 204 for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {
130 i++; 205 if (fdt64_ld(&re->size) == 0)
131 return i; 206 return i;
207 }
208 return -FDT_ERR_TRUNCATED;
132} 209}
133 210
134static int _nextprop(const void *fdt, int offset) 211static int nextprop_(const void *fdt, int offset)
135{ 212{
136 uint32_t tag; 213 uint32_t tag;
137 int nextoffset; 214 int nextoffset;
@@ -160,13 +237,13 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
160{ 237{
161 int depth; 238 int depth;
162 239
163 FDT_CHECK_HEADER(fdt); 240 FDT_RO_PROBE(fdt);
164 241
165 for (depth = 0; 242 for (depth = 0;
166 (offset >= 0) && (depth >= 0); 243 (offset >= 0) && (depth >= 0);
167 offset = fdt_next_node(fdt, offset, &depth)) 244 offset = fdt_next_node(fdt, offset, &depth))
168 if ((depth == 1) 245 if ((depth == 1)
169 && _fdt_nodename_eq(fdt, offset, name, namelen)) 246 && fdt_nodename_eq_(fdt, offset, name, namelen))
170 return offset; 247 return offset;
171 248
172 if (depth < 0) 249 if (depth < 0)
@@ -186,7 +263,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
186 const char *p = path; 263 const char *p = path;
187 int offset = 0; 264 int offset = 0;
188 265
189 FDT_CHECK_HEADER(fdt); 266 FDT_RO_PROBE(fdt);
190 267
191 /* see if we have an alias */ 268 /* see if we have an alias */
192 if (*path != '/') { 269 if (*path != '/') {
@@ -232,17 +309,35 @@ int fdt_path_offset(const void *fdt, const char *path)
232 309
233const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) 310const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
234{ 311{
235 const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); 312 const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset);
313 const char *nameptr;
236 int err; 314 int err;
237 315
238 if (((err = fdt_check_header(fdt)) != 0) 316 if (((err = fdt_ro_probe_(fdt)) != 0)
239 || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) 317 || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
240 goto fail; 318 goto fail;
241 319
320 nameptr = nh->name;
321
322 if (fdt_version(fdt) < 0x10) {
323 /*
324 * For old FDT versions, match the naming conventions of V16:
325 * give only the leaf name (after all /). The actual tree
326 * contents are loosely checked.
327 */
328 const char *leaf;
329 leaf = strrchr(nameptr, '/');
330 if (leaf == NULL) {
331 err = -FDT_ERR_BADSTRUCTURE;
332 goto fail;
333 }
334 nameptr = leaf+1;
335 }
336
242 if (len) 337 if (len)
243 *len = strlen(nh->name); 338 *len = strlen(nameptr);
244 339
245 return nh->name; 340 return nameptr;
246 341
247 fail: 342 fail:
248 if (len) 343 if (len)
@@ -254,58 +349,79 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset)
254{ 349{
255 int offset; 350 int offset;
256 351
257 if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) 352 if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
258 return offset; 353 return offset;
259 354
260 return _nextprop(fdt, offset); 355 return nextprop_(fdt, offset);
261} 356}
262 357
263int fdt_next_property_offset(const void *fdt, int offset) 358int fdt_next_property_offset(const void *fdt, int offset)
264{ 359{
265 if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) 360 if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0)
266 return offset; 361 return offset;
267 362
268 return _nextprop(fdt, offset); 363 return nextprop_(fdt, offset);
269} 364}
270 365
271const struct fdt_property *fdt_get_property_by_offset(const void *fdt, 366static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
272 int offset, 367 int offset,
273 int *lenp) 368 int *lenp)
274{ 369{
275 int err; 370 int err;
276 const struct fdt_property *prop; 371 const struct fdt_property *prop;
277 372
278 if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { 373 if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
279 if (lenp) 374 if (lenp)
280 *lenp = err; 375 *lenp = err;
281 return NULL; 376 return NULL;
282 } 377 }
283 378
284 prop = _fdt_offset_ptr(fdt, offset); 379 prop = fdt_offset_ptr_(fdt, offset);
285 380
286 if (lenp) 381 if (lenp)
287 *lenp = fdt32_to_cpu(prop->len); 382 *lenp = fdt32_ld(&prop->len);
288 383
289 return prop; 384 return prop;
290} 385}
291 386
292const struct fdt_property *fdt_get_property_namelen(const void *fdt, 387const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
293 int offset, 388 int offset,
294 const char *name, 389 int *lenp)
295 int namelen, int *lenp) 390{
391 /* Prior to version 16, properties may need realignment
392 * and this API does not work. fdt_getprop_*() will, however. */
393
394 if (fdt_version(fdt) < 0x10) {
395 if (lenp)
396 *lenp = -FDT_ERR_BADVERSION;
397 return NULL;
398 }
399
400 return fdt_get_property_by_offset_(fdt, offset, lenp);
401}
402
403static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
404 int offset,
405 const char *name,
406 int namelen,
407 int *lenp,
408 int *poffset)
296{ 409{
297 for (offset = fdt_first_property_offset(fdt, offset); 410 for (offset = fdt_first_property_offset(fdt, offset);
298 (offset >= 0); 411 (offset >= 0);
299 (offset = fdt_next_property_offset(fdt, offset))) { 412 (offset = fdt_next_property_offset(fdt, offset))) {
300 const struct fdt_property *prop; 413 const struct fdt_property *prop;
301 414
302 if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { 415 if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {
303 offset = -FDT_ERR_INTERNAL; 416 offset = -FDT_ERR_INTERNAL;
304 break; 417 break;
305 } 418 }
306 if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), 419 if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff),
307 name, namelen)) 420 name, namelen)) {
421 if (poffset)
422 *poffset = offset;
308 return prop; 423 return prop;
424 }
309 } 425 }
310 426
311 if (lenp) 427 if (lenp)
@@ -313,6 +429,25 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
313 return NULL; 429 return NULL;
314} 430}
315 431
432
433const struct fdt_property *fdt_get_property_namelen(const void *fdt,
434 int offset,
435 const char *name,
436 int namelen, int *lenp)
437{
438 /* Prior to version 16, properties may need realignment
439 * and this API does not work. fdt_getprop_*() will, however. */
440 if (fdt_version(fdt) < 0x10) {
441 if (lenp)
442 *lenp = -FDT_ERR_BADVERSION;
443 return NULL;
444 }
445
446 return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp,
447 NULL);
448}
449
450
316const struct fdt_property *fdt_get_property(const void *fdt, 451const struct fdt_property *fdt_get_property(const void *fdt,
317 int nodeoffset, 452 int nodeoffset,
318 const char *name, int *lenp) 453 const char *name, int *lenp)
@@ -324,12 +459,18 @@ const struct fdt_property *fdt_get_property(const void *fdt,
324const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, 459const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
325 const char *name, int namelen, int *lenp) 460 const char *name, int namelen, int *lenp)
326{ 461{
462 int poffset;
327 const struct fdt_property *prop; 463 const struct fdt_property *prop;
328 464
329 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); 465 prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp,
466 &poffset);
330 if (!prop) 467 if (!prop)
331 return NULL; 468 return NULL;
332 469
470 /* Handle realignment */
471 if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
472 fdt32_ld(&prop->len) >= 8)
473 return prop->data + 4;
333 return prop->data; 474 return prop->data;
334} 475}
335 476
@@ -338,11 +479,26 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
338{ 479{
339 const struct fdt_property *prop; 480 const struct fdt_property *prop;
340 481
341 prop = fdt_get_property_by_offset(fdt, offset, lenp); 482 prop = fdt_get_property_by_offset_(fdt, offset, lenp);
342 if (!prop) 483 if (!prop)
343 return NULL; 484 return NULL;
344 if (namep) 485 if (namep) {
345 *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); 486 const char *name;
487 int namelen;
488 name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
489 &namelen);
490 if (!name) {
491 if (lenp)
492 *lenp = namelen;
493 return NULL;
494 }
495 *namep = name;
496 }
497
498 /* Handle realignment */
499 if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
500 fdt32_ld(&prop->len) >= 8)
501 return prop->data + 4;
346 return prop->data; 502 return prop->data;
347} 503}
348 504
@@ -366,7 +522,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
366 return 0; 522 return 0;
367 } 523 }
368 524
369 return fdt32_to_cpu(*php); 525 return fdt32_ld(php);
370} 526}
371 527
372const char *fdt_get_alias_namelen(const void *fdt, 528const char *fdt_get_alias_namelen(const void *fdt,
@@ -392,7 +548,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
392 int offset, depth, namelen; 548 int offset, depth, namelen;
393 const char *name; 549 const char *name;
394 550
395 FDT_CHECK_HEADER(fdt); 551 FDT_RO_PROBE(fdt);
396 552
397 if (buflen < 2) 553 if (buflen < 2)
398 return -FDT_ERR_NOSPACE; 554 return -FDT_ERR_NOSPACE;
@@ -444,7 +600,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
444 int offset, depth; 600 int offset, depth;
445 int supernodeoffset = -FDT_ERR_INTERNAL; 601 int supernodeoffset = -FDT_ERR_INTERNAL;
446 602
447 FDT_CHECK_HEADER(fdt); 603 FDT_RO_PROBE(fdt);
448 604
449 if (supernodedepth < 0) 605 if (supernodedepth < 0)
450 return -FDT_ERR_NOTFOUND; 606 return -FDT_ERR_NOTFOUND;
@@ -503,7 +659,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
503 const void *val; 659 const void *val;
504 int len; 660 int len;
505 661
506 FDT_CHECK_HEADER(fdt); 662 FDT_RO_PROBE(fdt);
507 663
508 /* FIXME: The algorithm here is pretty horrible: we scan each 664 /* FIXME: The algorithm here is pretty horrible: we scan each
509 * property of a node in fdt_getprop(), then if that didn't 665 * property of a node in fdt_getprop(), then if that didn't
@@ -529,7 +685,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
529 if ((phandle == 0) || (phandle == -1)) 685 if ((phandle == 0) || (phandle == -1))
530 return -FDT_ERR_BADPHANDLE; 686 return -FDT_ERR_BADPHANDLE;
531 687
532 FDT_CHECK_HEADER(fdt); 688 FDT_RO_PROBE(fdt);
533 689
534 /* FIXME: The algorithm here is pretty horrible: we 690 /* FIXME: The algorithm here is pretty horrible: we
535 * potentially scan each property of a node in 691 * potentially scan each property of a node in
@@ -682,7 +838,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
682{ 838{
683 int offset, err; 839 int offset, err;
684 840
685 FDT_CHECK_HEADER(fdt); 841 FDT_RO_PROBE(fdt);
686 842
687 /* FIXME: The algorithm here is pretty horrible: we scan each 843 /* FIXME: The algorithm here is pretty horrible: we scan each
688 * property of a node in fdt_node_check_compatible(), then if 844 * property of a node in fdt_node_check_compatible(), then if
@@ -701,3 +857,66 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
701 857
702 return offset; /* error from fdt_next_node() */ 858 return offset; /* error from fdt_next_node() */
703} 859}
860
861int fdt_check_full(const void *fdt, size_t bufsize)
862{
863 int err;
864 int num_memrsv;
865 int offset, nextoffset = 0;
866 uint32_t tag;
867 unsigned depth = 0;
868 const void *prop;
869 const char *propname;
870
871 if (bufsize < FDT_V1_SIZE)
872 return -FDT_ERR_TRUNCATED;
873 err = fdt_check_header(fdt);
874 if (err != 0)
875 return err;
876 if (bufsize < fdt_totalsize(fdt))
877 return -FDT_ERR_TRUNCATED;
878
879 num_memrsv = fdt_num_mem_rsv(fdt);
880 if (num_memrsv < 0)
881 return num_memrsv;
882
883 while (1) {
884 offset = nextoffset;
885 tag = fdt_next_tag(fdt, offset, &nextoffset);
886
887 if (nextoffset < 0)
888 return nextoffset;
889
890 switch (tag) {
891 case FDT_NOP:
892 break;
893
894 case FDT_END:
895 if (depth != 0)
896 return -FDT_ERR_BADSTRUCTURE;
897 return 0;
898
899 case FDT_BEGIN_NODE:
900 depth++;
901 if (depth > INT_MAX)
902 return -FDT_ERR_BADSTRUCTURE;
903 break;
904
905 case FDT_END_NODE:
906 if (depth == 0)
907 return -FDT_ERR_BADSTRUCTURE;
908 depth--;
909 break;
910
911 case FDT_PROP:
912 prop = fdt_getprop_by_offset(fdt, offset, &propname,
913 &err);
914 if (!prop)
915 return err;
916 break;
917
918 default:
919 return -FDT_ERR_INTERNAL;
920 }
921 }
922}
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 5c3a2bb0bc6b..2e49855d7cf8 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -55,8 +55,8 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58static int _fdt_blocks_misordered(const void *fdt, 58static int fdt_blocks_misordered_(const void *fdt,
59 int mem_rsv_size, int struct_size) 59 int mem_rsv_size, int struct_size)
60{ 60{
61 return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) 61 return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
62 || (fdt_off_dt_struct(fdt) < 62 || (fdt_off_dt_struct(fdt) <
@@ -67,13 +67,13 @@ static int _fdt_blocks_misordered(const void *fdt,
67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); 67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
68} 68}
69 69
70static int _fdt_rw_check_header(void *fdt) 70static int fdt_rw_probe_(void *fdt)
71{ 71{
72 FDT_CHECK_HEADER(fdt); 72 FDT_RO_PROBE(fdt);
73 73
74 if (fdt_version(fdt) < 17) 74 if (fdt_version(fdt) < 17)
75 return -FDT_ERR_BADVERSION; 75 return -FDT_ERR_BADVERSION;
76 if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), 76 if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
77 fdt_size_dt_struct(fdt))) 77 fdt_size_dt_struct(fdt)))
78 return -FDT_ERR_BADLAYOUT; 78 return -FDT_ERR_BADLAYOUT;
79 if (fdt_version(fdt) > 17) 79 if (fdt_version(fdt) > 17)
@@ -82,22 +82,22 @@ static int _fdt_rw_check_header(void *fdt)
82 return 0; 82 return 0;
83} 83}
84 84
85#define FDT_RW_CHECK_HEADER(fdt) \ 85#define FDT_RW_PROBE(fdt) \
86 { \ 86 { \
87 int __err; \ 87 int err_; \
88 if ((__err = _fdt_rw_check_header(fdt)) != 0) \ 88 if ((err_ = fdt_rw_probe_(fdt)) != 0) \
89 return __err; \ 89 return err_; \
90 } 90 }
91 91
92static inline int _fdt_data_size(void *fdt) 92static inline int fdt_data_size_(void *fdt)
93{ 93{
94 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); 94 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
95} 95}
96 96
97static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) 97static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
98{ 98{
99 char *p = splicepoint; 99 char *p = splicepoint;
100 char *end = (char *)fdt + _fdt_data_size(fdt); 100 char *end = (char *)fdt + fdt_data_size_(fdt);
101 101
102 if (((p + oldlen) < p) || ((p + oldlen) > end)) 102 if (((p + oldlen) < p) || ((p + oldlen) > end))
103 return -FDT_ERR_BADOFFSET; 103 return -FDT_ERR_BADOFFSET;
@@ -109,12 +109,12 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
109 return 0; 109 return 0;
110} 110}
111 111
112static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, 112static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,
113 int oldn, int newn) 113 int oldn, int newn)
114{ 114{
115 int delta = (newn - oldn) * sizeof(*p); 115 int delta = (newn - oldn) * sizeof(*p);
116 int err; 116 int err;
117 err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); 117 err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
118 if (err) 118 if (err)
119 return err; 119 return err;
120 fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); 120 fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
@@ -122,13 +122,13 @@ static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
122 return 0; 122 return 0;
123} 123}
124 124
125static int _fdt_splice_struct(void *fdt, void *p, 125static int fdt_splice_struct_(void *fdt, void *p,
126 int oldlen, int newlen) 126 int oldlen, int newlen)
127{ 127{
128 int delta = newlen - oldlen; 128 int delta = newlen - oldlen;
129 int err; 129 int err;
130 130
131 if ((err = _fdt_splice(fdt, p, oldlen, newlen))) 131 if ((err = fdt_splice_(fdt, p, oldlen, newlen)))
132 return err; 132 return err;
133 133
134 fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); 134 fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
@@ -136,20 +136,20 @@ static int _fdt_splice_struct(void *fdt, void *p,
136 return 0; 136 return 0;
137} 137}
138 138
139static int _fdt_splice_string(void *fdt, int newlen) 139static int fdt_splice_string_(void *fdt, int newlen)
140{ 140{
141 void *p = (char *)fdt 141 void *p = (char *)fdt
142 + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); 142 + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
143 int err; 143 int err;
144 144
145 if ((err = _fdt_splice(fdt, p, 0, newlen))) 145 if ((err = fdt_splice_(fdt, p, 0, newlen)))
146 return err; 146 return err;
147 147
148 fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); 148 fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
149 return 0; 149 return 0;
150} 150}
151 151
152static int _fdt_find_add_string(void *fdt, const char *s) 152static int fdt_find_add_string_(void *fdt, const char *s)
153{ 153{
154 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); 154 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
155 const char *p; 155 const char *p;
@@ -157,13 +157,13 @@ static int _fdt_find_add_string(void *fdt, const char *s)
157 int len = strlen(s) + 1; 157 int len = strlen(s) + 1;
158 int err; 158 int err;
159 159
160 p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); 160 p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
161 if (p) 161 if (p)
162 /* found it */ 162 /* found it */
163 return (p - strtab); 163 return (p - strtab);
164 164
165 new = strtab + fdt_size_dt_strings(fdt); 165 new = strtab + fdt_size_dt_strings(fdt);
166 err = _fdt_splice_string(fdt, len); 166 err = fdt_splice_string_(fdt, len);
167 if (err) 167 if (err)
168 return err; 168 return err;
169 169
@@ -176,10 +176,10 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
176 struct fdt_reserve_entry *re; 176 struct fdt_reserve_entry *re;
177 int err; 177 int err;
178 178
179 FDT_RW_CHECK_HEADER(fdt); 179 FDT_RW_PROBE(fdt);
180 180
181 re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); 181 re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
182 err = _fdt_splice_mem_rsv(fdt, re, 0, 1); 182 err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
183 if (err) 183 if (err)
184 return err; 184 return err;
185 185
@@ -190,17 +190,17 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
190 190
191int fdt_del_mem_rsv(void *fdt, int n) 191int fdt_del_mem_rsv(void *fdt, int n)
192{ 192{
193 struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); 193 struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);
194 194
195 FDT_RW_CHECK_HEADER(fdt); 195 FDT_RW_PROBE(fdt);
196 196
197 if (n >= fdt_num_mem_rsv(fdt)) 197 if (n >= fdt_num_mem_rsv(fdt))
198 return -FDT_ERR_NOTFOUND; 198 return -FDT_ERR_NOTFOUND;
199 199
200 return _fdt_splice_mem_rsv(fdt, re, 1, 0); 200 return fdt_splice_mem_rsv_(fdt, re, 1, 0);
201} 201}
202 202
203static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, 203static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
204 int len, struct fdt_property **prop) 204 int len, struct fdt_property **prop)
205{ 205{
206 int oldlen; 206 int oldlen;
@@ -210,7 +210,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
210 if (!*prop) 210 if (!*prop)
211 return oldlen; 211 return oldlen;
212 212
213 if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), 213 if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
214 FDT_TAGALIGN(len)))) 214 FDT_TAGALIGN(len))))
215 return err; 215 return err;
216 216
@@ -218,7 +218,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
218 return 0; 218 return 0;
219} 219}
220 220
221static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, 221static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
222 int len, struct fdt_property **prop) 222 int len, struct fdt_property **prop)
223{ 223{
224 int proplen; 224 int proplen;
@@ -226,17 +226,17 @@ static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
226 int namestroff; 226 int namestroff;
227 int err; 227 int err;
228 228
229 if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) 229 if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
230 return nextoffset; 230 return nextoffset;
231 231
232 namestroff = _fdt_find_add_string(fdt, name); 232 namestroff = fdt_find_add_string_(fdt, name);
233 if (namestroff < 0) 233 if (namestroff < 0)
234 return namestroff; 234 return namestroff;
235 235
236 *prop = _fdt_offset_ptr_w(fdt, nextoffset); 236 *prop = fdt_offset_ptr_w_(fdt, nextoffset);
237 proplen = sizeof(**prop) + FDT_TAGALIGN(len); 237 proplen = sizeof(**prop) + FDT_TAGALIGN(len);
238 238
239 err = _fdt_splice_struct(fdt, *prop, 0, proplen); 239 err = fdt_splice_struct_(fdt, *prop, 0, proplen);
240 if (err) 240 if (err)
241 return err; 241 return err;
242 242
@@ -252,7 +252,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
252 int oldlen, newlen; 252 int oldlen, newlen;
253 int err; 253 int err;
254 254
255 FDT_RW_CHECK_HEADER(fdt); 255 FDT_RW_PROBE(fdt);
256 256
257 namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); 257 namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
258 if (!namep) 258 if (!namep)
@@ -260,7 +260,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
260 260
261 newlen = strlen(name); 261 newlen = strlen(name);
262 262
263 err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), 263 err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1),
264 FDT_TAGALIGN(newlen+1)); 264 FDT_TAGALIGN(newlen+1));
265 if (err) 265 if (err)
266 return err; 266 return err;
@@ -275,11 +275,11 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
275 struct fdt_property *prop; 275 struct fdt_property *prop;
276 int err; 276 int err;
277 277
278 FDT_RW_CHECK_HEADER(fdt); 278 FDT_RW_PROBE(fdt);
279 279
280 err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); 280 err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
281 if (err == -FDT_ERR_NOTFOUND) 281 if (err == -FDT_ERR_NOTFOUND)
282 err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); 282 err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
283 if (err) 283 if (err)
284 return err; 284 return err;
285 285
@@ -308,12 +308,12 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
308 struct fdt_property *prop; 308 struct fdt_property *prop;
309 int err, oldlen, newlen; 309 int err, oldlen, newlen;
310 310
311 FDT_RW_CHECK_HEADER(fdt); 311 FDT_RW_PROBE(fdt);
312 312
313 prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); 313 prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
314 if (prop) { 314 if (prop) {
315 newlen = len + oldlen; 315 newlen = len + oldlen;
316 err = _fdt_splice_struct(fdt, prop->data, 316 err = fdt_splice_struct_(fdt, prop->data,
317 FDT_TAGALIGN(oldlen), 317 FDT_TAGALIGN(oldlen),
318 FDT_TAGALIGN(newlen)); 318 FDT_TAGALIGN(newlen));
319 if (err) 319 if (err)
@@ -321,7 +321,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
321 prop->len = cpu_to_fdt32(newlen); 321 prop->len = cpu_to_fdt32(newlen);
322 memcpy(prop->data + oldlen, val, len); 322 memcpy(prop->data + oldlen, val, len);
323 } else { 323 } else {
324 err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); 324 err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
325 if (err) 325 if (err)
326 return err; 326 return err;
327 memcpy(prop->data, val, len); 327 memcpy(prop->data, val, len);
@@ -334,14 +334,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
334 struct fdt_property *prop; 334 struct fdt_property *prop;
335 int len, proplen; 335 int len, proplen;
336 336
337 FDT_RW_CHECK_HEADER(fdt); 337 FDT_RW_PROBE(fdt);
338 338
339 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 339 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
340 if (!prop) 340 if (!prop)
341 return len; 341 return len;
342 342
343 proplen = sizeof(*prop) + FDT_TAGALIGN(len); 343 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
344 return _fdt_splice_struct(fdt, prop, proplen, 0); 344 return fdt_splice_struct_(fdt, prop, proplen, 0);
345} 345}
346 346
347int fdt_add_subnode_namelen(void *fdt, int parentoffset, 347int fdt_add_subnode_namelen(void *fdt, int parentoffset,
@@ -354,7 +354,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
354 uint32_t tag; 354 uint32_t tag;
355 fdt32_t *endtag; 355 fdt32_t *endtag;
356 356
357 FDT_RW_CHECK_HEADER(fdt); 357 FDT_RW_PROBE(fdt);
358 358
359 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); 359 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
360 if (offset >= 0) 360 if (offset >= 0)
@@ -369,10 +369,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
369 tag = fdt_next_tag(fdt, offset, &nextoffset); 369 tag = fdt_next_tag(fdt, offset, &nextoffset);
370 } while ((tag == FDT_PROP) || (tag == FDT_NOP)); 370 } while ((tag == FDT_PROP) || (tag == FDT_NOP));
371 371
372 nh = _fdt_offset_ptr_w(fdt, offset); 372 nh = fdt_offset_ptr_w_(fdt, offset);
373 nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; 373 nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
374 374
375 err = _fdt_splice_struct(fdt, nh, 0, nodelen); 375 err = fdt_splice_struct_(fdt, nh, 0, nodelen);
376 if (err) 376 if (err)
377 return err; 377 return err;
378 378
@@ -394,17 +394,17 @@ int fdt_del_node(void *fdt, int nodeoffset)
394{ 394{
395 int endoffset; 395 int endoffset;
396 396
397 FDT_RW_CHECK_HEADER(fdt); 397 FDT_RW_PROBE(fdt);
398 398
399 endoffset = _fdt_node_end_offset(fdt, nodeoffset); 399 endoffset = fdt_node_end_offset_(fdt, nodeoffset);
400 if (endoffset < 0) 400 if (endoffset < 0)
401 return endoffset; 401 return endoffset;
402 402
403 return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), 403 return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset),
404 endoffset - nodeoffset, 0); 404 endoffset - nodeoffset, 0);
405} 405}
406 406
407static void _fdt_packblocks(const char *old, char *new, 407static void fdt_packblocks_(const char *old, char *new,
408 int mem_rsv_size, int struct_size) 408 int mem_rsv_size, int struct_size)
409{ 409{
410 int mem_rsv_off, struct_off, strings_off; 410 int mem_rsv_off, struct_off, strings_off;
@@ -435,7 +435,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
435 const char *fdtend = fdtstart + fdt_totalsize(fdt); 435 const char *fdtend = fdtstart + fdt_totalsize(fdt);
436 char *tmp; 436 char *tmp;
437 437
438 FDT_CHECK_HEADER(fdt); 438 FDT_RO_PROBE(fdt);
439 439
440 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) 440 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
441 * sizeof(struct fdt_reserve_entry); 441 * sizeof(struct fdt_reserve_entry);
@@ -450,7 +450,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
450 return struct_size; 450 return struct_size;
451 } 451 }
452 452
453 if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { 453 if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
454 /* no further work necessary */ 454 /* no further work necessary */
455 err = fdt_move(fdt, buf, bufsize); 455 err = fdt_move(fdt, buf, bufsize);
456 if (err) 456 if (err)
@@ -478,7 +478,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
478 return -FDT_ERR_NOSPACE; 478 return -FDT_ERR_NOSPACE;
479 } 479 }
480 480
481 _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); 481 fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
482 memmove(buf, tmp, newsize); 482 memmove(buf, tmp, newsize);
483 483
484 fdt_set_magic(buf, FDT_MAGIC); 484 fdt_set_magic(buf, FDT_MAGIC);
@@ -494,12 +494,12 @@ int fdt_pack(void *fdt)
494{ 494{
495 int mem_rsv_size; 495 int mem_rsv_size;
496 496
497 FDT_RW_CHECK_HEADER(fdt); 497 FDT_RW_PROBE(fdt);
498 498
499 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) 499 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
500 * sizeof(struct fdt_reserve_entry); 500 * sizeof(struct fdt_reserve_entry);
501 _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); 501 fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
502 fdt_set_totalsize(fdt, _fdt_data_size(fdt)); 502 fdt_set_totalsize(fdt, fdt_data_size_(fdt));
503 503
504 return 0; 504 return 0;
505} 505}
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 2bd15e7aef87..9fa4a94d83c3 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -55,22 +55,78 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58static int _fdt_sw_check_header(void *fdt) 58static int fdt_sw_probe_(void *fdt)
59{ 59{
60 if (fdt_magic(fdt) != FDT_SW_MAGIC) 60 if (fdt_magic(fdt) == FDT_MAGIC)
61 return -FDT_ERR_BADSTATE;
62 else if (fdt_magic(fdt) != FDT_SW_MAGIC)
61 return -FDT_ERR_BADMAGIC; 63 return -FDT_ERR_BADMAGIC;
62 /* FIXME: should check more details about the header state */
63 return 0; 64 return 0;
64} 65}
65 66
66#define FDT_SW_CHECK_HEADER(fdt) \ 67#define FDT_SW_PROBE(fdt) \
68 { \
69 int err; \
70 if ((err = fdt_sw_probe_(fdt)) != 0) \
71 return err; \
72 }
73
74/* 'memrsv' state: Initial state after fdt_create()
75 *
76 * Allowed functions:
77 * fdt_add_reservmap_entry()
78 * fdt_finish_reservemap() [moves to 'struct' state]
79 */
80static int fdt_sw_probe_memrsv_(void *fdt)
81{
82 int err = fdt_sw_probe_(fdt);
83 if (err)
84 return err;
85
86 if (fdt_off_dt_strings(fdt) != 0)
87 return -FDT_ERR_BADSTATE;
88 return 0;
89}
90
91#define FDT_SW_PROBE_MEMRSV(fdt) \
92 { \
93 int err; \
94 if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \
95 return err; \
96 }
97
98/* 'struct' state: Enter this state after fdt_finish_reservemap()
99 *
100 * Allowed functions:
101 * fdt_begin_node()
102 * fdt_end_node()
103 * fdt_property*()
104 * fdt_finish() [moves to 'complete' state]
105 */
106static int fdt_sw_probe_struct_(void *fdt)
107{
108 int err = fdt_sw_probe_(fdt);
109 if (err)
110 return err;
111
112 if (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))
113 return -FDT_ERR_BADSTATE;
114 return 0;
115}
116
117#define FDT_SW_PROBE_STRUCT(fdt) \
67 { \ 118 { \
68 int err; \ 119 int err; \
69 if ((err = _fdt_sw_check_header(fdt)) != 0) \ 120 if ((err = fdt_sw_probe_struct_(fdt)) != 0) \
70 return err; \ 121 return err; \
71 } 122 }
72 123
73static void *_fdt_grab_space(void *fdt, size_t len) 124/* 'complete' state: Enter this state after fdt_finish()
125 *
126 * Allowed functions: none
127 */
128
129static void *fdt_grab_space_(void *fdt, size_t len)
74{ 130{
75 int offset = fdt_size_dt_struct(fdt); 131 int offset = fdt_size_dt_struct(fdt);
76 int spaceleft; 132 int spaceleft;
@@ -82,14 +138,16 @@ static void *_fdt_grab_space(void *fdt, size_t len)
82 return NULL; 138 return NULL;
83 139
84 fdt_set_size_dt_struct(fdt, offset + len); 140 fdt_set_size_dt_struct(fdt, offset + len);
85 return _fdt_offset_ptr_w(fdt, offset); 141 return fdt_offset_ptr_w_(fdt, offset);
86} 142}
87 143
88int fdt_create(void *buf, int bufsize) 144int fdt_create(void *buf, int bufsize)
89{ 145{
146 const size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header),
147 sizeof(struct fdt_reserve_entry));
90 void *fdt = buf; 148 void *fdt = buf;
91 149
92 if (bufsize < sizeof(struct fdt_header)) 150 if (bufsize < hdrsize)
93 return -FDT_ERR_NOSPACE; 151 return -FDT_ERR_NOSPACE;
94 152
95 memset(buf, 0, bufsize); 153 memset(buf, 0, bufsize);
@@ -99,10 +157,9 @@ int fdt_create(void *buf, int bufsize)
99 fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); 157 fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
100 fdt_set_totalsize(fdt, bufsize); 158 fdt_set_totalsize(fdt, bufsize);
101 159
102 fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), 160 fdt_set_off_mem_rsvmap(fdt, hdrsize);
103 sizeof(struct fdt_reserve_entry)));
104 fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); 161 fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
105 fdt_set_off_dt_strings(fdt, bufsize); 162 fdt_set_off_dt_strings(fdt, 0);
106 163
107 return 0; 164 return 0;
108} 165}
@@ -112,11 +169,14 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
112 size_t headsize, tailsize; 169 size_t headsize, tailsize;
113 char *oldtail, *newtail; 170 char *oldtail, *newtail;
114 171
115 FDT_SW_CHECK_HEADER(fdt); 172 FDT_SW_PROBE(fdt);
116 173
117 headsize = fdt_off_dt_struct(fdt); 174 headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
118 tailsize = fdt_size_dt_strings(fdt); 175 tailsize = fdt_size_dt_strings(fdt);
119 176
177 if ((headsize + tailsize) > fdt_totalsize(fdt))
178 return -FDT_ERR_INTERNAL;
179
120 if ((headsize + tailsize) > bufsize) 180 if ((headsize + tailsize) > bufsize)
121 return -FDT_ERR_NOSPACE; 181 return -FDT_ERR_NOSPACE;
122 182
@@ -133,8 +193,9 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
133 memmove(buf, fdt, headsize); 193 memmove(buf, fdt, headsize);
134 } 194 }
135 195
136 fdt_set_off_dt_strings(buf, bufsize);
137 fdt_set_totalsize(buf, bufsize); 196 fdt_set_totalsize(buf, bufsize);
197 if (fdt_off_dt_strings(buf))
198 fdt_set_off_dt_strings(buf, bufsize);
138 199
139 return 0; 200 return 0;
140} 201}
@@ -144,10 +205,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
144 struct fdt_reserve_entry *re; 205 struct fdt_reserve_entry *re;
145 int offset; 206 int offset;
146 207
147 FDT_SW_CHECK_HEADER(fdt); 208 FDT_SW_PROBE_MEMRSV(fdt);
148
149 if (fdt_size_dt_struct(fdt))
150 return -FDT_ERR_BADSTATE;
151 209
152 offset = fdt_off_dt_struct(fdt); 210 offset = fdt_off_dt_struct(fdt);
153 if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) 211 if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
@@ -164,17 +222,24 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
164 222
165int fdt_finish_reservemap(void *fdt) 223int fdt_finish_reservemap(void *fdt)
166{ 224{
167 return fdt_add_reservemap_entry(fdt, 0, 0); 225 int err = fdt_add_reservemap_entry(fdt, 0, 0);
226
227 if (err)
228 return err;
229
230 fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt));
231 return 0;
168} 232}
169 233
170int fdt_begin_node(void *fdt, const char *name) 234int fdt_begin_node(void *fdt, const char *name)
171{ 235{
172 struct fdt_node_header *nh; 236 struct fdt_node_header *nh;
173 int namelen = strlen(name) + 1; 237 int namelen;
174 238
175 FDT_SW_CHECK_HEADER(fdt); 239 FDT_SW_PROBE_STRUCT(fdt);
176 240
177 nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); 241 namelen = strlen(name) + 1;
242 nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
178 if (! nh) 243 if (! nh)
179 return -FDT_ERR_NOSPACE; 244 return -FDT_ERR_NOSPACE;
180 245
@@ -187,9 +252,9 @@ int fdt_end_node(void *fdt)
187{ 252{
188 fdt32_t *en; 253 fdt32_t *en;
189 254
190 FDT_SW_CHECK_HEADER(fdt); 255 FDT_SW_PROBE_STRUCT(fdt);
191 256
192 en = _fdt_grab_space(fdt, FDT_TAGSIZE); 257 en = fdt_grab_space_(fdt, FDT_TAGSIZE);
193 if (! en) 258 if (! en)
194 return -FDT_ERR_NOSPACE; 259 return -FDT_ERR_NOSPACE;
195 260
@@ -197,7 +262,7 @@ int fdt_end_node(void *fdt)
197 return 0; 262 return 0;
198} 263}
199 264
200static int _fdt_find_add_string(void *fdt, const char *s) 265static int fdt_find_add_string_(void *fdt, const char *s)
201{ 266{
202 char *strtab = (char *)fdt + fdt_totalsize(fdt); 267 char *strtab = (char *)fdt + fdt_totalsize(fdt);
203 const char *p; 268 const char *p;
@@ -205,7 +270,7 @@ static int _fdt_find_add_string(void *fdt, const char *s)
205 int len = strlen(s) + 1; 270 int len = strlen(s) + 1;
206 int struct_top, offset; 271 int struct_top, offset;
207 272
208 p = _fdt_find_string(strtab - strtabsize, strtabsize, s); 273 p = fdt_find_string_(strtab - strtabsize, strtabsize, s);
209 if (p) 274 if (p)
210 return p - strtab; 275 return p - strtab;
211 276
@@ -225,13 +290,13 @@ int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
225 struct fdt_property *prop; 290 struct fdt_property *prop;
226 int nameoff; 291 int nameoff;
227 292
228 FDT_SW_CHECK_HEADER(fdt); 293 FDT_SW_PROBE_STRUCT(fdt);
229 294
230 nameoff = _fdt_find_add_string(fdt, name); 295 nameoff = fdt_find_add_string_(fdt, name);
231 if (nameoff == 0) 296 if (nameoff == 0)
232 return -FDT_ERR_NOSPACE; 297 return -FDT_ERR_NOSPACE;
233 298
234 prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); 299 prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
235 if (! prop) 300 if (! prop)
236 return -FDT_ERR_NOSPACE; 301 return -FDT_ERR_NOSPACE;
237 302
@@ -262,10 +327,10 @@ int fdt_finish(void *fdt)
262 uint32_t tag; 327 uint32_t tag;
263 int offset, nextoffset; 328 int offset, nextoffset;
264 329
265 FDT_SW_CHECK_HEADER(fdt); 330 FDT_SW_PROBE_STRUCT(fdt);
266 331
267 /* Add terminator */ 332 /* Add terminator */
268 end = _fdt_grab_space(fdt, sizeof(*end)); 333 end = fdt_grab_space_(fdt, sizeof(*end));
269 if (! end) 334 if (! end)
270 return -FDT_ERR_NOSPACE; 335 return -FDT_ERR_NOSPACE;
271 *end = cpu_to_fdt32(FDT_END); 336 *end = cpu_to_fdt32(FDT_END);
@@ -281,7 +346,7 @@ int fdt_finish(void *fdt)
281 while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { 346 while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
282 if (tag == FDT_PROP) { 347 if (tag == FDT_PROP) {
283 struct fdt_property *prop = 348 struct fdt_property *prop =
284 _fdt_offset_ptr_w(fdt, offset); 349 fdt_offset_ptr_w_(fdt, offset);
285 int nameoff; 350 int nameoff;
286 351
287 nameoff = fdt32_to_cpu(prop->nameoff); 352 nameoff = fdt32_to_cpu(prop->nameoff);
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index 5e859198622b..534c1cbbb2f3 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -93,7 +93,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
93 val, len); 93 val, len);
94} 94}
95 95
96static void _fdt_nop_region(void *start, int len) 96static void fdt_nop_region_(void *start, int len)
97{ 97{
98 fdt32_t *p; 98 fdt32_t *p;
99 99
@@ -110,12 +110,12 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
110 if (!prop) 110 if (!prop)
111 return len; 111 return len;
112 112
113 _fdt_nop_region(prop, len + sizeof(*prop)); 113 fdt_nop_region_(prop, len + sizeof(*prop));
114 114
115 return 0; 115 return 0;
116} 116}
117 117
118int _fdt_node_end_offset(void *fdt, int offset) 118int fdt_node_end_offset_(void *fdt, int offset)
119{ 119{
120 int depth = 0; 120 int depth = 0;
121 121
@@ -129,11 +129,11 @@ int fdt_nop_node(void *fdt, int nodeoffset)
129{ 129{
130 int endoffset; 130 int endoffset;
131 131
132 endoffset = _fdt_node_end_offset(fdt, nodeoffset); 132 endoffset = fdt_node_end_offset_(fdt, nodeoffset);
133 if (endoffset < 0) 133 if (endoffset < 0)
134 return endoffset; 134 return endoffset;
135 135
136 _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), 136 fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0),
137 endoffset - nodeoffset); 137 endoffset - nodeoffset);
138 return 0; 138 return 0;
139} 139}
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 7f83023ee109..2bd151dd355f 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -1,5 +1,5 @@
1#ifndef _LIBFDT_H 1#ifndef LIBFDT_H
2#define _LIBFDT_H 2#define LIBFDT_H
3/* 3/*
4 * libfdt - Flat Device Tree manipulation 4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation. 5 * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -54,7 +54,7 @@
54#include "libfdt_env.h" 54#include "libfdt_env.h"
55#include "fdt.h" 55#include "fdt.h"
56 56
57#define FDT_FIRST_SUPPORTED_VERSION 0x10 57#define FDT_FIRST_SUPPORTED_VERSION 0x02
58#define FDT_LAST_SUPPORTED_VERSION 0x11 58#define FDT_LAST_SUPPORTED_VERSION 0x11
59 59
60/* Error codes: informative error codes */ 60/* Error codes: informative error codes */
@@ -90,8 +90,9 @@
90 90
91/* Error codes: codes for bad device tree blobs */ 91/* Error codes: codes for bad device tree blobs */
92#define FDT_ERR_TRUNCATED 8 92#define FDT_ERR_TRUNCATED 8
93 /* FDT_ERR_TRUNCATED: Structure block of the given device tree 93 /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
94 * ends without an FDT_END tag. */ 94 * terminated (overflows, goes outside allowed bounds, or
95 * isn't properly terminated). */
95#define FDT_ERR_BADMAGIC 9 96#define FDT_ERR_BADMAGIC 9
96 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a 97 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
97 * device tree at all - it is missing the flattened device 98 * device tree at all - it is missing the flattened device
@@ -153,6 +154,29 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
153 154
154uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); 155uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
155 156
157/*
158 * Alignment helpers:
159 * These helpers access words from a device tree blob. They're
160 * built to work even with unaligned pointers on platforms (ike
161 * ARM) that don't like unaligned loads and stores
162 */
163
164static inline uint32_t fdt32_ld(const fdt32_t *p)
165{
166 fdt32_t v;
167
168 memcpy(&v, p, sizeof(v));
169 return fdt32_to_cpu(v);
170}
171
172static inline uint64_t fdt64_ld(const fdt64_t *p)
173{
174 fdt64_t v;
175
176 memcpy(&v, p, sizeof(v));
177 return fdt64_to_cpu(v);
178}
179
156/**********************************************************************/ 180/**********************************************************************/
157/* Traversal functions */ 181/* Traversal functions */
158/**********************************************************************/ 182/**********************************************************************/
@@ -213,7 +237,7 @@ int fdt_next_subnode(const void *fdt, int offset);
213/* General functions */ 237/* General functions */
214/**********************************************************************/ 238/**********************************************************************/
215#define fdt_get_header(fdt, field) \ 239#define fdt_get_header(fdt, field) \
216 (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) 240 (fdt32_ld(&((const struct fdt_header *)(fdt))->field))
217#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) 241#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
218#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) 242#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
219#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) 243#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
@@ -225,37 +249,50 @@ int fdt_next_subnode(const void *fdt, int offset);
225#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) 249#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
226#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) 250#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
227 251
228#define __fdt_set_hdr(name) \ 252#define fdt_set_hdr_(name) \
229 static inline void fdt_set_##name(void *fdt, uint32_t val) \ 253 static inline void fdt_set_##name(void *fdt, uint32_t val) \
230 { \ 254 { \
231 struct fdt_header *fdth = (struct fdt_header *)fdt; \ 255 struct fdt_header *fdth = (struct fdt_header *)fdt; \
232 fdth->name = cpu_to_fdt32(val); \ 256 fdth->name = cpu_to_fdt32(val); \
233 } 257 }
234__fdt_set_hdr(magic); 258fdt_set_hdr_(magic);
235__fdt_set_hdr(totalsize); 259fdt_set_hdr_(totalsize);
236__fdt_set_hdr(off_dt_struct); 260fdt_set_hdr_(off_dt_struct);
237__fdt_set_hdr(off_dt_strings); 261fdt_set_hdr_(off_dt_strings);
238__fdt_set_hdr(off_mem_rsvmap); 262fdt_set_hdr_(off_mem_rsvmap);
239__fdt_set_hdr(version); 263fdt_set_hdr_(version);
240__fdt_set_hdr(last_comp_version); 264fdt_set_hdr_(last_comp_version);
241__fdt_set_hdr(boot_cpuid_phys); 265fdt_set_hdr_(boot_cpuid_phys);
242__fdt_set_hdr(size_dt_strings); 266fdt_set_hdr_(size_dt_strings);
243__fdt_set_hdr(size_dt_struct); 267fdt_set_hdr_(size_dt_struct);
244#undef __fdt_set_hdr 268#undef fdt_set_hdr_
245 269
246/** 270/**
247 * fdt_check_header - sanity check a device tree or possible device tree 271 * fdt_header_size - return the size of the tree's header
272 * @fdt: pointer to a flattened device tree
273 */
274size_t fdt_header_size_(uint32_t version);
275static inline size_t fdt_header_size(const void *fdt)
276{
277 return fdt_header_size_(fdt_version(fdt));
278}
279
280/**
281 * fdt_check_header - sanity check a device tree header
282
248 * @fdt: pointer to data which might be a flattened device tree 283 * @fdt: pointer to data which might be a flattened device tree
249 * 284 *
250 * fdt_check_header() checks that the given buffer contains what 285 * fdt_check_header() checks that the given buffer contains what
251 * appears to be a flattened device tree with sane information in its 286 * appears to be a flattened device tree, and that the header contains
252 * header. 287 * valid information (to the extent that can be determined from the
288 * header alone).
253 * 289 *
254 * returns: 290 * returns:
255 * 0, if the buffer appears to contain a valid device tree 291 * 0, if the buffer appears to contain a valid device tree
256 * -FDT_ERR_BADMAGIC, 292 * -FDT_ERR_BADMAGIC,
257 * -FDT_ERR_BADVERSION, 293 * -FDT_ERR_BADVERSION,
258 * -FDT_ERR_BADSTATE, standard meanings, as above 294 * -FDT_ERR_BADSTATE,
295 * -FDT_ERR_TRUNCATED, standard meanings, as above
259 */ 296 */
260int fdt_check_header(const void *fdt); 297int fdt_check_header(const void *fdt);
261 298
@@ -284,6 +321,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
284/* Read-only functions */ 321/* Read-only functions */
285/**********************************************************************/ 322/**********************************************************************/
286 323
324int fdt_check_full(const void *fdt, size_t bufsize);
325
326/**
327 * fdt_get_string - retrieve a string from the strings block of a device tree
328 * @fdt: pointer to the device tree blob
329 * @stroffset: offset of the string within the strings block (native endian)
330 * @lenp: optional pointer to return the string's length
331 *
332 * fdt_get_string() retrieves a pointer to a single string from the
333 * strings block of the device tree blob at fdt, and optionally also
334 * returns the string's length in *lenp.
335 *
336 * returns:
337 * a pointer to the string, on success
338 * NULL, if stroffset is out of bounds, or doesn't point to a valid string
339 */
340const char *fdt_get_string(const void *fdt, int stroffset, int *lenp);
341
287/** 342/**
288 * fdt_string - retrieve a string from the strings block of a device tree 343 * fdt_string - retrieve a string from the strings block of a device tree
289 * @fdt: pointer to the device tree blob 344 * @fdt: pointer to the device tree blob
@@ -294,7 +349,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
294 * 349 *
295 * returns: 350 * returns:
296 * a pointer to the string, on success 351 * a pointer to the string, on success
297 * NULL, if stroffset is out of bounds 352 * NULL, if stroffset is out of bounds, or doesn't point to a valid string
298 */ 353 */
299const char *fdt_string(const void *fdt, int stroffset); 354const char *fdt_string(const void *fdt, int stroffset);
300 355
@@ -527,6 +582,9 @@ int fdt_next_property_offset(const void *fdt, int offset);
527 * offset. If lenp is non-NULL, the length of the property value is 582 * offset. If lenp is non-NULL, the length of the property value is
528 * also returned, in the integer pointed to by lenp. 583 * also returned, in the integer pointed to by lenp.
529 * 584 *
585 * Note that this code only works on device tree versions >= 16. fdt_getprop()
586 * works on all versions.
587 *
530 * returns: 588 * returns:
531 * pointer to the structure representing the property 589 * pointer to the structure representing the property
532 * if lenp is non-NULL, *lenp contains the length of the property 590 * if lenp is non-NULL, *lenp contains the length of the property
@@ -1087,7 +1145,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
1087 * 1145 *
1088 * returns: 1146 * returns:
1089 * 0 <= n < FDT_MAX_NCELLS, on success 1147 * 0 <= n < FDT_MAX_NCELLS, on success
1090 * 2, if the node has no #address-cells property 1148 * 2, if the node has no #size-cells property
1091 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 1149 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
1092 * #size-cells property 1150 * #size-cells property
1093 * -FDT_ERR_BADMAGIC, 1151 * -FDT_ERR_BADMAGIC,
@@ -1310,10 +1368,13 @@ static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
1310 fdt64_t tmp = cpu_to_fdt64(val); 1368 fdt64_t tmp = cpu_to_fdt64(val);
1311 return fdt_property(fdt, name, &tmp, sizeof(tmp)); 1369 return fdt_property(fdt, name, &tmp, sizeof(tmp));
1312} 1370}
1371
1372#ifndef SWIG /* Not available in Python */
1313static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) 1373static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
1314{ 1374{
1315 return fdt_property_u32(fdt, name, val); 1375 return fdt_property_u32(fdt, name, val);
1316} 1376}
1377#endif
1317 1378
1318/** 1379/**
1319 * fdt_property_placeholder - add a new property and return a ptr to its value 1380 * fdt_property_placeholder - add a new property and return a ptr to its value
@@ -1449,7 +1510,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
1449 const void *val, int len); 1510 const void *val, int len);
1450 1511
1451/** 1512/**
1452 * fdt_setprop _placeholder - allocate space for a property 1513 * fdt_setprop_placeholder - allocate space for a property
1453 * @fdt: pointer to the device tree blob 1514 * @fdt: pointer to the device tree blob
1454 * @nodeoffset: offset of the node whose property to change 1515 * @nodeoffset: offset of the node whose property to change
1455 * @name: name of the property to change 1516 * @name: name of the property to change
@@ -1896,4 +1957,4 @@ int fdt_overlay_apply(void *fdt, void *fdto);
1896 1957
1897const char *fdt_strerror(int errval); 1958const char *fdt_strerror(int errval);
1898 1959
1899#endif /* _LIBFDT_H */ 1960#endif /* LIBFDT_H */
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
index 952056cddf09..eb2053845c9c 100644
--- a/scripts/dtc/libfdt/libfdt_env.h
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -1,5 +1,5 @@
1#ifndef _LIBFDT_ENV_H 1#ifndef LIBFDT_ENV_H
2#define _LIBFDT_ENV_H 2#define LIBFDT_ENV_H
3/* 3/*
4 * libfdt - Flat Device Tree manipulation 4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation. 5 * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -56,6 +56,7 @@
56#include <stdint.h> 56#include <stdint.h>
57#include <stdlib.h> 57#include <stdlib.h>
58#include <string.h> 58#include <string.h>
59#include <limits.h>
59 60
60#ifdef __CHECKER__ 61#ifdef __CHECKER__
61#define FDT_FORCE __attribute__((force)) 62#define FDT_FORCE __attribute__((force))
@@ -109,4 +110,31 @@ static inline fdt64_t cpu_to_fdt64(uint64_t x)
109#undef CPU_TO_FDT16 110#undef CPU_TO_FDT16
110#undef EXTRACT_BYTE 111#undef EXTRACT_BYTE
111 112
112#endif /* _LIBFDT_ENV_H */ 113#ifdef __APPLE__
114#include <AvailabilityMacros.h>
115
116/* strnlen() is not available on Mac OS < 10.7 */
117# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \
118 MAC_OS_X_VERSION_10_7)
119
120#define strnlen fdt_strnlen
121
122/*
123 * fdt_strnlen: returns the length of a string or max_count - which ever is
124 * smallest.
125 * Input 1 string: the string whose size is to be determined
126 * Input 2 max_count: the maximum value returned by this function
127 * Output: length of the string or max_count (the smallest of the two)
128 */
129static inline size_t fdt_strnlen(const char *string, size_t max_count)
130{
131 const char *p = memchr(string, 0, max_count);
132 return p ? p - string : max_count;
133}
134
135#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <
136 MAC_OS_X_VERSION_10_7) */
137
138#endif /* __APPLE__ */
139
140#endif /* LIBFDT_ENV_H */
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
index 02cfa6fb612d..4109f890ae60 100644
--- a/scripts/dtc/libfdt/libfdt_internal.h
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -1,5 +1,5 @@
1#ifndef _LIBFDT_INTERNAL_H 1#ifndef LIBFDT_INTERNAL_H
2#define _LIBFDT_INTERNAL_H 2#define LIBFDT_INTERNAL_H
3/* 3/*
4 * libfdt - Flat Device Tree manipulation 4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation. 5 * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -55,29 +55,30 @@
55#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 55#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
56#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) 56#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
57 57
58#define FDT_CHECK_HEADER(fdt) \ 58int fdt_ro_probe_(const void *fdt);
59#define FDT_RO_PROBE(fdt) \
59 { \ 60 { \
60 int __err; \ 61 int err_; \
61 if ((__err = fdt_check_header(fdt)) != 0) \ 62 if ((err_ = fdt_ro_probe_(fdt)) != 0) \
62 return __err; \ 63 return err_; \
63 } 64 }
64 65
65int _fdt_check_node_offset(const void *fdt, int offset); 66int fdt_check_node_offset_(const void *fdt, int offset);
66int _fdt_check_prop_offset(const void *fdt, int offset); 67int fdt_check_prop_offset_(const void *fdt, int offset);
67const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); 68const char *fdt_find_string_(const char *strtab, int tabsize, const char *s);
68int _fdt_node_end_offset(void *fdt, int nodeoffset); 69int fdt_node_end_offset_(void *fdt, int nodeoffset);
69 70
70static inline const void *_fdt_offset_ptr(const void *fdt, int offset) 71static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
71{ 72{
72 return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; 73 return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
73} 74}
74 75
75static inline void *_fdt_offset_ptr_w(void *fdt, int offset) 76static inline void *fdt_offset_ptr_w_(void *fdt, int offset)
76{ 77{
77 return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); 78 return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset);
78} 79}
79 80
80static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) 81static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n)
81{ 82{
82 const struct fdt_reserve_entry *rsv_table = 83 const struct fdt_reserve_entry *rsv_table =
83 (const struct fdt_reserve_entry *) 84 (const struct fdt_reserve_entry *)
@@ -85,11 +86,11 @@ static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int
85 86
86 return rsv_table + n; 87 return rsv_table + n;
87} 88}
88static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) 89static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
89{ 90{
90 return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); 91 return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);
91} 92}
92 93
93#define FDT_SW_MAGIC (~FDT_MAGIC) 94#define FDT_SW_MAGIC (~FDT_MAGIC)
94 95
95#endif /* _LIBFDT_INTERNAL_H */ 96#endif /* LIBFDT_INTERNAL_H */
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 6846ad2fd6d2..4ff0679e0062 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)
134 return node; 134 return node;
135} 135}
136 136
137struct node *omit_node_if_unused(struct node *node)
138{
139 node->omit_if_unused = 1;
140
141 return node;
142}
143
144struct node *reference_node(struct node *node)
145{
146 node->is_referenced = 1;
147
148 return node;
149}
150
137struct node *merge_nodes(struct node *old_node, struct node *new_node) 151struct node *merge_nodes(struct node *old_node, struct node *new_node)
138{ 152{
139 struct property *new_prop, *old_prop; 153 struct property *new_prop, *old_prop;
@@ -216,7 +230,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
216 return old_node; 230 return old_node;
217} 231}
218 232
219void add_orphan_node(struct node *dt, struct node *new_node, char *ref) 233struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
220{ 234{
221 static unsigned int next_orphan_fragment = 0; 235 static unsigned int next_orphan_fragment = 0;
222 struct node *node; 236 struct node *node;
@@ -224,10 +238,16 @@ void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
224 struct data d = empty_data; 238 struct data d = empty_data;
225 char *name; 239 char *name;
226 240
227 d = data_add_marker(d, REF_PHANDLE, ref); 241 if (ref[0] == '/') {
228 d = data_append_integer(d, 0xffffffff, 32); 242 d = data_append_data(d, ref, strlen(ref) + 1);
243
244 p = build_property("target-path", d);
245 } else {
246 d = data_add_marker(d, REF_PHANDLE, ref);
247 d = data_append_integer(d, 0xffffffff, 32);
229 248
230 p = build_property("target", d); 249 p = build_property("target", d);
250 }
231 251
232 xasprintf(&name, "fragment@%u", 252 xasprintf(&name, "fragment@%u",
233 next_orphan_fragment++); 253 next_orphan_fragment++);
@@ -236,6 +256,7 @@ void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
236 name_node(node, name); 256 name_node(node, name);
237 257
238 add_child(dt, node); 258 add_child(dt, node);
259 return dt;
239} 260}
240 261
241struct node *chain_node(struct node *first, struct node *list) 262struct node *chain_node(struct node *first, struct node *list)
@@ -507,7 +528,7 @@ struct node *get_node_by_path(struct node *tree, const char *path)
507 528
508 for_each_child(tree, child) { 529 for_each_child(tree, child) {
509 if (p && (strlen(child->name) == p-path) && 530 if (p && (strlen(child->name) == p-path) &&
510 strneq(path, child->name, p-path)) 531 strprefixeq(path, p - path, child->name))
511 return get_node_by_path(child, p+1); 532 return get_node_by_path(child, p+1);
512 else if (!p && streq(path, child->name)) 533 else if (!p && streq(path, child->name))
513 return child; 534 return child;
@@ -540,7 +561,10 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
540{ 561{
541 struct node *child, *node; 562 struct node *child, *node;
542 563
543 assert((phandle != 0) && (phandle != -1)); 564 if ((phandle == 0) || (phandle == -1)) {
565 assert(generate_fixups);
566 return NULL;
567 }
544 568
545 if (tree->phandle == phandle) { 569 if (tree->phandle == phandle) {
546 if (tree->deleted) 570 if (tree->deleted)
@@ -570,6 +594,7 @@ struct node *get_node_by_ref(struct node *tree, const char *ref)
570cell_t get_node_phandle(struct node *root, struct node *node) 594cell_t get_node_phandle(struct node *root, struct node *node)
571{ 595{
572 static cell_t phandle = 1; /* FIXME: ick, static local */ 596 static cell_t phandle = 1; /* FIXME: ick, static local */
597 struct data d = empty_data;
573 598
574 if ((node->phandle != 0) && (node->phandle != -1)) 599 if ((node->phandle != 0) && (node->phandle != -1))
575 return node->phandle; 600 return node->phandle;
@@ -579,17 +604,16 @@ cell_t get_node_phandle(struct node *root, struct node *node)
579 604
580 node->phandle = phandle; 605 node->phandle = phandle;
581 606
607 d = data_add_marker(d, TYPE_UINT32, NULL);
608 d = data_append_cell(d, phandle);
609
582 if (!get_property(node, "linux,phandle") 610 if (!get_property(node, "linux,phandle")
583 && (phandle_format & PHANDLE_LEGACY)) 611 && (phandle_format & PHANDLE_LEGACY))
584 add_property(node, 612 add_property(node, build_property("linux,phandle", d));
585 build_property("linux,phandle",
586 data_append_cell(empty_data, phandle)));
587 613
588 if (!get_property(node, "phandle") 614 if (!get_property(node, "phandle")
589 && (phandle_format & PHANDLE_EPAPR)) 615 && (phandle_format & PHANDLE_EPAPR))
590 add_property(node, 616 add_property(node, build_property("phandle", d));
591 build_property("phandle",
592 data_append_cell(empty_data, phandle)));
593 617
594 /* If the node *does* have a phandle property, we must 618 /* If the node *does* have a phandle property, we must
595 * be dealing with a self-referencing phandle, which will be 619 * be dealing with a self-referencing phandle, which will be
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 9d38459902f3..cb6ed0e3e5e4 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -209,8 +209,6 @@ struct srcpos srcpos_empty = {
209 .file = NULL, 209 .file = NULL,
210}; 210};
211 211
212#define TAB_SIZE 8
213
214void srcpos_update(struct srcpos *pos, const char *text, int len) 212void srcpos_update(struct srcpos *pos, const char *text, int len)
215{ 213{
216 int i; 214 int i;
@@ -224,9 +222,6 @@ void srcpos_update(struct srcpos *pos, const char *text, int len)
224 if (text[i] == '\n') { 222 if (text[i] == '\n') {
225 current_srcfile->lineno++; 223 current_srcfile->lineno++;
226 current_srcfile->colno = 1; 224 current_srcfile->colno = 1;
227 } else if (text[i] == '\t') {
228 current_srcfile->colno =
229 ALIGN(current_srcfile->colno, TAB_SIZE);
230 } else { 225 } else {
231 current_srcfile->colno++; 226 current_srcfile->colno++;
232 } 227 }
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index 7caca8257c6d..9ded12a3830a 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -17,8 +17,8 @@
17 * USA 17 * USA
18 */ 18 */
19 19
20#ifndef _SRCPOS_H_ 20#ifndef SRCPOS_H
21#define _SRCPOS_H_ 21#define SRCPOS_H
22 22
23#include <stdio.h> 23#include <stdio.h>
24#include <stdbool.h> 24#include <stdbool.h>
@@ -114,4 +114,4 @@ extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix,
114 114
115extern void srcpos_set_line(char *f, int l); 115extern void srcpos_set_line(char *f, int l);
116 116
117#endif /* _SRCPOS_H_ */ 117#endif /* SRCPOS_H */
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index 2461a3d068a0..f2874f1d1465 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -61,24 +61,14 @@ static bool isstring(char c)
61 || strchr("\a\b\t\n\v\f\r", c)); 61 || strchr("\a\b\t\n\v\f\r", c));
62} 62}
63 63
64static void write_propval_string(FILE *f, struct data val) 64static void write_propval_string(FILE *f, const char *s, size_t len)
65{ 65{
66 const char *str = val.val; 66 const char *end = s + len - 1;
67 int i; 67 assert(*end == '\0');
68 struct marker *m = val.markers;
69
70 assert(str[val.len-1] == '\0');
71 68
72 while (m && (m->offset == 0)) {
73 if (m->type == LABEL)
74 fprintf(f, "%s: ", m->ref);
75 m = m->next;
76 }
77 fprintf(f, "\""); 69 fprintf(f, "\"");
78 70 while (s < end) {
79 for (i = 0; i < (val.len-1); i++) { 71 char c = *s++;
80 char c = str[i];
81
82 switch (c) { 72 switch (c) {
83 case '\a': 73 case '\a':
84 fprintf(f, "\\a"); 74 fprintf(f, "\\a");
@@ -108,91 +98,78 @@ static void write_propval_string(FILE *f, struct data val)
108 fprintf(f, "\\\""); 98 fprintf(f, "\\\"");
109 break; 99 break;
110 case '\0': 100 case '\0':
111 fprintf(f, "\", "); 101 fprintf(f, "\\0");
112 while (m && (m->offset <= (i + 1))) {
113 if (m->type == LABEL) {
114 assert(m->offset == (i+1));
115 fprintf(f, "%s: ", m->ref);
116 }
117 m = m->next;
118 }
119 fprintf(f, "\"");
120 break; 102 break;
121 default: 103 default:
122 if (isprint((unsigned char)c)) 104 if (isprint((unsigned char)c))
123 fprintf(f, "%c", c); 105 fprintf(f, "%c", c);
124 else 106 else
125 fprintf(f, "\\x%02hhx", c); 107 fprintf(f, "\\x%02"PRIx8, c);
126 } 108 }
127 } 109 }
128 fprintf(f, "\""); 110 fprintf(f, "\"");
129
130 /* Wrap up any labels at the end of the value */
131 for_each_marker_of_type(m, LABEL) {
132 assert (m->offset == val.len);
133 fprintf(f, " %s:", m->ref);
134 }
135} 111}
136 112
137static void write_propval_cells(FILE *f, struct data val) 113static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
138{ 114{
139 void *propend = val.val + val.len; 115 const char *end = p + len;
140 fdt32_t *cp = (fdt32_t *)val.val; 116 assert(len % width == 0);
141 struct marker *m = val.markers;
142
143 fprintf(f, "<");
144 for (;;) {
145 while (m && (m->offset <= ((char *)cp - val.val))) {
146 if (m->type == LABEL) {
147 assert(m->offset == ((char *)cp - val.val));
148 fprintf(f, "%s: ", m->ref);
149 }
150 m = m->next;
151 }
152 117
153 fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); 118 for (; p < end; p += width) {
154 if ((void *)cp >= propend) 119 switch (width) {
120 case 1:
121 fprintf(f, " %02"PRIx8, *(const uint8_t*)p);
122 break;
123 case 2:
124 fprintf(f, " 0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p));
125 break;
126 case 4:
127 fprintf(f, " 0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p));
128 break;
129 case 8:
130 fprintf(f, " 0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p));
155 break; 131 break;
156 fprintf(f, " "); 132 }
157 } 133 }
134}
158 135
159 /* Wrap up any labels at the end of the value */ 136static bool has_data_type_information(struct marker *m)
160 for_each_marker_of_type(m, LABEL) { 137{
161 assert (m->offset == val.len); 138 return m->type >= TYPE_UINT8;
162 fprintf(f, " %s:", m->ref);
163 }
164 fprintf(f, ">");
165} 139}
166 140
167static void write_propval_bytes(FILE *f, struct data val) 141static struct marker *next_type_marker(struct marker *m)
168{ 142{
169 void *propend = val.val + val.len; 143 while (m && !has_data_type_information(m))
170 const char *bp = val.val; 144 m = m->next;
171 struct marker *m = val.markers; 145 return m;
172 146}
173 fprintf(f, "[");
174 for (;;) {
175 while (m && (m->offset == (bp-val.val))) {
176 if (m->type == LABEL)
177 fprintf(f, "%s: ", m->ref);
178 m = m->next;
179 }
180 147
181 fprintf(f, "%02hhx", (unsigned char)(*bp++)); 148size_t type_marker_length(struct marker *m)
182 if ((const void *)bp >= propend) 149{
183 break; 150 struct marker *next = next_type_marker(m->next);
184 fprintf(f, " ");
185 }
186 151
187 /* Wrap up any labels at the end of the value */ 152 if (next)
188 for_each_marker_of_type(m, LABEL) { 153 return next->offset - m->offset;
189 assert (m->offset == val.len); 154 return 0;
190 fprintf(f, " %s:", m->ref);
191 }
192 fprintf(f, "]");
193} 155}
194 156
195static void write_propval(FILE *f, struct property *prop) 157static const char *delim_start[] = {
158 [TYPE_UINT8] = "[",
159 [TYPE_UINT16] = "/bits/ 16 <",
160 [TYPE_UINT32] = "<",
161 [TYPE_UINT64] = "/bits/ 64 <",
162 [TYPE_STRING] = "",
163};
164static const char *delim_end[] = {
165 [TYPE_UINT8] = " ]",
166 [TYPE_UINT16] = " >",
167 [TYPE_UINT32] = " >",
168 [TYPE_UINT64] = " >",
169 [TYPE_STRING] = "",
170};
171
172static enum markertype guess_value_type(struct property *prop)
196{ 173{
197 int len = prop->val.len; 174 int len = prop->val.len;
198 const char *p = prop->val.val; 175 const char *p = prop->val.val;
@@ -201,11 +178,6 @@ static void write_propval(FILE *f, struct property *prop)
201 int nnotstringlbl = 0, nnotcelllbl = 0; 178 int nnotstringlbl = 0, nnotcelllbl = 0;
202 int i; 179 int i;
203 180
204 if (len == 0) {
205 fprintf(f, ";\n");
206 return;
207 }
208
209 for (i = 0; i < len; i++) { 181 for (i = 0; i < len; i++) {
210 if (! isstring(p[i])) 182 if (! isstring(p[i]))
211 nnotstring++; 183 nnotstring++;
@@ -220,17 +192,91 @@ static void write_propval(FILE *f, struct property *prop)
220 nnotcelllbl++; 192 nnotcelllbl++;
221 } 193 }
222 194
223 fprintf(f, " = ");
224 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) 195 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
225 && (nnotstringlbl == 0)) { 196 && (nnotstringlbl == 0)) {
226 write_propval_string(f, prop->val); 197 return TYPE_STRING;
227 } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { 198 } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
228 write_propval_cells(f, prop->val); 199 return TYPE_UINT32;
229 } else {
230 write_propval_bytes(f, prop->val);
231 } 200 }
232 201
233 fprintf(f, ";\n"); 202 return TYPE_UINT8;
203}
204
205static void write_propval(FILE *f, struct property *prop)
206{
207 size_t len = prop->val.len;
208 struct marker *m = prop->val.markers;
209 struct marker dummy_marker;
210 enum markertype emit_type = TYPE_NONE;
211
212 if (len == 0) {
213 fprintf(f, ";\n");
214 return;
215 }
216
217 fprintf(f, " = ");
218
219 if (!next_type_marker(m)) {
220 /* data type information missing, need to guess */
221 dummy_marker.type = guess_value_type(prop);
222 dummy_marker.next = prop->val.markers;
223 dummy_marker.offset = 0;
224 dummy_marker.ref = NULL;
225 m = &dummy_marker;
226 }
227
228 struct marker *m_label = prop->val.markers;
229 for_each_marker(m) {
230 size_t chunk_len;
231 const char *p = &prop->val.val[m->offset];
232
233 if (!has_data_type_information(m))
234 continue;
235
236 chunk_len = type_marker_length(m);
237 if (!chunk_len)
238 chunk_len = len - m->offset;
239
240 if (emit_type != TYPE_NONE)
241 fprintf(f, "%s, ", delim_end[emit_type]);
242 emit_type = m->type;
243
244 for_each_marker_of_type(m_label, LABEL) {
245 if (m_label->offset > m->offset)
246 break;
247 fprintf(f, "%s: ", m_label->ref);
248 }
249
250 fprintf(f, "%s", delim_start[emit_type]);
251
252 if (chunk_len <= 0)
253 continue;
254
255 switch(emit_type) {
256 case TYPE_UINT16:
257 write_propval_int(f, p, chunk_len, 2);
258 break;
259 case TYPE_UINT32:
260 write_propval_int(f, p, chunk_len, 4);
261 break;
262 case TYPE_UINT64:
263 write_propval_int(f, p, chunk_len, 8);
264 break;
265 case TYPE_STRING:
266 write_propval_string(f, p, chunk_len);
267 break;
268 default:
269 write_propval_int(f, p, chunk_len, 1);
270 }
271 }
272
273 /* Wrap up any labels at the end of the value */
274 for_each_marker_of_type(m_label, LABEL) {
275 assert (m_label->offset == len);
276 fprintf(f, " %s:", m_label->ref);
277 }
278
279 fprintf(f, "%s;\n", delim_end[emit_type] ? : "");
234} 280}
235 281
236static void write_tree_source_node(FILE *f, struct node *tree, int level) 282static void write_tree_source_node(FILE *f, struct node *tree, int level)
@@ -281,4 +327,3 @@ void dt_to_source(FILE *f, struct dt_info *dti)
281 327
282 write_tree_source_node(f, dti->dt, 0); 328 write_tree_source_node(f, dti->dt, 0);
283} 329}
284
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
index fe8926bb3b54..7dd29a0362b8 100755
--- a/scripts/dtc/update-dtc-source.sh
+++ b/scripts/dtc/update-dtc-source.sh
@@ -4,7 +4,7 @@
4# 4#
5# This script assumes that the dtc and the linux git trees are in the 5# This script assumes that the dtc and the linux git trees are in the
6# same directory. After building dtc in the dtc directory, it copies the 6# same directory. After building dtc in the dtc directory, it copies the
7# source files and generated source files into the scripts/dtc directory 7# source files and generated source file(s) into the scripts/dtc directory
8# in the kernel and creates a git commit updating them to the new 8# in the kernel and creates a git commit updating them to the new
9# version. 9# version.
10# 10#
@@ -32,9 +32,8 @@ DTC_UPSTREAM_PATH=`pwd`/../dtc
32DTC_LINUX_PATH=`pwd`/scripts/dtc 32DTC_LINUX_PATH=`pwd`/scripts/dtc
33 33
34DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \ 34DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \
35 srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \ 35 srcpos.h treesource.c util.c util.h version_gen.h yamltree.c Makefile.dtc \
36 dtc-lexer.l dtc-parser.y" 36 dtc-lexer.l dtc-parser.y"
37DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
38LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ 37LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \
39 fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ 38 fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \
40 fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h" 39 fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
@@ -59,10 +58,6 @@ for f in $DTC_SOURCE; do
59 cp ${DTC_UPSTREAM_PATH}/${f} ${f} 58 cp ${DTC_UPSTREAM_PATH}/${f} ${f}
60 git add ${f} 59 git add ${f}
61done 60done
62for f in $DTC_GENERATED; do
63 cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped
64 git add ${f}_shipped
65done
66for f in $LIBFDT_SOURCE; do 61for f in $LIBFDT_SOURCE; do
67 cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f} 62 cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f}
68 git add libfdt/${f} 63 git add libfdt/${f}
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
index 9953c32a0244..a69b7a13463d 100644
--- a/scripts/dtc/util.c
+++ b/scripts/dtc/util.c
@@ -227,11 +227,11 @@ char get_escape_char(const char *s, int *i)
227 return val; 227 return val;
228} 228}
229 229
230int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len) 230int utilfdt_read_err(const char *filename, char **buffp, size_t *len)
231{ 231{
232 int fd = 0; /* assume stdin */ 232 int fd = 0; /* assume stdin */
233 char *buf = NULL; 233 char *buf = NULL;
234 off_t bufsize = 1024, offset = 0; 234 size_t bufsize = 1024, offset = 0;
235 int ret = 0; 235 int ret = 0;
236 236
237 *buffp = NULL; 237 *buffp = NULL;
@@ -264,20 +264,15 @@ int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len)
264 free(buf); 264 free(buf);
265 else 265 else
266 *buffp = buf; 266 *buffp = buf;
267 *len = bufsize; 267 if (len)
268 *len = bufsize;
268 return ret; 269 return ret;
269} 270}
270 271
271int utilfdt_read_err(const char *filename, char **buffp) 272char *utilfdt_read(const char *filename, size_t *len)
272{
273 off_t len;
274 return utilfdt_read_err_len(filename, buffp, &len);
275}
276
277char *utilfdt_read_len(const char *filename, off_t *len)
278{ 273{
279 char *buff; 274 char *buff;
280 int ret = utilfdt_read_err_len(filename, &buff, len); 275 int ret = utilfdt_read_err(filename, &buff, len);
281 276
282 if (ret) { 277 if (ret) {
283 fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename, 278 fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
@@ -288,12 +283,6 @@ char *utilfdt_read_len(const char *filename, off_t *len)
288 return buff; 283 return buff;
289} 284}
290 285
291char *utilfdt_read(const char *filename)
292{
293 off_t len;
294 return utilfdt_read_len(filename, &len);
295}
296
297int utilfdt_write_err(const char *filename, const void *blob) 286int utilfdt_write_err(const char *filename, const void *blob)
298{ 287{
299 int fd = 1; /* assume stdout */ 288 int fd = 1; /* assume stdout */
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index ad5f41199edb..f6cea8274174 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -1,5 +1,5 @@
1#ifndef _UTIL_H 1#ifndef UTIL_H
2#define _UTIL_H 2#define UTIL_H
3 3
4#include <stdarg.h> 4#include <stdarg.h>
5#include <stdbool.h> 5#include <stdbool.h>
@@ -35,6 +35,9 @@
35 35
36#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 36#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
37 37
38#define stringify(s) stringify_(s)
39#define stringify_(s) #s
40
38static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) 41static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
39{ 42{
40 va_list ap; 43 va_list ap;
@@ -95,16 +98,10 @@ char get_escape_char(const char *s, int *i);
95 * stderr. 98 * stderr.
96 * 99 *
97 * @param filename The filename to read, or - for stdin 100 * @param filename The filename to read, or - for stdin
98 * @return Pointer to allocated buffer containing fdt, or NULL on error
99 */
100char *utilfdt_read(const char *filename);
101
102/**
103 * Like utilfdt_read(), but also passes back the size of the file read.
104 *
105 * @param len If non-NULL, the amount of data we managed to read 101 * @param len If non-NULL, the amount of data we managed to read
102 * @return Pointer to allocated buffer containing fdt, or NULL on error
106 */ 103 */
107char *utilfdt_read_len(const char *filename, off_t *len); 104char *utilfdt_read(const char *filename, size_t *len);
108 105
109/** 106/**
110 * Read a device tree file into a buffer. Does not report errors, but only 107 * Read a device tree file into a buffer. Does not report errors, but only
@@ -113,16 +110,10 @@ char *utilfdt_read_len(const char *filename, off_t *len);
113 * 110 *
114 * @param filename The filename to read, or - for stdin 111 * @param filename The filename to read, or - for stdin
115 * @param buffp Returns pointer to buffer containing fdt 112 * @param buffp Returns pointer to buffer containing fdt
116 * @return 0 if ok, else an errno value representing the error
117 */
118int utilfdt_read_err(const char *filename, char **buffp);
119
120/**
121 * Like utilfdt_read_err(), but also passes back the size of the file read.
122 *
123 * @param len If non-NULL, the amount of data we managed to read 113 * @param len If non-NULL, the amount of data we managed to read
114 * @return 0 if ok, else an errno value representing the error
124 */ 115 */
125int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len); 116int utilfdt_read_err(const char *filename, char **buffp, size_t *len);
126 117
127/** 118/**
128 * Write a device tree buffer to a file. This will report any errors on 119 * Write a device tree buffer to a file. This will report any errors on
@@ -260,4 +251,4 @@ void NORETURN util_usage(const char *errmsg, const char *synopsis,
260 case 'V': util_version(); \ 251 case 'V': util_version(); \
261 case '?': usage("unknown option"); 252 case '?': usage("unknown option");
262 253
263#endif /* _UTIL_H */ 254#endif /* UTIL_H */
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 6a4e84798966..6d23fd095f16 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
#define DTC_VERSION "DTC 1.4.5-gc1e55a55" #define DTC_VERSION "DTC 1.4.7-gc86da84d"
diff --git a/scripts/dtc/yamltree.c b/scripts/dtc/yamltree.c
new file mode 100644
index 000000000000..a00285a5a9ec
--- /dev/null
+++ b/scripts/dtc/yamltree.c
@@ -0,0 +1,247 @@
1/*
2 * (C) Copyright Linaro, Ltd. 2018
3 * (C) Copyright Arm Holdings. 2017
4 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22#include <stdlib.h>
23#include <yaml.h>
24#include "dtc.h"
25#include "srcpos.h"
26
27char *yaml_error_name[] = {
28 [YAML_NO_ERROR] = "no error",
29 [YAML_MEMORY_ERROR] = "memory error",
30 [YAML_READER_ERROR] = "reader error",
31 [YAML_SCANNER_ERROR] = "scanner error",
32 [YAML_PARSER_ERROR] = "parser error",
33 [YAML_COMPOSER_ERROR] = "composer error",
34 [YAML_WRITER_ERROR] = "writer error",
35 [YAML_EMITTER_ERROR] = "emitter error",
36};
37
38#define yaml_emitter_emit_or_die(emitter, event) ( \
39{ \
40 if (!yaml_emitter_emit(emitter, event)) \
41 die("yaml '%s': %s in %s, line %i\n", \
42 yaml_error_name[(emitter)->error], \
43 (emitter)->problem, __func__, __LINE__); \
44})
45
46static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, char *data, int len, int width)
47{
48 yaml_event_t event;
49 void *tag;
50 int off, start_offset = markers->offset;
51
52 switch(width) {
53 case 1: tag = "!u8"; break;
54 case 2: tag = "!u16"; break;
55 case 4: tag = "!u32"; break;
56 case 8: tag = "!u64"; break;
57 default:
58 die("Invalid width %i", width);
59 }
60 assert(len % width == 0);
61
62 yaml_sequence_start_event_initialize(&event, NULL,
63 (yaml_char_t *)tag, width == 4, YAML_FLOW_SEQUENCE_STYLE);
64 yaml_emitter_emit_or_die(emitter, &event);
65
66 for (off = 0; off < len; off += width) {
67 char buf[32];
68 struct marker *m;
69 bool is_phandle = false;
70
71 switch(width) {
72 case 1:
73 sprintf(buf, "0x%"PRIx8, *(uint8_t*)(data + off));
74 break;
75 case 2:
76 sprintf(buf, "0x%"PRIx16, fdt16_to_cpu(*(fdt16_t*)(data + off)));
77 break;
78 case 4:
79 sprintf(buf, "0x%"PRIx32, fdt32_to_cpu(*(fdt32_t*)(data + off)));
80 m = markers;
81 is_phandle = false;
82 for_each_marker_of_type(m, REF_PHANDLE) {
83 if (m->offset == (start_offset + off)) {
84 is_phandle = true;
85 break;
86 }
87 }
88 break;
89 case 8:
90 sprintf(buf, "0x%"PRIx64, fdt64_to_cpu(*(fdt64_t*)(data + off)));
91 break;
92 }
93
94 if (is_phandle)
95 yaml_scalar_event_initialize(&event, NULL,
96 (yaml_char_t*)"!phandle", (yaml_char_t *)buf,
97 strlen(buf), 0, 0, YAML_PLAIN_SCALAR_STYLE);
98 else
99 yaml_scalar_event_initialize(&event, NULL,
100 (yaml_char_t*)YAML_INT_TAG, (yaml_char_t *)buf,
101 strlen(buf), 1, 1, YAML_PLAIN_SCALAR_STYLE);
102 yaml_emitter_emit_or_die(emitter, &event);
103 }
104
105 yaml_sequence_end_event_initialize(&event);
106 yaml_emitter_emit_or_die(emitter, &event);
107}
108
109static void yaml_propval_string(yaml_emitter_t *emitter, char *str, int len)
110{
111 yaml_event_t event;
112 int i;
113
114 assert(str[len-1] == '\0');
115
116 /* Make sure the entire string is in the lower 7-bit ascii range */
117 for (i = 0; i < len; i++)
118 assert(isascii(str[i]));
119
120 yaml_scalar_event_initialize(&event, NULL,
121 (yaml_char_t *)YAML_STR_TAG, (yaml_char_t*)str,
122 len-1, 0, 1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
123 yaml_emitter_emit_or_die(emitter, &event);
124}
125
126static void yaml_propval(yaml_emitter_t *emitter, struct property *prop)
127{
128 yaml_event_t event;
129 int len = prop->val.len;
130 struct marker *m = prop->val.markers;
131
132 /* Emit the property name */
133 yaml_scalar_event_initialize(&event, NULL,
134 (yaml_char_t *)YAML_STR_TAG, (yaml_char_t*)prop->name,
135 strlen(prop->name), 1, 1, YAML_PLAIN_SCALAR_STYLE);
136 yaml_emitter_emit_or_die(emitter, &event);
137
138 /* Boolean properties are easiest to deal with. Length is zero, so just emit 'true' */
139 if (len == 0) {
140 yaml_scalar_event_initialize(&event, NULL,
141 (yaml_char_t *)YAML_BOOL_TAG,
142 (yaml_char_t*)"true",
143 strlen("true"), 1, 0, YAML_PLAIN_SCALAR_STYLE);
144 yaml_emitter_emit_or_die(emitter, &event);
145 return;
146 }
147
148 if (!m)
149 die("No markers present in property '%s' value\n", prop->name);
150
151 yaml_sequence_start_event_initialize(&event, NULL,
152 (yaml_char_t *)YAML_SEQ_TAG, 1, YAML_FLOW_SEQUENCE_STYLE);
153 yaml_emitter_emit_or_die(emitter, &event);
154
155 for_each_marker(m) {
156 int chunk_len;
157 char *data = &prop->val.val[m->offset];
158
159 if (m->type < TYPE_UINT8)
160 continue;
161
162 chunk_len = type_marker_length(m) ? : len;
163 assert(chunk_len > 0);
164 len -= chunk_len;
165
166 switch(m->type) {
167 case TYPE_UINT16:
168 yaml_propval_int(emitter, m, data, chunk_len, 2);
169 break;
170 case TYPE_UINT32:
171 yaml_propval_int(emitter, m, data, chunk_len, 4);
172 break;
173 case TYPE_UINT64:
174 yaml_propval_int(emitter, m, data, chunk_len, 8);
175 break;
176 case TYPE_STRING:
177 yaml_propval_string(emitter, data, chunk_len);
178 break;
179 default:
180 yaml_propval_int(emitter, m, data, chunk_len, 1);
181 break;
182 }
183 }
184
185 yaml_sequence_end_event_initialize(&event);
186 yaml_emitter_emit_or_die(emitter, &event);
187}
188
189
190static void yaml_tree(struct node *tree, yaml_emitter_t *emitter)
191{
192 struct property *prop;
193 struct node *child;
194 yaml_event_t event;
195
196 if (tree->deleted)
197 return;
198
199 yaml_mapping_start_event_initialize(&event, NULL,
200 (yaml_char_t *)YAML_MAP_TAG, 1, YAML_ANY_MAPPING_STYLE);
201 yaml_emitter_emit_or_die(emitter, &event);
202
203 for_each_property(tree, prop)
204 yaml_propval(emitter, prop);
205
206 /* Loop over all the children, emitting them into the map */
207 for_each_child(tree, child) {
208 yaml_scalar_event_initialize(&event, NULL,
209 (yaml_char_t *)YAML_STR_TAG, (yaml_char_t*)child->name,
210 strlen(child->name), 1, 0, YAML_PLAIN_SCALAR_STYLE);
211 yaml_emitter_emit_or_die(emitter, &event);
212 yaml_tree(child, emitter);
213 }
214
215 yaml_mapping_end_event_initialize(&event);
216 yaml_emitter_emit_or_die(emitter, &event);
217}
218
219void dt_to_yaml(FILE *f, struct dt_info *dti)
220{
221 yaml_emitter_t emitter;
222 yaml_event_t event;
223
224 yaml_emitter_initialize(&emitter);
225 yaml_emitter_set_output_file(&emitter, f);
226 yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
227 yaml_emitter_emit_or_die(&emitter, &event);
228
229 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
230 yaml_emitter_emit_or_die(&emitter, &event);
231
232 yaml_sequence_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_SEQ_TAG, 1, YAML_ANY_SEQUENCE_STYLE);
233 yaml_emitter_emit_or_die(&emitter, &event);
234
235 yaml_tree(dti->dt, &emitter);
236
237 yaml_sequence_end_event_initialize(&event);
238 yaml_emitter_emit_or_die(&emitter, &event);
239
240 yaml_document_end_event_initialize(&event, 0);
241 yaml_emitter_emit_or_die(&emitter, &event);
242
243 yaml_stream_end_event_initialize(&event);
244 yaml_emitter_emit_or_die(&emitter, &event);
245
246 yaml_emitter_delete(&emitter);
247}
diff --git a/scripts/extract-vmlinux b/scripts/extract-vmlinux
index 5061abcc2540..85e1f32fb4a0 100755
--- a/scripts/extract-vmlinux
+++ b/scripts/extract-vmlinux
@@ -48,15 +48,17 @@ fi
48tmp=$(mktemp /tmp/vmlinux-XXX) 48tmp=$(mktemp /tmp/vmlinux-XXX)
49trap "rm -f $tmp" 0 49trap "rm -f $tmp" 0
50 50
51# Initial attempt for uncompressed images or objects:
52check_vmlinux $img
53
54# That didn't work, so retry after decompression. 51# That didn't work, so retry after decompression.
55try_decompress '\037\213\010' xy gunzip 52try_decompress '\037\213\010' xy gunzip
56try_decompress '\3757zXZ\000' abcde unxz 53try_decompress '\3757zXZ\000' abcde unxz
57try_decompress 'BZh' xy bunzip2 54try_decompress 'BZh' xy bunzip2
58try_decompress '\135\0\0\0' xxx unlzma 55try_decompress '\135\0\0\0' xxx unlzma
59try_decompress '\211\114\132' xy 'lzop -d' 56try_decompress '\211\114\132' xy 'lzop -d'
57try_decompress '\002!L\030' xxx 'lz4 -d'
58try_decompress '(\265/\375' xxx unzstd
59
60# Finally check for uncompressed images or objects:
61check_vmlinux $img
60 62
61# Bail out: 63# Bail out:
62echo "$me: Cannot find vmlinux." >&2 64echo "$me: Cannot find vmlinux." >&2
diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl
index 61d9b256c658..a1c51b7e4baf 100755
--- a/scripts/extract_xc3028.pl
+++ b/scripts/extract_xc3028.pl
@@ -1,6 +1,6 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2 2
3# Copyright (c) Mauro Carvalho Chehab <mchehab@infradead.org> 3# Copyright (c) Mauro Carvalho Chehab <mchehab@kernel.org>
4# Released under GPLv2 4# Released under GPLv2
5# 5#
6# In order to use, you need to: 6# In order to use, you need to:
diff --git a/scripts/faddr2line b/scripts/faddr2line
index 7721d5b2b0c0..a0149db00be7 100755
--- a/scripts/faddr2line
+++ b/scripts/faddr2line
@@ -56,7 +56,7 @@ command -v ${SIZE} >/dev/null 2>&1 || die "size isn't installed"
56command -v ${NM} >/dev/null 2>&1 || die "nm isn't installed" 56command -v ${NM} >/dev/null 2>&1 || die "nm isn't installed"
57 57
58usage() { 58usage() {
59 echo "usage: faddr2line <object file> <func+offset> <func+offset>..." >&2 59 echo "usage: faddr2line [--list] <object file> <func+offset> <func+offset>..." >&2
60 exit 1 60 exit 1
61} 61}
62 62
@@ -163,7 +163,30 @@ __faddr2line() {
163 163
164 # pass real address to addr2line 164 # pass real address to addr2line
165 echo "$func+$offset/$sym_size:" 165 echo "$func+$offset/$sym_size:"
166 ${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;" 166 local file_lines=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;")
167 [[ -z $file_lines ]] && return
168
169 if [[ $LIST = 0 ]]; then
170 echo "$file_lines" | while read -r line
171 do
172 echo $line
173 done
174 DONE=1;
175 return
176 fi
177
178 # show each line with context
179 echo "$file_lines" | while read -r line
180 do
181 echo
182 echo $line
183 n=$(echo $line | sed 's/.*:\([0-9]\+\).*/\1/g')
184 n1=$[$n-5]
185 n2=$[$n+5]
186 f=$(echo $line | sed 's/.*at \(.\+\):.*/\1/g')
187 awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f
188 done
189
167 DONE=1 190 DONE=1
168 191
169 done < <(${NM} -n $objfile | awk -v fn=$func -v end=$file_end '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, "0x"$1 } END {if (found == 1) print line, end; }') 192 done < <(${NM} -n $objfile | awk -v fn=$func -v end=$file_end '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, "0x"$1 } END {if (found == 1) print line, end; }')
@@ -172,6 +195,10 @@ __faddr2line() {
172[[ $# -lt 2 ]] && usage 195[[ $# -lt 2 ]] && usage
173 196
174objfile=$1 197objfile=$1
198
199LIST=0
200[[ "$objfile" == "--list" ]] && LIST=1 && shift && objfile=$1
201
175[[ ! -f $objfile ]] && die "can't find objfile $objfile" 202[[ ! -f $objfile ]] && die "can't find objfile $objfile"
176shift 203shift
177 204
diff --git a/scripts/file-size.sh b/scripts/file-size.sh
new file mode 100755
index 000000000000..7eb7423416b5
--- /dev/null
+++ b/scripts/file-size.sh
@@ -0,0 +1,4 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3set -- $(ls -dn "$1")
4printf '%s\n' "$5"
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
new file mode 100644
index 000000000000..0d5c799688f0
--- /dev/null
+++ b/scripts/gcc-plugins/Kconfig
@@ -0,0 +1,193 @@
1preferred-plugin-hostcc := $(if-success,[ $(gcc-version) -ge 40800 ],$(HOSTCXX),$(HOSTCC))
2
3config PLUGIN_HOSTCC
4 string
5 default "$(shell,$(srctree)/scripts/gcc-plugin.sh "$(preferred-plugin-hostcc)" "$(HOSTCXX)" "$(CC)")" if CC_IS_GCC
6 help
7 Host compiler used to build GCC plugins. This can be $(HOSTCXX),
8 $(HOSTCC), or a null string if GCC plugin is unsupported.
9
10config HAVE_GCC_PLUGINS
11 bool
12 help
13 An arch should select this symbol if it supports building with
14 GCC plugins.
15
16menuconfig GCC_PLUGINS
17 bool "GCC plugins"
18 depends on HAVE_GCC_PLUGINS
19 depends on PLUGIN_HOSTCC != ""
20 help
21 GCC plugins are loadable modules that provide extra features to the
22 compiler. They are useful for runtime instrumentation and static analysis.
23
24 See Documentation/gcc-plugins.txt for details.
25
26if GCC_PLUGINS
27
28config GCC_PLUGIN_CYC_COMPLEXITY
29 bool "Compute the cyclomatic complexity of a function" if EXPERT
30 depends on !COMPILE_TEST # too noisy
31 help
32 The complexity M of a function's control flow graph is defined as:
33 M = E - N + 2P
34 where
35
36 E = the number of edges
37 N = the number of nodes
38 P = the number of connected components (exit nodes).
39
40 Enabling this plugin reports the complexity to stderr during the
41 build. It mainly serves as a simple example of how to create a
42 gcc plugin for the kernel.
43
44config GCC_PLUGIN_SANCOV
45 bool
46 help
47 This plugin inserts a __sanitizer_cov_trace_pc() call at the start of
48 basic blocks. It supports all gcc versions with plugin support (from
49 gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
50 by Dmitry Vyukov <dvyukov@google.com>.
51
52config GCC_PLUGIN_LATENT_ENTROPY
53 bool "Generate some entropy during boot and runtime"
54 help
55 By saying Y here the kernel will instrument some kernel code to
56 extract some entropy from both original and artificially created
57 program state. This will help especially embedded systems where
58 there is little 'natural' source of entropy normally. The cost
59 is some slowdown of the boot process (about 0.5%) and fork and
60 irq processing.
61
62 Note that entropy extracted this way is not cryptographically
63 secure!
64
65 This plugin was ported from grsecurity/PaX. More information at:
66 * https://grsecurity.net/
67 * https://pax.grsecurity.net/
68
69config GCC_PLUGIN_STRUCTLEAK
70 bool "Force initialization of variables containing userspace addresses"
71 # Currently STRUCTLEAK inserts initialization out of live scope of
72 # variables from KASAN point of view. This leads to KASAN false
73 # positive reports. Prohibit this combination for now.
74 depends on !KASAN_EXTRA
75 help
76 This plugin zero-initializes any structures containing a
77 __user attribute. This can prevent some classes of information
78 exposures.
79
80 This plugin was ported from grsecurity/PaX. More information at:
81 * https://grsecurity.net/
82 * https://pax.grsecurity.net/
83
84config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
85 bool "Force initialize all struct type variables passed by reference"
86 depends on GCC_PLUGIN_STRUCTLEAK
87 depends on !COMPILE_TEST
88 help
89 Zero initialize any struct type local variable that may be passed by
90 reference without having been initialized.
91
92config GCC_PLUGIN_STRUCTLEAK_VERBOSE
93 bool "Report forcefully initialized variables"
94 depends on GCC_PLUGIN_STRUCTLEAK
95 depends on !COMPILE_TEST # too noisy
96 help
97 This option will cause a warning to be printed each time the
98 structleak plugin finds a variable it thinks needs to be
99 initialized. Since not all existing initializers are detected
100 by the plugin, this can produce false positive warnings.
101
102config GCC_PLUGIN_RANDSTRUCT
103 bool "Randomize layout of sensitive kernel structures"
104 select MODVERSIONS if MODULES
105 help
106 If you say Y here, the layouts of structures that are entirely
107 function pointers (and have not been manually annotated with
108 __no_randomize_layout), or structures that have been explicitly
109 marked with __randomize_layout, will be randomized at compile-time.
110 This can introduce the requirement of an additional information
111 exposure vulnerability for exploits targeting these structure
112 types.
113
114 Enabling this feature will introduce some performance impact,
115 slightly increase memory usage, and prevent the use of forensic
116 tools like Volatility against the system (unless the kernel
117 source tree isn't cleaned after kernel installation).
118
119 The seed used for compilation is located at
120 scripts/gcc-plgins/randomize_layout_seed.h. It remains after
121 a make clean to allow for external modules to be compiled with
122 the existing seed and will be removed by a make mrproper or
123 make distclean.
124
125 Note that the implementation requires gcc 4.7 or newer.
126
127 This plugin was ported from grsecurity/PaX. More information at:
128 * https://grsecurity.net/
129 * https://pax.grsecurity.net/
130
131config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
132 bool "Use cacheline-aware structure randomization"
133 depends on GCC_PLUGIN_RANDSTRUCT
134 depends on !COMPILE_TEST # do not reduce test coverage
135 help
136 If you say Y here, the RANDSTRUCT randomization will make a
137 best effort at restricting randomization to cacheline-sized
138 groups of elements. It will further not randomize bitfields
139 in structures. This reduces the performance hit of RANDSTRUCT
140 at the cost of weakened randomization.
141
142config GCC_PLUGIN_STACKLEAK
143 bool "Erase the kernel stack before returning from syscalls"
144 depends on GCC_PLUGINS
145 depends on HAVE_ARCH_STACKLEAK
146 help
147 This option makes the kernel erase the kernel stack before
148 returning from system calls. That reduces the information which
149 kernel stack leak bugs can reveal and blocks some uninitialized
150 stack variable attacks.
151
152 The tradeoff is the performance impact: on a single CPU system kernel
153 compilation sees a 1% slowdown, other systems and workloads may vary
154 and you are advised to test this feature on your expected workload
155 before deploying it.
156
157 This plugin was ported from grsecurity/PaX. More information at:
158 * https://grsecurity.net/
159 * https://pax.grsecurity.net/
160
161config STACKLEAK_TRACK_MIN_SIZE
162 int "Minimum stack frame size of functions tracked by STACKLEAK"
163 default 100
164 range 0 4096
165 depends on GCC_PLUGIN_STACKLEAK
166 help
167 The STACKLEAK gcc plugin instruments the kernel code for tracking
168 the lowest border of the kernel stack (and for some other purposes).
169 It inserts the stackleak_track_stack() call for the functions with
170 a stack frame size greater than or equal to this parameter.
171 If unsure, leave the default value 100.
172
173config STACKLEAK_METRICS
174 bool "Show STACKLEAK metrics in the /proc file system"
175 depends on GCC_PLUGIN_STACKLEAK
176 depends on PROC_FS
177 help
178 If this is set, STACKLEAK metrics for every task are available in
179 the /proc file system. In particular, /proc/<pid>/stack_depth
180 shows the maximum kernel stack consumption for the current and
181 previous syscalls. Although this information is not precise, it
182 can be useful for estimating the STACKLEAK performance impact for
183 your workloads.
184
185config STACKLEAK_RUNTIME_DISABLE
186 bool "Allow runtime disabling of kernel stack erasing"
187 depends on GCC_PLUGIN_STACKLEAK
188 help
189 This option provides 'stack_erasing' sysctl, which can be used in
190 runtime to control kernel stack erasing for kernels built with
191 CONFIG_GCC_PLUGIN_STACKLEAK.
192
193endif
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index e2ff425f4c7e..aa0d0ec6936d 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -1,4 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2PLUGINCC := $(CONFIG_PLUGIN_HOSTCC:"%"=%)
2GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) 3GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
3 4
4ifeq ($(PLUGINCC),$(HOSTCC)) 5ifeq ($(PLUGINCC),$(HOSTCC))
@@ -13,12 +14,6 @@ else
13 export HOST_EXTRACXXFLAGS 14 export HOST_EXTRACXXFLAGS
14endif 15endif
15 16
16ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN))
17 GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN))
18endif
19
20export HOSTLIBS
21
22$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h 17$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
23quiet_cmd_create_randomize_layout_seed = GENSEED $@ 18quiet_cmd_create_randomize_layout_seed = GENSEED $@
24cmd_create_randomize_layout_seed = \ 19cmd_create_randomize_layout_seed = \
@@ -32,7 +27,4 @@ always := $($(HOSTLIBS)-y)
32 27
33$(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o)) 28$(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o))
34 29
35subdir-y := $(GCC_PLUGIN_SUBDIR)
36subdir- += $(GCC_PLUGIN_SUBDIR)
37
38clean-files += *.so 30clean-files += *.so
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index f46750053377..552d5efd7cb7 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -392,13 +392,6 @@ static inline struct cgraph_node *cgraph_alias_target(struct cgraph_node *n)
392} 392}
393#endif 393#endif
394 394
395#if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION <= 4009
396#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \
397 cgraph_create_edge((caller), (callee), (call_stmt), (count), (freq))
398#define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \
399 cgraph_create_edge_including_clones((caller), (callee), (old_call_stmt), (call_stmt), (count), (freq), (reason))
400#endif
401
402#if BUILDING_GCC_VERSION <= 4008 395#if BUILDING_GCC_VERSION <= 4008
403#define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) 396#define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN)
404#define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN) 397#define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN)
@@ -723,10 +716,23 @@ static inline const char *get_decl_section_name(const_tree decl)
723#define varpool_get_node(decl) varpool_node::get(decl) 716#define varpool_get_node(decl) varpool_node::get(decl)
724#define dump_varpool_node(file, node) (node)->dump(file) 717#define dump_varpool_node(file, node) (node)->dump(file)
725 718
726#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \ 719#if BUILDING_GCC_VERSION >= 8000
720#define cgraph_create_edge(caller, callee, call_stmt, count, freq) \
721 (caller)->create_edge((callee), (call_stmt), (count))
722
723#define cgraph_create_edge_including_clones(caller, callee, \
724 old_call_stmt, call_stmt, count, freq, reason) \
725 (caller)->create_edge_including_clones((callee), \
726 (old_call_stmt), (call_stmt), (count), (reason))
727#else
728#define cgraph_create_edge(caller, callee, call_stmt, count, freq) \
727 (caller)->create_edge((callee), (call_stmt), (count), (freq)) 729 (caller)->create_edge((callee), (call_stmt), (count), (freq))
728#define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \ 730
729 (caller)->create_edge_including_clones((callee), (old_call_stmt), (call_stmt), (count), (freq), (reason)) 731#define cgraph_create_edge_including_clones(caller, callee, \
732 old_call_stmt, call_stmt, count, freq, reason) \
733 (caller)->create_edge_including_clones((callee), \
734 (old_call_stmt), (call_stmt), (count), (freq), (reason))
735#endif
730 736
731typedef struct cgraph_node *cgraph_node_ptr; 737typedef struct cgraph_node *cgraph_node_ptr;
732typedef struct cgraph_edge *cgraph_edge_p; 738typedef struct cgraph_edge *cgraph_edge_p;
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
index c4a345c3715b..6d5bbd31db7f 100644
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -52,8 +52,8 @@ static const struct whitelist_entry whitelist[] = {
52 { "net/unix/af_unix.c", "unix_skb_parms", "char" }, 52 { "net/unix/af_unix.c", "unix_skb_parms", "char" },
53 /* big_key payload.data struct splashing */ 53 /* big_key payload.data struct splashing */
54 { "security/keys/big_key.c", "path", "void *" }, 54 { "security/keys/big_key.c", "path", "void *" },
55 /* walk struct security_hook_heads as an array of struct list_head */ 55 /* walk struct security_hook_heads as an array of struct hlist_head */
56 { "security/security.c", "list_head", "security_hook_heads" }, 56 { "security/security.c", "hlist_head", "security_hook_heads" },
57 { } 57 { }
58}; 58};
59 59
diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
new file mode 100644
index 000000000000..2f48da98b5d4
--- /dev/null
+++ b/scripts/gcc-plugins/stackleak_plugin.c
@@ -0,0 +1,427 @@
1/*
2 * Copyright 2011-2017 by the PaX Team <pageexec@freemail.hu>
3 * Modified by Alexander Popov <alex.popov@linux.com>
4 * Licensed under the GPL v2
5 *
6 * Note: the choice of the license means that the compilation process is
7 * NOT 'eligible' as defined by gcc's library exception to the GPL v3,
8 * but for the kernel it doesn't matter since it doesn't link against
9 * any of the gcc libraries
10 *
11 * This gcc plugin is needed for tracking the lowest border of the kernel stack.
12 * It instruments the kernel code inserting stackleak_track_stack() calls:
13 * - after alloca();
14 * - for the functions with a stack frame size greater than or equal
15 * to the "track-min-size" plugin parameter.
16 *
17 * This plugin is ported from grsecurity/PaX. For more information see:
18 * https://grsecurity.net/
19 * https://pax.grsecurity.net/
20 *
21 * Debugging:
22 * - use fprintf() to stderr, debug_generic_expr(), debug_gimple_stmt(),
23 * print_rtl() and print_simple_rtl();
24 * - add "-fdump-tree-all -fdump-rtl-all" to the plugin CFLAGS in
25 * Makefile.gcc-plugins to see the verbose dumps of the gcc passes;
26 * - use gcc -E to understand the preprocessing shenanigans;
27 * - use gcc with enabled CFG/GIMPLE/SSA verification (--enable-checking).
28 */
29
30#include "gcc-common.h"
31
32__visible int plugin_is_GPL_compatible;
33
34static int track_frame_size = -1;
35static const char track_function[] = "stackleak_track_stack";
36
37/*
38 * Mark these global variables (roots) for gcc garbage collector since
39 * they point to the garbage-collected memory.
40 */
41static GTY(()) tree track_function_decl;
42
43static struct plugin_info stackleak_plugin_info = {
44 .version = "201707101337",
45 .help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n"
46 "disable\t\tdo not activate the plugin\n"
47};
48
49static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after)
50{
51 gimple stmt;
52 gcall *stackleak_track_stack;
53 cgraph_node_ptr node;
54 int frequency;
55 basic_block bb;
56
57 /* Insert call to void stackleak_track_stack(void) */
58 stmt = gimple_build_call(track_function_decl, 0);
59 stackleak_track_stack = as_a_gcall(stmt);
60 if (after) {
61 gsi_insert_after(gsi, stackleak_track_stack,
62 GSI_CONTINUE_LINKING);
63 } else {
64 gsi_insert_before(gsi, stackleak_track_stack, GSI_SAME_STMT);
65 }
66
67 /* Update the cgraph */
68 bb = gimple_bb(stackleak_track_stack);
69 node = cgraph_get_create_node(track_function_decl);
70 gcc_assert(node);
71 frequency = compute_call_stmt_bb_frequency(current_function_decl, bb);
72 cgraph_create_edge(cgraph_get_node(current_function_decl), node,
73 stackleak_track_stack, bb->count, frequency);
74}
75
76static bool is_alloca(gimple stmt)
77{
78 if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA))
79 return true;
80
81#if BUILDING_GCC_VERSION >= 4007
82 if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
83 return true;
84#endif
85
86 return false;
87}
88
89/*
90 * Work with the GIMPLE representation of the code. Insert the
91 * stackleak_track_stack() call after alloca() and into the beginning
92 * of the function if it is not instrumented.
93 */
94static unsigned int stackleak_instrument_execute(void)
95{
96 basic_block bb, entry_bb;
97 bool prologue_instrumented = false, is_leaf = true;
98 gimple_stmt_iterator gsi;
99
100 /*
101 * ENTRY_BLOCK_PTR is a basic block which represents possible entry
102 * point of a function. This block does not contain any code and
103 * has a CFG edge to its successor.
104 */
105 gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
106 entry_bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
107
108 /*
109 * Loop through the GIMPLE statements in each of cfun basic blocks.
110 * cfun is a global variable which represents the function that is
111 * currently processed.
112 */
113 FOR_EACH_BB_FN(bb, cfun) {
114 for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
115 gimple stmt;
116
117 stmt = gsi_stmt(gsi);
118
119 /* Leaf function is a function which makes no calls */
120 if (is_gimple_call(stmt))
121 is_leaf = false;
122
123 if (!is_alloca(stmt))
124 continue;
125
126 /* Insert stackleak_track_stack() call after alloca() */
127 stackleak_add_track_stack(&gsi, true);
128 if (bb == entry_bb)
129 prologue_instrumented = true;
130 }
131 }
132
133 if (prologue_instrumented)
134 return 0;
135
136 /*
137 * Special cases to skip the instrumentation.
138 *
139 * Taking the address of static inline functions materializes them,
140 * but we mustn't instrument some of them as the resulting stack
141 * alignment required by the function call ABI will break other
142 * assumptions regarding the expected (but not otherwise enforced)
143 * register clobbering ABI.
144 *
145 * Case in point: native_save_fl on amd64 when optimized for size
146 * clobbers rdx if it were instrumented here.
147 *
148 * TODO: any more special cases?
149 */
150 if (is_leaf &&
151 !TREE_PUBLIC(current_function_decl) &&
152 DECL_DECLARED_INLINE_P(current_function_decl)) {
153 return 0;
154 }
155
156 if (is_leaf &&
157 !strncmp(IDENTIFIER_POINTER(DECL_NAME(current_function_decl)),
158 "_paravirt_", 10)) {
159 return 0;
160 }
161
162 /* Insert stackleak_track_stack() call at the function beginning */
163 bb = entry_bb;
164 if (!single_pred_p(bb)) {
165 /* gcc_assert(bb_loop_depth(bb) ||
166 (bb->flags & BB_IRREDUCIBLE_LOOP)); */
167 split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
168 gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
169 bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
170 }
171 gsi = gsi_after_labels(bb);
172 stackleak_add_track_stack(&gsi, false);
173
174 return 0;
175}
176
177static bool large_stack_frame(void)
178{
179#if BUILDING_GCC_VERSION >= 8000
180 return maybe_ge(get_frame_size(), track_frame_size);
181#else
182 return (get_frame_size() >= track_frame_size);
183#endif
184}
185
186/*
187 * Work with the RTL representation of the code.
188 * Remove the unneeded stackleak_track_stack() calls from the functions
189 * which don't call alloca() and don't have a large enough stack frame size.
190 */
191static unsigned int stackleak_cleanup_execute(void)
192{
193 rtx_insn *insn, *next;
194
195 if (cfun->calls_alloca)
196 return 0;
197
198 if (large_stack_frame())
199 return 0;
200
201 /*
202 * Find stackleak_track_stack() calls. Loop through the chain of insns,
203 * which is an RTL representation of the code for a function.
204 *
205 * The example of a matching insn:
206 * (call_insn 8 4 10 2 (call (mem (symbol_ref ("stackleak_track_stack")
207 * [flags 0x41] <function_decl 0x7f7cd3302a80 stackleak_track_stack>)
208 * [0 stackleak_track_stack S1 A8]) (0)) 675 {*call} (expr_list
209 * (symbol_ref ("stackleak_track_stack") [flags 0x41] <function_decl
210 * 0x7f7cd3302a80 stackleak_track_stack>) (expr_list (0) (nil))) (nil))
211 */
212 for (insn = get_insns(); insn; insn = next) {
213 rtx body;
214
215 next = NEXT_INSN(insn);
216
217 /* Check the expression code of the insn */
218 if (!CALL_P(insn))
219 continue;
220
221 /*
222 * Check the expression code of the insn body, which is an RTL
223 * Expression (RTX) describing the side effect performed by
224 * that insn.
225 */
226 body = PATTERN(insn);
227
228 if (GET_CODE(body) == PARALLEL)
229 body = XVECEXP(body, 0, 0);
230
231 if (GET_CODE(body) != CALL)
232 continue;
233
234 /*
235 * Check the first operand of the call expression. It should
236 * be a mem RTX describing the needed subroutine with a
237 * symbol_ref RTX.
238 */
239 body = XEXP(body, 0);
240 if (GET_CODE(body) != MEM)
241 continue;
242
243 body = XEXP(body, 0);
244 if (GET_CODE(body) != SYMBOL_REF)
245 continue;
246
247 if (SYMBOL_REF_DECL(body) != track_function_decl)
248 continue;
249
250 /* Delete the stackleak_track_stack() call */
251 delete_insn_and_edges(insn);
252#if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION < 8000
253 if (GET_CODE(next) == NOTE &&
254 NOTE_KIND(next) == NOTE_INSN_CALL_ARG_LOCATION) {
255 insn = next;
256 next = NEXT_INSN(insn);
257 delete_insn_and_edges(insn);
258 }
259#endif
260 }
261
262 return 0;
263}
264
265static bool stackleak_gate(void)
266{
267 tree section;
268
269 section = lookup_attribute("section",
270 DECL_ATTRIBUTES(current_function_decl));
271 if (section && TREE_VALUE(section)) {
272 section = TREE_VALUE(TREE_VALUE(section));
273
274 if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10))
275 return false;
276 if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13))
277 return false;
278 if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13))
279 return false;
280 if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13))
281 return false;
282 }
283
284 return track_frame_size >= 0;
285}
286
287/* Build the function declaration for stackleak_track_stack() */
288static void stackleak_start_unit(void *gcc_data __unused,
289 void *user_data __unused)
290{
291 tree fntype;
292
293 /* void stackleak_track_stack(void) */
294 fntype = build_function_type_list(void_type_node, NULL_TREE);
295 track_function_decl = build_fn_decl(track_function, fntype);
296 DECL_ASSEMBLER_NAME(track_function_decl); /* for LTO */
297 TREE_PUBLIC(track_function_decl) = 1;
298 TREE_USED(track_function_decl) = 1;
299 DECL_EXTERNAL(track_function_decl) = 1;
300 DECL_ARTIFICIAL(track_function_decl) = 1;
301 DECL_PRESERVE_P(track_function_decl) = 1;
302}
303
304/*
305 * Pass gate function is a predicate function that gets executed before the
306 * corresponding pass. If the return value is 'true' the pass gets executed,
307 * otherwise, it is skipped.
308 */
309static bool stackleak_instrument_gate(void)
310{
311 return stackleak_gate();
312}
313
314#define PASS_NAME stackleak_instrument
315#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg
316#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts
317#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func \
318 | TODO_update_ssa | TODO_rebuild_cgraph_edges
319#include "gcc-generate-gimple-pass.h"
320
321static bool stackleak_cleanup_gate(void)
322{
323 return stackleak_gate();
324}
325
326#define PASS_NAME stackleak_cleanup
327#define TODO_FLAGS_FINISH TODO_dump_func
328#include "gcc-generate-rtl-pass.h"
329
330/*
331 * Every gcc plugin exports a plugin_init() function that is called right
332 * after the plugin is loaded. This function is responsible for registering
333 * the plugin callbacks and doing other required initialization.
334 */
335__visible int plugin_init(struct plugin_name_args *plugin_info,
336 struct plugin_gcc_version *version)
337{
338 const char * const plugin_name = plugin_info->base_name;
339 const int argc = plugin_info->argc;
340 const struct plugin_argument * const argv = plugin_info->argv;
341 int i = 0;
342
343 /* Extra GGC root tables describing our GTY-ed data */
344 static const struct ggc_root_tab gt_ggc_r_gt_stackleak[] = {
345 {
346 .base = &track_function_decl,
347 .nelt = 1,
348 .stride = sizeof(track_function_decl),
349 .cb = &gt_ggc_mx_tree_node,
350 .pchw = &gt_pch_nx_tree_node
351 },
352 LAST_GGC_ROOT_TAB
353 };
354
355 /*
356 * The stackleak_instrument pass should be executed before the
357 * "optimized" pass, which is the control flow graph cleanup that is
358 * performed just before expanding gcc trees to the RTL. In former
359 * versions of the plugin this new pass was inserted before the
360 * "tree_profile" pass, which is currently called "profile".
361 */
362 PASS_INFO(stackleak_instrument, "optimized", 1,
363 PASS_POS_INSERT_BEFORE);
364
365 /*
366 * The stackleak_cleanup pass should be executed after the
367 * "reload" pass, when the stack frame size is final.
368 */
369 PASS_INFO(stackleak_cleanup, "reload", 1, PASS_POS_INSERT_AFTER);
370
371 if (!plugin_default_version_check(version, &gcc_version)) {
372 error(G_("incompatible gcc/plugin versions"));
373 return 1;
374 }
375
376 /* Parse the plugin arguments */
377 for (i = 0; i < argc; i++) {
378 if (!strcmp(argv[i].key, "disable"))
379 return 0;
380
381 if (!strcmp(argv[i].key, "track-min-size")) {
382 if (!argv[i].value) {
383 error(G_("no value supplied for option '-fplugin-arg-%s-%s'"),
384 plugin_name, argv[i].key);
385 return 1;
386 }
387
388 track_frame_size = atoi(argv[i].value);
389 if (track_frame_size < 0) {
390 error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"),
391 plugin_name, argv[i].key, argv[i].value);
392 return 1;
393 }
394 } else {
395 error(G_("unknown option '-fplugin-arg-%s-%s'"),
396 plugin_name, argv[i].key);
397 return 1;
398 }
399 }
400
401 /* Give the information about the plugin */
402 register_callback(plugin_name, PLUGIN_INFO, NULL,
403 &stackleak_plugin_info);
404
405 /* Register to be called before processing a translation unit */
406 register_callback(plugin_name, PLUGIN_START_UNIT,
407 &stackleak_start_unit, NULL);
408
409 /* Register an extra GCC garbage collector (GGC) root table */
410 register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL,
411 (void *)&gt_ggc_r_gt_stackleak);
412
413 /*
414 * Hook into the Pass Manager to register new gcc passes.
415 *
416 * The stack frame size info is available only at the last RTL pass,
417 * when it's too late to insert complex code like a function call.
418 * So we register two gcc passes to instrument every function at first
419 * and remove the unneeded instrumentation later.
420 */
421 register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
422 &stackleak_instrument_pass_info);
423 register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
424 &stackleak_cleanup_pass_info);
425
426 return 0;
427}
diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh
index 6b2aeefb9cd3..f5c119495254 100755
--- a/scripts/gcc-x86_32-has-stack-protector.sh
+++ b/scripts/gcc-x86_32-has-stack-protector.sh
@@ -1,9 +1,4 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3 3
4echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs" 4echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m32 -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
5if [ "$?" -eq "0" ] ; then
6 echo y
7else
8 echo n
9fi
diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh
index 4a48bdcd4d6b..75e4e22b986a 100755
--- a/scripts/gcc-x86_64-has-stack-protector.sh
+++ b/scripts/gcc-x86_64-has-stack-protector.sh
@@ -1,9 +1,4 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3 3
4echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs" 4echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -m64 -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
5if [ "$?" -eq "0" ] ; then
6 echo y
7else
8 echo n
9fi
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
deleted file mode 100755
index 86a3c0e5cfbc..000000000000
--- a/scripts/gen_initramfs_list.sh
+++ /dev/null
@@ -1,328 +0,0 @@
1#!/bin/sh
2# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
3# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
4#
5# Released under the terms of the GNU GPL
6#
7# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
8# the cpio archive, and then compresses it.
9# The script may also be used to generate the inputfile used for gen_init_cpio
10# This script assumes that gen_init_cpio is located in usr/ directory
11
12# error out on errors
13set -e
14
15usage() {
16cat << EOF
17Usage:
18$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
19 -o <file> Create compressed initramfs file named <file> using
20 gen_init_cpio and compressor depending on the extension
21 -u <uid> User ID to map to user ID 0 (root).
22 <uid> is only meaningful if <cpio_source> is a
23 directory. "squash" forces all files to uid 0.
24 -g <gid> Group ID to map to group ID 0 (root).
25 <gid> is only meaningful if <cpio_source> is a
26 directory. "squash" forces all files to gid 0.
27 <cpio_source> File list or directory for cpio archive.
28 If <cpio_source> is a .cpio file it will be used
29 as direct input to initramfs.
30 -d Output the default cpio list.
31
32All options except -o and -l may be repeated and are interpreted
33sequentially and immediately. -u and -g states are preserved across
34<cpio_source> options so an explicit "-u 0 -g 0" is required
35to reset the root/group mapping.
36EOF
37}
38
39# awk style field access
40# $1 - field number; rest is argument string
41field() {
42 shift $1 ; echo $1
43}
44
45list_default_initramfs() {
46 # echo usr/kinit/kinit
47 :
48}
49
50default_initramfs() {
51 cat <<-EOF >> ${output}
52 # This is a very simple, default initramfs
53
54 dir /dev 0755 0 0
55 nod /dev/console 0600 0 0 c 5 1
56 dir /root 0700 0 0
57 # file /kinit usr/kinit/kinit 0755 0 0
58 # slink /init kinit 0755 0 0
59 EOF
60}
61
62filetype() {
63 local argv1="$1"
64
65 # symlink test must come before file test
66 if [ -L "${argv1}" ]; then
67 echo "slink"
68 elif [ -f "${argv1}" ]; then
69 echo "file"
70 elif [ -d "${argv1}" ]; then
71 echo "dir"
72 elif [ -b "${argv1}" -o -c "${argv1}" ]; then
73 echo "nod"
74 elif [ -p "${argv1}" ]; then
75 echo "pipe"
76 elif [ -S "${argv1}" ]; then
77 echo "sock"
78 else
79 echo "invalid"
80 fi
81 return 0
82}
83
84list_print_mtime() {
85 :
86}
87
88print_mtime() {
89 local my_mtime="0"
90
91 if [ -e "$1" ]; then
92 my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
93 fi
94
95 echo "# Last modified: ${my_mtime}" >> ${output}
96 echo "" >> ${output}
97}
98
99list_parse() {
100 if [ -L "$1" ]; then
101 return
102 fi
103 echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
104}
105
106# for each file print a line in following format
107# <filetype> <name> <path to file> <octal mode> <uid> <gid>
108# for links, devices etc the format differs. See gen_init_cpio for details
109parse() {
110 local location="$1"
111 local name="/${location#${srcdir}}"
112 # change '//' into '/'
113 name=$(echo "$name" | sed -e 's://*:/:g')
114 local mode="$2"
115 local uid="$3"
116 local gid="$4"
117 local ftype=$(filetype "${location}")
118 # remap uid/gid to 0 if necessary
119 [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
120 [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
121 local str="${mode} ${uid} ${gid}"
122
123 [ "${ftype}" = "invalid" ] && return 0
124 [ "${location}" = "${srcdir}" ] && return 0
125
126 case "${ftype}" in
127 "file")
128 str="${ftype} ${name} ${location} ${str}"
129 ;;
130 "nod")
131 local dev=`LC_ALL=C ls -l "${location}"`
132 local maj=`field 5 ${dev}`
133 local min=`field 6 ${dev}`
134 maj=${maj%,}
135
136 [ -b "${location}" ] && dev="b" || dev="c"
137
138 str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
139 ;;
140 "slink")
141 local target=`readlink "${location}"`
142 str="${ftype} ${name} ${target} ${str}"
143 ;;
144 *)
145 str="${ftype} ${name} ${str}"
146 ;;
147 esac
148
149 echo "${str}" >> ${output}
150
151 return 0
152}
153
154unknown_option() {
155 printf "ERROR: unknown option \"$arg\"\n" >&2
156 printf "If the filename validly begins with '-', " >&2
157 printf "then it must be prefixed\n" >&2
158 printf "by './' so that it won't be interpreted as an option." >&2
159 printf "\n" >&2
160 usage >&2
161 exit 1
162}
163
164list_header() {
165 :
166}
167
168header() {
169 printf "\n#####################\n# $1\n" >> ${output}
170}
171
172# process one directory (incl sub-directories)
173dir_filelist() {
174 ${dep_list}header "$1"
175
176 srcdir=$(echo "$1" | sed -e 's://*:/:g')
177 dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | sort)
178
179 # If $dirlist is only one line, then the directory is empty
180 if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
181 ${dep_list}print_mtime "$1"
182
183 echo "${dirlist}" | \
184 while read x; do
185 ${dep_list}parse ${x}
186 done
187 fi
188}
189
190# if only one file is specified and it is .cpio file then use it direct as fs
191# if a directory is specified then add all files in given direcotry to fs
192# if a regular file is specified assume it is in gen_initramfs format
193input_file() {
194 source="$1"
195 if [ -f "$1" ]; then
196 ${dep_list}header "$1"
197 is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\?/cpio/')"
198 if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
199 cpio_file=$1
200 echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
201 [ ! -z ${dep_list} ] && echo "$1"
202 return 0
203 fi
204 if [ -z ${dep_list} ]; then
205 print_mtime "$1" >> ${output}
206 cat "$1" >> ${output}
207 else
208 echo "$1 \\"
209 cat "$1" | while read type dir file perm ; do
210 if [ "$type" = "file" ]; then
211 echo "$file \\";
212 fi
213 done
214 fi
215 elif [ -d "$1" ]; then
216 dir_filelist "$1"
217 else
218 echo " ${prog}: Cannot open '$1'" >&2
219 exit 1
220 fi
221}
222
223prog=$0
224root_uid=0
225root_gid=0
226dep_list=
227cpio_file=
228cpio_list=
229output="/dev/stdout"
230output_file=""
231is_cpio_compressed=
232compr="gzip -n -9 -f"
233
234arg="$1"
235case "$arg" in
236 "-l") # files included in initramfs - used by kbuild
237 dep_list="list_"
238 echo "deps_initramfs := $0 \\"
239 shift
240 ;;
241 "-o") # generate compressed cpio image named $1
242 shift
243 output_file="$1"
244 cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
245 output=${cpio_list}
246 echo "$output_file" | grep -q "\.gz$" \
247 && [ -x "`which gzip 2> /dev/null`" ] \
248 && compr="gzip -n -9 -f"
249 echo "$output_file" | grep -q "\.bz2$" \
250 && [ -x "`which bzip2 2> /dev/null`" ] \
251 && compr="bzip2 -9 -f"
252 echo "$output_file" | grep -q "\.lzma$" \
253 && [ -x "`which lzma 2> /dev/null`" ] \
254 && compr="lzma -9 -f"
255 echo "$output_file" | grep -q "\.xz$" \
256 && [ -x "`which xz 2> /dev/null`" ] \
257 && compr="xz --check=crc32 --lzma2=dict=1MiB"
258 echo "$output_file" | grep -q "\.lzo$" \
259 && [ -x "`which lzop 2> /dev/null`" ] \
260 && compr="lzop -9 -f"
261 echo "$output_file" | grep -q "\.lz4$" \
262 && [ -x "`which lz4 2> /dev/null`" ] \
263 && compr="lz4 -l -9 -f"
264 echo "$output_file" | grep -q "\.cpio$" && compr="cat"
265 shift
266 ;;
267esac
268while [ $# -gt 0 ]; do
269 arg="$1"
270 shift
271 case "$arg" in
272 "-u") # map $1 to uid=0 (root)
273 root_uid="$1"
274 [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
275 shift
276 ;;
277 "-g") # map $1 to gid=0 (root)
278 root_gid="$1"
279 [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
280 shift
281 ;;
282 "-d") # display default initramfs list
283 default_list="$arg"
284 ${dep_list}default_initramfs
285 ;;
286 "-h")
287 usage
288 exit 0
289 ;;
290 *)
291 case "$arg" in
292 "-"*)
293 unknown_option
294 ;;
295 *) # input file/dir - process it
296 input_file "$arg" "$#"
297 ;;
298 esac
299 ;;
300 esac
301done
302
303# If output_file is set we will generate cpio archive and compress it
304# we are careful to delete tmp files
305if [ ! -z ${output_file} ]; then
306 if [ -z ${cpio_file} ]; then
307 timestamp=
308 if test -n "$KBUILD_BUILD_TIMESTAMP"; then
309 timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
310 if test -n "$timestamp"; then
311 timestamp="-t $timestamp"
312 fi
313 fi
314 cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
315 usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
316 else
317 cpio_tfile=${cpio_file}
318 fi
319 rm ${cpio_list}
320 if [ "${is_cpio_compressed}" = "compressed" ]; then
321 cat ${cpio_tfile} > ${output_file}
322 else
323 (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
324 || (rm -f ${output_file} ; false)
325 fi
326 [ -z ${cpio_file} ] && rm ${cpio_tfile}
327fi
328exit 0
diff --git a/scripts/genksyms/.gitignore b/scripts/genksyms/.gitignore
index e7836b47f060..b119c7da2863 100644
--- a/scripts/genksyms/.gitignore
+++ b/scripts/genksyms/.gitignore
@@ -1,4 +1 @@
1*.lex.c
2*.tab.c
3*.tab.h
4genksyms genksyms
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
index 34d6ab1811a4..03b7ce97de14 100644
--- a/scripts/genksyms/Makefile
+++ b/scripts/genksyms/Makefile
@@ -5,11 +5,34 @@ always := $(hostprogs-y)
5 5
6genksyms-objs := genksyms.o parse.tab.o lex.lex.o 6genksyms-objs := genksyms.o parse.tab.o lex.lex.o
7 7
8# FIXME: fix the ambiguous grammar in parse.y and delete this hack
9#
10# Suppress shift/reduce, reduce/reduce conflicts warnings
11# unless W=1 is specified.
12#
13# Just in case, run "$(YACC) --version" without suppressing stderr
14# so that 'bison: not found' will be displayed if it is missing.
15ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),)
16
17quiet_cmd_bison_no_warn = $(quiet_cmd_bison)
18 cmd_bison_no_warn = $(YACC) --version >/dev/null; \
19 $(cmd_bison) 2>/dev/null
20
21$(obj)/parse.tab.c: $(src)/parse.y FORCE
22 $(call if_changed,bison_no_warn)
23
24quiet_cmd_bison_h_no_warn = $(quiet_cmd_bison_h)
25 cmd_bison_h_no_warn = $(YACC) --version >/dev/null; \
26 $(cmd_bison_h) 2>/dev/null
27
28$(obj)/parse.tab.h: $(src)/parse.y FORCE
29 $(call if_changed,bison_h_no_warn)
30
31endif
32
8# -I needed for generated C source (shipped source) 33# -I needed for generated C source (shipped source)
9HOSTCFLAGS_parse.tab.o := -I$(src) 34HOSTCFLAGS_parse.tab.o := -I$(src)
10HOSTCFLAGS_lex.lex.o := -I$(src) 35HOSTCFLAGS_lex.lex.o := -I$(src)
11 36
12# dependencies on generated files need to be listed explicitly 37# dependencies on generated files need to be listed explicitly
13$(obj)/lex.lex.o: $(obj)/parse.tab.h 38$(obj)/lex.lex.o: $(obj)/parse.tab.h
14
15clean-files := lex.lex.c parse.tab.c parse.tab.h
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index c9235d8340f1..e007840f45b9 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -45,7 +45,6 @@ int in_source_file;
45 45
46static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, 46static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
47 flag_preserve, flag_warnings, flag_rel_crcs; 47 flag_preserve, flag_warnings, flag_rel_crcs;
48static const char *mod_prefix = "";
49 48
50static int errors; 49static int errors;
51static int nsyms; 50static int nsyms;
@@ -693,10 +692,10 @@ void export_symbol(const char *name)
693 fputs(">\n", debugfile); 692 fputs(">\n", debugfile);
694 693
695 /* Used as a linker script. */ 694 /* Used as a linker script. */
696 printf(!flag_rel_crcs ? "%s__crc_%s = 0x%08lx;\n" : 695 printf(!flag_rel_crcs ? "__crc_%s = 0x%08lx;\n" :
697 "SECTIONS { .rodata : ALIGN(4) { " 696 "SECTIONS { .rodata : ALIGN(4) { "
698 "%s__crc_%s = .; LONG(0x%08lx); } }\n", 697 "__crc_%s = .; LONG(0x%08lx); } }\n",
699 mod_prefix, name, crc); 698 name, crc);
700 } 699 }
701} 700}
702 701
@@ -769,7 +768,6 @@ int main(int argc, char **argv)
769 768
770#ifdef __GNU_LIBRARY__ 769#ifdef __GNU_LIBRARY__
771 struct option long_opts[] = { 770 struct option long_opts[] = {
772 {"symbol-prefix", 1, 0, 's'},
773 {"debug", 0, 0, 'd'}, 771 {"debug", 0, 0, 'd'},
774 {"warnings", 0, 0, 'w'}, 772 {"warnings", 0, 0, 'w'},
775 {"quiet", 0, 0, 'q'}, 773 {"quiet", 0, 0, 'q'},
@@ -789,9 +787,6 @@ int main(int argc, char **argv)
789 while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF) 787 while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF)
790#endif /* __GNU_LIBRARY__ */ 788#endif /* __GNU_LIBRARY__ */
791 switch (o) { 789 switch (o) {
792 case 's':
793 mod_prefix = optarg;
794 break;
795 case 'd': 790 case 'd':
796 flag_debug++; 791 flag_debug++;
797 break; 792 break;
diff --git a/scripts/genksyms/lex.lex.c_shipped b/scripts/genksyms/lex.lex.c_shipped
deleted file mode 100644
index ba2fda8dfdb2..000000000000
--- a/scripts/genksyms/lex.lex.c_shipped
+++ /dev/null
@@ -1,2291 +0,0 @@
1
2#line 3 "scripts/genksyms/lex.lex.c_shipped"
3
4#define YY_INT_ALIGNED short int
5
6/* A lexical scanner generated by flex */
7
8#define FLEX_SCANNER
9#define YY_FLEX_MAJOR_VERSION 2
10#define YY_FLEX_MINOR_VERSION 5
11#define YY_FLEX_SUBMINOR_VERSION 35
12#if YY_FLEX_SUBMINOR_VERSION > 0
13#define FLEX_BETA
14#endif
15
16/* First, we deal with platform-specific or compiler-specific issues. */
17
18/* begin standard C headers. */
19#include <stdio.h>
20#include <string.h>
21#include <errno.h>
22#include <stdlib.h>
23
24/* end standard C headers. */
25
26/* flex integer type definitions */
27
28#ifndef FLEXINT_H
29#define FLEXINT_H
30
31/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
32
33#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
34
35/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
36 * if you want the limit (max/min) macros for int types.
37 */
38#ifndef __STDC_LIMIT_MACROS
39#define __STDC_LIMIT_MACROS 1
40#endif
41
42#include <inttypes.h>
43typedef int8_t flex_int8_t;
44typedef uint8_t flex_uint8_t;
45typedef int16_t flex_int16_t;
46typedef uint16_t flex_uint16_t;
47typedef int32_t flex_int32_t;
48typedef uint32_t flex_uint32_t;
49#else
50typedef signed char flex_int8_t;
51typedef short int flex_int16_t;
52typedef int flex_int32_t;
53typedef unsigned char flex_uint8_t;
54typedef unsigned short int flex_uint16_t;
55typedef unsigned int flex_uint32_t;
56#endif /* ! C99 */
57
58/* Limits of integral types. */
59#ifndef INT8_MIN
60#define INT8_MIN (-128)
61#endif
62#ifndef INT16_MIN
63#define INT16_MIN (-32767-1)
64#endif
65#ifndef INT32_MIN
66#define INT32_MIN (-2147483647-1)
67#endif
68#ifndef INT8_MAX
69#define INT8_MAX (127)
70#endif
71#ifndef INT16_MAX
72#define INT16_MAX (32767)
73#endif
74#ifndef INT32_MAX
75#define INT32_MAX (2147483647)
76#endif
77#ifndef UINT8_MAX
78#define UINT8_MAX (255U)
79#endif
80#ifndef UINT16_MAX
81#define UINT16_MAX (65535U)
82#endif
83#ifndef UINT32_MAX
84#define UINT32_MAX (4294967295U)
85#endif
86
87#endif /* ! FLEXINT_H */
88
89#ifdef __cplusplus
90
91/* The "const" storage-class-modifier is valid. */
92#define YY_USE_CONST
93
94#else /* ! __cplusplus */
95
96/* C99 requires __STDC__ to be defined as 1. */
97#if defined (__STDC__)
98
99#define YY_USE_CONST
100
101#endif /* defined (__STDC__) */
102#endif /* ! __cplusplus */
103
104#ifdef YY_USE_CONST
105#define yyconst const
106#else
107#define yyconst
108#endif
109
110/* Returned upon end-of-file. */
111#define YY_NULL 0
112
113/* Promotes a possibly negative, possibly signed char to an unsigned
114 * integer for use as an array index. If the signed char is negative,
115 * we want to instead treat it as an 8-bit unsigned char, hence the
116 * double cast.
117 */
118#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
119
120/* Enter a start condition. This macro really ought to take a parameter,
121 * but we do it the disgusting crufty way forced on us by the ()-less
122 * definition of BEGIN.
123 */
124#define BEGIN (yy_start) = 1 + 2 *
125
126/* Translate the current start state into a value that can be later handed
127 * to BEGIN to return to the state. The YYSTATE alias is for lex
128 * compatibility.
129 */
130#define YY_START (((yy_start) - 1) / 2)
131#define YYSTATE YY_START
132
133/* Action number for EOF rule of a given start state. */
134#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
135
136/* Special action meaning "start processing a new file". */
137#define YY_NEW_FILE yyrestart(yyin )
138
139#define YY_END_OF_BUFFER_CHAR 0
140
141/* Size of default input buffer. */
142#ifndef YY_BUF_SIZE
143#define YY_BUF_SIZE 16384
144#endif
145
146/* The state buf must be large enough to hold one state per character in the main buffer.
147 */
148#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
149
150#ifndef YY_TYPEDEF_YY_BUFFER_STATE
151#define YY_TYPEDEF_YY_BUFFER_STATE
152typedef struct yy_buffer_state *YY_BUFFER_STATE;
153#endif
154
155extern int yyleng;
156
157extern FILE *yyin, *yyout;
158
159#define EOB_ACT_CONTINUE_SCAN 0
160#define EOB_ACT_END_OF_FILE 1
161#define EOB_ACT_LAST_MATCH 2
162
163 #define YY_LESS_LINENO(n)
164
165/* Return all but the first "n" matched characters back to the input stream. */
166#define yyless(n) \
167 do \
168 { \
169 /* Undo effects of setting up yytext. */ \
170 int yyless_macro_arg = (n); \
171 YY_LESS_LINENO(yyless_macro_arg);\
172 *yy_cp = (yy_hold_char); \
173 YY_RESTORE_YY_MORE_OFFSET \
174 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
175 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
176 } \
177 while ( 0 )
178
179#define unput(c) yyunput( c, (yytext_ptr) )
180
181#ifndef YY_TYPEDEF_YY_SIZE_T
182#define YY_TYPEDEF_YY_SIZE_T
183typedef size_t yy_size_t;
184#endif
185
186#ifndef YY_STRUCT_YY_BUFFER_STATE
187#define YY_STRUCT_YY_BUFFER_STATE
188struct yy_buffer_state
189 {
190 FILE *yy_input_file;
191
192 char *yy_ch_buf; /* input buffer */
193 char *yy_buf_pos; /* current position in input buffer */
194
195 /* Size of input buffer in bytes, not including room for EOB
196 * characters.
197 */
198 yy_size_t yy_buf_size;
199
200 /* Number of characters read into yy_ch_buf, not including EOB
201 * characters.
202 */
203 int yy_n_chars;
204
205 /* Whether we "own" the buffer - i.e., we know we created it,
206 * and can realloc() it to grow it, and should free() it to
207 * delete it.
208 */
209 int yy_is_our_buffer;
210
211 /* Whether this is an "interactive" input source; if so, and
212 * if we're using stdio for input, then we want to use getc()
213 * instead of fread(), to make sure we stop fetching input after
214 * each newline.
215 */
216 int yy_is_interactive;
217
218 /* Whether we're considered to be at the beginning of a line.
219 * If so, '^' rules will be active on the next match, otherwise
220 * not.
221 */
222 int yy_at_bol;
223
224 int yy_bs_lineno; /**< The line count. */
225 int yy_bs_column; /**< The column count. */
226
227 /* Whether to try to fill the input buffer when we reach the
228 * end of it.
229 */
230 int yy_fill_buffer;
231
232 int yy_buffer_status;
233
234#define YY_BUFFER_NEW 0
235#define YY_BUFFER_NORMAL 1
236 /* When an EOF's been seen but there's still some text to process
237 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
238 * shouldn't try reading from the input source any more. We might
239 * still have a bunch of tokens to match, though, because of
240 * possible backing-up.
241 *
242 * When we actually see the EOF, we change the status to "new"
243 * (via yyrestart()), so that the user can continue scanning by
244 * just pointing yyin at a new input file.
245 */
246#define YY_BUFFER_EOF_PENDING 2
247
248 };
249#endif /* !YY_STRUCT_YY_BUFFER_STATE */
250
251/* Stack of input buffers. */
252static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
253static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
254static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
255
256/* We provide macros for accessing buffer states in case in the
257 * future we want to put the buffer states in a more general
258 * "scanner state".
259 *
260 * Returns the top of the stack, or NULL.
261 */
262#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
263 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
264 : NULL)
265
266/* Same as previous macro, but useful when we know that the buffer stack is not
267 * NULL or when we need an lvalue. For internal use only.
268 */
269#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
270
271/* yy_hold_char holds the character lost when yytext is formed. */
272static char yy_hold_char;
273static int yy_n_chars; /* number of characters read into yy_ch_buf */
274int yyleng;
275
276/* Points to current character in buffer. */
277static char *yy_c_buf_p = (char *) 0;
278static int yy_init = 0; /* whether we need to initialize */
279static int yy_start = 0; /* start state number */
280
281/* Flag which is used to allow yywrap()'s to do buffer switches
282 * instead of setting up a fresh yyin. A bit of a hack ...
283 */
284static int yy_did_buffer_switch_on_eof;
285
286void yyrestart (FILE *input_file );
287void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
288YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
289void yy_delete_buffer (YY_BUFFER_STATE b );
290void yy_flush_buffer (YY_BUFFER_STATE b );
291void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
292void yypop_buffer_state (void );
293
294static void yyensure_buffer_stack (void );
295static void yy_load_buffer_state (void );
296static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
297
298#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
299
300YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
301YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
302YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
303
304void *yyalloc (yy_size_t );
305void *yyrealloc (void *,yy_size_t );
306void yyfree (void * );
307
308#define yy_new_buffer yy_create_buffer
309
310#define yy_set_interactive(is_interactive) \
311 { \
312 if ( ! YY_CURRENT_BUFFER ){ \
313 yyensure_buffer_stack (); \
314 YY_CURRENT_BUFFER_LVALUE = \
315 yy_create_buffer(yyin,YY_BUF_SIZE ); \
316 } \
317 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
318 }
319
320#define yy_set_bol(at_bol) \
321 { \
322 if ( ! YY_CURRENT_BUFFER ){\
323 yyensure_buffer_stack (); \
324 YY_CURRENT_BUFFER_LVALUE = \
325 yy_create_buffer(yyin,YY_BUF_SIZE ); \
326 } \
327 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
328 }
329
330#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
331
332/* Begin user sect3 */
333
334#define yywrap(n) 1
335#define YY_SKIP_YYWRAP
336
337typedef unsigned char YY_CHAR;
338
339FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
340
341typedef int yy_state_type;
342
343extern int yylineno;
344
345int yylineno = 1;
346
347extern char *yytext;
348#define yytext_ptr yytext
349
350static yy_state_type yy_get_previous_state (void );
351static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
352static int yy_get_next_buffer (void );
353static void yy_fatal_error (yyconst char msg[] );
354
355/* Done after the current pattern has been matched and before the
356 * corresponding action - sets up yytext.
357 */
358#define YY_DO_BEFORE_ACTION \
359 (yytext_ptr) = yy_bp; \
360 yyleng = (size_t) (yy_cp - yy_bp); \
361 (yy_hold_char) = *yy_cp; \
362 *yy_cp = '\0'; \
363 (yy_c_buf_p) = yy_cp;
364
365#define YY_NUM_RULES 13
366#define YY_END_OF_BUFFER 14
367/* This struct is not used in this scanner,
368 but its presence is necessary. */
369struct yy_trans_info
370 {
371 flex_int32_t yy_verify;
372 flex_int32_t yy_nxt;
373 };
374static yyconst flex_int16_t yy_accept[73] =
375 { 0,
376 0, 0, 14, 12, 4, 3, 12, 7, 12, 12,
377 12, 12, 12, 9, 9, 12, 12, 7, 12, 12,
378 4, 0, 5, 0, 7, 8, 0, 6, 0, 0,
379 10, 10, 9, 0, 0, 9, 9, 0, 9, 0,
380 0, 0, 0, 2, 0, 0, 11, 0, 10, 0,
381 10, 9, 9, 0, 0, 0, 10, 10, 0, 0,
382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
383 1, 0
384 } ;
385
386static yyconst flex_int32_t yy_ec[256] =
387 { 0,
388 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
389 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
390 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
391 1, 2, 1, 5, 6, 7, 8, 9, 10, 1,
392 1, 8, 11, 1, 12, 13, 8, 14, 15, 15,
393 15, 15, 15, 15, 15, 16, 16, 1, 1, 17,
394 18, 19, 1, 1, 20, 20, 20, 20, 21, 22,
395 7, 7, 7, 7, 7, 23, 7, 7, 7, 7,
396 7, 7, 7, 7, 24, 7, 7, 25, 7, 7,
397 1, 26, 1, 8, 7, 1, 20, 20, 20, 20,
398
399 21, 22, 7, 7, 7, 7, 7, 27, 7, 7,
400 7, 7, 7, 7, 7, 7, 24, 7, 7, 25,
401 7, 7, 1, 28, 1, 8, 1, 1, 1, 1,
402 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
403 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
404 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
405 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
406 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
407 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
408 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
409
410 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
411 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
412 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
413 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
414 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
415 1, 1, 1, 1, 1
416 } ;
417
418static yyconst flex_int32_t yy_meta[29] =
419 { 0,
420 1, 1, 2, 1, 1, 1, 3, 1, 1, 1,
421 4, 4, 5, 6, 6, 6, 1, 1, 1, 7,
422 8, 7, 3, 3, 3, 1, 3, 1
423 } ;
424
425static yyconst flex_int16_t yy_base[85] =
426 { 0,
427 0, 145, 150, 266, 27, 266, 25, 0, 131, 23,
428 23, 16, 23, 39, 31, 25, 39, 60, 22, 65,
429 57, 43, 266, 0, 0, 266, 61, 266, 0, 128,
430 74, 0, 113, 59, 62, 113, 52, 0, 0, 72,
431 66, 110, 100, 266, 73, 74, 266, 70, 266, 90,
432 103, 266, 84, 129, 108, 113, 143, 266, 107, 66,
433 118, 137, 168, 120, 80, 91, 145, 143, 83, 41,
434 266, 266, 190, 196, 204, 212, 220, 228, 232, 237,
435 238, 243, 249, 257
436 } ;
437
438static yyconst flex_int16_t yy_def[85] =
439 { 0,
440 72, 1, 72, 72, 72, 72, 73, 74, 72, 72,
441 75, 72, 72, 72, 14, 72, 72, 74, 72, 76,
442 72, 73, 72, 77, 74, 72, 75, 72, 78, 72,
443 72, 31, 14, 79, 80, 72, 72, 81, 15, 73,
444 75, 76, 76, 72, 73, 75, 72, 82, 72, 72,
445 72, 72, 81, 76, 54, 72, 72, 72, 76, 54,
446 76, 76, 76, 54, 83, 76, 63, 83, 84, 84,
447 72, 0, 72, 72, 72, 72, 72, 72, 72, 72,
448 72, 72, 72, 72
449 } ;
450
451static yyconst flex_int16_t yy_nxt[295] =
452 { 0,
453 4, 5, 6, 5, 7, 4, 8, 9, 10, 11,
454 9, 12, 13, 14, 15, 15, 16, 9, 17, 8,
455 8, 8, 18, 8, 8, 4, 8, 19, 21, 23,
456 21, 26, 28, 26, 26, 30, 31, 31, 31, 26,
457 26, 26, 26, 71, 39, 39, 39, 23, 29, 26,
458 24, 32, 33, 33, 34, 72, 26, 26, 21, 35,
459 21, 36, 37, 38, 40, 36, 43, 44, 24, 41,
460 28, 32, 50, 50, 52, 28, 23, 23, 52, 35,
461 56, 56, 44, 28, 42, 71, 29, 31, 31, 31,
462 42, 29, 59, 44, 48, 49, 49, 24, 24, 29,
463
464 49, 43, 44, 51, 51, 51, 36, 37, 59, 44,
465 36, 65, 44, 54, 55, 55, 51, 51, 51, 59,
466 44, 64, 64, 64, 58, 58, 57, 57, 57, 58,
467 59, 44, 42, 64, 64, 64, 52, 72, 59, 44,
468 47, 66, 60, 60, 42, 44, 59, 69, 26, 72,
469 20, 61, 62, 63, 72, 61, 57, 57, 57, 66,
470 72, 72, 72, 66, 49, 49, 72, 61, 62, 49,
471 44, 61, 72, 72, 72, 72, 72, 72, 72, 72,
472 72, 67, 67, 67, 72, 72, 72, 67, 67, 67,
473 22, 22, 22, 22, 22, 22, 22, 22, 25, 72,
474
475 72, 25, 25, 25, 27, 27, 27, 27, 27, 27,
476 27, 27, 42, 42, 42, 42, 42, 42, 42, 42,
477 45, 72, 45, 45, 45, 45, 45, 45, 46, 72,
478 46, 46, 46, 46, 46, 46, 34, 34, 72, 34,
479 51, 72, 51, 53, 53, 53, 57, 72, 57, 68,
480 68, 68, 68, 68, 68, 68, 68, 70, 70, 70,
481 70, 70, 70, 70, 70, 3, 72, 72, 72, 72,
482 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
483 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
484 72, 72, 72, 72
485
486 } ;
487
488static yyconst flex_int16_t yy_chk[295] =
489 { 0,
490 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
491 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
492 1, 1, 1, 1, 1, 1, 1, 1, 5, 7,
493 5, 10, 11, 12, 12, 13, 13, 13, 13, 19,
494 10, 16, 16, 70, 15, 15, 15, 22, 11, 19,
495 7, 14, 14, 14, 14, 15, 17, 17, 21, 14,
496 21, 14, 14, 14, 18, 14, 20, 20, 22, 18,
497 27, 34, 35, 35, 37, 41, 40, 45, 37, 34,
498 48, 48, 65, 46, 65, 69, 27, 31, 31, 31,
499 60, 41, 66, 66, 31, 31, 31, 40, 45, 46,
500
501 31, 43, 43, 50, 50, 50, 53, 53, 59, 59,
502 53, 59, 42, 43, 43, 43, 51, 51, 51, 61,
503 61, 55, 55, 55, 51, 51, 56, 56, 56, 51,
504 54, 54, 55, 64, 64, 64, 36, 33, 62, 62,
505 30, 61, 54, 54, 64, 68, 67, 68, 9, 3,
506 2, 54, 54, 54, 0, 54, 57, 57, 57, 62,
507 0, 0, 0, 62, 57, 57, 0, 67, 67, 57,
508 63, 67, 0, 0, 0, 0, 0, 0, 0, 0,
509 0, 63, 63, 63, 0, 0, 0, 63, 63, 63,
510 73, 73, 73, 73, 73, 73, 73, 73, 74, 0,
511
512 0, 74, 74, 74, 75, 75, 75, 75, 75, 75,
513 75, 75, 76, 76, 76, 76, 76, 76, 76, 76,
514 77, 0, 77, 77, 77, 77, 77, 77, 78, 0,
515 78, 78, 78, 78, 78, 78, 79, 79, 0, 79,
516 80, 0, 80, 81, 81, 81, 82, 0, 82, 83,
517 83, 83, 83, 83, 83, 83, 83, 84, 84, 84,
518 84, 84, 84, 84, 84, 72, 72, 72, 72, 72,
519 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
520 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
521 72, 72, 72, 72
522
523 } ;
524
525static yy_state_type yy_last_accepting_state;
526static char *yy_last_accepting_cpos;
527
528extern int yy_flex_debug;
529int yy_flex_debug = 0;
530
531/* The intent behind this definition is that it'll catch
532 * any uses of REJECT which flex missed.
533 */
534#define REJECT reject_used_but_not_detected
535#define yymore() yymore_used_but_not_detected
536#define YY_MORE_ADJ 0
537#define YY_RESTORE_YY_MORE_OFFSET
538char *yytext;
539/* Lexical analysis for genksyms.
540 Copyright 1996, 1997 Linux International.
541
542 New implementation contributed by Richard Henderson <rth@tamu.edu>
543 Based on original work by Bjorn Ekwall <bj0rn@blox.se>
544
545 Taken from Linux modutils 2.4.22.
546
547 This program is free software; you can redistribute it and/or modify it
548 under the terms of the GNU General Public License as published by the
549 Free Software Foundation; either version 2 of the License, or (at your
550 option) any later version.
551
552 This program is distributed in the hope that it will be useful, but
553 WITHOUT ANY WARRANTY; without even the implied warranty of
554 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
555 General Public License for more details.
556
557 You should have received a copy of the GNU General Public License
558 along with this program; if not, write to the Free Software Foundation,
559 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
560
561#include <limits.h>
562#include <stdlib.h>
563#include <string.h>
564#include <ctype.h>
565
566#include "genksyms.h"
567#include "parse.tab.h"
568
569/* We've got a two-level lexer here. We let flex do basic tokenization
570 and then we categorize those basic tokens in the second stage. */
571#define YY_DECL static int yylex1(void)
572
573/* We don't do multiple input files. */
574#define YY_NO_INPUT 1
575
576#define INITIAL 0
577
578#ifndef YY_NO_UNISTD_H
579/* Special case for "unistd.h", since it is non-ANSI. We include it way
580 * down here because we want the user's section 1 to have been scanned first.
581 * The user has a chance to override it with an option.
582 */
583#include <unistd.h>
584#endif
585
586#ifndef YY_EXTRA_TYPE
587#define YY_EXTRA_TYPE void *
588#endif
589
590static int yy_init_globals (void );
591
592/* Accessor methods to globals.
593 These are made visible to non-reentrant scanners for convenience. */
594
595int yylex_destroy (void );
596
597int yyget_debug (void );
598
599void yyset_debug (int debug_flag );
600
601YY_EXTRA_TYPE yyget_extra (void );
602
603void yyset_extra (YY_EXTRA_TYPE user_defined );
604
605FILE *yyget_in (void );
606
607void yyset_in (FILE * in_str );
608
609FILE *yyget_out (void );
610
611void yyset_out (FILE * out_str );
612
613int yyget_leng (void );
614
615char *yyget_text (void );
616
617int yyget_lineno (void );
618
619void yyset_lineno (int line_number );
620
621/* Macros after this point can all be overridden by user definitions in
622 * section 1.
623 */
624
625#ifndef YY_SKIP_YYWRAP
626#ifdef __cplusplus
627extern "C" int yywrap (void );
628#else
629extern int yywrap (void );
630#endif
631#endif
632
633 static void yyunput (int c,char *buf_ptr );
634
635#ifndef yytext_ptr
636static void yy_flex_strncpy (char *,yyconst char *,int );
637#endif
638
639#ifdef YY_NEED_STRLEN
640static int yy_flex_strlen (yyconst char * );
641#endif
642
643#ifndef YY_NO_INPUT
644
645#ifdef __cplusplus
646static int yyinput (void );
647#else
648static int input (void );
649#endif
650
651#endif
652
653/* Amount of stuff to slurp up with each read. */
654#ifndef YY_READ_BUF_SIZE
655#define YY_READ_BUF_SIZE 8192
656#endif
657
658/* Copy whatever the last rule matched to the standard output. */
659#ifndef ECHO
660/* This used to be an fputs(), but since the string might contain NUL's,
661 * we now use fwrite().
662 */
663#define ECHO fwrite( yytext, yyleng, 1, yyout )
664#endif
665
666/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
667 * is returned in "result".
668 */
669#ifndef YY_INPUT
670#define YY_INPUT(buf,result,max_size) \
671 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
672 { \
673 int c = '*'; \
674 int n; \
675 for ( n = 0; n < max_size && \
676 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
677 buf[n] = (char) c; \
678 if ( c == '\n' ) \
679 buf[n++] = (char) c; \
680 if ( c == EOF && ferror( yyin ) ) \
681 YY_FATAL_ERROR( "input in flex scanner failed" ); \
682 result = n; \
683 } \
684 else \
685 { \
686 errno=0; \
687 while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
688 { \
689 if( errno != EINTR) \
690 { \
691 YY_FATAL_ERROR( "input in flex scanner failed" ); \
692 break; \
693 } \
694 errno=0; \
695 clearerr(yyin); \
696 } \
697 }\
698\
699
700#endif
701
702/* No semi-colon after return; correct usage is to write "yyterminate();" -
703 * we don't want an extra ';' after the "return" because that will cause
704 * some compilers to complain about unreachable statements.
705 */
706#ifndef yyterminate
707#define yyterminate() return YY_NULL
708#endif
709
710/* Number of entries by which start-condition stack grows. */
711#ifndef YY_START_STACK_INCR
712#define YY_START_STACK_INCR 25
713#endif
714
715/* Report a fatal error. */
716#ifndef YY_FATAL_ERROR
717#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
718#endif
719
720/* end tables serialization structures and prototypes */
721
722/* Default declaration of generated scanner - a define so the user can
723 * easily add parameters.
724 */
725#ifndef YY_DECL
726#define YY_DECL_IS_OURS 1
727
728extern int yylex (void);
729
730#define YY_DECL int yylex (void)
731#endif /* !YY_DECL */
732
733/* Code executed at the beginning of each rule, after yytext and yyleng
734 * have been set up.
735 */
736#ifndef YY_USER_ACTION
737#define YY_USER_ACTION
738#endif
739
740/* Code executed at the end of each rule. */
741#ifndef YY_BREAK
742#define YY_BREAK break;
743#endif
744
745#define YY_RULE_SETUP \
746 if ( yyleng > 0 ) \
747 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
748 (yytext[yyleng - 1] == '\n'); \
749 YY_USER_ACTION
750
751/** The main scanner function which does all the work.
752 */
753YY_DECL
754{
755 register yy_state_type yy_current_state;
756 register char *yy_cp, *yy_bp;
757 register int yy_act;
758
759 /* Keep track of our location in the original source files. */
760
761 if ( !(yy_init) )
762 {
763 (yy_init) = 1;
764
765#ifdef YY_USER_INIT
766 YY_USER_INIT;
767#endif
768
769 if ( ! (yy_start) )
770 (yy_start) = 1; /* first start state */
771
772 if ( ! yyin )
773 yyin = stdin;
774
775 if ( ! yyout )
776 yyout = stdout;
777
778 if ( ! YY_CURRENT_BUFFER ) {
779 yyensure_buffer_stack ();
780 YY_CURRENT_BUFFER_LVALUE =
781 yy_create_buffer(yyin,YY_BUF_SIZE );
782 }
783
784 yy_load_buffer_state( );
785 }
786
787 while ( 1 ) /* loops until end-of-file is reached */
788 {
789 yy_cp = (yy_c_buf_p);
790
791 /* Support of yytext. */
792 *yy_cp = (yy_hold_char);
793
794 /* yy_bp points to the position in yy_ch_buf of the start of
795 * the current run.
796 */
797 yy_bp = yy_cp;
798
799 yy_current_state = (yy_start);
800 yy_current_state += YY_AT_BOL();
801yy_match:
802 do
803 {
804 register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
805 if ( yy_accept[yy_current_state] )
806 {
807 (yy_last_accepting_state) = yy_current_state;
808 (yy_last_accepting_cpos) = yy_cp;
809 }
810 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
811 {
812 yy_current_state = (int) yy_def[yy_current_state];
813 if ( yy_current_state >= 73 )
814 yy_c = yy_meta[(unsigned int) yy_c];
815 }
816 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
817 ++yy_cp;
818 }
819 while ( yy_base[yy_current_state] != 266 );
820
821yy_find_action:
822 yy_act = yy_accept[yy_current_state];
823 if ( yy_act == 0 )
824 { /* have to back up */
825 yy_cp = (yy_last_accepting_cpos);
826 yy_current_state = (yy_last_accepting_state);
827 yy_act = yy_accept[yy_current_state];
828 }
829
830 YY_DO_BEFORE_ACTION;
831
832do_action: /* This label is used only to access EOF actions. */
833
834 switch ( yy_act )
835 { /* beginning of action switch */
836 case 0: /* must back up */
837 /* undo the effects of YY_DO_BEFORE_ACTION */
838 *yy_cp = (yy_hold_char);
839 yy_cp = (yy_last_accepting_cpos);
840 yy_current_state = (yy_last_accepting_state);
841 goto yy_find_action;
842
843case 1:
844/* rule 1 can match eol */
845YY_RULE_SETUP
846return FILENAME;
847 YY_BREAK
848case 2:
849/* rule 2 can match eol */
850YY_RULE_SETUP
851cur_line++;
852 YY_BREAK
853case 3:
854/* rule 3 can match eol */
855YY_RULE_SETUP
856cur_line++;
857 YY_BREAK
858/* Ignore all other whitespace. */
859case 4:
860YY_RULE_SETUP
861;
862 YY_BREAK
863case 5:
864/* rule 5 can match eol */
865YY_RULE_SETUP
866return STRING;
867 YY_BREAK
868case 6:
869/* rule 6 can match eol */
870YY_RULE_SETUP
871return CHAR;
872 YY_BREAK
873case 7:
874YY_RULE_SETUP
875return IDENT;
876 YY_BREAK
877/* The Pedant requires that the other C multi-character tokens be
878 recognized as tokens. We don't actually use them since we don't
879 parse expressions, but we do want whitespace to be arranged
880 around them properly. */
881case 8:
882YY_RULE_SETUP
883return OTHER;
884 YY_BREAK
885case 9:
886YY_RULE_SETUP
887return INT;
888 YY_BREAK
889case 10:
890YY_RULE_SETUP
891return REAL;
892 YY_BREAK
893case 11:
894YY_RULE_SETUP
895return DOTS;
896 YY_BREAK
897/* All other tokens are single characters. */
898case 12:
899YY_RULE_SETUP
900return yytext[0];
901 YY_BREAK
902case 13:
903YY_RULE_SETUP
904ECHO;
905 YY_BREAK
906case YY_STATE_EOF(INITIAL):
907 yyterminate();
908
909 case YY_END_OF_BUFFER:
910 {
911 /* Amount of text matched not including the EOB char. */
912 int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
913
914 /* Undo the effects of YY_DO_BEFORE_ACTION. */
915 *yy_cp = (yy_hold_char);
916 YY_RESTORE_YY_MORE_OFFSET
917
918 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
919 {
920 /* We're scanning a new file or input source. It's
921 * possible that this happened because the user
922 * just pointed yyin at a new source and called
923 * yylex(). If so, then we have to assure
924 * consistency between YY_CURRENT_BUFFER and our
925 * globals. Here is the right place to do so, because
926 * this is the first action (other than possibly a
927 * back-up) that will match for the new input source.
928 */
929 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
930 YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
931 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
932 }
933
934 /* Note that here we test for yy_c_buf_p "<=" to the position
935 * of the first EOB in the buffer, since yy_c_buf_p will
936 * already have been incremented past the NUL character
937 * (since all states make transitions on EOB to the
938 * end-of-buffer state). Contrast this with the test
939 * in input().
940 */
941 if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
942 { /* This was really a NUL. */
943 yy_state_type yy_next_state;
944
945 (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
946
947 yy_current_state = yy_get_previous_state( );
948
949 /* Okay, we're now positioned to make the NUL
950 * transition. We couldn't have
951 * yy_get_previous_state() go ahead and do it
952 * for us because it doesn't know how to deal
953 * with the possibility of jamming (and we don't
954 * want to build jamming into it because then it
955 * will run more slowly).
956 */
957
958 yy_next_state = yy_try_NUL_trans( yy_current_state );
959
960 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
961
962 if ( yy_next_state )
963 {
964 /* Consume the NUL. */
965 yy_cp = ++(yy_c_buf_p);
966 yy_current_state = yy_next_state;
967 goto yy_match;
968 }
969
970 else
971 {
972 yy_cp = (yy_c_buf_p);
973 goto yy_find_action;
974 }
975 }
976
977 else switch ( yy_get_next_buffer( ) )
978 {
979 case EOB_ACT_END_OF_FILE:
980 {
981 (yy_did_buffer_switch_on_eof) = 0;
982
983 if ( yywrap( ) )
984 {
985 /* Note: because we've taken care in
986 * yy_get_next_buffer() to have set up
987 * yytext, we can now set up
988 * yy_c_buf_p so that if some total
989 * hoser (like flex itself) wants to
990 * call the scanner after we return the
991 * YY_NULL, it'll still work - another
992 * YY_NULL will get returned.
993 */
994 (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
995
996 yy_act = YY_STATE_EOF(YY_START);
997 goto do_action;
998 }
999
1000 else
1001 {
1002 if ( ! (yy_did_buffer_switch_on_eof) )
1003 YY_NEW_FILE;
1004 }
1005 break;
1006 }
1007
1008 case EOB_ACT_CONTINUE_SCAN:
1009 (yy_c_buf_p) =
1010 (yytext_ptr) + yy_amount_of_matched_text;
1011
1012 yy_current_state = yy_get_previous_state( );
1013
1014 yy_cp = (yy_c_buf_p);
1015 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1016 goto yy_match;
1017
1018 case EOB_ACT_LAST_MATCH:
1019 (yy_c_buf_p) =
1020 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
1021
1022 yy_current_state = yy_get_previous_state( );
1023
1024 yy_cp = (yy_c_buf_p);
1025 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1026 goto yy_find_action;
1027 }
1028 break;
1029 }
1030
1031 default:
1032 YY_FATAL_ERROR(
1033 "fatal flex scanner internal error--no action found" );
1034 } /* end of action switch */
1035 } /* end of scanning one token */
1036} /* end of yylex */
1037
1038/* yy_get_next_buffer - try to read in a new buffer
1039 *
1040 * Returns a code representing an action:
1041 * EOB_ACT_LAST_MATCH -
1042 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
1043 * EOB_ACT_END_OF_FILE - end of file
1044 */
1045static int yy_get_next_buffer (void)
1046{
1047 register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1048 register char *source = (yytext_ptr);
1049 register int number_to_move, i;
1050 int ret_val;
1051
1052 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
1053 YY_FATAL_ERROR(
1054 "fatal flex scanner internal error--end of buffer missed" );
1055
1056 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
1057 { /* Don't try to fill the buffer, so this is an EOF. */
1058 if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
1059 {
1060 /* We matched a single character, the EOB, so
1061 * treat this as a final EOF.
1062 */
1063 return EOB_ACT_END_OF_FILE;
1064 }
1065
1066 else
1067 {
1068 /* We matched some text prior to the EOB, first
1069 * process it.
1070 */
1071 return EOB_ACT_LAST_MATCH;
1072 }
1073 }
1074
1075 /* Try to read more data. */
1076
1077 /* First move last chars to start of buffer. */
1078 number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
1079
1080 for ( i = 0; i < number_to_move; ++i )
1081 *(dest++) = *(source++);
1082
1083 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1084 /* don't do the read, it's not guaranteed to return an EOF,
1085 * just force an EOF
1086 */
1087 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
1088
1089 else
1090 {
1091 int num_to_read =
1092 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1093
1094 while ( num_to_read <= 0 )
1095 { /* Not enough room in the buffer - grow it. */
1096
1097 /* just a shorter name for the current buffer */
1098 YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
1099
1100 int yy_c_buf_p_offset =
1101 (int) ((yy_c_buf_p) - b->yy_ch_buf);
1102
1103 if ( b->yy_is_our_buffer )
1104 {
1105 int new_size = b->yy_buf_size * 2;
1106
1107 if ( new_size <= 0 )
1108 b->yy_buf_size += b->yy_buf_size / 8;
1109 else
1110 b->yy_buf_size *= 2;
1111
1112 b->yy_ch_buf = (char *)
1113 /* Include room in for 2 EOB chars. */
1114 yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
1115 }
1116 else
1117 /* Can't grow it, we don't own it. */
1118 b->yy_ch_buf = 0;
1119
1120 if ( ! b->yy_ch_buf )
1121 YY_FATAL_ERROR(
1122 "fatal error - scanner input buffer overflow" );
1123
1124 (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
1125
1126 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
1127 number_to_move - 1;
1128
1129 }
1130
1131 if ( num_to_read > YY_READ_BUF_SIZE )
1132 num_to_read = YY_READ_BUF_SIZE;
1133
1134 /* Read in more data. */
1135 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1136 (yy_n_chars), (size_t) num_to_read );
1137
1138 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1139 }
1140
1141 if ( (yy_n_chars) == 0 )
1142 {
1143 if ( number_to_move == YY_MORE_ADJ )
1144 {
1145 ret_val = EOB_ACT_END_OF_FILE;
1146 yyrestart(yyin );
1147 }
1148
1149 else
1150 {
1151 ret_val = EOB_ACT_LAST_MATCH;
1152 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
1153 YY_BUFFER_EOF_PENDING;
1154 }
1155 }
1156
1157 else
1158 ret_val = EOB_ACT_CONTINUE_SCAN;
1159
1160 if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
1161 /* Extend the array by 50%, plus the number we really need. */
1162 yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
1163 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
1164 if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1165 YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
1166 }
1167
1168 (yy_n_chars) += number_to_move;
1169 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1170 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
1171
1172 (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
1173
1174 return ret_val;
1175}
1176
1177/* yy_get_previous_state - get the state just before the EOB char was reached */
1178
1179 static yy_state_type yy_get_previous_state (void)
1180{
1181 register yy_state_type yy_current_state;
1182 register char *yy_cp;
1183
1184 yy_current_state = (yy_start);
1185 yy_current_state += YY_AT_BOL();
1186
1187 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1188 {
1189 register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1190 if ( yy_accept[yy_current_state] )
1191 {
1192 (yy_last_accepting_state) = yy_current_state;
1193 (yy_last_accepting_cpos) = yy_cp;
1194 }
1195 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1196 {
1197 yy_current_state = (int) yy_def[yy_current_state];
1198 if ( yy_current_state >= 73 )
1199 yy_c = yy_meta[(unsigned int) yy_c];
1200 }
1201 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1202 }
1203
1204 return yy_current_state;
1205}
1206
1207/* yy_try_NUL_trans - try to make a transition on the NUL character
1208 *
1209 * synopsis
1210 * next_state = yy_try_NUL_trans( current_state );
1211 */
1212 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
1213{
1214 register int yy_is_jam;
1215 register char *yy_cp = (yy_c_buf_p);
1216
1217 register YY_CHAR yy_c = 1;
1218 if ( yy_accept[yy_current_state] )
1219 {
1220 (yy_last_accepting_state) = yy_current_state;
1221 (yy_last_accepting_cpos) = yy_cp;
1222 }
1223 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1224 {
1225 yy_current_state = (int) yy_def[yy_current_state];
1226 if ( yy_current_state >= 73 )
1227 yy_c = yy_meta[(unsigned int) yy_c];
1228 }
1229 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1230 yy_is_jam = (yy_current_state == 72);
1231
1232 return yy_is_jam ? 0 : yy_current_state;
1233}
1234
1235 static void yyunput (int c, register char * yy_bp )
1236{
1237 register char *yy_cp;
1238
1239 yy_cp = (yy_c_buf_p);
1240
1241 /* undo effects of setting up yytext */
1242 *yy_cp = (yy_hold_char);
1243
1244 if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
1245 { /* need to shift things up to make room */
1246 /* +2 for EOB chars. */
1247 register int number_to_move = (yy_n_chars) + 2;
1248 register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
1249 YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
1250 register char *source =
1251 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
1252
1253 while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1254 *--dest = *--source;
1255
1256 yy_cp += (int) (dest - source);
1257 yy_bp += (int) (dest - source);
1258 YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
1259 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
1260
1261 if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
1262 YY_FATAL_ERROR( "flex scanner push-back overflow" );
1263 }
1264
1265 *--yy_cp = (char) c;
1266
1267 (yytext_ptr) = yy_bp;
1268 (yy_hold_char) = *yy_cp;
1269 (yy_c_buf_p) = yy_cp;
1270}
1271
1272#ifndef YY_NO_INPUT
1273#ifdef __cplusplus
1274 static int yyinput (void)
1275#else
1276 static int input (void)
1277#endif
1278
1279{
1280 int c;
1281
1282 *(yy_c_buf_p) = (yy_hold_char);
1283
1284 if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
1285 {
1286 /* yy_c_buf_p now points to the character we want to return.
1287 * If this occurs *before* the EOB characters, then it's a
1288 * valid NUL; if not, then we've hit the end of the buffer.
1289 */
1290 if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1291 /* This was really a NUL. */
1292 *(yy_c_buf_p) = '\0';
1293
1294 else
1295 { /* need more input */
1296 int offset = (yy_c_buf_p) - (yytext_ptr);
1297 ++(yy_c_buf_p);
1298
1299 switch ( yy_get_next_buffer( ) )
1300 {
1301 case EOB_ACT_LAST_MATCH:
1302 /* This happens because yy_g_n_b()
1303 * sees that we've accumulated a
1304 * token and flags that we need to
1305 * try matching the token before
1306 * proceeding. But for input(),
1307 * there's no matching to consider.
1308 * So convert the EOB_ACT_LAST_MATCH
1309 * to EOB_ACT_END_OF_FILE.
1310 */
1311
1312 /* Reset buffer status. */
1313 yyrestart(yyin );
1314
1315 /*FALLTHROUGH*/
1316
1317 case EOB_ACT_END_OF_FILE:
1318 {
1319 if ( yywrap( ) )
1320 return EOF;
1321
1322 if ( ! (yy_did_buffer_switch_on_eof) )
1323 YY_NEW_FILE;
1324#ifdef __cplusplus
1325 return yyinput();
1326#else
1327 return input();
1328#endif
1329 }
1330
1331 case EOB_ACT_CONTINUE_SCAN:
1332 (yy_c_buf_p) = (yytext_ptr) + offset;
1333 break;
1334 }
1335 }
1336 }
1337
1338 c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
1339 *(yy_c_buf_p) = '\0'; /* preserve yytext */
1340 (yy_hold_char) = *++(yy_c_buf_p);
1341
1342 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
1343
1344 return c;
1345}
1346#endif /* ifndef YY_NO_INPUT */
1347
1348/** Immediately switch to a different input stream.
1349 * @param input_file A readable stream.
1350 *
1351 * @note This function does not reset the start condition to @c INITIAL .
1352 */
1353 void yyrestart (FILE * input_file )
1354{
1355
1356 if ( ! YY_CURRENT_BUFFER ){
1357 yyensure_buffer_stack ();
1358 YY_CURRENT_BUFFER_LVALUE =
1359 yy_create_buffer(yyin,YY_BUF_SIZE );
1360 }
1361
1362 yy_init_buffer(YY_CURRENT_BUFFER,input_file );
1363 yy_load_buffer_state( );
1364}
1365
1366/** Switch to a different input buffer.
1367 * @param new_buffer The new input buffer.
1368 *
1369 */
1370 void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
1371{
1372
1373 /* TODO. We should be able to replace this entire function body
1374 * with
1375 * yypop_buffer_state();
1376 * yypush_buffer_state(new_buffer);
1377 */
1378 yyensure_buffer_stack ();
1379 if ( YY_CURRENT_BUFFER == new_buffer )
1380 return;
1381
1382 if ( YY_CURRENT_BUFFER )
1383 {
1384 /* Flush out information for old buffer. */
1385 *(yy_c_buf_p) = (yy_hold_char);
1386 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1387 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1388 }
1389
1390 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1391 yy_load_buffer_state( );
1392
1393 /* We don't actually know whether we did this switch during
1394 * EOF (yywrap()) processing, but the only time this flag
1395 * is looked at is after yywrap() is called, so it's safe
1396 * to go ahead and always set it.
1397 */
1398 (yy_did_buffer_switch_on_eof) = 1;
1399}
1400
1401static void yy_load_buffer_state (void)
1402{
1403 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1404 (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
1405 yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
1406 (yy_hold_char) = *(yy_c_buf_p);
1407}
1408
1409/** Allocate and initialize an input buffer state.
1410 * @param file A readable stream.
1411 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1412 *
1413 * @return the allocated buffer state.
1414 */
1415 YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
1416{
1417 YY_BUFFER_STATE b;
1418
1419 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1420 if ( ! b )
1421 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1422
1423 b->yy_buf_size = size;
1424
1425 /* yy_ch_buf has to be 2 characters longer than the size given because
1426 * we need to put in 2 end-of-buffer characters.
1427 */
1428 b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
1429 if ( ! b->yy_ch_buf )
1430 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1431
1432 b->yy_is_our_buffer = 1;
1433
1434 yy_init_buffer(b,file );
1435
1436 return b;
1437}
1438
1439/** Destroy the buffer.
1440 * @param b a buffer created with yy_create_buffer()
1441 *
1442 */
1443 void yy_delete_buffer (YY_BUFFER_STATE b )
1444{
1445
1446 if ( ! b )
1447 return;
1448
1449 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
1450 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
1451
1452 if ( b->yy_is_our_buffer )
1453 yyfree((void *) b->yy_ch_buf );
1454
1455 yyfree((void *) b );
1456}
1457
1458#ifndef __cplusplus
1459extern int isatty (int );
1460#endif /* __cplusplus */
1461
1462/* Initializes or reinitializes a buffer.
1463 * This function is sometimes called more than once on the same buffer,
1464 * such as during a yyrestart() or at EOF.
1465 */
1466 static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
1467
1468{
1469 int oerrno = errno;
1470
1471 yy_flush_buffer(b );
1472
1473 b->yy_input_file = file;
1474 b->yy_fill_buffer = 1;
1475
1476 /* If b is the current buffer, then yy_init_buffer was _probably_
1477 * called from yyrestart() or through yy_get_next_buffer.
1478 * In that case, we don't want to reset the lineno or column.
1479 */
1480 if (b != YY_CURRENT_BUFFER){
1481 b->yy_bs_lineno = 1;
1482 b->yy_bs_column = 0;
1483 }
1484
1485 b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
1486
1487 errno = oerrno;
1488}
1489
1490/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1491 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1492 *
1493 */
1494 void yy_flush_buffer (YY_BUFFER_STATE b )
1495{
1496 if ( ! b )
1497 return;
1498
1499 b->yy_n_chars = 0;
1500
1501 /* We always need two end-of-buffer characters. The first causes
1502 * a transition to the end-of-buffer state. The second causes
1503 * a jam in that state.
1504 */
1505 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1506 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1507
1508 b->yy_buf_pos = &b->yy_ch_buf[0];
1509
1510 b->yy_at_bol = 1;
1511 b->yy_buffer_status = YY_BUFFER_NEW;
1512
1513 if ( b == YY_CURRENT_BUFFER )
1514 yy_load_buffer_state( );
1515}
1516
1517/** Pushes the new state onto the stack. The new state becomes
1518 * the current state. This function will allocate the stack
1519 * if necessary.
1520 * @param new_buffer The new state.
1521 *
1522 */
1523void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
1524{
1525 if (new_buffer == NULL)
1526 return;
1527
1528 yyensure_buffer_stack();
1529
1530 /* This block is copied from yy_switch_to_buffer. */
1531 if ( YY_CURRENT_BUFFER )
1532 {
1533 /* Flush out information for old buffer. */
1534 *(yy_c_buf_p) = (yy_hold_char);
1535 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1536 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1537 }
1538
1539 /* Only push if top exists. Otherwise, replace top. */
1540 if (YY_CURRENT_BUFFER)
1541 (yy_buffer_stack_top)++;
1542 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1543
1544 /* copied from yy_switch_to_buffer. */
1545 yy_load_buffer_state( );
1546 (yy_did_buffer_switch_on_eof) = 1;
1547}
1548
1549/** Removes and deletes the top of the stack, if present.
1550 * The next element becomes the new top.
1551 *
1552 */
1553void yypop_buffer_state (void)
1554{
1555 if (!YY_CURRENT_BUFFER)
1556 return;
1557
1558 yy_delete_buffer(YY_CURRENT_BUFFER );
1559 YY_CURRENT_BUFFER_LVALUE = NULL;
1560 if ((yy_buffer_stack_top) > 0)
1561 --(yy_buffer_stack_top);
1562
1563 if (YY_CURRENT_BUFFER) {
1564 yy_load_buffer_state( );
1565 (yy_did_buffer_switch_on_eof) = 1;
1566 }
1567}
1568
1569/* Allocates the stack if it does not exist.
1570 * Guarantees space for at least one push.
1571 */
1572static void yyensure_buffer_stack (void)
1573{
1574 int num_to_alloc;
1575
1576 if (!(yy_buffer_stack)) {
1577
1578 /* First allocation is just for 2 elements, since we don't know if this
1579 * scanner will even need a stack. We use 2 instead of 1 to avoid an
1580 * immediate realloc on the next call.
1581 */
1582 num_to_alloc = 1;
1583 (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
1584 (num_to_alloc * sizeof(struct yy_buffer_state*)
1585 );
1586 if ( ! (yy_buffer_stack) )
1587 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1588
1589 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1590
1591 (yy_buffer_stack_max) = num_to_alloc;
1592 (yy_buffer_stack_top) = 0;
1593 return;
1594 }
1595
1596 if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
1597
1598 /* Increase the buffer to prepare for a possible push. */
1599 int grow_size = 8 /* arbitrary grow size */;
1600
1601 num_to_alloc = (yy_buffer_stack_max) + grow_size;
1602 (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
1603 ((yy_buffer_stack),
1604 num_to_alloc * sizeof(struct yy_buffer_state*)
1605 );
1606 if ( ! (yy_buffer_stack) )
1607 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1608
1609 /* zero only the new slots.*/
1610 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
1611 (yy_buffer_stack_max) = num_to_alloc;
1612 }
1613}
1614
1615/** Setup the input buffer state to scan directly from a user-specified character buffer.
1616 * @param base the character buffer
1617 * @param size the size in bytes of the character buffer
1618 *
1619 * @return the newly allocated buffer state object.
1620 */
1621YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
1622{
1623 YY_BUFFER_STATE b;
1624
1625 if ( size < 2 ||
1626 base[size-2] != YY_END_OF_BUFFER_CHAR ||
1627 base[size-1] != YY_END_OF_BUFFER_CHAR )
1628 /* They forgot to leave room for the EOB's. */
1629 return 0;
1630
1631 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1632 if ( ! b )
1633 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
1634
1635 b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
1636 b->yy_buf_pos = b->yy_ch_buf = base;
1637 b->yy_is_our_buffer = 0;
1638 b->yy_input_file = 0;
1639 b->yy_n_chars = b->yy_buf_size;
1640 b->yy_is_interactive = 0;
1641 b->yy_at_bol = 1;
1642 b->yy_fill_buffer = 0;
1643 b->yy_buffer_status = YY_BUFFER_NEW;
1644
1645 yy_switch_to_buffer(b );
1646
1647 return b;
1648}
1649
1650/** Setup the input buffer state to scan a string. The next call to yylex() will
1651 * scan from a @e copy of @a str.
1652 * @param yystr a NUL-terminated string to scan
1653 *
1654 * @return the newly allocated buffer state object.
1655 * @note If you want to scan bytes that may contain NUL values, then use
1656 * yy_scan_bytes() instead.
1657 */
1658YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1659{
1660
1661 return yy_scan_bytes(yystr,strlen(yystr) );
1662}
1663
1664/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1665 * scan from a @e copy of @a bytes.
1666 * @param bytes the byte buffer to scan
1667 * @param len the number of bytes in the buffer pointed to by @a bytes.
1668 *
1669 * @return the newly allocated buffer state object.
1670 */
1671YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
1672{
1673 YY_BUFFER_STATE b;
1674 char *buf;
1675 yy_size_t n;
1676 int i;
1677
1678 /* Get memory for full buffer, including space for trailing EOB's. */
1679 n = _yybytes_len + 2;
1680 buf = (char *) yyalloc(n );
1681 if ( ! buf )
1682 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
1683
1684 for ( i = 0; i < _yybytes_len; ++i )
1685 buf[i] = yybytes[i];
1686
1687 buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
1688
1689 b = yy_scan_buffer(buf,n );
1690 if ( ! b )
1691 YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
1692
1693 /* It's okay to grow etc. this buffer, and we should throw it
1694 * away when we're done.
1695 */
1696 b->yy_is_our_buffer = 1;
1697
1698 return b;
1699}
1700
1701#ifndef YY_EXIT_FAILURE
1702#define YY_EXIT_FAILURE 2
1703#endif
1704
1705static void yy_fatal_error (yyconst char* msg )
1706{
1707 (void) fprintf( stderr, "%s\n", msg );
1708 exit( YY_EXIT_FAILURE );
1709}
1710
1711/* Redefine yyless() so it works in section 3 code. */
1712
1713#undef yyless
1714#define yyless(n) \
1715 do \
1716 { \
1717 /* Undo effects of setting up yytext. */ \
1718 int yyless_macro_arg = (n); \
1719 YY_LESS_LINENO(yyless_macro_arg);\
1720 yytext[yyleng] = (yy_hold_char); \
1721 (yy_c_buf_p) = yytext + yyless_macro_arg; \
1722 (yy_hold_char) = *(yy_c_buf_p); \
1723 *(yy_c_buf_p) = '\0'; \
1724 yyleng = yyless_macro_arg; \
1725 } \
1726 while ( 0 )
1727
1728/* Accessor methods (get/set functions) to struct members. */
1729
1730/** Get the current line number.
1731 *
1732 */
1733int yyget_lineno (void)
1734{
1735
1736 return yylineno;
1737}
1738
1739/** Get the input stream.
1740 *
1741 */
1742FILE *yyget_in (void)
1743{
1744 return yyin;
1745}
1746
1747/** Get the output stream.
1748 *
1749 */
1750FILE *yyget_out (void)
1751{
1752 return yyout;
1753}
1754
1755/** Get the length of the current token.
1756 *
1757 */
1758int yyget_leng (void)
1759{
1760 return yyleng;
1761}
1762
1763/** Get the current token.
1764 *
1765 */
1766
1767char *yyget_text (void)
1768{
1769 return yytext;
1770}
1771
1772/** Set the current line number.
1773 * @param line_number
1774 *
1775 */
1776void yyset_lineno (int line_number )
1777{
1778
1779 yylineno = line_number;
1780}
1781
1782/** Set the input stream. This does not discard the current
1783 * input buffer.
1784 * @param in_str A readable stream.
1785 *
1786 * @see yy_switch_to_buffer
1787 */
1788void yyset_in (FILE * in_str )
1789{
1790 yyin = in_str ;
1791}
1792
1793void yyset_out (FILE * out_str )
1794{
1795 yyout = out_str ;
1796}
1797
1798int yyget_debug (void)
1799{
1800 return yy_flex_debug;
1801}
1802
1803void yyset_debug (int bdebug )
1804{
1805 yy_flex_debug = bdebug ;
1806}
1807
1808static int yy_init_globals (void)
1809{
1810 /* Initialization is the same as for the non-reentrant scanner.
1811 * This function is called from yylex_destroy(), so don't allocate here.
1812 */
1813
1814 (yy_buffer_stack) = 0;
1815 (yy_buffer_stack_top) = 0;
1816 (yy_buffer_stack_max) = 0;
1817 (yy_c_buf_p) = (char *) 0;
1818 (yy_init) = 0;
1819 (yy_start) = 0;
1820
1821/* Defined in main.c */
1822#ifdef YY_STDINIT
1823 yyin = stdin;
1824 yyout = stdout;
1825#else
1826 yyin = (FILE *) 0;
1827 yyout = (FILE *) 0;
1828#endif
1829
1830 /* For future reference: Set errno on error, since we are called by
1831 * yylex_init()
1832 */
1833 return 0;
1834}
1835
1836/* yylex_destroy is for both reentrant and non-reentrant scanners. */
1837int yylex_destroy (void)
1838{
1839
1840 /* Pop the buffer stack, destroying each element. */
1841 while(YY_CURRENT_BUFFER){
1842 yy_delete_buffer(YY_CURRENT_BUFFER );
1843 YY_CURRENT_BUFFER_LVALUE = NULL;
1844 yypop_buffer_state();
1845 }
1846
1847 /* Destroy the stack itself. */
1848 yyfree((yy_buffer_stack) );
1849 (yy_buffer_stack) = NULL;
1850
1851 /* Reset the globals. This is important in a non-reentrant scanner so the next time
1852 * yylex() is called, initialization will occur. */
1853 yy_init_globals( );
1854
1855 return 0;
1856}
1857
1858/*
1859 * Internal utility routines.
1860 */
1861
1862#ifndef yytext_ptr
1863static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
1864{
1865 register int i;
1866 for ( i = 0; i < n; ++i )
1867 s1[i] = s2[i];
1868}
1869#endif
1870
1871#ifdef YY_NEED_STRLEN
1872static int yy_flex_strlen (yyconst char * s )
1873{
1874 register int n;
1875 for ( n = 0; s[n]; ++n )
1876 ;
1877
1878 return n;
1879}
1880#endif
1881
1882void *yyalloc (yy_size_t size )
1883{
1884 return (void *) malloc( size );
1885}
1886
1887void *yyrealloc (void * ptr, yy_size_t size )
1888{
1889 /* The cast to (char *) in the following accommodates both
1890 * implementations that use char* generic pointers, and those
1891 * that use void* generic pointers. It works with the latter
1892 * because both ANSI C and C++ allow castless assignment from
1893 * any pointer type to void*, and deal with argument conversions
1894 * as though doing an assignment.
1895 */
1896 return (void *) realloc( (char *) ptr, size );
1897}
1898
1899void yyfree (void * ptr )
1900{
1901 free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
1902}
1903
1904#define YYTABLES_NAME "yytables"
1905
1906/* Bring in the keyword recognizer. */
1907
1908#include "keywords.c"
1909
1910/* Macros to append to our phrase collection list. */
1911
1912/*
1913 * We mark any token, that that equals to a known enumerator, as
1914 * SYM_ENUM_CONST. The parser will change this for struct and union tags later,
1915 * the only problem is struct and union members:
1916 * enum e { a, b }; struct s { int a, b; }
1917 * but in this case, the only effect will be, that the ABI checksums become
1918 * more volatile, which is acceptable. Also, such collisions are quite rare,
1919 * so far it was only observed in include/linux/telephony.h.
1920 */
1921#define _APP(T,L) do { \
1922 cur_node = next_node; \
1923 next_node = xmalloc(sizeof(*next_node)); \
1924 next_node->next = cur_node; \
1925 cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
1926 cur_node->tag = \
1927 find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
1928 SYM_ENUM_CONST : SYM_NORMAL ; \
1929 cur_node->in_source_file = in_source_file; \
1930 } while (0)
1931
1932#define APP _APP(yytext, yyleng)
1933
1934/* The second stage lexer. Here we incorporate knowledge of the state
1935 of the parser to tailor the tokens that are returned. */
1936
1937int
1938yylex(void)
1939{
1940 static enum {
1941 ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_TYPEOF, ST_TYPEOF_1,
1942 ST_BRACKET, ST_BRACE, ST_EXPRESSION,
1943 ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
1944 ST_TABLE_5, ST_TABLE_6
1945 } lexstate = ST_NOTSTARTED;
1946
1947 static int suppress_type_lookup, dont_want_brace_phrase;
1948 static struct string_list *next_node;
1949
1950 int token, count = 0;
1951 struct string_list *cur_node;
1952
1953 if (lexstate == ST_NOTSTARTED)
1954 {
1955 next_node = xmalloc(sizeof(*next_node));
1956 next_node->next = NULL;
1957 lexstate = ST_NORMAL;
1958 }
1959
1960repeat:
1961 token = yylex1();
1962
1963 if (token == 0)
1964 return 0;
1965 else if (token == FILENAME)
1966 {
1967 char *file, *e;
1968
1969 /* Save the filename and line number for later error messages. */
1970
1971 if (cur_filename)
1972 free(cur_filename);
1973
1974 file = strchr(yytext, '\"')+1;
1975 e = strchr(file, '\"');
1976 *e = '\0';
1977 cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
1978 cur_line = atoi(yytext+2);
1979
1980 if (!source_file) {
1981 source_file = xstrdup(cur_filename);
1982 in_source_file = 1;
1983 } else {
1984 in_source_file = (strcmp(cur_filename, source_file) == 0);
1985 }
1986
1987 goto repeat;
1988 }
1989
1990 switch (lexstate)
1991 {
1992 case ST_NORMAL:
1993 switch (token)
1994 {
1995 case IDENT:
1996 APP;
1997 {
1998 int r = is_reserved_word(yytext, yyleng);
1999 if (r >= 0)
2000 {
2001 switch (token = r)
2002 {
2003 case ATTRIBUTE_KEYW:
2004 lexstate = ST_ATTRIBUTE;
2005 count = 0;
2006 goto repeat;
2007 case ASM_KEYW:
2008 lexstate = ST_ASM;
2009 count = 0;
2010 goto repeat;
2011 case TYPEOF_KEYW:
2012 lexstate = ST_TYPEOF;
2013 count = 0;
2014 goto repeat;
2015
2016 case STRUCT_KEYW:
2017 case UNION_KEYW:
2018 case ENUM_KEYW:
2019 dont_want_brace_phrase = 3;
2020 suppress_type_lookup = 2;
2021 goto fini;
2022
2023 case EXPORT_SYMBOL_KEYW:
2024 goto fini;
2025 }
2026 }
2027 if (!suppress_type_lookup)
2028 {
2029 if (find_symbol(yytext, SYM_TYPEDEF, 1))
2030 token = TYPE;
2031 }
2032 }
2033 break;
2034
2035 case '[':
2036 APP;
2037 lexstate = ST_BRACKET;
2038 count = 1;
2039 goto repeat;
2040
2041 case '{':
2042 APP;
2043 if (dont_want_brace_phrase)
2044 break;
2045 lexstate = ST_BRACE;
2046 count = 1;
2047 goto repeat;
2048
2049 case '=': case ':':
2050 APP;
2051 lexstate = ST_EXPRESSION;
2052 break;
2053
2054 case DOTS:
2055 default:
2056 APP;
2057 break;
2058 }
2059 break;
2060
2061 case ST_ATTRIBUTE:
2062 APP;
2063 switch (token)
2064 {
2065 case '(':
2066 ++count;
2067 goto repeat;
2068 case ')':
2069 if (--count == 0)
2070 {
2071 lexstate = ST_NORMAL;
2072 token = ATTRIBUTE_PHRASE;
2073 break;
2074 }
2075 goto repeat;
2076 default:
2077 goto repeat;
2078 }
2079 break;
2080
2081 case ST_ASM:
2082 APP;
2083 switch (token)
2084 {
2085 case '(':
2086 ++count;
2087 goto repeat;
2088 case ')':
2089 if (--count == 0)
2090 {
2091 lexstate = ST_NORMAL;
2092 token = ASM_PHRASE;
2093 break;
2094 }
2095 goto repeat;
2096 default:
2097 goto repeat;
2098 }
2099 break;
2100
2101 case ST_TYPEOF_1:
2102 if (token == IDENT)
2103 {
2104 if (is_reserved_word(yytext, yyleng) >= 0
2105 || find_symbol(yytext, SYM_TYPEDEF, 1))
2106 {
2107 yyless(0);
2108 unput('(');
2109 lexstate = ST_NORMAL;
2110 token = TYPEOF_KEYW;
2111 break;
2112 }
2113 _APP("(", 1);
2114 }
2115 lexstate = ST_TYPEOF;
2116 /* FALLTHRU */
2117
2118 case ST_TYPEOF:
2119 switch (token)
2120 {
2121 case '(':
2122 if ( ++count == 1 )
2123 lexstate = ST_TYPEOF_1;
2124 else
2125 APP;
2126 goto repeat;
2127 case ')':
2128 APP;
2129 if (--count == 0)
2130 {
2131 lexstate = ST_NORMAL;
2132 token = TYPEOF_PHRASE;
2133 break;
2134 }
2135 goto repeat;
2136 default:
2137 APP;
2138 goto repeat;
2139 }
2140 break;
2141
2142 case ST_BRACKET:
2143 APP;
2144 switch (token)
2145 {
2146 case '[':
2147 ++count;
2148 goto repeat;
2149 case ']':
2150 if (--count == 0)
2151 {
2152 lexstate = ST_NORMAL;
2153 token = BRACKET_PHRASE;
2154 break;
2155 }
2156 goto repeat;
2157 default:
2158 goto repeat;
2159 }
2160 break;
2161
2162 case ST_BRACE:
2163 APP;
2164 switch (token)
2165 {
2166 case '{':
2167 ++count;
2168 goto repeat;
2169 case '}':
2170 if (--count == 0)
2171 {
2172 lexstate = ST_NORMAL;
2173 token = BRACE_PHRASE;
2174 break;
2175 }
2176 goto repeat;
2177 default:
2178 goto repeat;
2179 }
2180 break;
2181
2182 case ST_EXPRESSION:
2183 switch (token)
2184 {
2185 case '(': case '[': case '{':
2186 ++count;
2187 APP;
2188 goto repeat;
2189 case '}':
2190 /* is this the last line of an enum declaration? */
2191 if (count == 0)
2192 {
2193 /* Put back the token we just read so's we can find it again
2194 after registering the expression. */
2195 unput(token);
2196
2197 lexstate = ST_NORMAL;
2198 token = EXPRESSION_PHRASE;
2199 break;
2200 }
2201 /* FALLTHRU */
2202 case ')': case ']':
2203 --count;
2204 APP;
2205 goto repeat;
2206 case ',': case ';':
2207 if (count == 0)
2208 {
2209 /* Put back the token we just read so's we can find it again
2210 after registering the expression. */
2211 unput(token);
2212
2213 lexstate = ST_NORMAL;
2214 token = EXPRESSION_PHRASE;
2215 break;
2216 }
2217 APP;
2218 goto repeat;
2219 default:
2220 APP;
2221 goto repeat;
2222 }
2223 break;
2224
2225 case ST_TABLE_1:
2226 goto repeat;
2227
2228 case ST_TABLE_2:
2229 if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
2230 {
2231 token = EXPORT_SYMBOL_KEYW;
2232 lexstate = ST_TABLE_5;
2233 APP;
2234 break;
2235 }
2236 lexstate = ST_TABLE_6;
2237 /* FALLTHRU */
2238
2239 case ST_TABLE_6:
2240 switch (token)
2241 {
2242 case '{': case '[': case '(':
2243 ++count;
2244 break;
2245 case '}': case ']': case ')':
2246 --count;
2247 break;
2248 case ',':
2249 if (count == 0)
2250 lexstate = ST_TABLE_2;
2251 break;
2252 };
2253 goto repeat;
2254
2255 case ST_TABLE_3:
2256 goto repeat;
2257
2258 case ST_TABLE_4:
2259 if (token == ';')
2260 lexstate = ST_NORMAL;
2261 goto repeat;
2262
2263 case ST_TABLE_5:
2264 switch (token)
2265 {
2266 case ',':
2267 token = ';';
2268 lexstate = ST_TABLE_2;
2269 APP;
2270 break;
2271 default:
2272 APP;
2273 break;
2274 }
2275 break;
2276
2277 default:
2278 exit(1);
2279 }
2280fini:
2281
2282 if (suppress_type_lookup > 0)
2283 --suppress_type_lookup;
2284 if (dont_want_brace_phrase > 0)
2285 --dont_want_brace_phrase;
2286
2287 yylval = &next_node->next;
2288
2289 return token;
2290}
2291
diff --git a/scripts/genksyms/parse.tab.c_shipped b/scripts/genksyms/parse.tab.c_shipped
deleted file mode 100644
index d02258bafe7b..000000000000
--- a/scripts/genksyms/parse.tab.c_shipped
+++ /dev/null
@@ -1,2394 +0,0 @@
1/* A Bison parser, made by GNU Bison 2.7. */
2
3/* Bison implementation for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33/* C LALR(1) parser skeleton written by Richard Stallman, by
34 simplifying the original so-called "semantic" parser. */
35
36/* All symbols defined below should begin with yy or YY, to avoid
37 infringing on user name space. This should be done even for local
38 variables, as they might otherwise be expanded by user macros.
39 There are some unavoidable exceptions within include files to
40 define necessary library symbols; they are noted "INFRINGES ON
41 USER NAME SPACE" below. */
42
43/* Identify Bison output. */
44#define YYBISON 1
45
46/* Bison version. */
47#define YYBISON_VERSION "2.7"
48
49/* Skeleton name. */
50#define YYSKELETON_NAME "yacc.c"
51
52/* Pure parsers. */
53#define YYPURE 0
54
55/* Push parsers. */
56#define YYPUSH 0
57
58/* Pull parsers. */
59#define YYPULL 1
60
61
62
63
64/* Copy the first part of user declarations. */
65
66
67
68#include <assert.h>
69#include <stdlib.h>
70#include <string.h>
71#include "genksyms.h"
72
73static int is_typedef;
74static int is_extern;
75static char *current_name;
76static struct string_list *decl_spec;
77
78static void yyerror(const char *);
79
80static inline void
81remove_node(struct string_list **p)
82{
83 struct string_list *node = *p;
84 *p = node->next;
85 free_node(node);
86}
87
88static inline void
89remove_list(struct string_list **pb, struct string_list **pe)
90{
91 struct string_list *b = *pb, *e = *pe;
92 *pb = e;
93 free_list(b, e);
94}
95
96/* Record definition of a struct/union/enum */
97static void record_compound(struct string_list **keyw,
98 struct string_list **ident,
99 struct string_list **body,
100 enum symbol_type type)
101{
102 struct string_list *b = *body, *i = *ident, *r;
103
104 if (i->in_source_file) {
105 remove_node(keyw);
106 (*ident)->tag = type;
107 remove_list(body, ident);
108 return;
109 }
110 r = copy_node(i); r->tag = type;
111 r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
112 add_symbol(i->string, type, b, is_extern);
113}
114
115
116
117
118# ifndef YY_NULL
119# if defined __cplusplus && 201103L <= __cplusplus
120# define YY_NULL nullptr
121# else
122# define YY_NULL 0
123# endif
124# endif
125
126/* Enabling verbose error messages. */
127#ifdef YYERROR_VERBOSE
128# undef YYERROR_VERBOSE
129# define YYERROR_VERBOSE 1
130#else
131# define YYERROR_VERBOSE 0
132#endif
133
134
135/* Enabling traces. */
136#ifndef YYDEBUG
137# define YYDEBUG 1
138#endif
139#if YYDEBUG
140extern int yydebug;
141#endif
142
143/* Tokens. */
144#ifndef YYTOKENTYPE
145# define YYTOKENTYPE
146 /* Put the tokens into the symbol table, so that GDB and other debuggers
147 know about them. */
148 enum yytokentype {
149 ASM_KEYW = 258,
150 ATTRIBUTE_KEYW = 259,
151 AUTO_KEYW = 260,
152 BOOL_KEYW = 261,
153 CHAR_KEYW = 262,
154 CONST_KEYW = 263,
155 DOUBLE_KEYW = 264,
156 ENUM_KEYW = 265,
157 EXTERN_KEYW = 266,
158 EXTENSION_KEYW = 267,
159 FLOAT_KEYW = 268,
160 INLINE_KEYW = 269,
161 INT_KEYW = 270,
162 LONG_KEYW = 271,
163 REGISTER_KEYW = 272,
164 RESTRICT_KEYW = 273,
165 SHORT_KEYW = 274,
166 SIGNED_KEYW = 275,
167 STATIC_KEYW = 276,
168 STRUCT_KEYW = 277,
169 TYPEDEF_KEYW = 278,
170 UNION_KEYW = 279,
171 UNSIGNED_KEYW = 280,
172 VOID_KEYW = 281,
173 VOLATILE_KEYW = 282,
174 TYPEOF_KEYW = 283,
175 VA_LIST_KEYW = 284,
176 EXPORT_SYMBOL_KEYW = 285,
177 ASM_PHRASE = 286,
178 ATTRIBUTE_PHRASE = 287,
179 TYPEOF_PHRASE = 288,
180 BRACE_PHRASE = 289,
181 BRACKET_PHRASE = 290,
182 EXPRESSION_PHRASE = 291,
183 CHAR = 292,
184 DOTS = 293,
185 IDENT = 294,
186 INT = 295,
187 REAL = 296,
188 STRING = 297,
189 TYPE = 298,
190 OTHER = 299,
191 FILENAME = 300
192 };
193#endif
194
195
196#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
197typedef int YYSTYPE;
198# define YYSTYPE_IS_TRIVIAL 1
199# define yystype YYSTYPE /* obsolescent; will be withdrawn */
200# define YYSTYPE_IS_DECLARED 1
201#endif
202
203extern YYSTYPE yylval;
204
205#ifdef YYPARSE_PARAM
206#if defined __STDC__ || defined __cplusplus
207int yyparse (void *YYPARSE_PARAM);
208#else
209int yyparse ();
210#endif
211#else /* ! YYPARSE_PARAM */
212#if defined __STDC__ || defined __cplusplus
213int yyparse (void);
214#else
215int yyparse ();
216#endif
217#endif /* ! YYPARSE_PARAM */
218
219
220
221/* Copy the second part of user declarations. */
222
223
224
225#ifdef short
226# undef short
227#endif
228
229#ifdef YYTYPE_UINT8
230typedef YYTYPE_UINT8 yytype_uint8;
231#else
232typedef unsigned char yytype_uint8;
233#endif
234
235#ifdef YYTYPE_INT8
236typedef YYTYPE_INT8 yytype_int8;
237#elif (defined __STDC__ || defined __C99__FUNC__ \
238 || defined __cplusplus || defined _MSC_VER)
239typedef signed char yytype_int8;
240#else
241typedef short int yytype_int8;
242#endif
243
244#ifdef YYTYPE_UINT16
245typedef YYTYPE_UINT16 yytype_uint16;
246#else
247typedef unsigned short int yytype_uint16;
248#endif
249
250#ifdef YYTYPE_INT16
251typedef YYTYPE_INT16 yytype_int16;
252#else
253typedef short int yytype_int16;
254#endif
255
256#ifndef YYSIZE_T
257# ifdef __SIZE_TYPE__
258# define YYSIZE_T __SIZE_TYPE__
259# elif defined size_t
260# define YYSIZE_T size_t
261# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
262 || defined __cplusplus || defined _MSC_VER)
263# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
264# define YYSIZE_T size_t
265# else
266# define YYSIZE_T unsigned int
267# endif
268#endif
269
270#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
271
272#ifndef YY_
273# if defined YYENABLE_NLS && YYENABLE_NLS
274# if ENABLE_NLS
275# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
276# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
277# endif
278# endif
279# ifndef YY_
280# define YY_(Msgid) Msgid
281# endif
282#endif
283
284/* Suppress unused-variable warnings by "using" E. */
285#if ! defined lint || defined __GNUC__
286# define YYUSE(E) ((void) (E))
287#else
288# define YYUSE(E) /* empty */
289#endif
290
291/* Identity function, used to suppress warnings about constant conditions. */
292#ifndef lint
293# define YYID(N) (N)
294#else
295#if (defined __STDC__ || defined __C99__FUNC__ \
296 || defined __cplusplus || defined _MSC_VER)
297static int
298YYID (int yyi)
299#else
300static int
301YYID (yyi)
302 int yyi;
303#endif
304{
305 return yyi;
306}
307#endif
308
309#if ! defined yyoverflow || YYERROR_VERBOSE
310
311/* The parser invokes alloca or malloc; define the necessary symbols. */
312
313# ifdef YYSTACK_USE_ALLOCA
314# if YYSTACK_USE_ALLOCA
315# ifdef __GNUC__
316# define YYSTACK_ALLOC __builtin_alloca
317# elif defined __BUILTIN_VA_ARG_INCR
318# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
319# elif defined _AIX
320# define YYSTACK_ALLOC __alloca
321# elif defined _MSC_VER
322# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
323# define alloca _alloca
324# else
325# define YYSTACK_ALLOC alloca
326# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
327 || defined __cplusplus || defined _MSC_VER)
328# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
329 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
330# ifndef EXIT_SUCCESS
331# define EXIT_SUCCESS 0
332# endif
333# endif
334# endif
335# endif
336# endif
337
338# ifdef YYSTACK_ALLOC
339 /* Pacify GCC's `empty if-body' warning. */
340# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
341# ifndef YYSTACK_ALLOC_MAXIMUM
342 /* The OS might guarantee only one guard page at the bottom of the stack,
343 and a page size can be as small as 4096 bytes. So we cannot safely
344 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
345 to allow for a few compiler-allocated temporary stack slots. */
346# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
347# endif
348# else
349# define YYSTACK_ALLOC YYMALLOC
350# define YYSTACK_FREE YYFREE
351# ifndef YYSTACK_ALLOC_MAXIMUM
352# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
353# endif
354# if (defined __cplusplus && ! defined EXIT_SUCCESS \
355 && ! ((defined YYMALLOC || defined malloc) \
356 && (defined YYFREE || defined free)))
357# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
358# ifndef EXIT_SUCCESS
359# define EXIT_SUCCESS 0
360# endif
361# endif
362# ifndef YYMALLOC
363# define YYMALLOC malloc
364# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
365 || defined __cplusplus || defined _MSC_VER)
366void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
367# endif
368# endif
369# ifndef YYFREE
370# define YYFREE free
371# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
372 || defined __cplusplus || defined _MSC_VER)
373void free (void *); /* INFRINGES ON USER NAME SPACE */
374# endif
375# endif
376# endif
377#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
378
379
380#if (! defined yyoverflow \
381 && (! defined __cplusplus \
382 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
383
384/* A type that is properly aligned for any stack member. */
385union yyalloc
386{
387 yytype_int16 yyss_alloc;
388 YYSTYPE yyvs_alloc;
389};
390
391/* The size of the maximum gap between one aligned stack and the next. */
392# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
393
394/* The size of an array large to enough to hold all stacks, each with
395 N elements. */
396# define YYSTACK_BYTES(N) \
397 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
398 + YYSTACK_GAP_MAXIMUM)
399
400# define YYCOPY_NEEDED 1
401
402/* Relocate STACK from its old location to the new one. The
403 local variables YYSIZE and YYSTACKSIZE give the old and new number of
404 elements in the stack, and YYPTR gives the new location of the
405 stack. Advance YYPTR to a properly aligned location for the next
406 stack. */
407# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
408 do \
409 { \
410 YYSIZE_T yynewbytes; \
411 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
412 Stack = &yyptr->Stack_alloc; \
413 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
414 yyptr += yynewbytes / sizeof (*yyptr); \
415 } \
416 while (YYID (0))
417
418#endif
419
420#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
421/* Copy COUNT objects from SRC to DST. The source and destination do
422 not overlap. */
423# ifndef YYCOPY
424# if defined __GNUC__ && 1 < __GNUC__
425# define YYCOPY(Dst, Src, Count) \
426 __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
427# else
428# define YYCOPY(Dst, Src, Count) \
429 do \
430 { \
431 YYSIZE_T yyi; \
432 for (yyi = 0; yyi < (Count); yyi++) \
433 (Dst)[yyi] = (Src)[yyi]; \
434 } \
435 while (YYID (0))
436# endif
437# endif
438#endif /* !YYCOPY_NEEDED */
439
440/* YYFINAL -- State number of the termination state. */
441#define YYFINAL 4
442/* YYLAST -- Last index in YYTABLE. */
443#define YYLAST 522
444
445/* YYNTOKENS -- Number of terminals. */
446#define YYNTOKENS 55
447/* YYNNTS -- Number of nonterminals. */
448#define YYNNTS 49
449/* YYNRULES -- Number of rules. */
450#define YYNRULES 133
451/* YYNRULES -- Number of states. */
452#define YYNSTATES 187
453
454/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
455#define YYUNDEFTOK 2
456#define YYMAXUTOK 300
457
458#define YYTRANSLATE(YYX) \
459 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
460
461/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
462static const yytype_uint8 yytranslate[] =
463{
464 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
465 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
466 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
467 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
468 49, 50, 51, 2, 48, 2, 2, 2, 2, 2,
469 2, 2, 2, 2, 2, 2, 2, 2, 54, 46,
470 2, 52, 2, 2, 2, 2, 2, 2, 2, 2,
471 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
472 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
473 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
474 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
475 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
476 2, 2, 2, 53, 2, 47, 2, 2, 2, 2,
477 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
478 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
479 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
480 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
481 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
482 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
483 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
484 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
485 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
486 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
487 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
488 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
489 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
490 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
491 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
492 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
493 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
494 45
495};
496
497#if YYDEBUG
498/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
499 YYRHS. */
500static const yytype_uint16 yyprhs[] =
501{
502 0, 0, 3, 5, 8, 9, 12, 13, 18, 19,
503 23, 25, 27, 29, 31, 34, 37, 41, 42, 44,
504 46, 50, 55, 56, 58, 60, 63, 65, 67, 69,
505 71, 73, 75, 77, 79, 81, 86, 88, 91, 94,
506 97, 101, 105, 109, 112, 115, 118, 120, 122, 124,
507 126, 128, 130, 132, 134, 136, 138, 140, 142, 145,
508 146, 148, 150, 153, 155, 157, 159, 161, 164, 166,
509 168, 170, 175, 180, 183, 187, 190, 192, 194, 196,
510 201, 206, 209, 213, 217, 220, 222, 226, 227, 229,
511 231, 235, 238, 241, 243, 244, 246, 248, 253, 258,
512 261, 265, 269, 273, 274, 276, 279, 283, 287, 288,
513 290, 292, 295, 299, 302, 303, 305, 307, 311, 314,
514 317, 319, 322, 323, 326, 330, 335, 337, 341, 343,
515 347, 350, 351, 353
516};
517
518/* YYRHS -- A `-1'-separated list of the rules' RHS. */
519static const yytype_int8 yyrhs[] =
520{
521 56, 0, -1, 57, -1, 56, 57, -1, -1, 58,
522 59, -1, -1, 12, 23, 60, 62, -1, -1, 23,
523 61, 62, -1, 62, -1, 86, -1, 101, -1, 103,
524 -1, 1, 46, -1, 1, 47, -1, 66, 63, 46,
525 -1, -1, 64, -1, 65, -1, 64, 48, 65, -1,
526 76, 102, 97, 87, -1, -1, 67, -1, 68, -1,
527 67, 68, -1, 69, -1, 70, -1, 5, -1, 17,
528 -1, 21, -1, 11, -1, 14, -1, 71, -1, 75,
529 -1, 28, 49, 83, 50, -1, 33, -1, 22, 39,
530 -1, 24, 39, -1, 10, 39, -1, 22, 39, 89,
531 -1, 24, 39, 89, -1, 10, 39, 98, -1, 10,
532 98, -1, 22, 89, -1, 24, 89, -1, 7, -1,
533 19, -1, 15, -1, 16, -1, 20, -1, 25, -1,
534 13, -1, 9, -1, 26, -1, 6, -1, 29, -1,
535 43, -1, 51, 73, -1, -1, 74, -1, 75, -1,
536 74, 75, -1, 8, -1, 27, -1, 32, -1, 18,
537 -1, 72, 76, -1, 77, -1, 39, -1, 43, -1,
538 77, 49, 80, 50, -1, 77, 49, 1, 50, -1,
539 77, 35, -1, 49, 76, 50, -1, 72, 78, -1,
540 79, -1, 39, -1, 43, -1, 79, 49, 80, 50,
541 -1, 79, 49, 1, 50, -1, 79, 35, -1, 49,
542 78, 50, -1, 49, 1, 50, -1, 81, 38, -1,
543 81, -1, 82, 48, 38, -1, -1, 82, -1, 83,
544 -1, 82, 48, 83, -1, 67, 84, -1, 72, 84,
545 -1, 85, -1, -1, 39, -1, 43, -1, 85, 49,
546 80, 50, -1, 85, 49, 1, 50, -1, 85, 35,
547 -1, 49, 84, 50, -1, 49, 1, 50, -1, 66,
548 76, 34, -1, -1, 88, -1, 52, 36, -1, 53,
549 90, 47, -1, 53, 1, 47, -1, -1, 91, -1,
550 92, -1, 91, 92, -1, 66, 93, 46, -1, 1,
551 46, -1, -1, 94, -1, 95, -1, 94, 48, 95,
552 -1, 78, 97, -1, 39, 96, -1, 96, -1, 54,
553 36, -1, -1, 97, 32, -1, 53, 99, 47, -1,
554 53, 99, 48, 47, -1, 100, -1, 99, 48, 100,
555 -1, 39, -1, 39, 52, 36, -1, 31, 46, -1,
556 -1, 31, -1, 30, 49, 39, 50, 46, -1
557};
558
559/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
560static const yytype_uint16 yyrline[] =
561{
562 0, 125, 125, 126, 130, 130, 136, 136, 138, 138,
563 140, 141, 142, 143, 144, 145, 149, 163, 164, 168,
564 176, 189, 195, 196, 200, 201, 205, 211, 215, 216,
565 217, 218, 219, 223, 224, 225, 226, 230, 232, 234,
566 238, 240, 242, 247, 250, 251, 255, 256, 257, 258,
567 259, 260, 261, 262, 263, 264, 265, 266, 270, 275,
568 276, 280, 281, 285, 285, 285, 286, 294, 295, 299,
569 308, 317, 319, 321, 323, 330, 331, 335, 336, 337,
570 339, 341, 343, 345, 350, 351, 352, 356, 357, 361,
571 362, 367, 372, 374, 378, 379, 387, 391, 393, 395,
572 397, 399, 404, 413, 414, 419, 424, 425, 429, 430,
573 434, 435, 439, 441, 446, 447, 451, 452, 456, 457,
574 458, 462, 466, 467, 471, 472, 476, 477, 480, 485,
575 493, 497, 498, 502
576};
577#endif
578
579#if YYDEBUG || YYERROR_VERBOSE || 0
580/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
581 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
582static const char *const yytname[] =
583{
584 "$end", "error", "$undefined", "ASM_KEYW", "ATTRIBUTE_KEYW",
585 "AUTO_KEYW", "BOOL_KEYW", "CHAR_KEYW", "CONST_KEYW", "DOUBLE_KEYW",
586 "ENUM_KEYW", "EXTERN_KEYW", "EXTENSION_KEYW", "FLOAT_KEYW",
587 "INLINE_KEYW", "INT_KEYW", "LONG_KEYW", "REGISTER_KEYW", "RESTRICT_KEYW",
588 "SHORT_KEYW", "SIGNED_KEYW", "STATIC_KEYW", "STRUCT_KEYW",
589 "TYPEDEF_KEYW", "UNION_KEYW", "UNSIGNED_KEYW", "VOID_KEYW",
590 "VOLATILE_KEYW", "TYPEOF_KEYW", "VA_LIST_KEYW", "EXPORT_SYMBOL_KEYW",
591 "ASM_PHRASE", "ATTRIBUTE_PHRASE", "TYPEOF_PHRASE", "BRACE_PHRASE",
592 "BRACKET_PHRASE", "EXPRESSION_PHRASE", "CHAR", "DOTS", "IDENT", "INT",
593 "REAL", "STRING", "TYPE", "OTHER", "FILENAME", "';'", "'}'", "','",
594 "'('", "')'", "'*'", "'='", "'{'", "':'", "$accept", "declaration_seq",
595 "declaration", "$@1", "declaration1", "$@2", "$@3", "simple_declaration",
596 "init_declarator_list_opt", "init_declarator_list", "init_declarator",
597 "decl_specifier_seq_opt", "decl_specifier_seq", "decl_specifier",
598 "storage_class_specifier", "type_specifier", "simple_type_specifier",
599 "ptr_operator", "cvar_qualifier_seq_opt", "cvar_qualifier_seq",
600 "cvar_qualifier", "declarator", "direct_declarator", "nested_declarator",
601 "direct_nested_declarator", "parameter_declaration_clause",
602 "parameter_declaration_list_opt", "parameter_declaration_list",
603 "parameter_declaration", "m_abstract_declarator",
604 "direct_m_abstract_declarator", "function_definition", "initializer_opt",
605 "initializer", "class_body", "member_specification_opt",
606 "member_specification", "member_declaration",
607 "member_declarator_list_opt", "member_declarator_list",
608 "member_declarator", "member_bitfield_declarator", "attribute_opt",
609 "enum_body", "enumerator_list", "enumerator", "asm_definition",
610 "asm_phrase_opt", "export_definition", YY_NULL
611};
612#endif
613
614# ifdef YYPRINT
615/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
616 token YYLEX-NUM. */
617static const yytype_uint16 yytoknum[] =
618{
619 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
620 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
621 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
622 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
623 295, 296, 297, 298, 299, 300, 59, 125, 44, 40,
624 41, 42, 61, 123, 58
625};
626# endif
627
628/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
629static const yytype_uint8 yyr1[] =
630{
631 0, 55, 56, 56, 58, 57, 60, 59, 61, 59,
632 59, 59, 59, 59, 59, 59, 62, 63, 63, 64,
633 64, 65, 66, 66, 67, 67, 68, 68, 69, 69,
634 69, 69, 69, 70, 70, 70, 70, 70, 70, 70,
635 70, 70, 70, 70, 70, 70, 71, 71, 71, 71,
636 71, 71, 71, 71, 71, 71, 71, 71, 72, 73,
637 73, 74, 74, 75, 75, 75, 75, 76, 76, 77,
638 77, 77, 77, 77, 77, 78, 78, 79, 79, 79,
639 79, 79, 79, 79, 80, 80, 80, 81, 81, 82,
640 82, 83, 84, 84, 85, 85, 85, 85, 85, 85,
641 85, 85, 86, 87, 87, 88, 89, 89, 90, 90,
642 91, 91, 92, 92, 93, 93, 94, 94, 95, 95,
643 95, 96, 97, 97, 98, 98, 99, 99, 100, 100,
644 101, 102, 102, 103
645};
646
647/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
648static const yytype_uint8 yyr2[] =
649{
650 0, 2, 1, 2, 0, 2, 0, 4, 0, 3,
651 1, 1, 1, 1, 2, 2, 3, 0, 1, 1,
652 3, 4, 0, 1, 1, 2, 1, 1, 1, 1,
653 1, 1, 1, 1, 1, 4, 1, 2, 2, 2,
654 3, 3, 3, 2, 2, 2, 1, 1, 1, 1,
655 1, 1, 1, 1, 1, 1, 1, 1, 2, 0,
656 1, 1, 2, 1, 1, 1, 1, 2, 1, 1,
657 1, 4, 4, 2, 3, 2, 1, 1, 1, 4,
658 4, 2, 3, 3, 2, 1, 3, 0, 1, 1,
659 3, 2, 2, 1, 0, 1, 1, 4, 4, 2,
660 3, 3, 3, 0, 1, 2, 3, 3, 0, 1,
661 1, 2, 3, 2, 0, 1, 1, 3, 2, 2,
662 1, 2, 0, 2, 3, 4, 1, 3, 1, 3,
663 2, 0, 1, 5
664};
665
666/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
667 Performed when YYTABLE doesn't specify something else to do. Zero
668 means the default is an error. */
669static const yytype_uint8 yydefact[] =
670{
671 4, 4, 2, 0, 1, 3, 0, 28, 55, 46,
672 63, 53, 0, 31, 0, 52, 32, 48, 49, 29,
673 66, 47, 50, 30, 0, 8, 0, 51, 54, 64,
674 0, 56, 0, 0, 65, 36, 57, 5, 10, 17,
675 23, 24, 26, 27, 33, 34, 11, 12, 13, 14,
676 15, 39, 0, 43, 6, 37, 0, 44, 22, 38,
677 45, 0, 0, 130, 69, 70, 0, 59, 0, 18,
678 19, 0, 131, 68, 25, 42, 128, 0, 126, 22,
679 40, 0, 114, 0, 0, 110, 9, 17, 41, 94,
680 0, 0, 0, 58, 60, 61, 16, 0, 67, 132,
681 102, 122, 73, 0, 0, 124, 0, 7, 113, 107,
682 77, 78, 0, 0, 0, 122, 76, 0, 115, 116,
683 120, 106, 0, 111, 131, 95, 57, 0, 94, 91,
684 93, 35, 0, 74, 62, 20, 103, 0, 0, 85,
685 88, 89, 129, 125, 127, 119, 0, 77, 0, 121,
686 75, 118, 81, 0, 112, 0, 0, 96, 0, 92,
687 99, 0, 133, 123, 0, 21, 104, 72, 71, 84,
688 0, 83, 82, 0, 0, 117, 101, 100, 0, 0,
689 105, 86, 90, 80, 79, 98, 97
690};
691
692/* YYDEFGOTO[NTERM-NUM]. */
693static const yytype_int16 yydefgoto[] =
694{
695 -1, 1, 2, 3, 37, 79, 58, 38, 68, 69,
696 70, 82, 40, 41, 42, 43, 44, 71, 93, 94,
697 45, 124, 73, 115, 116, 138, 139, 140, 141, 129,
698 130, 46, 165, 166, 57, 83, 84, 85, 117, 118,
699 119, 120, 136, 53, 77, 78, 47, 101, 48
700};
701
702/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
703 STATE-NUM. */
704#define YYPACT_NINF -94
705static const yytype_int16 yypact[] =
706{
707 -94, 15, -94, 208, -94, -94, 34, -94, -94, -94,
708 -94, -94, -27, -94, -5, -94, -94, -94, -94, -94,
709 -94, -94, -94, -94, -25, -94, -16, -94, -94, -94,
710 -4, -94, 19, -24, -94, -94, -94, -94, -94, 24,
711 479, -94, -94, -94, -94, -94, -94, -94, -94, -94,
712 -94, 29, 48, -94, -94, 37, 106, -94, 479, 37,
713 -94, 479, 54, -94, -94, -94, 24, -2, 49, 53,
714 -94, 24, -14, -11, -94, -94, 47, 38, -94, 479,
715 -94, 51, 23, 55, 157, -94, -94, 24, -94, 393,
716 56, 58, 68, -94, -2, -94, -94, 24, -94, -94,
717 -94, -94, -94, 255, 67, -94, 5, -94, -94, -94,
718 50, -94, 7, 69, 40, -94, -8, 83, 88, -94,
719 -94, -94, 91, -94, 109, -94, -94, 4, 45, -94,
720 16, -94, 95, -94, -94, -94, -23, 92, 93, 108,
721 96, -94, -94, -94, -94, -94, 97, -94, 98, -94,
722 -94, 118, -94, 301, -94, 23, 101, -94, 104, -94,
723 -94, 347, -94, -94, 120, -94, -94, -94, -94, -94,
724 440, -94, -94, 111, 119, -94, -94, -94, 130, 137,
725 -94, -94, -94, -94, -94, -94, -94
726};
727
728/* YYPGOTO[NTERM-NUM]. */
729static const yytype_int16 yypgoto[] =
730{
731 -94, -94, 158, -94, -94, -94, -94, -45, -94, -94,
732 94, -1, -61, -29, -94, -94, -94, -79, -94, -94,
733 -63, -7, -94, -93, -94, -92, -94, -94, -60, -57,
734 -94, -94, -94, -94, -19, -94, -94, 110, -94, -94,
735 33, 82, 78, 144, -94, 99, -94, -94, -94
736};
737
738/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
739 positive, shift that token. If negative, reduce the rule which
740 number is the opposite. If YYTABLE_NINF, syntax error. */
741#define YYTABLE_NINF -110
742static const yytype_int16 yytable[] =
743{
744 89, 90, 39, 114, 95, 156, 10, 60, 146, 163,
745 128, 74, 51, 86, 55, 4, 20, 99, 54, 148,
746 100, 150, 63, 59, 102, 29, 52, 152, 56, 164,
747 34, 134, 72, 114, 107, 114, 80, 56, 103, -94,
748 88, 153, 89, 125, 76, 61, 147, 157, 128, 128,
749 111, 160, 143, 127, -94, 67, 112, 87, 67, 92,
750 74, 174, 110, 64, 98, 161, 111, 65, 62, 179,
751 158, 159, 112, 66, 67, 67, 114, 113, 87, 147,
752 49, 50, 52, 111, 125, 105, 106, 76, 157, 112,
753 56, 67, 89, 91, 127, 96, 67, 108, 109, 104,
754 89, 97, 121, 142, 113, 149, 131, 81, 132, 89,
755 182, 7, 8, 9, 10, 11, 12, 13, 133, 15,
756 16, 17, 18, 19, 20, 21, 22, 23, 24, 154,
757 26, 27, 28, 29, 30, 31, 155, 108, 34, 35,
758 99, 162, 167, 168, 170, -22, 169, 171, 172, 36,
759 163, 176, -22, -108, 177, -22, 180, -22, 122, 5,
760 -22, 183, 7, 8, 9, 10, 11, 12, 13, 184,
761 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
762 185, 26, 27, 28, 29, 30, 31, 186, 175, 34,
763 35, 135, 145, 151, 123, 75, -22, 0, 0, 0,
764 36, 0, 0, -22, -109, 144, -22, 0, -22, 6,
765 0, -22, 0, 7, 8, 9, 10, 11, 12, 13,
766 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
767 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
768 34, 35, 0, 0, 0, 0, 0, -22, 0, 0,
769 0, 36, 0, 0, -22, 0, 137, -22, 0, -22,
770 7, 8, 9, 10, 11, 12, 13, 0, 15, 16,
771 17, 18, 19, 20, 21, 22, 23, 24, 0, 26,
772 27, 28, 29, 30, 31, 0, 0, 34, 35, 0,
773 0, 0, 0, -87, 0, 0, 0, 0, 36, 0,
774 0, 0, 173, 0, 0, -87, 7, 8, 9, 10,
775 11, 12, 13, 0, 15, 16, 17, 18, 19, 20,
776 21, 22, 23, 24, 0, 26, 27, 28, 29, 30,
777 31, 0, 0, 34, 35, 0, 0, 0, 0, -87,
778 0, 0, 0, 0, 36, 0, 0, 0, 178, 0,
779 0, -87, 7, 8, 9, 10, 11, 12, 13, 0,
780 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
781 0, 26, 27, 28, 29, 30, 31, 0, 0, 34,
782 35, 0, 0, 0, 0, -87, 0, 0, 0, 0,
783 36, 0, 0, 0, 0, 0, 0, -87, 7, 8,
784 9, 10, 11, 12, 13, 0, 15, 16, 17, 18,
785 19, 20, 21, 22, 23, 24, 0, 26, 27, 28,
786 29, 30, 31, 0, 0, 34, 35, 0, 0, 0,
787 0, 0, 125, 0, 0, 0, 126, 0, 0, 0,
788 0, 0, 127, 0, 67, 7, 8, 9, 10, 11,
789 12, 13, 0, 15, 16, 17, 18, 19, 20, 21,
790 22, 23, 24, 0, 26, 27, 28, 29, 30, 31,
791 0, 0, 34, 35, 0, 0, 0, 0, 181, 0,
792 0, 0, 0, 36, 7, 8, 9, 10, 11, 12,
793 13, 0, 15, 16, 17, 18, 19, 20, 21, 22,
794 23, 24, 0, 26, 27, 28, 29, 30, 31, 0,
795 0, 34, 35, 0, 0, 0, 0, 0, 0, 0,
796 0, 0, 36
797};
798
799#define yypact_value_is_default(Yystate) \
800 (!!((Yystate) == (-94)))
801
802#define yytable_value_is_error(Yytable_value) \
803 YYID (0)
804
805static const yytype_int16 yycheck[] =
806{
807 61, 61, 3, 82, 67, 1, 8, 26, 1, 32,
808 89, 40, 39, 58, 39, 0, 18, 31, 23, 112,
809 34, 114, 46, 39, 35, 27, 53, 35, 53, 52,
810 32, 94, 39, 112, 79, 114, 55, 53, 49, 35,
811 59, 49, 103, 39, 39, 49, 39, 43, 127, 128,
812 43, 35, 47, 49, 50, 51, 49, 58, 51, 66,
813 89, 153, 39, 39, 71, 49, 43, 43, 49, 161,
814 127, 128, 49, 49, 51, 51, 155, 54, 79, 39,
815 46, 47, 53, 43, 39, 47, 48, 39, 43, 49,
816 53, 51, 153, 39, 49, 46, 51, 46, 47, 52,
817 161, 48, 47, 36, 54, 36, 50, 1, 50, 170,
818 170, 5, 6, 7, 8, 9, 10, 11, 50, 13,
819 14, 15, 16, 17, 18, 19, 20, 21, 22, 46,
820 24, 25, 26, 27, 28, 29, 48, 46, 32, 33,
821 31, 46, 50, 50, 48, 39, 38, 50, 50, 43,
822 32, 50, 46, 47, 50, 49, 36, 51, 1, 1,
823 54, 50, 5, 6, 7, 8, 9, 10, 11, 50,
824 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
825 50, 24, 25, 26, 27, 28, 29, 50, 155, 32,
826 33, 97, 110, 115, 84, 51, 39, -1, -1, -1,
827 43, -1, -1, 46, 47, 106, 49, -1, 51, 1,
828 -1, 54, -1, 5, 6, 7, 8, 9, 10, 11,
829 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
830 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
831 32, 33, -1, -1, -1, -1, -1, 39, -1, -1,
832 -1, 43, -1, -1, 46, -1, 1, 49, -1, 51,
833 5, 6, 7, 8, 9, 10, 11, -1, 13, 14,
834 15, 16, 17, 18, 19, 20, 21, 22, -1, 24,
835 25, 26, 27, 28, 29, -1, -1, 32, 33, -1,
836 -1, -1, -1, 38, -1, -1, -1, -1, 43, -1,
837 -1, -1, 1, -1, -1, 50, 5, 6, 7, 8,
838 9, 10, 11, -1, 13, 14, 15, 16, 17, 18,
839 19, 20, 21, 22, -1, 24, 25, 26, 27, 28,
840 29, -1, -1, 32, 33, -1, -1, -1, -1, 38,
841 -1, -1, -1, -1, 43, -1, -1, -1, 1, -1,
842 -1, 50, 5, 6, 7, 8, 9, 10, 11, -1,
843 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
844 -1, 24, 25, 26, 27, 28, 29, -1, -1, 32,
845 33, -1, -1, -1, -1, 38, -1, -1, -1, -1,
846 43, -1, -1, -1, -1, -1, -1, 50, 5, 6,
847 7, 8, 9, 10, 11, -1, 13, 14, 15, 16,
848 17, 18, 19, 20, 21, 22, -1, 24, 25, 26,
849 27, 28, 29, -1, -1, 32, 33, -1, -1, -1,
850 -1, -1, 39, -1, -1, -1, 43, -1, -1, -1,
851 -1, -1, 49, -1, 51, 5, 6, 7, 8, 9,
852 10, 11, -1, 13, 14, 15, 16, 17, 18, 19,
853 20, 21, 22, -1, 24, 25, 26, 27, 28, 29,
854 -1, -1, 32, 33, -1, -1, -1, -1, 38, -1,
855 -1, -1, -1, 43, 5, 6, 7, 8, 9, 10,
856 11, -1, 13, 14, 15, 16, 17, 18, 19, 20,
857 21, 22, -1, 24, 25, 26, 27, 28, 29, -1,
858 -1, 32, 33, -1, -1, -1, -1, -1, -1, -1,
859 -1, -1, 43
860};
861
862/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
863 symbol of state STATE-NUM. */
864static const yytype_uint8 yystos[] =
865{
866 0, 56, 57, 58, 0, 57, 1, 5, 6, 7,
867 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
868 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
869 28, 29, 30, 31, 32, 33, 43, 59, 62, 66,
870 67, 68, 69, 70, 71, 75, 86, 101, 103, 46,
871 47, 39, 53, 98, 23, 39, 53, 89, 61, 39,
872 89, 49, 49, 46, 39, 43, 49, 51, 63, 64,
873 65, 72, 76, 77, 68, 98, 39, 99, 100, 60,
874 89, 1, 66, 90, 91, 92, 62, 66, 89, 67,
875 83, 39, 76, 73, 74, 75, 46, 48, 76, 31,
876 34, 102, 35, 49, 52, 47, 48, 62, 46, 47,
877 39, 43, 49, 54, 72, 78, 79, 93, 94, 95,
878 96, 47, 1, 92, 76, 39, 43, 49, 72, 84,
879 85, 50, 50, 50, 75, 65, 97, 1, 80, 81,
880 82, 83, 36, 47, 100, 96, 1, 39, 78, 36,
881 78, 97, 35, 49, 46, 48, 1, 43, 84, 84,
882 35, 49, 46, 32, 52, 87, 88, 50, 50, 38,
883 48, 50, 50, 1, 80, 95, 50, 50, 1, 80,
884 36, 38, 83, 50, 50, 50, 50
885};
886
887#define yyerrok (yyerrstatus = 0)
888#define yyclearin (yychar = YYEMPTY)
889#define YYEMPTY (-2)
890#define YYEOF 0
891
892#define YYACCEPT goto yyacceptlab
893#define YYABORT goto yyabortlab
894#define YYERROR goto yyerrorlab
895
896
897/* Like YYERROR except do call yyerror. This remains here temporarily
898 to ease the transition to the new meaning of YYERROR, for GCC.
899 Once GCC version 2 has supplanted version 1, this can go. However,
900 YYFAIL appears to be in use. Nevertheless, it is formally deprecated
901 in Bison 2.4.2's NEWS entry, where a plan to phase it out is
902 discussed. */
903
904#define YYFAIL goto yyerrlab
905#if defined YYFAIL
906 /* This is here to suppress warnings from the GCC cpp's
907 -Wunused-macros. Normally we don't worry about that warning, but
908 some users do, and we want to make it easy for users to remove
909 YYFAIL uses, which will produce warnings from Bison 2.5. */
910#endif
911
912#define YYRECOVERING() (!!yyerrstatus)
913
914#define YYBACKUP(Token, Value) \
915do \
916 if (yychar == YYEMPTY) \
917 { \
918 yychar = (Token); \
919 yylval = (Value); \
920 YYPOPSTACK (yylen); \
921 yystate = *yyssp; \
922 goto yybackup; \
923 } \
924 else \
925 { \
926 yyerror (YY_("syntax error: cannot back up")); \
927 YYERROR; \
928 } \
929while (YYID (0))
930
931/* Error token number */
932#define YYTERROR 1
933#define YYERRCODE 256
934
935
936/* This macro is provided for backward compatibility. */
937#ifndef YY_LOCATION_PRINT
938# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
939#endif
940
941
942/* YYLEX -- calling `yylex' with the right arguments. */
943#ifdef YYLEX_PARAM
944# define YYLEX yylex (YYLEX_PARAM)
945#else
946# define YYLEX yylex ()
947#endif
948
949/* Enable debugging if requested. */
950#if YYDEBUG
951
952# ifndef YYFPRINTF
953# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
954# define YYFPRINTF fprintf
955# endif
956
957# define YYDPRINTF(Args) \
958do { \
959 if (yydebug) \
960 YYFPRINTF Args; \
961} while (YYID (0))
962
963# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
964do { \
965 if (yydebug) \
966 { \
967 YYFPRINTF (stderr, "%s ", Title); \
968 yy_symbol_print (stderr, \
969 Type, Value); \
970 YYFPRINTF (stderr, "\n"); \
971 } \
972} while (YYID (0))
973
974
975/*--------------------------------.
976| Print this symbol on YYOUTPUT. |
977`--------------------------------*/
978
979/*ARGSUSED*/
980#if (defined __STDC__ || defined __C99__FUNC__ \
981 || defined __cplusplus || defined _MSC_VER)
982static void
983yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
984#else
985static void
986yy_symbol_value_print (yyoutput, yytype, yyvaluep)
987 FILE *yyoutput;
988 int yytype;
989 YYSTYPE const * const yyvaluep;
990#endif
991{
992 FILE *yyo = yyoutput;
993 YYUSE (yyo);
994 if (!yyvaluep)
995 return;
996# ifdef YYPRINT
997 if (yytype < YYNTOKENS)
998 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
999# else
1000 YYUSE (yyoutput);
1001# endif
1002 switch (yytype)
1003 {
1004 default:
1005 break;
1006 }
1007}
1008
1009
1010/*--------------------------------.
1011| Print this symbol on YYOUTPUT. |
1012`--------------------------------*/
1013
1014#if (defined __STDC__ || defined __C99__FUNC__ \
1015 || defined __cplusplus || defined _MSC_VER)
1016static void
1017yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1018#else
1019static void
1020yy_symbol_print (yyoutput, yytype, yyvaluep)
1021 FILE *yyoutput;
1022 int yytype;
1023 YYSTYPE const * const yyvaluep;
1024#endif
1025{
1026 if (yytype < YYNTOKENS)
1027 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
1028 else
1029 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1030
1031 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1032 YYFPRINTF (yyoutput, ")");
1033}
1034
1035/*------------------------------------------------------------------.
1036| yy_stack_print -- Print the state stack from its BOTTOM up to its |
1037| TOP (included). |
1038`------------------------------------------------------------------*/
1039
1040#if (defined __STDC__ || defined __C99__FUNC__ \
1041 || defined __cplusplus || defined _MSC_VER)
1042static void
1043yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1044#else
1045static void
1046yy_stack_print (yybottom, yytop)
1047 yytype_int16 *yybottom;
1048 yytype_int16 *yytop;
1049#endif
1050{
1051 YYFPRINTF (stderr, "Stack now");
1052 for (; yybottom <= yytop; yybottom++)
1053 {
1054 int yybot = *yybottom;
1055 YYFPRINTF (stderr, " %d", yybot);
1056 }
1057 YYFPRINTF (stderr, "\n");
1058}
1059
1060# define YY_STACK_PRINT(Bottom, Top) \
1061do { \
1062 if (yydebug) \
1063 yy_stack_print ((Bottom), (Top)); \
1064} while (YYID (0))
1065
1066
1067/*------------------------------------------------.
1068| Report that the YYRULE is going to be reduced. |
1069`------------------------------------------------*/
1070
1071#if (defined __STDC__ || defined __C99__FUNC__ \
1072 || defined __cplusplus || defined _MSC_VER)
1073static void
1074yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
1075#else
1076static void
1077yy_reduce_print (yyvsp, yyrule)
1078 YYSTYPE *yyvsp;
1079 int yyrule;
1080#endif
1081{
1082 int yynrhs = yyr2[yyrule];
1083 int yyi;
1084 unsigned long int yylno = yyrline[yyrule];
1085 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1086 yyrule - 1, yylno);
1087 /* The symbols being reduced. */
1088 for (yyi = 0; yyi < yynrhs; yyi++)
1089 {
1090 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1091 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1092 &(yyvsp[(yyi + 1) - (yynrhs)])
1093 );
1094 YYFPRINTF (stderr, "\n");
1095 }
1096}
1097
1098# define YY_REDUCE_PRINT(Rule) \
1099do { \
1100 if (yydebug) \
1101 yy_reduce_print (yyvsp, Rule); \
1102} while (YYID (0))
1103
1104/* Nonzero means print parse trace. It is left uninitialized so that
1105 multiple parsers can coexist. */
1106int yydebug;
1107#else /* !YYDEBUG */
1108# define YYDPRINTF(Args)
1109# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1110# define YY_STACK_PRINT(Bottom, Top)
1111# define YY_REDUCE_PRINT(Rule)
1112#endif /* !YYDEBUG */
1113
1114
1115/* YYINITDEPTH -- initial size of the parser's stacks. */
1116#ifndef YYINITDEPTH
1117# define YYINITDEPTH 200
1118#endif
1119
1120/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1121 if the built-in stack extension method is used).
1122
1123 Do not make this value too large; the results are undefined if
1124 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1125 evaluated with infinite-precision integer arithmetic. */
1126
1127#ifndef YYMAXDEPTH
1128# define YYMAXDEPTH 10000
1129#endif
1130
1131
1132#if YYERROR_VERBOSE
1133
1134# ifndef yystrlen
1135# if defined __GLIBC__ && defined _STRING_H
1136# define yystrlen strlen
1137# else
1138/* Return the length of YYSTR. */
1139#if (defined __STDC__ || defined __C99__FUNC__ \
1140 || defined __cplusplus || defined _MSC_VER)
1141static YYSIZE_T
1142yystrlen (const char *yystr)
1143#else
1144static YYSIZE_T
1145yystrlen (yystr)
1146 const char *yystr;
1147#endif
1148{
1149 YYSIZE_T yylen;
1150 for (yylen = 0; yystr[yylen]; yylen++)
1151 continue;
1152 return yylen;
1153}
1154# endif
1155# endif
1156
1157# ifndef yystpcpy
1158# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1159# define yystpcpy stpcpy
1160# else
1161/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1162 YYDEST. */
1163#if (defined __STDC__ || defined __C99__FUNC__ \
1164 || defined __cplusplus || defined _MSC_VER)
1165static char *
1166yystpcpy (char *yydest, const char *yysrc)
1167#else
1168static char *
1169yystpcpy (yydest, yysrc)
1170 char *yydest;
1171 const char *yysrc;
1172#endif
1173{
1174 char *yyd = yydest;
1175 const char *yys = yysrc;
1176
1177 while ((*yyd++ = *yys++) != '\0')
1178 continue;
1179
1180 return yyd - 1;
1181}
1182# endif
1183# endif
1184
1185# ifndef yytnamerr
1186/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1187 quotes and backslashes, so that it's suitable for yyerror. The
1188 heuristic is that double-quoting is unnecessary unless the string
1189 contains an apostrophe, a comma, or backslash (other than
1190 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1191 null, do not copy; instead, return the length of what the result
1192 would have been. */
1193static YYSIZE_T
1194yytnamerr (char *yyres, const char *yystr)
1195{
1196 if (*yystr == '"')
1197 {
1198 YYSIZE_T yyn = 0;
1199 char const *yyp = yystr;
1200
1201 for (;;)
1202 switch (*++yyp)
1203 {
1204 case '\'':
1205 case ',':
1206 goto do_not_strip_quotes;
1207
1208 case '\\':
1209 if (*++yyp != '\\')
1210 goto do_not_strip_quotes;
1211 /* Fall through. */
1212 default:
1213 if (yyres)
1214 yyres[yyn] = *yyp;
1215 yyn++;
1216 break;
1217
1218 case '"':
1219 if (yyres)
1220 yyres[yyn] = '\0';
1221 return yyn;
1222 }
1223 do_not_strip_quotes: ;
1224 }
1225
1226 if (! yyres)
1227 return yystrlen (yystr);
1228
1229 return yystpcpy (yyres, yystr) - yyres;
1230}
1231# endif
1232
1233/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1234 about the unexpected token YYTOKEN for the state stack whose top is
1235 YYSSP.
1236
1237 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
1238 not large enough to hold the message. In that case, also set
1239 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
1240 required number of bytes is too large to store. */
1241static int
1242yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1243 yytype_int16 *yyssp, int yytoken)
1244{
1245 YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
1246 YYSIZE_T yysize = yysize0;
1247 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1248 /* Internationalized format string. */
1249 const char *yyformat = YY_NULL;
1250 /* Arguments of yyformat. */
1251 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1252 /* Number of reported tokens (one for the "unexpected", one per
1253 "expected"). */
1254 int yycount = 0;
1255
1256 /* There are many possibilities here to consider:
1257 - Assume YYFAIL is not used. It's too flawed to consider. See
1258 <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
1259 for details. YYERROR is fine as it does not invoke this
1260 function.
1261 - If this state is a consistent state with a default action, then
1262 the only way this function was invoked is if the default action
1263 is an error action. In that case, don't check for expected
1264 tokens because there are none.
1265 - The only way there can be no lookahead present (in yychar) is if
1266 this state is a consistent state with a default action. Thus,
1267 detecting the absence of a lookahead is sufficient to determine
1268 that there is no unexpected or expected token to report. In that
1269 case, just report a simple "syntax error".
1270 - Don't assume there isn't a lookahead just because this state is a
1271 consistent state with a default action. There might have been a
1272 previous inconsistent state, consistent state with a non-default
1273 action, or user semantic action that manipulated yychar.
1274 - Of course, the expected token list depends on states to have
1275 correct lookahead information, and it depends on the parser not
1276 to perform extra reductions after fetching a lookahead from the
1277 scanner and before detecting a syntax error. Thus, state merging
1278 (from LALR or IELR) and default reductions corrupt the expected
1279 token list. However, the list is correct for canonical LR with
1280 one exception: it will still contain any token that will not be
1281 accepted due to an error action in a later state.
1282 */
1283 if (yytoken != YYEMPTY)
1284 {
1285 int yyn = yypact[*yyssp];
1286 yyarg[yycount++] = yytname[yytoken];
1287 if (!yypact_value_is_default (yyn))
1288 {
1289 /* Start YYX at -YYN if negative to avoid negative indexes in
1290 YYCHECK. In other words, skip the first -YYN actions for
1291 this state because they are default actions. */
1292 int yyxbegin = yyn < 0 ? -yyn : 0;
1293 /* Stay within bounds of both yycheck and yytname. */
1294 int yychecklim = YYLAST - yyn + 1;
1295 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1296 int yyx;
1297
1298 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1299 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1300 && !yytable_value_is_error (yytable[yyx + yyn]))
1301 {
1302 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1303 {
1304 yycount = 1;
1305 yysize = yysize0;
1306 break;
1307 }
1308 yyarg[yycount++] = yytname[yyx];
1309 {
1310 YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
1311 if (! (yysize <= yysize1
1312 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1313 return 2;
1314 yysize = yysize1;
1315 }
1316 }
1317 }
1318 }
1319
1320 switch (yycount)
1321 {
1322# define YYCASE_(N, S) \
1323 case N: \
1324 yyformat = S; \
1325 break
1326 YYCASE_(0, YY_("syntax error"));
1327 YYCASE_(1, YY_("syntax error, unexpected %s"));
1328 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1329 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1330 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1331 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1332# undef YYCASE_
1333 }
1334
1335 {
1336 YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1337 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1338 return 2;
1339 yysize = yysize1;
1340 }
1341
1342 if (*yymsg_alloc < yysize)
1343 {
1344 *yymsg_alloc = 2 * yysize;
1345 if (! (yysize <= *yymsg_alloc
1346 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1347 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1348 return 1;
1349 }
1350
1351 /* Avoid sprintf, as that infringes on the user's name space.
1352 Don't have undefined behavior even if the translation
1353 produced a string with the wrong number of "%s"s. */
1354 {
1355 char *yyp = *yymsg;
1356 int yyi = 0;
1357 while ((*yyp = *yyformat) != '\0')
1358 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1359 {
1360 yyp += yytnamerr (yyp, yyarg[yyi++]);
1361 yyformat += 2;
1362 }
1363 else
1364 {
1365 yyp++;
1366 yyformat++;
1367 }
1368 }
1369 return 0;
1370}
1371#endif /* YYERROR_VERBOSE */
1372
1373/*-----------------------------------------------.
1374| Release the memory associated to this symbol. |
1375`-----------------------------------------------*/
1376
1377/*ARGSUSED*/
1378#if (defined __STDC__ || defined __C99__FUNC__ \
1379 || defined __cplusplus || defined _MSC_VER)
1380static void
1381yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1382#else
1383static void
1384yydestruct (yymsg, yytype, yyvaluep)
1385 const char *yymsg;
1386 int yytype;
1387 YYSTYPE *yyvaluep;
1388#endif
1389{
1390 YYUSE (yyvaluep);
1391
1392 if (!yymsg)
1393 yymsg = "Deleting";
1394 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1395
1396 switch (yytype)
1397 {
1398
1399 default:
1400 break;
1401 }
1402}
1403
1404
1405
1406
1407/* The lookahead symbol. */
1408int yychar;
1409
1410
1411#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1412# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1413# define YY_IGNORE_MAYBE_UNINITIALIZED_END
1414#endif
1415#ifndef YY_INITIAL_VALUE
1416# define YY_INITIAL_VALUE(Value) /* Nothing. */
1417#endif
1418
1419/* The semantic value of the lookahead symbol. */
1420YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
1421
1422/* Number of syntax errors so far. */
1423int yynerrs;
1424
1425
1426/*----------.
1427| yyparse. |
1428`----------*/
1429
1430#ifdef YYPARSE_PARAM
1431#if (defined __STDC__ || defined __C99__FUNC__ \
1432 || defined __cplusplus || defined _MSC_VER)
1433int
1434yyparse (void *YYPARSE_PARAM)
1435#else
1436int
1437yyparse (YYPARSE_PARAM)
1438 void *YYPARSE_PARAM;
1439#endif
1440#else /* ! YYPARSE_PARAM */
1441#if (defined __STDC__ || defined __C99__FUNC__ \
1442 || defined __cplusplus || defined _MSC_VER)
1443int
1444yyparse (void)
1445#else
1446int
1447yyparse ()
1448
1449#endif
1450#endif
1451{
1452 int yystate;
1453 /* Number of tokens to shift before error messages enabled. */
1454 int yyerrstatus;
1455
1456 /* The stacks and their tools:
1457 `yyss': related to states.
1458 `yyvs': related to semantic values.
1459
1460 Refer to the stacks through separate pointers, to allow yyoverflow
1461 to reallocate them elsewhere. */
1462
1463 /* The state stack. */
1464 yytype_int16 yyssa[YYINITDEPTH];
1465 yytype_int16 *yyss;
1466 yytype_int16 *yyssp;
1467
1468 /* The semantic value stack. */
1469 YYSTYPE yyvsa[YYINITDEPTH];
1470 YYSTYPE *yyvs;
1471 YYSTYPE *yyvsp;
1472
1473 YYSIZE_T yystacksize;
1474
1475 int yyn;
1476 int yyresult;
1477 /* Lookahead token as an internal (translated) token number. */
1478 int yytoken = 0;
1479 /* The variables used to return semantic value and location from the
1480 action routines. */
1481 YYSTYPE yyval;
1482
1483#if YYERROR_VERBOSE
1484 /* Buffer for error messages, and its allocated size. */
1485 char yymsgbuf[128];
1486 char *yymsg = yymsgbuf;
1487 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1488#endif
1489
1490#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1491
1492 /* The number of symbols on the RHS of the reduced rule.
1493 Keep to zero when no symbol should be popped. */
1494 int yylen = 0;
1495
1496 yyssp = yyss = yyssa;
1497 yyvsp = yyvs = yyvsa;
1498 yystacksize = YYINITDEPTH;
1499
1500 YYDPRINTF ((stderr, "Starting parse\n"));
1501
1502 yystate = 0;
1503 yyerrstatus = 0;
1504 yynerrs = 0;
1505 yychar = YYEMPTY; /* Cause a token to be read. */
1506 goto yysetstate;
1507
1508/*------------------------------------------------------------.
1509| yynewstate -- Push a new state, which is found in yystate. |
1510`------------------------------------------------------------*/
1511 yynewstate:
1512 /* In all cases, when you get here, the value and location stacks
1513 have just been pushed. So pushing a state here evens the stacks. */
1514 yyssp++;
1515
1516 yysetstate:
1517 *yyssp = yystate;
1518
1519 if (yyss + yystacksize - 1 <= yyssp)
1520 {
1521 /* Get the current used size of the three stacks, in elements. */
1522 YYSIZE_T yysize = yyssp - yyss + 1;
1523
1524#ifdef yyoverflow
1525 {
1526 /* Give user a chance to reallocate the stack. Use copies of
1527 these so that the &'s don't force the real ones into
1528 memory. */
1529 YYSTYPE *yyvs1 = yyvs;
1530 yytype_int16 *yyss1 = yyss;
1531
1532 /* Each stack pointer address is followed by the size of the
1533 data in use in that stack, in bytes. This used to be a
1534 conditional around just the two extra args, but that might
1535 be undefined if yyoverflow is a macro. */
1536 yyoverflow (YY_("memory exhausted"),
1537 &yyss1, yysize * sizeof (*yyssp),
1538 &yyvs1, yysize * sizeof (*yyvsp),
1539 &yystacksize);
1540
1541 yyss = yyss1;
1542 yyvs = yyvs1;
1543 }
1544#else /* no yyoverflow */
1545# ifndef YYSTACK_RELOCATE
1546 goto yyexhaustedlab;
1547# else
1548 /* Extend the stack our own way. */
1549 if (YYMAXDEPTH <= yystacksize)
1550 goto yyexhaustedlab;
1551 yystacksize *= 2;
1552 if (YYMAXDEPTH < yystacksize)
1553 yystacksize = YYMAXDEPTH;
1554
1555 {
1556 yytype_int16 *yyss1 = yyss;
1557 union yyalloc *yyptr =
1558 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1559 if (! yyptr)
1560 goto yyexhaustedlab;
1561 YYSTACK_RELOCATE (yyss_alloc, yyss);
1562 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1563# undef YYSTACK_RELOCATE
1564 if (yyss1 != yyssa)
1565 YYSTACK_FREE (yyss1);
1566 }
1567# endif
1568#endif /* no yyoverflow */
1569
1570 yyssp = yyss + yysize - 1;
1571 yyvsp = yyvs + yysize - 1;
1572
1573 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1574 (unsigned long int) yystacksize));
1575
1576 if (yyss + yystacksize - 1 <= yyssp)
1577 YYABORT;
1578 }
1579
1580 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1581
1582 if (yystate == YYFINAL)
1583 YYACCEPT;
1584
1585 goto yybackup;
1586
1587/*-----------.
1588| yybackup. |
1589`-----------*/
1590yybackup:
1591
1592 /* Do appropriate processing given the current state. Read a
1593 lookahead token if we need one and don't already have one. */
1594
1595 /* First try to decide what to do without reference to lookahead token. */
1596 yyn = yypact[yystate];
1597 if (yypact_value_is_default (yyn))
1598 goto yydefault;
1599
1600 /* Not known => get a lookahead token if don't already have one. */
1601
1602 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1603 if (yychar == YYEMPTY)
1604 {
1605 YYDPRINTF ((stderr, "Reading a token: "));
1606 yychar = YYLEX;
1607 }
1608
1609 if (yychar <= YYEOF)
1610 {
1611 yychar = yytoken = YYEOF;
1612 YYDPRINTF ((stderr, "Now at end of input.\n"));
1613 }
1614 else
1615 {
1616 yytoken = YYTRANSLATE (yychar);
1617 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1618 }
1619
1620 /* If the proper action on seeing token YYTOKEN is to reduce or to
1621 detect an error, take that action. */
1622 yyn += yytoken;
1623 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1624 goto yydefault;
1625 yyn = yytable[yyn];
1626 if (yyn <= 0)
1627 {
1628 if (yytable_value_is_error (yyn))
1629 goto yyerrlab;
1630 yyn = -yyn;
1631 goto yyreduce;
1632 }
1633
1634 /* Count tokens shifted since error; after three, turn off error
1635 status. */
1636 if (yyerrstatus)
1637 yyerrstatus--;
1638
1639 /* Shift the lookahead token. */
1640 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1641
1642 /* Discard the shifted token. */
1643 yychar = YYEMPTY;
1644
1645 yystate = yyn;
1646 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1647 *++yyvsp = yylval;
1648 YY_IGNORE_MAYBE_UNINITIALIZED_END
1649
1650 goto yynewstate;
1651
1652
1653/*-----------------------------------------------------------.
1654| yydefault -- do the default action for the current state. |
1655`-----------------------------------------------------------*/
1656yydefault:
1657 yyn = yydefact[yystate];
1658 if (yyn == 0)
1659 goto yyerrlab;
1660 goto yyreduce;
1661
1662
1663/*-----------------------------.
1664| yyreduce -- Do a reduction. |
1665`-----------------------------*/
1666yyreduce:
1667 /* yyn is the number of a rule to reduce with. */
1668 yylen = yyr2[yyn];
1669
1670 /* If YYLEN is nonzero, implement the default value of the action:
1671 `$$ = $1'.
1672
1673 Otherwise, the following line sets YYVAL to garbage.
1674 This behavior is undocumented and Bison
1675 users should not rely upon it. Assigning to YYVAL
1676 unconditionally makes the parser a bit smaller, and it avoids a
1677 GCC warning that YYVAL may be used uninitialized. */
1678 yyval = yyvsp[1-yylen];
1679
1680
1681 YY_REDUCE_PRINT (yyn);
1682 switch (yyn)
1683 {
1684 case 4:
1685
1686 { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
1687 break;
1688
1689 case 5:
1690
1691 { free_list(*(yyvsp[(2) - (2)]), NULL); *(yyvsp[(2) - (2)]) = NULL; }
1692 break;
1693
1694 case 6:
1695
1696 { is_typedef = 1; }
1697 break;
1698
1699 case 7:
1700
1701 { (yyval) = (yyvsp[(4) - (4)]); }
1702 break;
1703
1704 case 8:
1705
1706 { is_typedef = 1; }
1707 break;
1708
1709 case 9:
1710
1711 { (yyval) = (yyvsp[(3) - (3)]); }
1712 break;
1713
1714 case 14:
1715
1716 { (yyval) = (yyvsp[(2) - (2)]); }
1717 break;
1718
1719 case 15:
1720
1721 { (yyval) = (yyvsp[(2) - (2)]); }
1722 break;
1723
1724 case 16:
1725
1726 { if (current_name) {
1727 struct string_list *decl = (*(yyvsp[(3) - (3)]))->next;
1728 (*(yyvsp[(3) - (3)]))->next = NULL;
1729 add_symbol(current_name,
1730 is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
1731 decl, is_extern);
1732 current_name = NULL;
1733 }
1734 (yyval) = (yyvsp[(3) - (3)]);
1735 }
1736 break;
1737
1738 case 17:
1739
1740 { (yyval) = NULL; }
1741 break;
1742
1743 case 19:
1744
1745 { struct string_list *decl = *(yyvsp[(1) - (1)]);
1746 *(yyvsp[(1) - (1)]) = NULL;
1747 add_symbol(current_name,
1748 is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1749 current_name = NULL;
1750 (yyval) = (yyvsp[(1) - (1)]);
1751 }
1752 break;
1753
1754 case 20:
1755
1756 { struct string_list *decl = *(yyvsp[(3) - (3)]);
1757 *(yyvsp[(3) - (3)]) = NULL;
1758 free_list(*(yyvsp[(2) - (3)]), NULL);
1759 *(yyvsp[(2) - (3)]) = decl_spec;
1760 add_symbol(current_name,
1761 is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1762 current_name = NULL;
1763 (yyval) = (yyvsp[(3) - (3)]);
1764 }
1765 break;
1766
1767 case 21:
1768
1769 { (yyval) = (yyvsp[(4) - (4)]) ? (yyvsp[(4) - (4)]) : (yyvsp[(3) - (4)]) ? (yyvsp[(3) - (4)]) : (yyvsp[(2) - (4)]) ? (yyvsp[(2) - (4)]) : (yyvsp[(1) - (4)]); }
1770 break;
1771
1772 case 22:
1773
1774 { decl_spec = NULL; }
1775 break;
1776
1777 case 24:
1778
1779 { decl_spec = *(yyvsp[(1) - (1)]); }
1780 break;
1781
1782 case 25:
1783
1784 { decl_spec = *(yyvsp[(2) - (2)]); }
1785 break;
1786
1787 case 26:
1788
1789 { /* Version 2 checksumming ignores storage class, as that
1790 is really irrelevant to the linkage. */
1791 remove_node((yyvsp[(1) - (1)]));
1792 (yyval) = (yyvsp[(1) - (1)]);
1793 }
1794 break;
1795
1796 case 31:
1797
1798 { is_extern = 1; (yyval) = (yyvsp[(1) - (1)]); }
1799 break;
1800
1801 case 32:
1802
1803 { is_extern = 0; (yyval) = (yyvsp[(1) - (1)]); }
1804 break;
1805
1806 case 37:
1807
1808 { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_STRUCT; (yyval) = (yyvsp[(2) - (2)]); }
1809 break;
1810
1811 case 38:
1812
1813 { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_UNION; (yyval) = (yyvsp[(2) - (2)]); }
1814 break;
1815
1816 case 39:
1817
1818 { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_ENUM; (yyval) = (yyvsp[(2) - (2)]); }
1819 break;
1820
1821 case 40:
1822
1823 { record_compound((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), SYM_STRUCT); (yyval) = (yyvsp[(3) - (3)]); }
1824 break;
1825
1826 case 41:
1827
1828 { record_compound((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), SYM_UNION); (yyval) = (yyvsp[(3) - (3)]); }
1829 break;
1830
1831 case 42:
1832
1833 { record_compound((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), SYM_ENUM); (yyval) = (yyvsp[(3) - (3)]); }
1834 break;
1835
1836 case 43:
1837
1838 { add_symbol(NULL, SYM_ENUM, NULL, 0); (yyval) = (yyvsp[(2) - (2)]); }
1839 break;
1840
1841 case 44:
1842
1843 { (yyval) = (yyvsp[(2) - (2)]); }
1844 break;
1845
1846 case 45:
1847
1848 { (yyval) = (yyvsp[(2) - (2)]); }
1849 break;
1850
1851 case 57:
1852
1853 { (*(yyvsp[(1) - (1)]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[(1) - (1)]); }
1854 break;
1855
1856 case 58:
1857
1858 { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
1859 break;
1860
1861 case 59:
1862
1863 { (yyval) = NULL; }
1864 break;
1865
1866 case 62:
1867
1868 { (yyval) = (yyvsp[(2) - (2)]); }
1869 break;
1870
1871 case 66:
1872
1873 { /* restrict has no effect in prototypes so ignore it */
1874 remove_node((yyvsp[(1) - (1)]));
1875 (yyval) = (yyvsp[(1) - (1)]);
1876 }
1877 break;
1878
1879 case 67:
1880
1881 { (yyval) = (yyvsp[(2) - (2)]); }
1882 break;
1883
1884 case 69:
1885
1886 { if (current_name != NULL) {
1887 error_with_pos("unexpected second declaration name");
1888 YYERROR;
1889 } else {
1890 current_name = (*(yyvsp[(1) - (1)]))->string;
1891 (yyval) = (yyvsp[(1) - (1)]);
1892 }
1893 }
1894 break;
1895
1896 case 70:
1897
1898 { if (current_name != NULL) {
1899 error_with_pos("unexpected second declaration name");
1900 YYERROR;
1901 } else {
1902 current_name = (*(yyvsp[(1) - (1)]))->string;
1903 (yyval) = (yyvsp[(1) - (1)]);
1904 }
1905 }
1906 break;
1907
1908 case 71:
1909
1910 { (yyval) = (yyvsp[(4) - (4)]); }
1911 break;
1912
1913 case 72:
1914
1915 { (yyval) = (yyvsp[(4) - (4)]); }
1916 break;
1917
1918 case 73:
1919
1920 { (yyval) = (yyvsp[(2) - (2)]); }
1921 break;
1922
1923 case 74:
1924
1925 { (yyval) = (yyvsp[(3) - (3)]); }
1926 break;
1927
1928 case 75:
1929
1930 { (yyval) = (yyvsp[(2) - (2)]); }
1931 break;
1932
1933 case 79:
1934
1935 { (yyval) = (yyvsp[(4) - (4)]); }
1936 break;
1937
1938 case 80:
1939
1940 { (yyval) = (yyvsp[(4) - (4)]); }
1941 break;
1942
1943 case 81:
1944
1945 { (yyval) = (yyvsp[(2) - (2)]); }
1946 break;
1947
1948 case 82:
1949
1950 { (yyval) = (yyvsp[(3) - (3)]); }
1951 break;
1952
1953 case 83:
1954
1955 { (yyval) = (yyvsp[(3) - (3)]); }
1956 break;
1957
1958 case 84:
1959
1960 { (yyval) = (yyvsp[(2) - (2)]); }
1961 break;
1962
1963 case 86:
1964
1965 { (yyval) = (yyvsp[(3) - (3)]); }
1966 break;
1967
1968 case 87:
1969
1970 { (yyval) = NULL; }
1971 break;
1972
1973 case 90:
1974
1975 { (yyval) = (yyvsp[(3) - (3)]); }
1976 break;
1977
1978 case 91:
1979
1980 { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
1981 break;
1982
1983 case 92:
1984
1985 { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
1986 break;
1987
1988 case 94:
1989
1990 { (yyval) = NULL; }
1991 break;
1992
1993 case 95:
1994
1995 { /* For version 2 checksums, we don't want to remember
1996 private parameter names. */
1997 remove_node((yyvsp[(1) - (1)]));
1998 (yyval) = (yyvsp[(1) - (1)]);
1999 }
2000 break;
2001
2002 case 96:
2003
2004 { remove_node((yyvsp[(1) - (1)]));
2005 (yyval) = (yyvsp[(1) - (1)]);
2006 }
2007 break;
2008
2009 case 97:
2010
2011 { (yyval) = (yyvsp[(4) - (4)]); }
2012 break;
2013
2014 case 98:
2015
2016 { (yyval) = (yyvsp[(4) - (4)]); }
2017 break;
2018
2019 case 99:
2020
2021 { (yyval) = (yyvsp[(2) - (2)]); }
2022 break;
2023
2024 case 100:
2025
2026 { (yyval) = (yyvsp[(3) - (3)]); }
2027 break;
2028
2029 case 101:
2030
2031 { (yyval) = (yyvsp[(3) - (3)]); }
2032 break;
2033
2034 case 102:
2035
2036 { struct string_list *decl = *(yyvsp[(2) - (3)]);
2037 *(yyvsp[(2) - (3)]) = NULL;
2038 add_symbol(current_name, SYM_NORMAL, decl, is_extern);
2039 (yyval) = (yyvsp[(3) - (3)]);
2040 }
2041 break;
2042
2043 case 103:
2044
2045 { (yyval) = NULL; }
2046 break;
2047
2048 case 105:
2049
2050 { remove_list((yyvsp[(2) - (2)]), &(*(yyvsp[(1) - (2)]))->next); (yyval) = (yyvsp[(2) - (2)]); }
2051 break;
2052
2053 case 106:
2054
2055 { (yyval) = (yyvsp[(3) - (3)]); }
2056 break;
2057
2058 case 107:
2059
2060 { (yyval) = (yyvsp[(3) - (3)]); }
2061 break;
2062
2063 case 108:
2064
2065 { (yyval) = NULL; }
2066 break;
2067
2068 case 111:
2069
2070 { (yyval) = (yyvsp[(2) - (2)]); }
2071 break;
2072
2073 case 112:
2074
2075 { (yyval) = (yyvsp[(3) - (3)]); }
2076 break;
2077
2078 case 113:
2079
2080 { (yyval) = (yyvsp[(2) - (2)]); }
2081 break;
2082
2083 case 114:
2084
2085 { (yyval) = NULL; }
2086 break;
2087
2088 case 117:
2089
2090 { (yyval) = (yyvsp[(3) - (3)]); }
2091 break;
2092
2093 case 118:
2094
2095 { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
2096 break;
2097
2098 case 119:
2099
2100 { (yyval) = (yyvsp[(2) - (2)]); }
2101 break;
2102
2103 case 121:
2104
2105 { (yyval) = (yyvsp[(2) - (2)]); }
2106 break;
2107
2108 case 122:
2109
2110 { (yyval) = NULL; }
2111 break;
2112
2113 case 124:
2114
2115 { (yyval) = (yyvsp[(3) - (3)]); }
2116 break;
2117
2118 case 125:
2119
2120 { (yyval) = (yyvsp[(4) - (4)]); }
2121 break;
2122
2123 case 128:
2124
2125 {
2126 const char *name = strdup((*(yyvsp[(1) - (1)]))->string);
2127 add_symbol(name, SYM_ENUM_CONST, NULL, 0);
2128 }
2129 break;
2130
2131 case 129:
2132
2133 {
2134 const char *name = strdup((*(yyvsp[(1) - (3)]))->string);
2135 struct string_list *expr = copy_list_range(*(yyvsp[(3) - (3)]), *(yyvsp[(2) - (3)]));
2136 add_symbol(name, SYM_ENUM_CONST, expr, 0);
2137 }
2138 break;
2139
2140 case 130:
2141
2142 { (yyval) = (yyvsp[(2) - (2)]); }
2143 break;
2144
2145 case 131:
2146
2147 { (yyval) = NULL; }
2148 break;
2149
2150 case 133:
2151
2152 { export_symbol((*(yyvsp[(3) - (5)]))->string); (yyval) = (yyvsp[(5) - (5)]); }
2153 break;
2154
2155
2156
2157 default: break;
2158 }
2159 /* User semantic actions sometimes alter yychar, and that requires
2160 that yytoken be updated with the new translation. We take the
2161 approach of translating immediately before every use of yytoken.
2162 One alternative is translating here after every semantic action,
2163 but that translation would be missed if the semantic action invokes
2164 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
2165 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
2166 incorrect destructor might then be invoked immediately. In the
2167 case of YYERROR or YYBACKUP, subsequent parser actions might lead
2168 to an incorrect destructor call or verbose syntax error message
2169 before the lookahead is translated. */
2170 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
2171
2172 YYPOPSTACK (yylen);
2173 yylen = 0;
2174 YY_STACK_PRINT (yyss, yyssp);
2175
2176 *++yyvsp = yyval;
2177
2178 /* Now `shift' the result of the reduction. Determine what state
2179 that goes to, based on the state we popped back to and the rule
2180 number reduced by. */
2181
2182 yyn = yyr1[yyn];
2183
2184 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
2185 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2186 yystate = yytable[yystate];
2187 else
2188 yystate = yydefgoto[yyn - YYNTOKENS];
2189
2190 goto yynewstate;
2191
2192
2193/*------------------------------------.
2194| yyerrlab -- here on detecting error |
2195`------------------------------------*/
2196yyerrlab:
2197 /* Make sure we have latest lookahead translation. See comments at
2198 user semantic actions for why this is necessary. */
2199 yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
2200
2201 /* If not already recovering from an error, report this error. */
2202 if (!yyerrstatus)
2203 {
2204 ++yynerrs;
2205#if ! YYERROR_VERBOSE
2206 yyerror (YY_("syntax error"));
2207#else
2208# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
2209 yyssp, yytoken)
2210 {
2211 char const *yymsgp = YY_("syntax error");
2212 int yysyntax_error_status;
2213 yysyntax_error_status = YYSYNTAX_ERROR;
2214 if (yysyntax_error_status == 0)
2215 yymsgp = yymsg;
2216 else if (yysyntax_error_status == 1)
2217 {
2218 if (yymsg != yymsgbuf)
2219 YYSTACK_FREE (yymsg);
2220 yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
2221 if (!yymsg)
2222 {
2223 yymsg = yymsgbuf;
2224 yymsg_alloc = sizeof yymsgbuf;
2225 yysyntax_error_status = 2;
2226 }
2227 else
2228 {
2229 yysyntax_error_status = YYSYNTAX_ERROR;
2230 yymsgp = yymsg;
2231 }
2232 }
2233 yyerror (yymsgp);
2234 if (yysyntax_error_status == 2)
2235 goto yyexhaustedlab;
2236 }
2237# undef YYSYNTAX_ERROR
2238#endif
2239 }
2240
2241
2242
2243 if (yyerrstatus == 3)
2244 {
2245 /* If just tried and failed to reuse lookahead token after an
2246 error, discard it. */
2247
2248 if (yychar <= YYEOF)
2249 {
2250 /* Return failure if at end of input. */
2251 if (yychar == YYEOF)
2252 YYABORT;
2253 }
2254 else
2255 {
2256 yydestruct ("Error: discarding",
2257 yytoken, &yylval);
2258 yychar = YYEMPTY;
2259 }
2260 }
2261
2262 /* Else will try to reuse lookahead token after shifting the error
2263 token. */
2264 goto yyerrlab1;
2265
2266
2267/*---------------------------------------------------.
2268| yyerrorlab -- error raised explicitly by YYERROR. |
2269`---------------------------------------------------*/
2270yyerrorlab:
2271
2272 /* Pacify compilers like GCC when the user code never invokes
2273 YYERROR and the label yyerrorlab therefore never appears in user
2274 code. */
2275 if (/*CONSTCOND*/ 0)
2276 goto yyerrorlab;
2277
2278 /* Do not reclaim the symbols of the rule which action triggered
2279 this YYERROR. */
2280 YYPOPSTACK (yylen);
2281 yylen = 0;
2282 YY_STACK_PRINT (yyss, yyssp);
2283 yystate = *yyssp;
2284 goto yyerrlab1;
2285
2286
2287/*-------------------------------------------------------------.
2288| yyerrlab1 -- common code for both syntax error and YYERROR. |
2289`-------------------------------------------------------------*/
2290yyerrlab1:
2291 yyerrstatus = 3; /* Each real token shifted decrements this. */
2292
2293 for (;;)
2294 {
2295 yyn = yypact[yystate];
2296 if (!yypact_value_is_default (yyn))
2297 {
2298 yyn += YYTERROR;
2299 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
2300 {
2301 yyn = yytable[yyn];
2302 if (0 < yyn)
2303 break;
2304 }
2305 }
2306
2307 /* Pop the current state because it cannot handle the error token. */
2308 if (yyssp == yyss)
2309 YYABORT;
2310
2311
2312 yydestruct ("Error: popping",
2313 yystos[yystate], yyvsp);
2314 YYPOPSTACK (1);
2315 yystate = *yyssp;
2316 YY_STACK_PRINT (yyss, yyssp);
2317 }
2318
2319 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
2320 *++yyvsp = yylval;
2321 YY_IGNORE_MAYBE_UNINITIALIZED_END
2322
2323
2324 /* Shift the error token. */
2325 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
2326
2327 yystate = yyn;
2328 goto yynewstate;
2329
2330
2331/*-------------------------------------.
2332| yyacceptlab -- YYACCEPT comes here. |
2333`-------------------------------------*/
2334yyacceptlab:
2335 yyresult = 0;
2336 goto yyreturn;
2337
2338/*-----------------------------------.
2339| yyabortlab -- YYABORT comes here. |
2340`-----------------------------------*/
2341yyabortlab:
2342 yyresult = 1;
2343 goto yyreturn;
2344
2345#if !defined yyoverflow || YYERROR_VERBOSE
2346/*-------------------------------------------------.
2347| yyexhaustedlab -- memory exhaustion comes here. |
2348`-------------------------------------------------*/
2349yyexhaustedlab:
2350 yyerror (YY_("memory exhausted"));
2351 yyresult = 2;
2352 /* Fall through. */
2353#endif
2354
2355yyreturn:
2356 if (yychar != YYEMPTY)
2357 {
2358 /* Make sure we have latest lookahead translation. See comments at
2359 user semantic actions for why this is necessary. */
2360 yytoken = YYTRANSLATE (yychar);
2361 yydestruct ("Cleanup: discarding lookahead",
2362 yytoken, &yylval);
2363 }
2364 /* Do not reclaim the symbols of the rule which action triggered
2365 this YYABORT or YYACCEPT. */
2366 YYPOPSTACK (yylen);
2367 YY_STACK_PRINT (yyss, yyssp);
2368 while (yyssp != yyss)
2369 {
2370 yydestruct ("Cleanup: popping",
2371 yystos[*yyssp], yyvsp);
2372 YYPOPSTACK (1);
2373 }
2374#ifndef yyoverflow
2375 if (yyss != yyssa)
2376 YYSTACK_FREE (yyss);
2377#endif
2378#if YYERROR_VERBOSE
2379 if (yymsg != yymsgbuf)
2380 YYSTACK_FREE (yymsg);
2381#endif
2382 /* Make sure YYID is used. */
2383 return YYID (yyresult);
2384}
2385
2386
2387
2388
2389
2390static void
2391yyerror(const char *e)
2392{
2393 error_with_pos("%s", e);
2394}
diff --git a/scripts/genksyms/parse.tab.h_shipped b/scripts/genksyms/parse.tab.h_shipped
deleted file mode 100644
index 46a5e124eda1..000000000000
--- a/scripts/genksyms/parse.tab.h_shipped
+++ /dev/null
@@ -1,119 +0,0 @@
1/* A Bison parser, made by GNU Bison 2.7. */
2
3/* Bison interface for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33#ifndef YY_YY_SCRIPTS_GENKSYMS_PARSE_TAB_H_SHIPPED_INCLUDED
34# define YY_YY_SCRIPTS_GENKSYMS_PARSE_TAB_H_SHIPPED_INCLUDED
35/* Enabling traces. */
36#ifndef YYDEBUG
37# define YYDEBUG 1
38#endif
39#if YYDEBUG
40extern int yydebug;
41#endif
42
43/* Tokens. */
44#ifndef YYTOKENTYPE
45# define YYTOKENTYPE
46 /* Put the tokens into the symbol table, so that GDB and other debuggers
47 know about them. */
48 enum yytokentype {
49 ASM_KEYW = 258,
50 ATTRIBUTE_KEYW = 259,
51 AUTO_KEYW = 260,
52 BOOL_KEYW = 261,
53 CHAR_KEYW = 262,
54 CONST_KEYW = 263,
55 DOUBLE_KEYW = 264,
56 ENUM_KEYW = 265,
57 EXTERN_KEYW = 266,
58 EXTENSION_KEYW = 267,
59 FLOAT_KEYW = 268,
60 INLINE_KEYW = 269,
61 INT_KEYW = 270,
62 LONG_KEYW = 271,
63 REGISTER_KEYW = 272,
64 RESTRICT_KEYW = 273,
65 SHORT_KEYW = 274,
66 SIGNED_KEYW = 275,
67 STATIC_KEYW = 276,
68 STRUCT_KEYW = 277,
69 TYPEDEF_KEYW = 278,
70 UNION_KEYW = 279,
71 UNSIGNED_KEYW = 280,
72 VOID_KEYW = 281,
73 VOLATILE_KEYW = 282,
74 TYPEOF_KEYW = 283,
75 VA_LIST_KEYW = 284,
76 EXPORT_SYMBOL_KEYW = 285,
77 ASM_PHRASE = 286,
78 ATTRIBUTE_PHRASE = 287,
79 TYPEOF_PHRASE = 288,
80 BRACE_PHRASE = 289,
81 BRACKET_PHRASE = 290,
82 EXPRESSION_PHRASE = 291,
83 CHAR = 292,
84 DOTS = 293,
85 IDENT = 294,
86 INT = 295,
87 REAL = 296,
88 STRING = 297,
89 TYPE = 298,
90 OTHER = 299,
91 FILENAME = 300
92 };
93#endif
94
95
96#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
97typedef int YYSTYPE;
98# define YYSTYPE_IS_TRIVIAL 1
99# define yystype YYSTYPE /* obsolescent; will be withdrawn */
100# define YYSTYPE_IS_DECLARED 1
101#endif
102
103extern YYSTYPE yylval;
104
105#ifdef YYPARSE_PARAM
106#if defined __STDC__ || defined __cplusplus
107int yyparse (void *YYPARSE_PARAM);
108#else
109int yyparse ();
110#endif
111#else /* ! YYPARSE_PARAM */
112#if defined __STDC__ || defined __cplusplus
113int yyparse (void);
114#else
115int yyparse ();
116#endif
117#endif /* ! YYPARSE_PARAM */
118
119#endif /* !YY_YY_SCRIPTS_GENKSYMS_PARSE_TAB_H_SHIPPED_INCLUDED */
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 99c96e86eccb..c1c088ef1420 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -1,4 +1,6 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2# SPDX-License-Identifier: GPL-2.0
3#
2# (c) 2007, Joe Perches <joe@perches.com> 4# (c) 2007, Joe Perches <joe@perches.com>
3# created from checkpatch.pl 5# created from checkpatch.pl
4# 6#
@@ -7,8 +9,6 @@
7# 9#
8# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch> 10# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
9# perl scripts/get_maintainer.pl [OPTIONS] -f <file> 11# perl scripts/get_maintainer.pl [OPTIONS] -f <file>
10#
11# Licensed under the terms of the GNU GPL License version 2
12 12
13use warnings; 13use warnings;
14use strict; 14use strict;
@@ -48,6 +48,7 @@ my $output_roles = 0;
48my $output_rolestats = 1; 48my $output_rolestats = 1;
49my $output_section_maxlen = 50; 49my $output_section_maxlen = 50;
50my $scm = 0; 50my $scm = 0;
51my $tree = 1;
51my $web = 0; 52my $web = 0;
52my $subsystem = 0; 53my $subsystem = 0;
53my $status = 0; 54my $status = 0;
@@ -61,7 +62,7 @@ my $self_test = undef;
61my $version = 0; 62my $version = 0;
62my $help = 0; 63my $help = 0;
63my $find_maintainer_files = 0; 64my $find_maintainer_files = 0;
64 65my $maintainer_path;
65my $vcs_used = 0; 66my $vcs_used = 0;
66 67
67my $exit = 0; 68my $exit = 0;
@@ -255,6 +256,7 @@ if (!GetOptions(
255 'subsystem!' => \$subsystem, 256 'subsystem!' => \$subsystem,
256 'status!' => \$status, 257 'status!' => \$status,
257 'scm!' => \$scm, 258 'scm!' => \$scm,
259 'tree!' => \$tree,
258 'web!' => \$web, 260 'web!' => \$web,
259 'letters=s' => \$letters, 261 'letters=s' => \$letters,
260 'pattern-depth=i' => \$pattern_depth, 262 'pattern-depth=i' => \$pattern_depth,
@@ -263,6 +265,7 @@ if (!GetOptions(
263 'fe|file-emails!' => \$file_emails, 265 'fe|file-emails!' => \$file_emails,
264 'f|file' => \$from_filename, 266 'f|file' => \$from_filename,
265 'find-maintainer-files' => \$find_maintainer_files, 267 'find-maintainer-files' => \$find_maintainer_files,
268 'mpath|maintainer-path=s' => \$maintainer_path,
266 'self-test:s' => \$self_test, 269 'self-test:s' => \$self_test,
267 'v|version' => \$version, 270 'v|version' => \$version,
268 'h|help|usage' => \$help, 271 'h|help|usage' => \$help,
@@ -319,7 +322,7 @@ if ($email &&
319 die "$P: Please select at least 1 email option\n"; 322 die "$P: Please select at least 1 email option\n";
320} 323}
321 324
322if (!top_of_kernel_tree($lk_path)) { 325if ($tree && !top_of_kernel_tree($lk_path)) {
323 die "$P: The current directory does not appear to be " 326 die "$P: The current directory does not appear to be "
324 . "a linux kernel source tree.\n"; 327 . "a linux kernel source tree.\n";
325} 328}
@@ -384,26 +387,36 @@ sub find_ignore_git {
384read_all_maintainer_files(); 387read_all_maintainer_files();
385 388
386sub read_all_maintainer_files { 389sub read_all_maintainer_files {
387 if (-d "${lk_path}MAINTAINERS") { 390 my $path = "${lk_path}MAINTAINERS";
388 opendir(DIR, "${lk_path}MAINTAINERS") or die $!; 391 if (defined $maintainer_path) {
389 my @files = readdir(DIR); 392 $path = $maintainer_path;
390 closedir(DIR); 393 # Perl Cookbook tilde expansion if necessary
391 foreach my $file (@files) { 394 $path =~ s@^~([^/]*)@ $1 ? (getpwnam($1))[7] : ( $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($<))[7])@ex;
392 push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./); 395 }
393 } 396
394 } 397 if (-d $path) {
395 398 $path .= '/' if ($path !~ m@/$@);
396 if ($find_maintainer_files) { 399 if ($find_maintainer_files) {
397 find( { wanted => \&find_is_maintainer_file, 400 find( { wanted => \&find_is_maintainer_file,
398 preprocess => \&find_ignore_git, 401 preprocess => \&find_ignore_git,
399 no_chdir => 1, 402 no_chdir => 1,
400 }, "${lk_path}"); 403 }, "$path");
404 } else {
405 opendir(DIR, "$path") or die $!;
406 my @files = readdir(DIR);
407 closedir(DIR);
408 foreach my $file (@files) {
409 push(@mfiles, "$path$file") if ($file !~ /^\./);
410 }
411 }
412 } elsif (-f "$path") {
413 push(@mfiles, "$path");
401 } else { 414 } else {
402 push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS"; 415 die "$P: MAINTAINER file not found '$path'\n";
403 } 416 }
404 417 die "$P: No MAINTAINER files found in '$path'\n" if (scalar(@mfiles) == 0);
405 foreach my $file (@mfiles) { 418 foreach my $file (@mfiles) {
406 read_maintainer_file("$file"); 419 read_maintainer_file("$file");
407 } 420 }
408} 421}
409 422
@@ -542,7 +555,18 @@ foreach my $file (@ARGV) {
542 555
543 while (<$patch>) { 556 while (<$patch>) {
544 my $patch_line = $_; 557 my $patch_line = $_;
545 if (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) { 558 if (m/^ mode change [0-7]+ => [0-7]+ (\S+)\s*$/) {
559 my $filename = $1;
560 push(@files, $filename);
561 } elsif (m/^rename (?:from|to) (\S+)\s*$/) {
562 my $filename = $1;
563 push(@files, $filename);
564 } elsif (m/^diff --git a\/(\S+) b\/(\S+)\s*$/) {
565 my $filename1 = $1;
566 my $filename2 = $2;
567 push(@files, $filename1);
568 push(@files, $filename2);
569 } elsif (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) {
546 my $filename = $1; 570 my $filename = $1;
547 $filename =~ s@^[^/]*/@@; 571 $filename =~ s@^[^/]*/@@;
548 $filename =~ s@\n@@; 572 $filename =~ s@\n@@;
@@ -1020,13 +1044,14 @@ Other options:
1020 --sections => print all of the subsystem sections with pattern matches 1044 --sections => print all of the subsystem sections with pattern matches
1021 --letters => print all matching 'letter' types from all matching sections 1045 --letters => print all matching 'letter' types from all matching sections
1022 --mailmap => use .mailmap file (default: $email_use_mailmap) 1046 --mailmap => use .mailmap file (default: $email_use_mailmap)
1047 --no-tree => run without a kernel tree
1023 --self-test => show potential issues with MAINTAINERS file content 1048 --self-test => show potential issues with MAINTAINERS file content
1024 --version => show version 1049 --version => show version
1025 --help => show this help information 1050 --help => show this help information
1026 1051
1027Default options: 1052Default options:
1028 [--email --nogit --git-fallback --m --r --n --l --multiline --pattern-depth=0 1053 [--email --tree --nogit --git-fallback --m --r --n --l --multiline
1029 --remove-duplicates --rolestats] 1054 --pattern-depth=0 --remove-duplicates --rolestats]
1030 1055
1031Notes: 1056Notes:
1032 Using "-f directory" may give unexpected results: 1057 Using "-f directory" may give unexpected results:
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh
index a18bca720995..593f8879c641 100755
--- a/scripts/headers_install.sh
+++ b/scripts/headers_install.sh
@@ -31,13 +31,13 @@ trap 'rm -f "$OUTDIR/$FILE" "$OUTDIR/$FILE.sed"' EXIT
31for i in "$@" 31for i in "$@"
32do 32do
33 FILE="$(basename "$i")" 33 FILE="$(basename "$i")"
34 sed -r \ 34 sed -E \
35 -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \ 35 -e 's/([[:space:](])(__user|__force|__iomem)[[:space:]]/\1/g' \
36 -e 's/__attribute_const__([ \t]|$)/\1/g' \ 36 -e 's/__attribute_const__([[:space:]]|$)/\1/g' \
37 -e 's@^#include <linux/compiler(|_types).h>@@' \ 37 -e 's@^#include <linux/compiler(|_types).h>@@' \
38 -e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \ 38 -e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \
39 -e 's/(^|[ \t(])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \ 39 -e 's/(^|[[:space:](])(inline|asm|volatile)([[:space:](]|$)/\1__\2__\3/g' \
40 -e 's@#(ifndef|define|endif[ \t]*/[*])[ \t]*_UAPI@#\1 @' \ 40 -e 's@#(ifndef|define|endif[[:space:]]*/[*])[[:space:]]*_UAPI@#\1 @' \
41 "$SRCDIR/$i" > "$OUTDIR/$FILE.sed" || exit 1 41 "$SRCDIR/$i" > "$OUTDIR/$FILE.sed" || exit 1
42 scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$FILE.sed" \ 42 scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$FILE.sed" \
43 > "$OUTDIR/$FILE" 43 > "$OUTDIR/$FILE"
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 65792650c630..109a1af7e444 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -48,8 +48,6 @@ static unsigned long long relative_base;
48static struct addr_range text_ranges[] = { 48static struct addr_range text_ranges[] = {
49 { "_stext", "_etext" }, 49 { "_stext", "_etext" },
50 { "_sinittext", "_einittext" }, 50 { "_sinittext", "_einittext" },
51 { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */
52 { "_stext_l2", "_etext_l2" }, /* Blackfin on-chip L2 SRAM */
53}; 51};
54#define text_range_text (&text_ranges[0]) 52#define text_range_text (&text_ranges[0])
55#define text_range_inittext (&text_ranges[1]) 53#define text_range_inittext (&text_ranges[1])
@@ -62,7 +60,6 @@ static struct sym_entry *table;
62static unsigned int table_size, table_cnt; 60static unsigned int table_size, table_cnt;
63static int all_symbols = 0; 61static int all_symbols = 0;
64static int absolute_percpu = 0; 62static int absolute_percpu = 0;
65static char symbol_prefix_char = '\0';
66static int base_relative = 0; 63static int base_relative = 0;
67 64
68int token_profit[0x10000]; 65int token_profit[0x10000];
@@ -75,7 +72,6 @@ unsigned char best_table_len[256];
75static void usage(void) 72static void usage(void)
76{ 73{
77 fprintf(stderr, "Usage: kallsyms [--all-symbols] " 74 fprintf(stderr, "Usage: kallsyms [--all-symbols] "
78 "[--symbol-prefix=<prefix char>] "
79 "[--base-relative] < in.map > out.S\n"); 75 "[--base-relative] < in.map > out.S\n");
80 exit(1); 76 exit(1);
81} 77}
@@ -113,28 +109,22 @@ static int check_symbol_range(const char *sym, unsigned long long addr,
113 109
114static int read_symbol(FILE *in, struct sym_entry *s) 110static int read_symbol(FILE *in, struct sym_entry *s)
115{ 111{
116 char str[500]; 112 char sym[500], stype;
117 char *sym, stype;
118 int rc; 113 int rc;
119 114
120 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); 115 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, sym);
121 if (rc != 3) { 116 if (rc != 3) {
122 if (rc != EOF && fgets(str, 500, in) == NULL) 117 if (rc != EOF && fgets(sym, 500, in) == NULL)
123 fprintf(stderr, "Read error or end of file.\n"); 118 fprintf(stderr, "Read error or end of file.\n");
124 return -1; 119 return -1;
125 } 120 }
126 if (strlen(str) > KSYM_NAME_LEN) { 121 if (strlen(sym) > KSYM_NAME_LEN) {
127 fprintf(stderr, "Symbol %s too long for kallsyms (%zu vs %d).\n" 122 fprintf(stderr, "Symbol %s too long for kallsyms (%zu vs %d).\n"
128 "Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n", 123 "Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n",
129 str, strlen(str), KSYM_NAME_LEN); 124 sym, strlen(sym), KSYM_NAME_LEN);
130 return -1; 125 return -1;
131 } 126 }
132 127
133 sym = str;
134 /* skip prefix char */
135 if (symbol_prefix_char && str[0] == symbol_prefix_char)
136 sym++;
137
138 /* Ignore most absolute/undefined (?) symbols. */ 128 /* Ignore most absolute/undefined (?) symbols. */
139 if (strcmp(sym, "_text") == 0) 129 if (strcmp(sym, "_text") == 0)
140 _text = s->addr; 130 _text = s->addr;
@@ -155,7 +145,7 @@ static int read_symbol(FILE *in, struct sym_entry *s)
155 is_arm_mapping_symbol(sym)) 145 is_arm_mapping_symbol(sym))
156 return -1; 146 return -1;
157 /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */ 147 /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */
158 else if (str[0] == '$') 148 else if (sym[0] == '$')
159 return -1; 149 return -1;
160 /* exclude debugging symbols */ 150 /* exclude debugging symbols */
161 else if (stype == 'N' || stype == 'n') 151 else if (stype == 'N' || stype == 'n')
@@ -163,14 +153,14 @@ static int read_symbol(FILE *in, struct sym_entry *s)
163 153
164 /* include the type field in the symbol name, so that it gets 154 /* include the type field in the symbol name, so that it gets
165 * compressed together */ 155 * compressed together */
166 s->len = strlen(str) + 1; 156 s->len = strlen(sym) + 1;
167 s->sym = malloc(s->len + 1); 157 s->sym = malloc(s->len + 1);
168 if (!s->sym) { 158 if (!s->sym) {
169 fprintf(stderr, "kallsyms failure: " 159 fprintf(stderr, "kallsyms failure: "
170 "unable to allocate required amount of memory\n"); 160 "unable to allocate required amount of memory\n");
171 exit(EXIT_FAILURE); 161 exit(EXIT_FAILURE);
172 } 162 }
173 strcpy((char *)s->sym + 1, str); 163 strcpy((char *)s->sym + 1, sym);
174 s->sym[0] = stype; 164 s->sym[0] = stype;
175 165
176 s->percpu_absolute = 0; 166 s->percpu_absolute = 0;
@@ -221,6 +211,7 @@ static int symbol_valid(struct sym_entry *s)
221 211
222 static char *special_prefixes[] = { 212 static char *special_prefixes[] = {
223 "__crc_", /* modversions */ 213 "__crc_", /* modversions */
214 "__efistub_", /* arm64 EFI stub namespace */
224 NULL }; 215 NULL };
225 216
226 static char *special_suffixes[] = { 217 static char *special_suffixes[] = {
@@ -232,11 +223,6 @@ static int symbol_valid(struct sym_entry *s)
232 int i; 223 int i;
233 char *sym_name = (char *)s->sym + 1; 224 char *sym_name = (char *)s->sym + 1;
234 225
235 /* skip prefix char */
236 if (symbol_prefix_char && *sym_name == symbol_prefix_char)
237 sym_name++;
238
239
240 /* if --all-symbols is not specified, then symbols outside the text 226 /* if --all-symbols is not specified, then symbols outside the text
241 * and inittext sections are discarded */ 227 * and inittext sections are discarded */
242 if (!all_symbols) { 228 if (!all_symbols) {
@@ -301,15 +287,9 @@ static void read_map(FILE *in)
301 287
302static void output_label(char *label) 288static void output_label(char *label)
303{ 289{
304 if (symbol_prefix_char) 290 printf(".globl %s\n", label);
305 printf(".globl %c%s\n", symbol_prefix_char, label);
306 else
307 printf(".globl %s\n", label);
308 printf("\tALGN\n"); 291 printf("\tALGN\n");
309 if (symbol_prefix_char) 292 printf("%s:\n", label);
310 printf("%c%s:\n", symbol_prefix_char, label);
311 else
312 printf("%s:\n", label);
313} 293}
314 294
315/* uncompress a compressed symbol. When this function is called, the best table 295/* uncompress a compressed symbol. When this function is called, the best table
@@ -423,7 +403,7 @@ static void write_src(void)
423 } 403 }
424 404
425 output_label("kallsyms_num_syms"); 405 output_label("kallsyms_num_syms");
426 printf("\tPTR\t%d\n", table_cnt); 406 printf("\t.long\t%u\n", table_cnt);
427 printf("\n"); 407 printf("\n");
428 408
429 /* table of offset markers, that give the offset in the compressed stream 409 /* table of offset markers, that give the offset in the compressed stream
@@ -452,7 +432,7 @@ static void write_src(void)
452 432
453 output_label("kallsyms_markers"); 433 output_label("kallsyms_markers");
454 for (i = 0; i < ((table_cnt + 255) >> 8); i++) 434 for (i = 0; i < ((table_cnt + 255) >> 8); i++)
455 printf("\tPTR\t%d\n", markers[i]); 435 printf("\t.long\t%u\n", markers[i]);
456 printf("\n"); 436 printf("\n");
457 437
458 free(markers); 438 free(markers);
@@ -767,13 +747,7 @@ int main(int argc, char **argv)
767 all_symbols = 1; 747 all_symbols = 1;
768 else if (strcmp(argv[i], "--absolute-percpu") == 0) 748 else if (strcmp(argv[i], "--absolute-percpu") == 0)
769 absolute_percpu = 1; 749 absolute_percpu = 1;
770 else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) { 750 else if (strcmp(argv[i], "--base-relative") == 0)
771 char *p = &argv[i][16];
772 /* skip quote */
773 if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
774 p++;
775 symbol_prefix_char = *p;
776 } else if (strcmp(argv[i], "--base-relative") == 0)
777 base_relative = 1; 751 base_relative = 1;
778 else 752 else
779 usage(); 753 usage();
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index a76856e559c0..0aabc1d6a182 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -1,13 +1,7 @@
1# 1#
2# Generated files 2# Generated files
3# 3#
4*.lex.c
5*.tab.c
6*.tab.h
7*.moc 4*.moc
8gconf.glade.h
9*.pot
10*.mo
11 5
12# 6#
13# configuration programs 7# configuration programs
@@ -17,4 +11,3 @@ mconf
17nconf 11nconf
18qconf 12qconf
19gconf 13gconf
20kxgettext
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index cb3ec53a7c29..63b609243d03 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -3,8 +3,8 @@
3# Kernel configuration targets 3# Kernel configuration targets
4# These targets are used from top-level makefile 4# These targets are used from top-level makefile
5 5
6PHONY += xconfig gconfig menuconfig config silentoldconfig update-po-config \ 6PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig \
7 localmodconfig localyesconfig 7 build_menuconfig build_nconfig build_gconfig build_xconfig
8 8
9ifdef KBUILD_KCONFIG 9ifdef KBUILD_KCONFIG
10Kconfig := $(KBUILD_KCONFIG) 10Kconfig := $(KBUILD_KCONFIG)
@@ -34,68 +34,41 @@ config: $(obj)/conf
34nconfig: $(obj)/nconf 34nconfig: $(obj)/nconf
35 $< $(silent) $(Kconfig) 35 $< $(silent) $(Kconfig)
36 36
37# This has become an internal implementation detail and is now deprecated 37build_menuconfig: $(obj)/mconf
38# for external use. 38
39silentoldconfig: $(obj)/conf 39build_nconfig: $(obj)/nconf
40 $(Q)mkdir -p include/config include/generated 40
41 $(Q)test -e include/generated/autoksyms.h || \ 41build_gconfig: $(obj)/gconf
42 touch include/generated/autoksyms.h
43 $< $(silent) --$@ $(Kconfig)
44 42
45localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 43build_xconfig: $(obj)/qconf
46 $(Q)mkdir -p include/config include/generated 44
47 $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config 45localyesconfig localmodconfig: $(obj)/conf
46 $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config
48 $(Q)if [ -f .config ]; then \ 47 $(Q)if [ -f .config ]; then \
49 cmp -s .tmp.config .config || \ 48 cmp -s .tmp.config .config || \
50 (mv -f .config .config.old.1; \ 49 (mv -f .config .config.old.1; \
51 mv -f .tmp.config .config; \ 50 mv -f .tmp.config .config; \
52 $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \ 51 $< $(silent) --oldconfig $(Kconfig); \
53 mv -f .config.old.1 .config.old) \ 52 mv -f .config.old.1 .config.old) \
54 else \ 53 else \
55 mv -f .tmp.config .config; \ 54 mv -f .tmp.config .config; \
56 $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \ 55 $< $(silent) --oldconfig $(Kconfig); \
57 fi 56 fi
58 $(Q)rm -f .tmp.config 57 $(Q)rm -f .tmp.config
59 58
60# Create new linux.pot file
61# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
62update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
63 $(Q)$(kecho) " GEN config.pot"
64 $(Q)xgettext --default-domain=linux \
65 --add-comments --keyword=_ --keyword=N_ \
66 --from-code=UTF-8 \
67 --files-from=$(srctree)/scripts/kconfig/POTFILES.in \
68 --directory=$(srctree) --directory=$(objtree) \
69 --output $(obj)/config.pot
70 $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
71 $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \
72 $(srctree)/arch/*/um/Kconfig`; \
73 do \
74 $(kecho) " GEN $$i"; \
75 $(obj)/kxgettext $$i \
76 >> $(obj)/config.pot; \
77 done )
78 $(Q)$(kecho) " GEN linux.pot"
79 $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
80 --output $(obj)/linux.pot
81 $(Q)rm -f $(obj)/config.pot
82
83# These targets map 1:1 to the commandline options of 'conf' 59# These targets map 1:1 to the commandline options of 'conf'
60#
61# Note:
62# syncconfig has become an internal implementation detail and is now
63# deprecated for external use
84simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \ 64simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
85 alldefconfig randconfig listnewconfig olddefconfig 65 alldefconfig randconfig listnewconfig olddefconfig syncconfig
86PHONY += $(simple-targets) 66PHONY += $(simple-targets)
87 67
88$(simple-targets): $(obj)/conf 68$(simple-targets): $(obj)/conf
89 $< $(silent) --$@ $(Kconfig) 69 $< $(silent) --$@ $(Kconfig)
90 70
91PHONY += oldnoconfig savedefconfig defconfig 71PHONY += savedefconfig defconfig
92
93# oldnoconfig is an alias of olddefconfig, because people already are dependent
94# on its behavior (sets new symbols to their default value but not 'n') with the
95# counter-intuitive name.
96oldnoconfig: olddefconfig
97 @echo " WARNING: \"oldnoconfig\" target will be removed after Linux 4.19"
98 @echo " Please use \"olddefconfig\" instead, which is an alias."
99 72
100savedefconfig: $(obj)/conf 73savedefconfig: $(obj)/conf
101 $< $(silent) --$@=defconfig $(Kconfig) 74 $< $(silent) --$@=defconfig $(Kconfig)
@@ -135,11 +108,18 @@ PHONY += tinyconfig
135tinyconfig: 108tinyconfig:
136 $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config 109 $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
137 110
111# CHECK: -o cache_dir=<path> working?
112PHONY += testconfig
113testconfig: $(obj)/conf
114 $(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \
115 -o cache_dir=$(abspath $(obj)/tests/.cache) \
116 $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no)
117clean-dirs += tests/.cache
118
138# Help text used by make help 119# Help text used by make help
139help: 120help:
140 @echo ' config - Update current config utilising a line-oriented program' 121 @echo ' config - Update current config utilising a line-oriented program'
141 @echo ' nconfig - Update current config utilising a ncurses menu based' 122 @echo ' nconfig - Update current config utilising a ncurses menu based program'
142 @echo ' program'
143 @echo ' menuconfig - Update current config utilising a menu based program' 123 @echo ' menuconfig - Update current config utilising a menu based program'
144 @echo ' xconfig - Update current config utilising a Qt based front-end' 124 @echo ' xconfig - Update current config utilising a Qt based front-end'
145 @echo ' gconfig - Update current config utilising a GTK+ based front-end' 125 @echo ' gconfig - Update current config utilising a GTK+ based front-end'
@@ -159,141 +139,78 @@ help:
159 @echo ' kvmconfig - Enable additional options for kvm guest kernel support' 139 @echo ' kvmconfig - Enable additional options for kvm guest kernel support'
160 @echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support' 140 @echo ' xenconfig - Enable additional options for xen dom0 and guest kernel support'
161 @echo ' tinyconfig - Configure the tiniest possible kernel' 141 @echo ' tinyconfig - Configure the tiniest possible kernel'
162 142 @echo ' testconfig - Run Kconfig unit tests (requires python3 and pytest)'
163# lxdialog stuff
164check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
165
166# Use recursively expanded variables so we do not call gcc unless
167# we really need to do so. (Do not call gcc as part of make mrproper)
168HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
169 -DLOCALE
170 143
171# =========================================================================== 144# ===========================================================================
172# Shared Makefile for the various kconfig executables: 145# Shared Makefile for the various kconfig executables:
173# conf: Used for defconfig, oldconfig and related targets 146# conf: Used for defconfig, oldconfig and related targets
174# nconf: Used for the nconfig target.
175# Utilizes ncurses
176# mconf: Used for the menuconfig target
177# Utilizes the lxdialog package
178# qconf: Used for the xconfig target
179# Based on Qt which needs to be installed to compile it
180# gconf: Used for the gconfig target
181# Based on GTK+ which needs to be installed to compile it
182# object files used by all kconfig flavours 147# object files used by all kconfig flavours
183 148
184lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
185lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
186
187conf-objs := conf.o zconf.tab.o 149conf-objs := conf.o zconf.tab.o
188mconf-objs := mconf.o zconf.tab.o $(lxdialog)
189nconf-objs := nconf.o zconf.tab.o nconf.gui.o
190kxgettext-objs := kxgettext.o zconf.tab.o
191qconf-cxxobjs := qconf.o
192qconf-objs := zconf.tab.o
193gconf-objs := gconf.o zconf.tab.o
194
195hostprogs-y := conf nconf mconf kxgettext qconf gconf
196 150
197targets += zconf.tab.c zconf.lex.c 151hostprogs-y := conf
198clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck
199clean-files += zconf.tab.c zconf.lex.c gconf.glade.h
200clean-files += config.pot linux.pot
201 152
202# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) 153targets += zconf.lex.c
203PHONY += $(obj)/dochecklxdialog
204$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog
205$(obj)/dochecklxdialog:
206 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
207
208always := dochecklxdialog
209
210# Add environment specific flags
211HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
212HOST_EXTRACXXFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCXX) $(HOSTCXXFLAGS))
213 154
214# generated files seem to need this to find local include files 155# generated files seem to need this to find local include files
215HOSTCFLAGS_zconf.lex.o := -I$(src) 156HOSTCFLAGS_zconf.lex.o := -I$(src)
216HOSTCFLAGS_zconf.tab.o := -I$(src) 157HOSTCFLAGS_zconf.tab.o := -I$(src)
217 158
218HOSTLOADLIBES_qconf = $(KC_QT_LIBS) 159# nconf: Used for the nconfig target based on ncurses
219HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) 160hostprogs-y += nconf
220 161nconf-objs := nconf.o zconf.tab.o nconf.gui.o
221HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0`
222HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
223 -Wno-missing-prototypes
224
225HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
226
227HOSTLOADLIBES_nconf = $(shell \
228 pkg-config --libs menuw panelw ncursesw 2>/dev/null \
229 || pkg-config --libs menu panel ncurses 2>/dev/null \
230 || echo "-lmenu -lpanel -lncurses" )
231$(obj)/qconf.o: $(obj)/.tmp_qtcheck
232
233ifeq ($(MAKECMDGOALS),xconfig)
234$(obj)/.tmp_qtcheck: $(src)/Makefile
235-include $(obj)/.tmp_qtcheck
236
237# Qt needs some extra effort...
238$(obj)/.tmp_qtcheck:
239 @set -e; $(kecho) " CHECK qt"; \
240 if pkg-config --exists Qt5Core; then \
241 cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
242 libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
243 moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
244 elif pkg-config --exists QtCore; then \
245 cflags=`pkg-config --cflags QtCore QtGui`; \
246 libs=`pkg-config --libs QtCore QtGui`; \
247 moc=`pkg-config --variable=moc_location QtCore`; \
248 else \
249 echo >&2 "*"; \
250 echo >&2 "* Could not find Qt via pkg-config."; \
251 echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
252 echo >&2 "*"; \
253 exit 1; \
254 fi; \
255 echo "KC_QT_CFLAGS=$$cflags" > $@; \
256 echo "KC_QT_LIBS=$$libs" >> $@; \
257 echo "KC_QT_MOC=$$moc" >> $@
258endif
259 162
260$(obj)/gconf.o: $(obj)/.tmp_gtkcheck 163HOSTLDLIBS_nconf = $(shell . $(obj)/.nconf-cfg && echo $$libs)
261 164HOSTCFLAGS_nconf.o = $(shell . $(obj)/.nconf-cfg && echo $$cflags)
262ifeq ($(MAKECMDGOALS),gconfig) 165HOSTCFLAGS_nconf.gui.o = $(shell . $(obj)/.nconf-cfg && echo $$cflags)
263-include $(obj)/.tmp_gtkcheck
264
265# GTK+ needs some extra effort, too...
266$(obj)/.tmp_gtkcheck:
267 @if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \
268 if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \
269 touch $@; \
270 else \
271 echo >&2 "*"; \
272 echo >&2 "* GTK+ is present but version >= 2.0.0 is required."; \
273 echo >&2 "*"; \
274 false; \
275 fi \
276 else \
277 echo >&2 "*"; \
278 echo >&2 "* Unable to find the GTK+ installation. Please make sure that"; \
279 echo >&2 "* the GTK+ 2.0 development package is correctly installed..."; \
280 echo >&2 "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \
281 echo >&2 "*"; \
282 false; \
283 fi
284endif
285 166
286$(obj)/zconf.tab.o: $(obj)/zconf.lex.c 167$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/.nconf-cfg
168
169# mconf: Used for the menuconfig target based on lxdialog
170hostprogs-y += mconf
171lxdialog := checklist.o inputbox.o menubox.o textbox.o util.o yesno.o
172mconf-objs := mconf.o zconf.tab.o $(addprefix lxdialog/, $(lxdialog))
173
174HOSTLDLIBS_mconf = $(shell . $(obj)/.mconf-cfg && echo $$libs)
175$(foreach f, mconf.o $(lxdialog), \
176 $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/.mconf-cfg && echo $$$$cflags)))
177
178$(obj)/mconf.o: $(obj)/.mconf-cfg
179$(addprefix $(obj)/lxdialog/, $(lxdialog)): $(obj)/.mconf-cfg
180
181# qconf: Used for the xconfig target based on Qt
182hostprogs-y += qconf
183qconf-cxxobjs := qconf.o
184qconf-objs := zconf.tab.o
185
186HOSTLDLIBS_qconf = $(shell . $(obj)/.qconf-cfg && echo $$libs)
187HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/.qconf-cfg && echo $$cflags)
287 188
288$(obj)/qconf.o: $(obj)/qconf.moc 189$(obj)/qconf.o: $(obj)/.qconf-cfg $(obj)/qconf.moc
289 190
290quiet_cmd_moc = MOC $@ 191quiet_cmd_moc = MOC $@
291 cmd_moc = $(KC_QT_MOC) -i $< -o $@ 192 cmd_moc = $(shell . $(obj)/.qconf-cfg && echo $$moc) -i $< -o $@
292 193
293$(obj)/%.moc: $(src)/%.h $(obj)/.tmp_qtcheck 194$(obj)/%.moc: $(src)/%.h $(obj)/.qconf-cfg
294 $(call cmd,moc) 195 $(call cmd,moc)
295 196
296# Extract gconf menu items for i18n support 197# gconf: Used for the gconfig target based on GTK+
297$(obj)/gconf.glade.h: $(obj)/gconf.glade 198hostprogs-y += gconf
298 $(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \ 199gconf-objs := gconf.o zconf.tab.o
299 $(obj)/gconf.glade 200
201HOSTLDLIBS_gconf = $(shell . $(obj)/.gconf-cfg && echo $$libs)
202HOSTCFLAGS_gconf.o = $(shell . $(obj)/.gconf-cfg && echo $$cflags)
203
204$(obj)/gconf.o: $(obj)/.gconf-cfg
205
206$(obj)/zconf.tab.o: $(obj)/zconf.lex.c
207
208# check if necessary packages are available, and configure build flags
209define filechk_conf_cfg
210 $(CONFIG_SHELL) $<
211endef
212
213$(obj)/.%conf-cfg: $(src)/%conf-cfg.sh FORCE
214 $(call filechk,conf_cfg)
215
216clean-files += .*conf-cfg
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in
deleted file mode 100644
index 967457396990..000000000000
--- a/scripts/kconfig/POTFILES.in
+++ /dev/null
@@ -1,12 +0,0 @@
1scripts/kconfig/lxdialog/checklist.c
2scripts/kconfig/lxdialog/inputbox.c
3scripts/kconfig/lxdialog/menubox.c
4scripts/kconfig/lxdialog/textbox.c
5scripts/kconfig/lxdialog/util.c
6scripts/kconfig/lxdialog/yesno.c
7scripts/kconfig/mconf.c
8scripts/kconfig/conf.c
9scripts/kconfig/confdata.c
10scripts/kconfig/gconf.c
11scripts/kconfig/gconf.glade.h
12scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
deleted file mode 100755
index 97f0fee7d173..000000000000
--- a/scripts/kconfig/check.sh
+++ /dev/null
@@ -1,14 +0,0 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# Needed for systems without gettext
4$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
5#include <libintl.h>
6int main()
7{
8 gettext("");
9 return 0;
10}
11EOF
12if [ ! "$?" -eq "0" ]; then
13 echo -DKBUILD_NO_NLS;
14fi
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 822dc51923d6..98e0c7a34699 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -3,7 +3,6 @@
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <locale.h>
7#include <ctype.h> 6#include <ctype.h>
8#include <limits.h> 7#include <limits.h>
9#include <stdio.h> 8#include <stdio.h>
@@ -23,7 +22,7 @@ static void check_conf(struct menu *menu);
23 22
24enum input_mode { 23enum input_mode {
25 oldaskconfig, 24 oldaskconfig,
26 silentoldconfig, 25 syncconfig,
27 oldconfig, 26 oldconfig,
28 allnoconfig, 27 allnoconfig,
29 allyesconfig, 28 allyesconfig,
@@ -86,7 +85,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
86 enum symbol_type type = sym_get_type(sym); 85 enum symbol_type type = sym_get_type(sym);
87 86
88 if (!sym_has_value(sym)) 87 if (!sym_has_value(sym))
89 printf(_("(NEW) ")); 88 printf("(NEW) ");
90 89
91 line[0] = '\n'; 90 line[0] = '\n';
92 line[1] = 0; 91 line[1] = 0;
@@ -100,7 +99,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
100 99
101 switch (input_mode) { 100 switch (input_mode) {
102 case oldconfig: 101 case oldconfig:
103 case silentoldconfig: 102 case syncconfig:
104 if (sym_has_value(sym)) { 103 if (sym_has_value(sym)) {
105 printf("%s\n", def); 104 printf("%s\n", def);
106 return 0; 105 return 0;
@@ -133,7 +132,7 @@ static int conf_string(struct menu *menu)
133 const char *def; 132 const char *def;
134 133
135 while (1) { 134 while (1) {
136 printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); 135 printf("%*s%s ", indent - 1, "", menu->prompt->text);
137 printf("(%s) ", sym->name); 136 printf("(%s) ", sym->name);
138 def = sym_get_string_value(sym); 137 def = sym_get_string_value(sym);
139 if (sym_get_string_value(sym)) 138 if (sym_get_string_value(sym))
@@ -166,7 +165,7 @@ static int conf_sym(struct menu *menu)
166 tristate oldval, newval; 165 tristate oldval, newval;
167 166
168 while (1) { 167 while (1) {
169 printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); 168 printf("%*s%s ", indent - 1, "", menu->prompt->text);
170 if (sym->name) 169 if (sym->name)
171 printf("(%s) ", sym->name); 170 printf("(%s) ", sym->name);
172 putchar('['); 171 putchar('[');
@@ -251,7 +250,7 @@ static int conf_choice(struct menu *menu)
251 case no: 250 case no:
252 return 1; 251 return 1;
253 case mod: 252 case mod:
254 printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); 253 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
255 return 0; 254 return 0;
256 case yes: 255 case yes:
257 break; 256 break;
@@ -261,7 +260,7 @@ static int conf_choice(struct menu *menu)
261 while (1) { 260 while (1) {
262 int cnt, def; 261 int cnt, def;
263 262
264 printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); 263 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
265 def_sym = sym_get_choice_value(sym); 264 def_sym = sym_get_choice_value(sym);
266 cnt = def = 0; 265 cnt = def = 0;
267 line[0] = 0; 266 line[0] = 0;
@@ -269,7 +268,7 @@ static int conf_choice(struct menu *menu)
269 if (!menu_is_visible(child)) 268 if (!menu_is_visible(child))
270 continue; 269 continue;
271 if (!child->sym) { 270 if (!child->sym) {
272 printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); 271 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
273 continue; 272 continue;
274 } 273 }
275 cnt++; 274 cnt++;
@@ -278,14 +277,14 @@ static int conf_choice(struct menu *menu)
278 printf("%*c", indent, '>'); 277 printf("%*c", indent, '>');
279 } else 278 } else
280 printf("%*c", indent, ' '); 279 printf("%*c", indent, ' ');
281 printf(" %d. %s", cnt, _(menu_get_prompt(child))); 280 printf(" %d. %s", cnt, menu_get_prompt(child));
282 if (child->sym->name) 281 if (child->sym->name)
283 printf(" (%s)", child->sym->name); 282 printf(" (%s)", child->sym->name);
284 if (!sym_has_value(child->sym)) 283 if (!sym_has_value(child->sym))
285 printf(_(" (NEW)")); 284 printf(" (NEW)");
286 printf("\n"); 285 printf("\n");
287 } 286 }
288 printf(_("%*schoice"), indent - 1, ""); 287 printf("%*schoice", indent - 1, "");
289 if (cnt == 1) { 288 if (cnt == 1) {
290 printf("[1]: 1\n"); 289 printf("[1]: 1\n");
291 goto conf_childs; 290 goto conf_childs;
@@ -293,7 +292,7 @@ static int conf_choice(struct menu *menu)
293 printf("[1-%d?]: ", cnt); 292 printf("[1-%d?]: ", cnt);
294 switch (input_mode) { 293 switch (input_mode) {
295 case oldconfig: 294 case oldconfig:
296 case silentoldconfig: 295 case syncconfig:
297 if (!is_new) { 296 if (!is_new) {
298 cnt = def; 297 cnt = def;
299 printf("%d\n", cnt); 298 printf("%d\n", cnt);
@@ -358,10 +357,11 @@ static void conf(struct menu *menu)
358 357
359 switch (prop->type) { 358 switch (prop->type) {
360 case P_MENU: 359 case P_MENU:
361 if ((input_mode == silentoldconfig || 360 /*
362 input_mode == listnewconfig || 361 * Except in oldaskconfig mode, we show only menus that
363 input_mode == olddefconfig) && 362 * contain new symbols.
364 rootEntry != menu) { 363 */
364 if (input_mode != oldaskconfig && rootEntry != menu) {
365 check_conf(menu); 365 check_conf(menu);
366 return; 366 return;
367 } 367 }
@@ -371,7 +371,7 @@ static void conf(struct menu *menu)
371 if (prompt) 371 if (prompt)
372 printf("%*c\n%*c %s\n%*c\n", 372 printf("%*c\n%*c %s\n%*c\n",
373 indent, '*', 373 indent, '*',
374 indent, '*', _(prompt), 374 indent, '*', prompt,
375 indent, '*'); 375 indent, '*');
376 default: 376 default:
377 ; 377 ;
@@ -421,12 +421,22 @@ static void check_conf(struct menu *menu)
421 if (sym_is_changable(sym) || 421 if (sym_is_changable(sym) ||
422 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { 422 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
423 if (input_mode == listnewconfig) { 423 if (input_mode == listnewconfig) {
424 if (sym->name && !sym_is_choice_value(sym)) { 424 if (sym->name) {
425 printf("%s%s\n", CONFIG_, sym->name); 425 const char *str;
426
427 if (sym->type == S_STRING) {
428 str = sym_get_string_value(sym);
429 str = sym_escape_string_value(str);
430 printf("%s%s=%s\n", CONFIG_, sym->name, str);
431 free((void *)str);
432 } else {
433 str = sym_get_string_value(sym);
434 printf("%s%s=%s\n", CONFIG_, sym->name, str);
435 }
426 } 436 }
427 } else if (input_mode != olddefconfig) { 437 } else {
428 if (!conf_cnt++) 438 if (!conf_cnt++)
429 printf(_("*\n* Restart config...\n*\n")); 439 printf("*\n* Restart config...\n*\n");
430 rootEntry = menu_get_parent_menu(menu); 440 rootEntry = menu_get_parent_menu(menu);
431 conf(rootEntry); 441 conf(rootEntry);
432 } 442 }
@@ -440,7 +450,7 @@ static void check_conf(struct menu *menu)
440static struct option long_opts[] = { 450static struct option long_opts[] = {
441 {"oldaskconfig", no_argument, NULL, oldaskconfig}, 451 {"oldaskconfig", no_argument, NULL, oldaskconfig},
442 {"oldconfig", no_argument, NULL, oldconfig}, 452 {"oldconfig", no_argument, NULL, oldconfig},
443 {"silentoldconfig", no_argument, NULL, silentoldconfig}, 453 {"syncconfig", no_argument, NULL, syncconfig},
444 {"defconfig", optional_argument, NULL, defconfig}, 454 {"defconfig", optional_argument, NULL, defconfig},
445 {"savedefconfig", required_argument, NULL, savedefconfig}, 455 {"savedefconfig", required_argument, NULL, savedefconfig},
446 {"allnoconfig", no_argument, NULL, allnoconfig}, 456 {"allnoconfig", no_argument, NULL, allnoconfig},
@@ -450,12 +460,6 @@ static struct option long_opts[] = {
450 {"randconfig", no_argument, NULL, randconfig}, 460 {"randconfig", no_argument, NULL, randconfig},
451 {"listnewconfig", no_argument, NULL, listnewconfig}, 461 {"listnewconfig", no_argument, NULL, listnewconfig},
452 {"olddefconfig", no_argument, NULL, olddefconfig}, 462 {"olddefconfig", no_argument, NULL, olddefconfig},
453 /*
454 * oldnoconfig is an alias of olddefconfig, because people already
455 * are dependent on its behavior(sets new symbols to their default
456 * value but not 'n') with the counter-intuitive name.
457 */
458 {"oldnoconfig", no_argument, NULL, olddefconfig},
459 {NULL, 0, NULL, 0} 463 {NULL, 0, NULL, 0}
460}; 464};
461 465
@@ -467,10 +471,9 @@ static void conf_usage(const char *progname)
467 printf(" --listnewconfig List new options\n"); 471 printf(" --listnewconfig List new options\n");
468 printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); 472 printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
469 printf(" --oldconfig Update a configuration using a provided .config as base\n"); 473 printf(" --oldconfig Update a configuration using a provided .config as base\n");
470 printf(" --silentoldconfig Similar to oldconfig but generates configuration in\n" 474 printf(" --syncconfig Similar to oldconfig but generates configuration in\n"
471 " include/{generated/,config/} (oldconfig used to be more verbose)\n"); 475 " include/{generated/,config/}\n");
472 printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n"); 476 printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n");
473 printf(" --oldnoconfig An alias of olddefconfig\n");
474 printf(" --defconfig <file> New config with default defined in <file>\n"); 477 printf(" --defconfig <file> New config with default defined in <file>\n");
475 printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n"); 478 printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
476 printf(" --allnoconfig New config where all options are answered with no\n"); 479 printf(" --allnoconfig New config where all options are answered with no\n");
@@ -486,10 +489,7 @@ int main(int ac, char **av)
486 int opt; 489 int opt;
487 const char *name, *defconfig_file = NULL /* gcc uninit */; 490 const char *name, *defconfig_file = NULL /* gcc uninit */;
488 struct stat tmpstat; 491 struct stat tmpstat;
489 492 int no_conf_write = 0;
490 setlocale(LC_ALL, "");
491 bindtextdomain(PACKAGE, LOCALEDIR);
492 textdomain(PACKAGE);
493 493
494 tty_stdio = isatty(0) && isatty(1); 494 tty_stdio = isatty(0) && isatty(1);
495 495
@@ -500,7 +500,12 @@ int main(int ac, char **av)
500 } 500 }
501 input_mode = (enum input_mode)opt; 501 input_mode = (enum input_mode)opt;
502 switch (opt) { 502 switch (opt) {
503 case silentoldconfig: 503 case syncconfig:
504 /*
505 * syncconfig is invoked during the build stage.
506 * Suppress distracting "configuration written to ..."
507 */
508 conf_set_message_callback(NULL);
504 sync_kconfig = 1; 509 sync_kconfig = 1;
505 break; 510 break;
506 case defconfig: 511 case defconfig:
@@ -548,7 +553,7 @@ int main(int ac, char **av)
548 } 553 }
549 } 554 }
550 if (ac == optind) { 555 if (ac == optind) {
551 fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]); 556 fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
552 conf_usage(progname); 557 conf_usage(progname);
553 exit(1); 558 exit(1);
554 } 559 }
@@ -558,12 +563,12 @@ int main(int ac, char **av)
558 if (sync_kconfig) { 563 if (sync_kconfig) {
559 name = conf_get_configname(); 564 name = conf_get_configname();
560 if (stat(name, &tmpstat)) { 565 if (stat(name, &tmpstat)) {
561 fprintf(stderr, _("***\n" 566 fprintf(stderr, "***\n"
562 "*** Configuration file \"%s\" not found!\n" 567 "*** Configuration file \"%s\" not found!\n"
563 "***\n" 568 "***\n"
564 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 569 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
565 "*** \"make menuconfig\" or \"make xconfig\").\n" 570 "*** \"make menuconfig\" or \"make xconfig\").\n"
566 "***\n"), name); 571 "***\n", name);
567 exit(1); 572 exit(1);
568 } 573 }
569 } 574 }
@@ -574,15 +579,15 @@ int main(int ac, char **av)
574 defconfig_file = conf_get_default_confname(); 579 defconfig_file = conf_get_default_confname();
575 if (conf_read(defconfig_file)) { 580 if (conf_read(defconfig_file)) {
576 fprintf(stderr, 581 fprintf(stderr,
577 _("***\n" 582 "***\n"
578 "*** Can't find default configuration \"%s\"!\n" 583 "*** Can't find default configuration \"%s\"!\n"
579 "***\n"), 584 "***\n",
580 defconfig_file); 585 defconfig_file);
581 exit(1); 586 exit(1);
582 } 587 }
583 break; 588 break;
584 case savedefconfig: 589 case savedefconfig:
585 case silentoldconfig: 590 case syncconfig:
586 case oldaskconfig: 591 case oldaskconfig:
587 case oldconfig: 592 case oldconfig:
588 case listnewconfig: 593 case listnewconfig:
@@ -600,7 +605,7 @@ int main(int ac, char **av)
600 if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { 605 if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
601 if (conf_read_simple(name, S_DEF_USER)) { 606 if (conf_read_simple(name, S_DEF_USER)) {
602 fprintf(stderr, 607 fprintf(stderr,
603 _("*** Can't read seed configuration \"%s\"!\n"), 608 "*** Can't read seed configuration \"%s\"!\n",
604 name); 609 name);
605 exit(1); 610 exit(1);
606 } 611 }
@@ -617,7 +622,7 @@ int main(int ac, char **av)
617 if (conf_read_simple(name, S_DEF_USER) && 622 if (conf_read_simple(name, S_DEF_USER) &&
618 conf_read_simple("all.config", S_DEF_USER)) { 623 conf_read_simple("all.config", S_DEF_USER)) {
619 fprintf(stderr, 624 fprintf(stderr,
620 _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), 625 "*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
621 name); 626 name);
622 exit(1); 627 exit(1);
623 } 628 }
@@ -627,13 +632,14 @@ int main(int ac, char **av)
627 } 632 }
628 633
629 if (sync_kconfig) { 634 if (sync_kconfig) {
630 if (conf_get_changed()) { 635 name = getenv("KCONFIG_NOSILENTUPDATE");
631 name = getenv("KCONFIG_NOSILENTUPDATE"); 636 if (name && *name) {
632 if (name && *name) { 637 if (conf_get_changed()) {
633 fprintf(stderr, 638 fprintf(stderr,
634 _("\n*** The configuration requires explicit update.\n\n")); 639 "\n*** The configuration requires explicit update.\n\n");
635 return 1; 640 return 1;
636 } 641 }
642 no_conf_write = 1;
637 } 643 }
638 } 644 }
639 645
@@ -662,45 +668,48 @@ int main(int ac, char **av)
662 case oldaskconfig: 668 case oldaskconfig:
663 rootEntry = &rootmenu; 669 rootEntry = &rootmenu;
664 conf(&rootmenu); 670 conf(&rootmenu);
665 input_mode = silentoldconfig; 671 input_mode = oldconfig;
666 /* fall through */ 672 /* fall through */
667 case oldconfig: 673 case oldconfig:
668 case listnewconfig: 674 case listnewconfig:
669 case olddefconfig: 675 case syncconfig:
670 case silentoldconfig:
671 /* Update until a loop caused no more changes */ 676 /* Update until a loop caused no more changes */
672 do { 677 do {
673 conf_cnt = 0; 678 conf_cnt = 0;
674 check_conf(&rootmenu); 679 check_conf(&rootmenu);
675 } while (conf_cnt && 680 } while (conf_cnt);
676 (input_mode != listnewconfig && 681 break;
677 input_mode != olddefconfig)); 682 case olddefconfig:
683 default:
678 break; 684 break;
679 } 685 }
680 686
681 if (sync_kconfig) { 687 if (input_mode == savedefconfig) {
682 /* silentoldconfig is used during the build so we shall update autoconf.
683 * All other commands are only used to generate a config.
684 */
685 if (conf_get_changed() && conf_write(NULL)) {
686 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
687 exit(1);
688 }
689 if (conf_write_autoconf()) {
690 fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
691 return 1;
692 }
693 } else if (input_mode == savedefconfig) {
694 if (conf_write_defconfig(defconfig_file)) { 688 if (conf_write_defconfig(defconfig_file)) {
695 fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), 689 fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
696 defconfig_file); 690 defconfig_file);
697 return 1; 691 return 1;
698 } 692 }
699 } else if (input_mode != listnewconfig) { 693 } else if (input_mode != listnewconfig) {
700 if (conf_write(NULL)) { 694 if (!no_conf_write && conf_write(NULL)) {
701 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); 695 fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
702 exit(1); 696 exit(1);
703 } 697 }
698
699 /*
700 * Create auto.conf if it does not exist.
701 * This prevents GNU Make 4.1 or older from emitting
702 * "include/config/auto.conf: No such file or directory"
703 * in the top-level Makefile
704 *
705 * syncconfig always creates or updates auto.conf because it is
706 * used during the build.
707 */
708 if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
709 fprintf(stderr,
710 "\n*** Error during sync of the configuration.\n\n");
711 return 1;
712 }
704 } 713 }
705 return 0; 714 return 0;
706} 715}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index df26c7b0fe13..91d0a5c014ac 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -16,6 +16,64 @@
16 16
17#include "lkc.h" 17#include "lkc.h"
18 18
19/* return true if 'path' exists, false otherwise */
20static bool is_present(const char *path)
21{
22 struct stat st;
23
24 return !stat(path, &st);
25}
26
27/* return true if 'path' exists and it is a directory, false otherwise */
28static bool is_dir(const char *path)
29{
30 struct stat st;
31
32 if (stat(path, &st))
33 return 0;
34
35 return S_ISDIR(st.st_mode);
36}
37
38/*
39 * Create the parent directory of the given path.
40 *
41 * For example, if 'include/config/auto.conf' is given, create 'include/config'.
42 */
43static int make_parent_dir(const char *path)
44{
45 char tmp[PATH_MAX + 1];
46 char *p;
47
48 strncpy(tmp, path, sizeof(tmp));
49 tmp[sizeof(tmp) - 1] = 0;
50
51 /* Remove the base name. Just return if nothing is left */
52 p = strrchr(tmp, '/');
53 if (!p)
54 return 0;
55 *(p + 1) = 0;
56
57 /* Just in case it is an absolute path */
58 p = tmp;
59 while (*p == '/')
60 p++;
61
62 while ((p = strchr(p, '/'))) {
63 *p = 0;
64
65 /* skip if the directory exists */
66 if (!is_dir(tmp) && mkdir(tmp, 0755))
67 return -1;
68
69 *p = '/';
70 while (*p == '/')
71 p++;
72 }
73
74 return 0;
75}
76
19struct conf_printer { 77struct conf_printer {
20 void (*print_symbol)(FILE *, struct symbol *, const char *, void *); 78 void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
21 void (*print_comment)(FILE *, const char *, void *); 79 void (*print_comment)(FILE *, const char *, void *);
@@ -30,7 +88,7 @@ static void conf_message(const char *fmt, ...)
30static const char *conf_filename; 88static const char *conf_filename;
31static int conf_lineno, conf_warnings; 89static int conf_lineno, conf_warnings;
32 90
33const char conf_defname[] = "arch/$ARCH/defconfig"; 91const char conf_defname[] = "arch/$(ARCH)/defconfig";
34 92
35static void conf_warning(const char *fmt, ...) 93static void conf_warning(const char *fmt, ...)
36{ 94{
@@ -43,16 +101,16 @@ static void conf_warning(const char *fmt, ...)
43 conf_warnings++; 101 conf_warnings++;
44} 102}
45 103
46static void conf_default_message_callback(const char *fmt, va_list ap) 104static void conf_default_message_callback(const char *s)
47{ 105{
48 printf("#\n# "); 106 printf("#\n# ");
49 vprintf(fmt, ap); 107 printf("%s", s);
50 printf("\n#\n"); 108 printf("\n#\n");
51} 109}
52 110
53static void (*conf_message_callback) (const char *fmt, va_list ap) = 111static void (*conf_message_callback)(const char *s) =
54 conf_default_message_callback; 112 conf_default_message_callback;
55void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) 113void conf_set_message_callback(void (*fn)(const char *s))
56{ 114{
57 conf_message_callback = fn; 115 conf_message_callback = fn;
58} 116}
@@ -60,10 +118,15 @@ void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
60static void conf_message(const char *fmt, ...) 118static void conf_message(const char *fmt, ...)
61{ 119{
62 va_list ap; 120 va_list ap;
121 char buf[4096];
122
123 if (!conf_message_callback)
124 return;
63 125
64 va_start(ap, fmt); 126 va_start(ap, fmt);
65 if (conf_message_callback) 127
66 conf_message_callback(fmt, ap); 128 vsnprintf(buf, sizeof(buf), fmt, ap);
129 conf_message_callback(buf);
67 va_end(ap); 130 va_end(ap);
68} 131}
69 132
@@ -81,43 +144,16 @@ const char *conf_get_autoconfig_name(void)
81 return name ? name : "include/config/auto.conf"; 144 return name ? name : "include/config/auto.conf";
82} 145}
83 146
84static char *conf_expand_value(const char *in)
85{
86 struct symbol *sym;
87 const char *src;
88 static char res_value[SYMBOL_MAXLENGTH];
89 char *dst, name[SYMBOL_MAXLENGTH];
90
91 res_value[0] = 0;
92 dst = name;
93 while ((src = strchr(in, '$'))) {
94 strncat(res_value, in, src - in);
95 src++;
96 dst = name;
97 while (isalnum(*src) || *src == '_')
98 *dst++ = *src++;
99 *dst = 0;
100 sym = sym_lookup(name, 0);
101 sym_calc_value(sym);
102 strcat(res_value, sym_get_string_value(sym));
103 in = src;
104 }
105 strcat(res_value, in);
106
107 return res_value;
108}
109
110char *conf_get_default_confname(void) 147char *conf_get_default_confname(void)
111{ 148{
112 struct stat buf;
113 static char fullname[PATH_MAX+1]; 149 static char fullname[PATH_MAX+1];
114 char *env, *name; 150 char *env, *name;
115 151
116 name = conf_expand_value(conf_defname); 152 name = expand_string(conf_defname);
117 env = getenv(SRCTREE); 153 env = getenv(SRCTREE);
118 if (env) { 154 if (env) {
119 sprintf(fullname, "%s/%s", env, name); 155 sprintf(fullname, "%s/%s", env, name);
120 if (!stat(fullname, &buf)) 156 if (is_present(fullname))
121 return fullname; 157 return fullname;
122 } 158 }
123 return name; 159 return name;
@@ -274,10 +310,11 @@ int conf_read_simple(const char *name, int def)
274 if (expr_calc_value(prop->visible.expr) == no || 310 if (expr_calc_value(prop->visible.expr) == no ||
275 prop->expr->type != E_SYMBOL) 311 prop->expr->type != E_SYMBOL)
276 continue; 312 continue;
277 name = conf_expand_value(prop->expr->left.sym->name); 313 sym_calc_value(prop->expr->left.sym);
314 name = sym_get_string_value(prop->expr->left.sym);
278 in = zconf_fopen(name); 315 in = zconf_fopen(name);
279 if (in) { 316 if (in) {
280 conf_message(_("using defaults found in %s"), 317 conf_message("using defaults found in %s",
281 name); 318 name);
282 goto load; 319 goto load;
283 } 320 }
@@ -422,7 +459,7 @@ int conf_read(const char *name)
422 459
423 for_all_symbols(i, sym) { 460 for_all_symbols(i, sym) {
424 sym_calc_value(sym); 461 sym_calc_value(sym);
425 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) 462 if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
426 continue; 463 continue;
427 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 464 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
428 /* check that calculated value agrees with saved value */ 465 /* check that calculated value agrees with saved value */
@@ -745,15 +782,14 @@ int conf_write(const char *name)
745 struct menu *menu; 782 struct menu *menu;
746 const char *basename; 783 const char *basename;
747 const char *str; 784 const char *str;
748 char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; 785 char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
749 char *env; 786 char *env;
750 787
751 dirname[0] = 0; 788 dirname[0] = 0;
752 if (name && name[0]) { 789 if (name && name[0]) {
753 struct stat st;
754 char *slash; 790 char *slash;
755 791
756 if (!stat(name, &st) && S_ISDIR(st.st_mode)) { 792 if (is_dir(name)) {
757 strcpy(dirname, name); 793 strcpy(dirname, name);
758 strcat(dirname, "/"); 794 strcat(dirname, "/");
759 basename = conf_get_configname(); 795 basename = conf_get_configname();
@@ -831,33 +867,66 @@ next:
831 return 1; 867 return 1;
832 } 868 }
833 869
834 conf_message(_("configuration written to %s"), newname); 870 conf_message("configuration written to %s", newname);
835 871
836 sym_set_change_count(0); 872 sym_set_change_count(0);
837 873
838 return 0; 874 return 0;
839} 875}
840 876
877/* write a dependency file as used by kbuild to track dependencies */
878static int conf_write_dep(const char *name)
879{
880 struct file *file;
881 FILE *out;
882
883 if (!name)
884 name = ".kconfig.d";
885 out = fopen("..config.tmp", "w");
886 if (!out)
887 return 1;
888 fprintf(out, "deps_config := \\\n");
889 for (file = file_list; file; file = file->next) {
890 if (file->next)
891 fprintf(out, "\t%s \\\n", file->name);
892 else
893 fprintf(out, "\t%s\n", file->name);
894 }
895 fprintf(out, "\n%s: \\\n"
896 "\t$(deps_config)\n\n", conf_get_autoconfig_name());
897
898 env_write_dep(out, conf_get_autoconfig_name());
899
900 fprintf(out, "\n$(deps_config): ;\n");
901 fclose(out);
902
903 if (make_parent_dir(name))
904 return 1;
905 rename("..config.tmp", name);
906 return 0;
907}
908
841static int conf_split_config(void) 909static int conf_split_config(void)
842{ 910{
843 const char *name; 911 const char *name;
844 char path[PATH_MAX+1]; 912 char path[PATH_MAX+1];
845 char *s, *d, c; 913 char *s, *d, c;
846 struct symbol *sym; 914 struct symbol *sym;
847 struct stat sb;
848 int res, i, fd; 915 int res, i, fd;
849 916
850 name = conf_get_autoconfig_name(); 917 name = conf_get_autoconfig_name();
851 conf_read_simple(name, S_DEF_AUTO); 918 conf_read_simple(name, S_DEF_AUTO);
852 sym_calc_value(modules_sym); 919 sym_calc_value(modules_sym);
853 920
921 if (make_parent_dir("include/config/foo.h"))
922 return 1;
854 if (chdir("include/config")) 923 if (chdir("include/config"))
855 return 1; 924 return 1;
856 925
857 res = 0; 926 res = 0;
858 for_all_symbols(i, sym) { 927 for_all_symbols(i, sym) {
859 sym_calc_value(sym); 928 sym_calc_value(sym);
860 if ((sym->flags & SYMBOL_AUTO) || !sym->name) 929 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
861 continue; 930 continue;
862 if (sym->flags & SYMBOL_WRITE) { 931 if (sym->flags & SYMBOL_WRITE) {
863 if (sym->flags & SYMBOL_DEF_AUTO) { 932 if (sym->flags & SYMBOL_DEF_AUTO) {
@@ -922,19 +991,12 @@ static int conf_split_config(void)
922 res = 1; 991 res = 1;
923 break; 992 break;
924 } 993 }
925 /* 994
926 * Create directory components, 995 if (make_parent_dir(path)) {
927 * unless they exist already. 996 res = 1;
928 */ 997 goto out;
929 d = path;
930 while ((d = strchr(d, '/'))) {
931 *d = 0;
932 if (stat(path, &sb) && mkdir(path, 0755)) {
933 res = 1;
934 goto out;
935 }
936 *d++ = '/';
937 } 998 }
999
938 /* Try it again. */ 1000 /* Try it again. */
939 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1001 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
940 if (fd == -1) { 1002 if (fd == -1) {
@@ -951,16 +1013,20 @@ out:
951 return res; 1013 return res;
952} 1014}
953 1015
954int conf_write_autoconf(void) 1016int conf_write_autoconf(int overwrite)
955{ 1017{
956 struct symbol *sym; 1018 struct symbol *sym;
957 const char *name; 1019 const char *name;
1020 const char *autoconf_name = conf_get_autoconfig_name();
958 FILE *out, *tristate, *out_h; 1021 FILE *out, *tristate, *out_h;
959 int i; 1022 int i;
960 1023
1024 if (!overwrite && is_present(autoconf_name))
1025 return 0;
1026
961 sym_clear_all_valid(); 1027 sym_clear_all_valid();
962 1028
963 file_write_dep("include/config/auto.conf.cmd"); 1029 conf_write_dep("include/config/auto.conf.cmd");
964 1030
965 if (conf_split_config()) 1031 if (conf_split_config())
966 return 1; 1032 return 1;
@@ -1007,19 +1073,26 @@ int conf_write_autoconf(void)
1007 name = getenv("KCONFIG_AUTOHEADER"); 1073 name = getenv("KCONFIG_AUTOHEADER");
1008 if (!name) 1074 if (!name)
1009 name = "include/generated/autoconf.h"; 1075 name = "include/generated/autoconf.h";
1076 if (make_parent_dir(name))
1077 return 1;
1010 if (rename(".tmpconfig.h", name)) 1078 if (rename(".tmpconfig.h", name))
1011 return 1; 1079 return 1;
1080
1012 name = getenv("KCONFIG_TRISTATE"); 1081 name = getenv("KCONFIG_TRISTATE");
1013 if (!name) 1082 if (!name)
1014 name = "include/config/tristate.conf"; 1083 name = "include/config/tristate.conf";
1084 if (make_parent_dir(name))
1085 return 1;
1015 if (rename(".tmpconfig_tristate", name)) 1086 if (rename(".tmpconfig_tristate", name))
1016 return 1; 1087 return 1;
1017 name = conf_get_autoconfig_name(); 1088
1089 if (make_parent_dir(autoconf_name))
1090 return 1;
1018 /* 1091 /*
1019 * This must be the last step, kbuild has a dependency on auto.conf 1092 * This must be the last step, kbuild has a dependency on auto.conf
1020 * and this marks the successful completion of the previous steps. 1093 * and this marks the successful completion of the previous steps.
1021 */ 1094 */
1022 if (rename(".tmpconfig", name)) 1095 if (rename(".tmpconfig", autoconf_name))
1023 return 1; 1096 return 1;
1024 1097
1025 return 0; 1098 return 0;
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d45381986ac7..e1a39e90841d 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1137,49 +1137,9 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1137 return 0; 1137 return 0;
1138} 1138}
1139 1139
1140static inline struct expr * 1140void expr_print(struct expr *e,
1141expr_get_leftmost_symbol(const struct expr *e) 1141 void (*fn)(void *, struct symbol *, const char *),
1142{ 1142 void *data, int prevtoken)
1143
1144 if (e == NULL)
1145 return NULL;
1146
1147 while (e->type != E_SYMBOL)
1148 e = e->left.expr;
1149
1150 return expr_copy(e);
1151}
1152
1153/*
1154 * Given expression `e1' and `e2', returns the leaf of the longest
1155 * sub-expression of `e1' not containing 'e2.
1156 */
1157struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1158{
1159 struct expr *ret;
1160
1161 switch (e1->type) {
1162 case E_OR:
1163 return expr_alloc_and(
1164 expr_simplify_unmet_dep(e1->left.expr, e2),
1165 expr_simplify_unmet_dep(e1->right.expr, e2));
1166 case E_AND: {
1167 struct expr *e;
1168 e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
1169 e = expr_eliminate_dups(e);
1170 ret = (!expr_eq(e, e1)) ? e1 : NULL;
1171 expr_free(e);
1172 break;
1173 }
1174 default:
1175 ret = e1;
1176 break;
1177 }
1178
1179 return expr_get_leftmost_symbol(ret);
1180}
1181
1182static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken, bool revdep)
1183{ 1143{
1184 if (!e) { 1144 if (!e) {
1185 fn(data, NULL, "y"); 1145 fn(data, NULL, "y");
@@ -1234,14 +1194,9 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
1234 fn(data, e->right.sym, e->right.sym->name); 1194 fn(data, e->right.sym, e->right.sym->name);
1235 break; 1195 break;
1236 case E_OR: 1196 case E_OR:
1237 if (revdep && e->left.expr->type != E_OR) 1197 expr_print(e->left.expr, fn, data, E_OR);
1238 fn(data, NULL, "\n - "); 1198 fn(data, NULL, " || ");
1239 __expr_print(e->left.expr, fn, data, E_OR, revdep); 1199 expr_print(e->right.expr, fn, data, E_OR);
1240 if (revdep)
1241 fn(data, NULL, "\n - ");
1242 else
1243 fn(data, NULL, " || ");
1244 __expr_print(e->right.expr, fn, data, E_OR, revdep);
1245 break; 1200 break;
1246 case E_AND: 1201 case E_AND:
1247 expr_print(e->left.expr, fn, data, E_AND); 1202 expr_print(e->left.expr, fn, data, E_AND);
@@ -1274,11 +1229,6 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
1274 fn(data, NULL, ")"); 1229 fn(data, NULL, ")");
1275} 1230}
1276 1231
1277void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1278{
1279 __expr_print(e, fn, data, prevtoken, false);
1280}
1281
1282static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 1232static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1283{ 1233{
1284 xfwrite(str, strlen(str), 1, data); 1234 xfwrite(str, strlen(str), 1, data);
@@ -1329,7 +1279,27 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
1329 * line with a minus. This makes expressions much easier to read. 1279 * line with a minus. This makes expressions much easier to read.
1330 * Suitable for reverse dependency expressions. 1280 * Suitable for reverse dependency expressions.
1331 */ 1281 */
1332void expr_gstr_print_revdep(struct expr *e, struct gstr *gs) 1282static void expr_print_revdep(struct expr *e,
1283 void (*fn)(void *, struct symbol *, const char *),
1284 void *data, tristate pr_type, const char **title)
1285{
1286 if (e->type == E_OR) {
1287 expr_print_revdep(e->left.expr, fn, data, pr_type, title);
1288 expr_print_revdep(e->right.expr, fn, data, pr_type, title);
1289 } else if (expr_calc_value(e) == pr_type) {
1290 if (*title) {
1291 fn(data, NULL, *title);
1292 *title = NULL;
1293 }
1294
1295 fn(data, NULL, " - ");
1296 expr_print(e, fn, data, E_NONE);
1297 fn(data, NULL, "\n");
1298 }
1299}
1300
1301void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
1302 tristate pr_type, const char *title)
1333{ 1303{
1334 __expr_print(e, expr_print_gstr_helper, gs, E_NONE, true); 1304 expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
1335} 1305}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index c16e82e302a2..7c329e179007 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -141,7 +141,7 @@ struct symbol {
141#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ 141#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
142#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ 142#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
143#define SYMBOL_CHANGED 0x0400 /* ? */ 143#define SYMBOL_CHANGED 0x0400 /* ? */
144#define SYMBOL_AUTO 0x1000 /* value from environment variable */ 144#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */
145#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ 145#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
146#define SYMBOL_WARNED 0x8000 /* warning has been issued */ 146#define SYMBOL_WARNED 0x8000 /* warning has been issued */
147 147
@@ -171,6 +171,9 @@ struct symbol {
171 * config BAZ 171 * config BAZ
172 * int "BAZ Value" 172 * int "BAZ Value"
173 * range 1..255 173 * range 1..255
174 *
175 * Please, also check zconf.y:print_symbol() when modifying the
176 * list of property types!
174 */ 177 */
175enum prop_type { 178enum prop_type {
176 P_UNKNOWN, 179 P_UNKNOWN,
@@ -182,7 +185,6 @@ enum prop_type {
182 P_SELECT, /* select BAR */ 185 P_SELECT, /* select BAR */
183 P_IMPLY, /* imply BAR */ 186 P_IMPLY, /* imply BAR */
184 P_RANGE, /* range 7..100 (for a symbol) */ 187 P_RANGE, /* range 7..100 (for a symbol) */
185 P_ENV, /* value from environment variable */
186 P_SYMBOL, /* where a symbol is defined */ 188 P_SYMBOL, /* where a symbol is defined */
187}; 189};
188 190
@@ -305,12 +307,12 @@ struct expr *expr_transform(struct expr *e);
305int expr_contains_symbol(struct expr *dep, struct symbol *sym); 307int expr_contains_symbol(struct expr *dep, struct symbol *sym);
306bool expr_depends_symbol(struct expr *dep, struct symbol *sym); 308bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
307struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); 309struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
308struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
309 310
310void expr_fprint(struct expr *e, FILE *out); 311void expr_fprint(struct expr *e, FILE *out);
311struct gstr; /* forward */ 312struct gstr; /* forward */
312void expr_gstr_print(struct expr *e, struct gstr *gs); 313void expr_gstr_print(struct expr *e, struct gstr *gs);
313void expr_gstr_print_revdep(struct expr *e, struct gstr *gs); 314void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
315 tristate pr_type, const char *title);
314 316
315static inline int expr_is_yes(struct expr *e) 317static inline int expr_is_yes(struct expr *e)
316{ 318{
diff --git a/scripts/kconfig/gconf-cfg.sh b/scripts/kconfig/gconf-cfg.sh
new file mode 100755
index 000000000000..480ecd8b9f41
--- /dev/null
+++ b/scripts/kconfig/gconf-cfg.sh
@@ -0,0 +1,30 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
5
6if [ -z "$(command -v pkg-config)" ]; then
7 echo >&2 "*"
8 echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it."
9 echo >&2 "*"
10 exit 1
11fi
12
13if ! pkg-config --exists $PKG; then
14 echo >&2 "*"
15 echo >&2 "* Unable to find the GTK+ installation. Please make sure that"
16 echo >&2 "* the GTK+ 2.0 development package is correctly installed."
17 echo >&2 "* You need $PKG"
18 echo >&2 "*"
19 exit 1
20fi
21
22if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then
23 echo >&2 "*"
24 echo >&2 "* GTK+ is present but version >= 2.0.0 is required."
25 echo >&2 "*"
26 exit 1
27fi
28
29echo cflags=\"$(pkg-config --cflags $PKG)\"
30echo libs=\"$(pkg-config --libs $PKG)\"
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index cfddddb9c9d7..36f578415c4a 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -101,8 +101,8 @@ const char *dbg_sym_flags(int val)
101 strcat(buf, "write/"); 101 strcat(buf, "write/");
102 if (val & SYMBOL_CHANGED) 102 if (val & SYMBOL_CHANGED)
103 strcat(buf, "changed/"); 103 strcat(buf, "changed/");
104 if (val & SYMBOL_AUTO) 104 if (val & SYMBOL_NO_WRITE)
105 strcat(buf, "auto/"); 105 strcat(buf, "no_write/");
106 106
107 buf[strlen(buf) - 1] = '\0'; 107 buf[strlen(buf) - 1] = '\0';
108 108
@@ -137,7 +137,7 @@ void init_main_window(const gchar * glade_file)
137 137
138 xml = glade_xml_new(glade_file, "window1", NULL); 138 xml = glade_xml_new(glade_file, "window1", NULL);
139 if (!xml) 139 if (!xml)
140 g_error(_("GUI loading failed !\n")); 140 g_error("GUI loading failed !\n");
141 glade_xml_signal_autoconnect(xml); 141 glade_xml_signal_autoconnect(xml);
142 142
143 main_wnd = glade_xml_get_widget(xml, "window1"); 143 main_wnd = glade_xml_get_widget(xml, "window1");
@@ -233,7 +233,7 @@ void init_left_tree(void)
233 233
234 column = gtk_tree_view_column_new(); 234 column = gtk_tree_view_column_new();
235 gtk_tree_view_append_column(view, column); 235 gtk_tree_view_append_column(view, column);
236 gtk_tree_view_column_set_title(column, _("Options")); 236 gtk_tree_view_column_set_title(column, "Options");
237 237
238 renderer = gtk_cell_renderer_toggle_new(); 238 renderer = gtk_cell_renderer_toggle_new();
239 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), 239 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -276,7 +276,7 @@ void init_right_tree(void)
276 276
277 column = gtk_tree_view_column_new(); 277 column = gtk_tree_view_column_new();
278 gtk_tree_view_append_column(view, column); 278 gtk_tree_view_append_column(view, column);
279 gtk_tree_view_column_set_title(column, _("Options")); 279 gtk_tree_view_column_set_title(column, "Options");
280 280
281 renderer = gtk_cell_renderer_pixbuf_new(); 281 renderer = gtk_cell_renderer_pixbuf_new();
282 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), 282 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
@@ -305,7 +305,7 @@ void init_right_tree(void)
305 305
306 renderer = gtk_cell_renderer_text_new(); 306 renderer = gtk_cell_renderer_text_new();
307 gtk_tree_view_insert_column_with_attributes(view, -1, 307 gtk_tree_view_insert_column_with_attributes(view, -1,
308 _("Name"), renderer, 308 "Name", renderer,
309 "text", COL_NAME, 309 "text", COL_NAME,
310 "foreground-gdk", 310 "foreground-gdk",
311 COL_COLOR, NULL); 311 COL_COLOR, NULL);
@@ -329,7 +329,7 @@ void init_right_tree(void)
329 COL_COLOR, NULL); 329 COL_COLOR, NULL);
330 renderer = gtk_cell_renderer_text_new(); 330 renderer = gtk_cell_renderer_text_new();
331 gtk_tree_view_insert_column_with_attributes(view, -1, 331 gtk_tree_view_insert_column_with_attributes(view, -1,
332 _("Value"), renderer, 332 "Value", renderer,
333 "text", COL_VALUE, 333 "text", COL_VALUE,
334 "editable", 334 "editable",
335 COL_EDIT, 335 COL_EDIT,
@@ -368,7 +368,7 @@ static void text_insert_help(struct menu *menu)
368{ 368{
369 GtkTextBuffer *buffer; 369 GtkTextBuffer *buffer;
370 GtkTextIter start, end; 370 GtkTextIter start, end;
371 const char *prompt = _(menu_get_prompt(menu)); 371 const char *prompt = menu_get_prompt(menu);
372 struct gstr help = str_new(); 372 struct gstr help = str_new();
373 373
374 menu_get_ext_help(menu, &help); 374 menu_get_ext_help(menu, &help);
@@ -422,7 +422,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
422 if (!conf_get_changed()) 422 if (!conf_get_changed())
423 return FALSE; 423 return FALSE;
424 424
425 dialog = gtk_dialog_new_with_buttons(_("Warning !"), 425 dialog = gtk_dialog_new_with_buttons("Warning !",
426 GTK_WINDOW(main_wnd), 426 GTK_WINDOW(main_wnd),
427 (GtkDialogFlags) 427 (GtkDialogFlags)
428 (GTK_DIALOG_MODAL | 428 (GTK_DIALOG_MODAL |
@@ -436,7 +436,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
436 gtk_dialog_set_default_response(GTK_DIALOG(dialog), 436 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
437 GTK_RESPONSE_CANCEL); 437 GTK_RESPONSE_CANCEL);
438 438
439 label = gtk_label_new(_("\nSave configuration ?\n")); 439 label = gtk_label_new("\nSave configuration ?\n");
440 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); 440 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
441 gtk_widget_show(label); 441 gtk_widget_show(label);
442 442
@@ -496,7 +496,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data)
496 (user_data)); 496 (user_data));
497 497
498 if (conf_read(fn)) 498 if (conf_read(fn))
499 text_insert_msg(_("Error"), _("Unable to load configuration !")); 499 text_insert_msg("Error", "Unable to load configuration !");
500 else 500 else
501 display_tree(&rootmenu); 501 display_tree(&rootmenu);
502} 502}
@@ -505,7 +505,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
505{ 505{
506 GtkWidget *fs; 506 GtkWidget *fs;
507 507
508 fs = gtk_file_selection_new(_("Load file...")); 508 fs = gtk_file_selection_new("Load file...");
509 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), 509 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
510 "clicked", 510 "clicked",
511 G_CALLBACK(load_filename), (gpointer) fs); 511 G_CALLBACK(load_filename), (gpointer) fs);
@@ -524,7 +524,8 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
524void on_save_activate(GtkMenuItem * menuitem, gpointer user_data) 524void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
525{ 525{
526 if (conf_write(NULL)) 526 if (conf_write(NULL))
527 text_insert_msg(_("Error"), _("Unable to save configuration !")); 527 text_insert_msg("Error", "Unable to save configuration !");
528 conf_write_autoconf(0);
528} 529}
529 530
530 531
@@ -537,7 +538,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data)
537 (user_data)); 538 (user_data));
538 539
539 if (conf_write(fn)) 540 if (conf_write(fn))
540 text_insert_msg(_("Error"), _("Unable to save configuration !")); 541 text_insert_msg("Error", "Unable to save configuration !");
541 542
542 gtk_widget_destroy(GTK_WIDGET(user_data)); 543 gtk_widget_destroy(GTK_WIDGET(user_data));
543} 544}
@@ -546,7 +547,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
546{ 547{
547 GtkWidget *fs; 548 GtkWidget *fs;
548 549
549 fs = gtk_file_selection_new(_("Save file as...")); 550 fs = gtk_file_selection_new("Save file as...");
550 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), 551 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
551 "clicked", 552 "clicked",
552 G_CALLBACK(store_filename), (gpointer) fs); 553 G_CALLBACK(store_filename), (gpointer) fs);
@@ -639,7 +640,7 @@ on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
639void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) 640void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
640{ 641{
641 GtkWidget *dialog; 642 GtkWidget *dialog;
642 const gchar *intro_text = _( 643 const gchar *intro_text =
643 "Welcome to gkc, the GTK+ graphical configuration tool\n" 644 "Welcome to gkc, the GTK+ graphical configuration tool\n"
644 "For each option, a blank box indicates the feature is disabled, a\n" 645 "For each option, a blank box indicates the feature is disabled, a\n"
645 "check indicates it is enabled, and a dot indicates that it is to\n" 646 "check indicates it is enabled, and a dot indicates that it is to\n"
@@ -654,7 +655,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
654 "option.\n" 655 "option.\n"
655 "\n" 656 "\n"
656 "Toggling Show Debug Info under the Options menu will show \n" 657 "Toggling Show Debug Info under the Options menu will show \n"
657 "the dependencies, which you can then match by examining other options."); 658 "the dependencies, which you can then match by examining other options.";
658 659
659 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), 660 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
660 GTK_DIALOG_DESTROY_WITH_PARENT, 661 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -671,8 +672,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
671{ 672{
672 GtkWidget *dialog; 673 GtkWidget *dialog;
673 const gchar *about_text = 674 const gchar *about_text =
674 _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" 675 "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
675 "Based on the source code from Roman Zippel.\n"); 676 "Based on the source code from Roman Zippel.\n";
676 677
677 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), 678 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
678 GTK_DIALOG_DESTROY_WITH_PARENT, 679 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -689,9 +690,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
689{ 690{
690 GtkWidget *dialog; 691 GtkWidget *dialog;
691 const gchar *license_text = 692 const gchar *license_text =
692 _("gkc is released under the terms of the GNU GPL v2.\n" 693 "gkc is released under the terms of the GNU GPL v2.\n"
693 "For more information, please see the source code or\n" 694 "For more information, please see the source code or\n"
694 "visit http://www.fsf.org/licenses/licenses.html\n"); 695 "visit http://www.fsf.org/licenses/licenses.html\n";
695 696
696 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), 697 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
697 GTK_DIALOG_DESTROY_WITH_PARENT, 698 GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1049,7 +1050,7 @@ static gchar **fill_row(struct menu *menu)
1049 bzero(row, sizeof(row)); 1050 bzero(row, sizeof(row));
1050 1051
1051 row[COL_OPTION] = 1052 row[COL_OPTION] =
1052 g_strdup_printf("%s %s", _(menu_get_prompt(menu)), 1053 g_strdup_printf("%s %s", menu_get_prompt(menu),
1053 sym && !sym_has_value(sym) ? "(NEW)" : ""); 1054 sym && !sym_has_value(sym) ? "(NEW)" : "");
1054 1055
1055 if (opt_mode == OPT_ALL && !menu_is_visible(menu)) 1056 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
@@ -1102,7 +1103,7 @@ static gchar **fill_row(struct menu *menu)
1102 1103
1103 if (def_menu) 1104 if (def_menu)
1104 row[COL_VALUE] = 1105 row[COL_VALUE] =
1105 g_strdup(_(menu_get_prompt(def_menu))); 1106 g_strdup(menu_get_prompt(def_menu));
1106 } 1107 }
1107 if (sym->flags & SYMBOL_CHOICEVAL) 1108 if (sym->flags & SYMBOL_CHOICEVAL)
1108 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); 1109 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
@@ -1447,10 +1448,6 @@ int main(int ac, char *av[])
1447 char *env; 1448 char *env;
1448 gchar *glade_file; 1449 gchar *glade_file;
1449 1450
1450 bindtextdomain(PACKAGE, LOCALEDIR);
1451 bind_textdomain_codeset(PACKAGE, "UTF-8");
1452 textdomain(PACKAGE);
1453
1454 /* GTK stuffs */ 1451 /* GTK stuffs */
1455 gtk_set_locale(); 1452 gtk_set_locale();
1456 gtk_init(&ac, &av); 1453 gtk_init(&ac, &av);
diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c
index 3ea9c5f9f730..b3e0ea0ac732 100644
--- a/scripts/kconfig/kconf_id.c
+++ b/scripts/kconfig/kconf_id.c
@@ -32,7 +32,6 @@ static struct kconf_id kconf_id_array[] = {
32 { "on", T_ON, TF_PARAM }, 32 { "on", T_ON, TF_PARAM },
33 { "modules", T_OPT_MODULES, TF_OPTION }, 33 { "modules", T_OPT_MODULES, TF_OPTION },
34 { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, 34 { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION },
35 { "env", T_OPT_ENV, TF_OPTION },
36 { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, 35 { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION },
37}; 36};
38 37
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c
deleted file mode 100644
index 240880a89111..000000000000
--- a/scripts/kconfig/kxgettext.c
+++ /dev/null
@@ -1,235 +0,0 @@
1/*
2 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
3 *
4 * Released under the terms of the GNU GPL v2.0
5 */
6
7#include <stdlib.h>
8#include <string.h>
9
10#include "lkc.h"
11
12static char *escape(const char* text, char *bf, int len)
13{
14 char *bfp = bf;
15 int multiline = strchr(text, '\n') != NULL;
16 int eol = 0;
17 int textlen = strlen(text);
18
19 if ((textlen > 0) && (text[textlen-1] == '\n'))
20 eol = 1;
21
22 *bfp++ = '"';
23 --len;
24
25 if (multiline) {
26 *bfp++ = '"';
27 *bfp++ = '\n';
28 *bfp++ = '"';
29 len -= 3;
30 }
31
32 while (*text != '\0' && len > 1) {
33 if (*text == '"')
34 *bfp++ = '\\';
35 else if (*text == '\n') {
36 *bfp++ = '\\';
37 *bfp++ = 'n';
38 *bfp++ = '"';
39 *bfp++ = '\n';
40 *bfp++ = '"';
41 len -= 5;
42 ++text;
43 goto next;
44 }
45 else if (*text == '\\') {
46 *bfp++ = '\\';
47 len--;
48 }
49 *bfp++ = *text++;
50next:
51 --len;
52 }
53
54 if (multiline && eol)
55 bfp -= 3;
56
57 *bfp++ = '"';
58 *bfp = '\0';
59
60 return bf;
61}
62
63struct file_line {
64 struct file_line *next;
65 const char *file;
66 int lineno;
67};
68
69static struct file_line *file_line__new(const char *file, int lineno)
70{
71 struct file_line *self = malloc(sizeof(*self));
72
73 if (self == NULL)
74 goto out;
75
76 self->file = file;
77 self->lineno = lineno;
78 self->next = NULL;
79out:
80 return self;
81}
82
83struct message {
84 const char *msg;
85 const char *option;
86 struct message *next;
87 struct file_line *files;
88};
89
90static struct message *message__list;
91
92static struct message *message__new(const char *msg, char *option,
93 const char *file, int lineno)
94{
95 struct message *self = malloc(sizeof(*self));
96
97 if (self == NULL)
98 goto out;
99
100 self->files = file_line__new(file, lineno);
101 if (self->files == NULL)
102 goto out_fail;
103
104 self->msg = xstrdup(msg);
105 if (self->msg == NULL)
106 goto out_fail_msg;
107
108 self->option = option;
109 self->next = NULL;
110out:
111 return self;
112out_fail_msg:
113 free(self->files);
114out_fail:
115 free(self);
116 self = NULL;
117 goto out;
118}
119
120static struct message *mesage__find(const char *msg)
121{
122 struct message *m = message__list;
123
124 while (m != NULL) {
125 if (strcmp(m->msg, msg) == 0)
126 break;
127 m = m->next;
128 }
129
130 return m;
131}
132
133static int message__add_file_line(struct message *self, const char *file,
134 int lineno)
135{
136 int rc = -1;
137 struct file_line *fl = file_line__new(file, lineno);
138
139 if (fl == NULL)
140 goto out;
141
142 fl->next = self->files;
143 self->files = fl;
144 rc = 0;
145out:
146 return rc;
147}
148
149static int message__add(const char *msg, char *option, const char *file,
150 int lineno)
151{
152 int rc = 0;
153 char bf[16384];
154 char *escaped = escape(msg, bf, sizeof(bf));
155 struct message *m = mesage__find(escaped);
156
157 if (m != NULL)
158 rc = message__add_file_line(m, file, lineno);
159 else {
160 m = message__new(escaped, option, file, lineno);
161
162 if (m != NULL) {
163 m->next = message__list;
164 message__list = m;
165 } else
166 rc = -1;
167 }
168 return rc;
169}
170
171static void menu_build_message_list(struct menu *menu)
172{
173 struct menu *child;
174
175 message__add(menu_get_prompt(menu), NULL,
176 menu->file == NULL ? "Root Menu" : menu->file->name,
177 menu->lineno);
178
179 if (menu->sym != NULL && menu_has_help(menu))
180 message__add(menu_get_help(menu), menu->sym->name,
181 menu->file == NULL ? "Root Menu" : menu->file->name,
182 menu->lineno);
183
184 for (child = menu->list; child != NULL; child = child->next)
185 if (child->prompt != NULL)
186 menu_build_message_list(child);
187}
188
189static void message__print_file_lineno(struct message *self)
190{
191 struct file_line *fl = self->files;
192
193 putchar('\n');
194 if (self->option != NULL)
195 printf("# %s:00000\n", self->option);
196
197 printf("#: %s:%d", fl->file, fl->lineno);
198 fl = fl->next;
199
200 while (fl != NULL) {
201 printf(", %s:%d", fl->file, fl->lineno);
202 fl = fl->next;
203 }
204
205 putchar('\n');
206}
207
208static void message__print_gettext_msgid_msgstr(struct message *self)
209{
210 message__print_file_lineno(self);
211
212 printf("msgid %s\n"
213 "msgstr \"\"\n", self->msg);
214}
215
216static void menu__xgettext(void)
217{
218 struct message *m = message__list;
219
220 while (m != NULL) {
221 /* skip empty lines ("") */
222 if (strlen(m->msg) > sizeof("\"\""))
223 message__print_gettext_msgid_msgstr(m);
224 m = m->next;
225 }
226}
227
228int main(int ac, char **av)
229{
230 conf_parse(av[1]);
231
232 menu_build_message_list(menu_get_root_menu(NULL));
233 menu__xgettext();
234 return 0;
235}
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 2d5ec2d0e952..9eb7c837cd8f 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -8,15 +8,6 @@
8 8
9#include "expr.h" 9#include "expr.h"
10 10
11#ifndef KBUILD_NO_NLS
12# include <libintl.h>
13#else
14static inline const char *gettext(const char *txt) { return txt; }
15static inline void textdomain(const char *domainname) {}
16static inline void bindtextdomain(const char *name, const char *dir) {}
17static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
18#endif
19
20#ifdef __cplusplus 11#ifdef __cplusplus
21extern "C" { 12extern "C" {
22#endif 13#endif
@@ -29,11 +20,6 @@ extern "C" {
29#define PACKAGE "linux" 20#define PACKAGE "linux"
30#endif 21#endif
31 22
32#define LOCALEDIR "/usr/share/locale"
33
34#define _(text) gettext(text)
35#define N_(text) (text)
36
37#ifndef CONFIG_ 23#ifndef CONFIG_
38#define CONFIG_ "CONFIG_" 24#define CONFIG_ "CONFIG_"
39#endif 25#endif
@@ -58,7 +44,6 @@ enum conf_def_mode {
58 44
59#define T_OPT_MODULES 1 45#define T_OPT_MODULES 1
60#define T_OPT_DEFCONFIG_LIST 2 46#define T_OPT_DEFCONFIG_LIST 2
61#define T_OPT_ENV 3
62#define T_OPT_ALLNOCONFIG_Y 4 47#define T_OPT_ALLNOCONFIG_Y 4
63 48
64struct kconf_id { 49struct kconf_id {
@@ -68,6 +53,7 @@ struct kconf_id {
68 enum symbol_type stype; 53 enum symbol_type stype;
69}; 54};
70 55
56extern int yylineno;
71void zconfdump(FILE *out); 57void zconfdump(FILE *out);
72void zconf_starthelp(void); 58void zconf_starthelp(void);
73FILE *zconf_fopen(const char *name); 59FILE *zconf_fopen(const char *name);
@@ -111,11 +97,11 @@ void menu_set_type(int type);
111 97
112/* util.c */ 98/* util.c */
113struct file *file_lookup(const char *name); 99struct file *file_lookup(const char *name);
114int file_write_dep(const char *name);
115void *xmalloc(size_t size); 100void *xmalloc(size_t size);
116void *xcalloc(size_t nmemb, size_t size); 101void *xcalloc(size_t nmemb, size_t size);
117void *xrealloc(void *p, size_t size); 102void *xrealloc(void *p, size_t size);
118char *xstrdup(const char *s); 103char *xstrdup(const char *s);
104char *xstrndup(const char *s, size_t n);
119 105
120struct gstr { 106struct gstr {
121 size_t len; 107 size_t len;
@@ -133,16 +119,12 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
133const char *str_get(struct gstr *gs); 119const char *str_get(struct gstr *gs);
134 120
135/* symbol.c */ 121/* symbol.c */
136extern struct expr *sym_env_list;
137
138void sym_init(void);
139void sym_clear_all_valid(void); 122void sym_clear_all_valid(void);
140struct symbol *sym_choice_default(struct symbol *sym); 123struct symbol *sym_choice_default(struct symbol *sym);
141const char *sym_get_string_default(struct symbol *sym); 124const char *sym_get_string_default(struct symbol *sym);
142struct symbol *sym_check_deps(struct symbol *sym); 125struct symbol *sym_check_deps(struct symbol *sym);
143struct property *prop_alloc(enum prop_type type, struct symbol *sym); 126struct property *prop_alloc(enum prop_type type, struct symbol *sym);
144struct symbol *prop_get_symbol(struct property *prop); 127struct symbol *prop_get_symbol(struct property *prop);
145struct property *sym_get_env_prop(struct symbol *sym);
146 128
147static inline tristate sym_get_tristate_value(struct symbol *sym) 129static inline tristate sym_get_tristate_value(struct symbol *sym)
148{ 130{
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 9dc8abfb1dc3..86c267540ccc 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -7,10 +7,10 @@ int conf_read(const char *name);
7int conf_read_simple(const char *name, int); 7int conf_read_simple(const char *name, int);
8int conf_write_defconfig(const char *name); 8int conf_write_defconfig(const char *name);
9int conf_write(const char *name); 9int conf_write(const char *name);
10int conf_write_autoconf(void); 10int conf_write_autoconf(int overwrite);
11bool conf_get_changed(void); 11bool conf_get_changed(void);
12void conf_set_changed_callback(void (*fn)(void)); 12void conf_set_changed_callback(void (*fn)(void));
13void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap)); 13void conf_set_message_callback(void (*fn)(const char *s));
14 14
15/* menu.c */ 15/* menu.c */
16extern struct menu rootmenu; 16extern struct menu rootmenu;
@@ -31,7 +31,6 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
31 31
32struct symbol * sym_lookup(const char *name, int flags); 32struct symbol * sym_lookup(const char *name, int flags);
33struct symbol * sym_find(const char *name); 33struct symbol * sym_find(const char *name);
34char *sym_expand_string_value(const char *in);
35const char * sym_escape_string_value(const char *in); 34const char * sym_escape_string_value(const char *in);
36struct symbol ** sym_re_search(const char *pattern); 35struct symbol ** sym_re_search(const char *pattern);
37const char * sym_type_name(enum symbol_type type); 36const char * sym_type_name(enum symbol_type type);
@@ -49,5 +48,19 @@ const char * sym_get_string_value(struct symbol *sym);
49 48
50const char * prop_get_type_name(enum prop_type type); 49const char * prop_get_type_name(enum prop_type type);
51 50
51/* preprocess.c */
52enum variable_flavor {
53 VAR_SIMPLE,
54 VAR_RECURSIVE,
55 VAR_APPEND,
56};
57void env_write_dep(FILE *f, const char *auto_conf_name);
58void variable_add(const char *name, const char *value,
59 enum variable_flavor flavor);
60void variable_all_del(void);
61char *expand_string(const char *in);
62char *expand_dollar(const char **str);
63char *expand_one_token(const char **str);
64
52/* expr.c */ 65/* expr.c */
53void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); 66void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
deleted file mode 100755
index 6c0bcd9c472d..000000000000
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ /dev/null
@@ -1,93 +0,0 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# Check ncurses compatibility
4
5# What library to link
6ldflags()
7{
8 pkg-config --libs ncursesw 2>/dev/null && exit
9 pkg-config --libs ncurses 2>/dev/null && exit
10 for ext in so a dll.a dylib ; do
11 for lib in ncursesw ncurses curses ; do
12 $cc -print-file-name=lib${lib}.${ext} | grep -q /
13 if [ $? -eq 0 ]; then
14 echo "-l${lib}"
15 exit
16 fi
17 done
18 done
19 exit 1
20}
21
22# Where is ncurses.h?
23ccflags()
24{
25 if pkg-config --cflags ncursesw 2>/dev/null; then
26 echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
27 elif pkg-config --cflags ncurses 2>/dev/null; then
28 echo '-DCURSES_LOC="<ncurses.h>"'
29 elif [ -f /usr/include/ncursesw/curses.h ]; then
30 echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
31 echo ' -DNCURSES_WIDECHAR=1'
32 elif [ -f /usr/include/ncurses/ncurses.h ]; then
33 echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
34 elif [ -f /usr/include/ncurses/curses.h ]; then
35 echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
36 elif [ -f /usr/include/ncurses.h ]; then
37 echo '-DCURSES_LOC="<ncurses.h>"'
38 else
39 echo '-DCURSES_LOC="<curses.h>"'
40 fi
41}
42
43# Temp file, try to clean up after us
44tmp=.lxdialog.tmp
45trap "rm -f $tmp" 0 1 2 3 15
46
47# Check if we can link to ncurses
48check() {
49 $cc -x c - -o $tmp 2>/dev/null <<'EOF'
50#include CURSES_LOC
51main() {}
52EOF
53 if [ $? != 0 ]; then
54 echo " *** Unable to find the ncurses libraries or the" 1>&2
55 echo " *** required header files." 1>&2
56 echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
57 echo " *** " 1>&2
58 echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2
59 echo " *** depending on your distribution) and try again." 1>&2
60 echo " *** " 1>&2
61 exit 1
62 fi
63}
64
65usage() {
66 printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n"
67}
68
69if [ $# -eq 0 ]; then
70 usage
71 exit 1
72fi
73
74cc=""
75case "$1" in
76 "-check")
77 shift
78 cc="$@"
79 check
80 ;;
81 "-ccflags")
82 ccflags
83 ;;
84 "-ldflags")
85 shift
86 cc="$@"
87 ldflags
88 ;;
89 "*")
90 usage
91 exit 1
92 ;;
93esac
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index 8d016faa28d7..2e96323ad11b 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -103,8 +103,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
103 int x = width / 2 - 11; 103 int x = width / 2 - 11;
104 int y = height - 2; 104 int y = height - 2;
105 105
106 print_button(dialog, gettext("Select"), y, x, selected == 0); 106 print_button(dialog, "Select", y, x, selected == 0);
107 print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); 107 print_button(dialog, " Help ", y, x + 14, selected == 1);
108 108
109 wmove(dialog, y, x + 1 + 14 * selected); 109 wmove(dialog, y, x + 1 + 14 * selected);
110 wrefresh(dialog); 110 wrefresh(dialog);
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index fcffd5b41fb0..0b00be5abaa6 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -26,16 +26,10 @@
26#include <string.h> 26#include <string.h>
27#include <stdbool.h> 27#include <stdbool.h>
28 28
29#ifndef KBUILD_NO_NLS
30# include <libintl.h>
31#else
32# define gettext(Msgid) ((const char *) (Msgid))
33#endif
34
35#ifdef __sun__ 29#ifdef __sun__
36#define CURS_MACROS 30#define CURS_MACROS
37#endif 31#endif
38#include CURSES_LOC 32#include <ncurses.h>
39 33
40/* 34/*
41 * Colors in ncurses 1.9.9e do not work properly since foreground and 35 * Colors in ncurses 1.9.9e do not work properly since foreground and
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index d58de1dc5360..fe82ff6d744e 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
31 int x = width / 2 - 11; 31 int x = width / 2 - 11;
32 int y = height - 2; 32 int y = height - 2;
33 33
34 print_button(dialog, gettext(" Ok "), y, x, selected == 0); 34 print_button(dialog, " Ok ", y, x, selected == 0);
35 print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); 35 print_button(dialog, " Help ", y, x + 14, selected == 1);
36 36
37 wmove(dialog, y, x + 1 + 14 * selected); 37 wmove(dialog, y, x + 1 + 14 * selected);
38 wrefresh(dialog); 38 wrefresh(dialog);
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index 11ae9ad7ac7b..d70cab36137e 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -157,11 +157,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
157 int x = width / 2 - 28; 157 int x = width / 2 - 28;
158 int y = height - 2; 158 int y = height - 2;
159 159
160 print_button(win, gettext("Select"), y, x, selected == 0); 160 print_button(win, "Select", y, x, selected == 0);
161 print_button(win, gettext(" Exit "), y, x + 12, selected == 1); 161 print_button(win, " Exit ", y, x + 12, selected == 1);
162 print_button(win, gettext(" Help "), y, x + 24, selected == 2); 162 print_button(win, " Help ", y, x + 24, selected == 2);
163 print_button(win, gettext(" Save "), y, x + 36, selected == 3); 163 print_button(win, " Save ", y, x + 36, selected == 3);
164 print_button(win, gettext(" Load "), y, x + 48, selected == 4); 164 print_button(win, " Load ", y, x + 48, selected == 4);
165 165
166 wmove(win, y, x + 1 + 12 * selected); 166 wmove(win, y, x + 1 + 12 * selected);
167 wrefresh(win); 167 wrefresh(win);
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 1773319b95e7..88d2818ed956 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -129,7 +129,7 @@ do_resize:
129 129
130 print_title(dialog, title, width); 130 print_title(dialog, title, width);
131 131
132 print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); 132 print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
133 wnoutrefresh(dialog); 133 wnoutrefresh(dialog);
134 getyx(dialog, cur_y, cur_x); /* Save cursor position */ 134 getyx(dialog, cur_y, cur_x); /* Save cursor position */
135 135
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index 676fb2f824a3..cd1223c903d1 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
29 int x = width / 2 - 10; 29 int x = width / 2 - 10;
30 int y = height - 2; 30 int y = height - 2;
31 31
32 print_button(dialog, gettext(" Yes "), y, x, selected == 0); 32 print_button(dialog, " Yes ", y, x, selected == 0);
33 print_button(dialog, gettext(" No "), y, x + 13, selected == 1); 33 print_button(dialog, " No ", y, x + 13, selected == 1);
34 34
35 wmove(dialog, y, x + 1 + 13 * selected); 35 wmove(dialog, y, x + 1 + 13 * selected);
36 wrefresh(dialog); 36 wrefresh(dialog);
diff --git a/scripts/kconfig/mconf-cfg.sh b/scripts/kconfig/mconf-cfg.sh
new file mode 100755
index 000000000000..c812872d7f9d
--- /dev/null
+++ b/scripts/kconfig/mconf-cfg.sh
@@ -0,0 +1,47 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4PKG="ncursesw"
5PKG2="ncurses"
6
7if [ -n "$(command -v pkg-config)" ]; then
8 if pkg-config --exists $PKG; then
9 echo cflags=\"$(pkg-config --cflags $PKG)\"
10 echo libs=\"$(pkg-config --libs $PKG)\"
11 exit 0
12 fi
13
14 if pkg-config --exists $PKG2; then
15 echo cflags=\"$(pkg-config --cflags $PKG2)\"
16 echo libs=\"$(pkg-config --libs $PKG2)\"
17 exit 0
18 fi
19fi
20
21# Check the default paths in case pkg-config is not installed.
22# (Even if it is installed, some distributions such as openSUSE cannot
23# find ncurses by pkg-config.)
24if [ -f /usr/include/ncursesw/ncurses.h ]; then
25 echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
26 echo libs=\"-lncursesw\"
27 exit 0
28fi
29
30if [ -f /usr/include/ncurses/ncurses.h ]; then
31 echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
32 echo libs=\"-lncurses\"
33 exit 0
34fi
35
36if [ -f /usr/include/ncurses.h ]; then
37 echo cflags=\"-D_GNU_SOURCE\"
38 echo libs=\"-lncurses\"
39 exit 0
40fi
41
42echo >&2 "*"
43echo >&2 "* Unable to find the ncurses package."
44echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
45echo >&2 "* depending on your distribution)."
46echo >&2 "*"
47exit 1
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index c829be8bb19f..143c05fec161 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -17,12 +17,11 @@
17#include <string.h> 17#include <string.h>
18#include <signal.h> 18#include <signal.h>
19#include <unistd.h> 19#include <unistd.h>
20#include <locale.h>
21 20
22#include "lkc.h" 21#include "lkc.h"
23#include "lxdialog/dialog.h" 22#include "lxdialog/dialog.h"
24 23
25static const char mconf_readme[] = N_( 24static const char mconf_readme[] =
26"Overview\n" 25"Overview\n"
27"--------\n" 26"--------\n"
28"This interface lets you select features and parameters for the build.\n" 27"This interface lets you select features and parameters for the build.\n"
@@ -171,37 +170,37 @@ static const char mconf_readme[] = N_(
171" blackbg => selects a color scheme with black background\n" 170" blackbg => selects a color scheme with black background\n"
172" classic => theme with blue background. The classic look\n" 171" classic => theme with blue background. The classic look\n"
173" bluetitle => an LCD friendly version of classic. (default)\n" 172" bluetitle => an LCD friendly version of classic. (default)\n"
174"\n"), 173"\n",
175menu_instructions[] = N_( 174menu_instructions[] =
176 "Arrow keys navigate the menu. " 175 "Arrow keys navigate the menu. "
177 "<Enter> selects submenus ---> (or empty submenus ----). " 176 "<Enter> selects submenus ---> (or empty submenus ----). "
178 "Highlighted letters are hotkeys. " 177 "Highlighted letters are hotkeys. "
179 "Pressing <Y> includes, <N> excludes, <M> modularizes features. " 178 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
180 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " 179 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
181 "Legend: [*] built-in [ ] excluded <M> module < > module capable"), 180 "Legend: [*] built-in [ ] excluded <M> module < > module capable",
182radiolist_instructions[] = N_( 181radiolist_instructions[] =
183 "Use the arrow keys to navigate this window or " 182 "Use the arrow keys to navigate this window or "
184 "press the hotkey of the item you wish to select " 183 "press the hotkey of the item you wish to select "
185 "followed by the <SPACE BAR>. " 184 "followed by the <SPACE BAR>. "
186 "Press <?> for additional information about this option."), 185 "Press <?> for additional information about this option.",
187inputbox_instructions_int[] = N_( 186inputbox_instructions_int[] =
188 "Please enter a decimal value. " 187 "Please enter a decimal value. "
189 "Fractions will not be accepted. " 188 "Fractions will not be accepted. "
190 "Use the <TAB> key to move from the input field to the buttons below it."), 189 "Use the <TAB> key to move from the input field to the buttons below it.",
191inputbox_instructions_hex[] = N_( 190inputbox_instructions_hex[] =
192 "Please enter a hexadecimal value. " 191 "Please enter a hexadecimal value. "
193 "Use the <TAB> key to move from the input field to the buttons below it."), 192 "Use the <TAB> key to move from the input field to the buttons below it.",
194inputbox_instructions_string[] = N_( 193inputbox_instructions_string[] =
195 "Please enter a string value. " 194 "Please enter a string value. "
196 "Use the <TAB> key to move from the input field to the buttons below it."), 195 "Use the <TAB> key to move from the input field to the buttons below it.",
197setmod_text[] = N_( 196setmod_text[] =
198 "This feature depends on another which has been configured as a module.\n" 197 "This feature depends on another which has been configured as a module.\n"
199 "As a result, this feature will be built as a module."), 198 "As a result, this feature will be built as a module.",
200load_config_text[] = N_( 199load_config_text[] =
201 "Enter the name of the configuration file you wish to load. " 200 "Enter the name of the configuration file you wish to load. "
202 "Accept the name shown to restore the configuration you " 201 "Accept the name shown to restore the configuration you "
203 "last retrieved. Leave blank to abort."), 202 "last retrieved. Leave blank to abort.",
204load_config_help[] = N_( 203load_config_help[] =
205 "\n" 204 "\n"
206 "For various reasons, one may wish to keep several different\n" 205 "For various reasons, one may wish to keep several different\n"
207 "configurations available on a single machine.\n" 206 "configurations available on a single machine.\n"
@@ -211,11 +210,11 @@ load_config_help[] = N_(
211 "configuration.\n" 210 "configuration.\n"
212 "\n" 211 "\n"
213 "If you are uncertain, then you have probably never used alternate\n" 212 "If you are uncertain, then you have probably never used alternate\n"
214 "configuration files. You should therefore leave this blank to abort.\n"), 213 "configuration files. You should therefore leave this blank to abort.\n",
215save_config_text[] = N_( 214save_config_text[] =
216 "Enter a filename to which this configuration should be saved " 215 "Enter a filename to which this configuration should be saved "
217 "as an alternate. Leave blank to abort."), 216 "as an alternate. Leave blank to abort.",
218save_config_help[] = N_( 217save_config_help[] =
219 "\n" 218 "\n"
220 "For various reasons, one may wish to keep different configurations\n" 219 "For various reasons, one may wish to keep different configurations\n"
221 "available on a single machine.\n" 220 "available on a single machine.\n"
@@ -225,8 +224,8 @@ save_config_help[] = N_(
225 "configuration options you have selected at that time.\n" 224 "configuration options you have selected at that time.\n"
226 "\n" 225 "\n"
227 "If you are uncertain what all this means then you should probably\n" 226 "If you are uncertain what all this means then you should probably\n"
228 "leave this blank.\n"), 227 "leave this blank.\n",
229search_help[] = N_( 228search_help[] =
230 "\n" 229 "\n"
231 "Search for symbols and display their relations.\n" 230 "Search for symbols and display their relations.\n"
232 "Regular expressions are allowed.\n" 231 "Regular expressions are allowed.\n"
@@ -271,7 +270,7 @@ search_help[] = N_(
271 "Examples: USB => find all symbols containing USB\n" 270 "Examples: USB => find all symbols containing USB\n"
272 " ^USB => find all symbols starting with USB\n" 271 " ^USB => find all symbols starting with USB\n"
273 " USB$ => find all symbols ending with USB\n" 272 " USB$ => find all symbols ending with USB\n"
274 "\n"); 273 "\n";
275 274
276static int indent; 275static int indent;
277static struct menu *current_menu; 276static struct menu *current_menu;
@@ -400,19 +399,19 @@ static void search_conf(void)
400 struct subtitle_part stpart; 399 struct subtitle_part stpart;
401 400
402 title = str_new(); 401 title = str_new();
403 str_printf( &title, _("Enter (sub)string or regexp to search for " 402 str_printf( &title, "Enter (sub)string or regexp to search for "
404 "(with or without \"%s\")"), CONFIG_); 403 "(with or without \"%s\")", CONFIG_);
405 404
406again: 405again:
407 dialog_clear(); 406 dialog_clear();
408 dres = dialog_inputbox(_("Search Configuration Parameter"), 407 dres = dialog_inputbox("Search Configuration Parameter",
409 str_get(&title), 408 str_get(&title),
410 10, 75, ""); 409 10, 75, "");
411 switch (dres) { 410 switch (dres) {
412 case 0: 411 case 0:
413 break; 412 break;
414 case 1: 413 case 1:
415 show_helptext(_("Search Configuration"), search_help); 414 show_helptext("Search Configuration", search_help);
416 goto again; 415 goto again;
417 default: 416 default:
418 str_free(&title); 417 str_free(&title);
@@ -443,7 +442,7 @@ again:
443 442
444 res = get_relations_str(sym_arr, &head); 443 res = get_relations_str(sym_arr, &head);
445 set_subtitle(); 444 set_subtitle();
446 dres = show_textbox_ext(_("Search Results"), (char *) 445 dres = show_textbox_ext("Search Results", (char *)
447 str_get(&res), 0, 0, keys, &vscroll, 446 str_get(&res), 0, 0, keys, &vscroll,
448 &hscroll, &update_text, (void *) 447 &hscroll, &update_text, (void *)
449 &data); 448 &data);
@@ -491,7 +490,6 @@ static void build_conf(struct menu *menu)
491 switch (prop->type) { 490 switch (prop->type) {
492 case P_MENU: 491 case P_MENU:
493 child_count++; 492 child_count++;
494 prompt = _(prompt);
495 if (single_menu_mode) { 493 if (single_menu_mode) {
496 item_make("%s%*c%s", 494 item_make("%s%*c%s",
497 menu->data ? "-->" : "++>", 495 menu->data ? "-->" : "++>",
@@ -508,7 +506,7 @@ static void build_conf(struct menu *menu)
508 case P_COMMENT: 506 case P_COMMENT:
509 if (prompt) { 507 if (prompt) {
510 child_count++; 508 child_count++;
511 item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt)); 509 item_make(" %*c*** %s ***", indent + 1, ' ', prompt);
512 item_set_tag(':'); 510 item_set_tag(':');
513 item_set_data(menu); 511 item_set_data(menu);
514 } 512 }
@@ -516,7 +514,7 @@ static void build_conf(struct menu *menu)
516 default: 514 default:
517 if (prompt) { 515 if (prompt) {
518 child_count++; 516 child_count++;
519 item_make("---%*c%s", indent + 1, ' ', _(prompt)); 517 item_make("---%*c%s", indent + 1, ' ', prompt);
520 item_set_tag(':'); 518 item_set_tag(':');
521 item_set_data(menu); 519 item_set_data(menu);
522 } 520 }
@@ -560,10 +558,10 @@ static void build_conf(struct menu *menu)
560 item_set_data(menu); 558 item_set_data(menu);
561 } 559 }
562 560
563 item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); 561 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
564 if (val == yes) { 562 if (val == yes) {
565 if (def_menu) { 563 if (def_menu) {
566 item_add_str(" (%s)", _(menu_get_prompt(def_menu))); 564 item_add_str(" (%s)", menu_get_prompt(def_menu));
567 item_add_str(" --->"); 565 item_add_str(" --->");
568 if (def_menu->list) { 566 if (def_menu->list) {
569 indent += 2; 567 indent += 2;
@@ -575,7 +573,7 @@ static void build_conf(struct menu *menu)
575 } 573 }
576 } else { 574 } else {
577 if (menu == current_menu) { 575 if (menu == current_menu) {
578 item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); 576 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
579 item_set_tag(':'); 577 item_set_tag(':');
580 item_set_data(menu); 578 item_set_data(menu);
581 goto conf_childs; 579 goto conf_childs;
@@ -618,17 +616,17 @@ static void build_conf(struct menu *menu)
618 tmp = indent - tmp + 4; 616 tmp = indent - tmp + 4;
619 if (tmp < 0) 617 if (tmp < 0)
620 tmp = 0; 618 tmp = 0;
621 item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), 619 item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
622 (sym_has_value(sym) || !sym_is_changable(sym)) ? 620 (sym_has_value(sym) || !sym_is_changable(sym)) ?
623 "" : _(" (NEW)")); 621 "" : " (NEW)");
624 item_set_tag('s'); 622 item_set_tag('s');
625 item_set_data(menu); 623 item_set_data(menu);
626 goto conf_childs; 624 goto conf_childs;
627 } 625 }
628 } 626 }
629 item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), 627 item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
630 (sym_has_value(sym) || !sym_is_changable(sym)) ? 628 (sym_has_value(sym) || !sym_is_changable(sym)) ?
631 "" : _(" (NEW)")); 629 "" : " (NEW)");
632 if (menu->prompt->type == P_MENU) { 630 if (menu->prompt->type == P_MENU) {
633 item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); 631 item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
634 return; 632 return;
@@ -665,8 +663,8 @@ static void conf(struct menu *menu, struct menu *active_menu)
665 break; 663 break;
666 set_subtitle(); 664 set_subtitle();
667 dialog_clear(); 665 dialog_clear();
668 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), 666 res = dialog_menu(prompt ? prompt : "Main Menu",
669 _(menu_instructions), 667 menu_instructions,
670 active_menu, &s_scroll); 668 active_menu, &s_scroll);
671 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) 669 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
672 break; 670 break;
@@ -708,7 +706,7 @@ static void conf(struct menu *menu, struct menu *active_menu)
708 show_help(submenu); 706 show_help(submenu);
709 else { 707 else {
710 reset_subtitle(); 708 reset_subtitle();
711 show_helptext(_("README"), _(mconf_readme)); 709 show_helptext("README", mconf_readme);
712 } 710 }
713 break; 711 break;
714 case 3: 712 case 3:
@@ -773,16 +771,13 @@ static void show_helptext(const char *title, const char *text)
773 show_textbox(title, text, 0, 0); 771 show_textbox(title, text, 0, 0);
774} 772}
775 773
776static void conf_message_callback(const char *fmt, va_list ap) 774static void conf_message_callback(const char *s)
777{ 775{
778 char buf[PATH_MAX+1];
779
780 vsnprintf(buf, sizeof(buf), fmt, ap);
781 if (save_and_exit) { 776 if (save_and_exit) {
782 if (!silent) 777 if (!silent)
783 printf("%s", buf); 778 printf("%s", s);
784 } else { 779 } else {
785 show_textbox(NULL, buf, 6, 60); 780 show_textbox(NULL, s, 6, 60);
786 } 781 }
787} 782}
788 783
@@ -793,13 +788,13 @@ static void show_help(struct menu *menu)
793 help.max_width = getmaxx(stdscr) - 10; 788 help.max_width = getmaxx(stdscr) - 10;
794 menu_get_ext_help(menu, &help); 789 menu_get_ext_help(menu, &help);
795 790
796 show_helptext(_(menu_get_prompt(menu)), str_get(&help)); 791 show_helptext(menu_get_prompt(menu), str_get(&help));
797 str_free(&help); 792 str_free(&help);
798} 793}
799 794
800static void conf_choice(struct menu *menu) 795static void conf_choice(struct menu *menu)
801{ 796{
802 const char *prompt = _(menu_get_prompt(menu)); 797 const char *prompt = menu_get_prompt(menu);
803 struct menu *child; 798 struct menu *child;
804 struct symbol *active; 799 struct symbol *active;
805 800
@@ -814,9 +809,9 @@ static void conf_choice(struct menu *menu)
814 if (!menu_is_visible(child)) 809 if (!menu_is_visible(child))
815 continue; 810 continue;
816 if (child->sym) 811 if (child->sym)
817 item_make("%s", _(menu_get_prompt(child))); 812 item_make("%s", menu_get_prompt(child));
818 else { 813 else {
819 item_make("*** %s ***", _(menu_get_prompt(child))); 814 item_make("*** %s ***", menu_get_prompt(child));
820 item_set_tag(':'); 815 item_set_tag(':');
821 } 816 }
822 item_set_data(child); 817 item_set_data(child);
@@ -826,8 +821,8 @@ static void conf_choice(struct menu *menu)
826 item_set_tag('X'); 821 item_set_tag('X');
827 } 822 }
828 dialog_clear(); 823 dialog_clear();
829 res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), 824 res = dialog_checklist(prompt ? prompt : "Main Menu",
830 _(radiolist_instructions), 825 radiolist_instructions,
831 MENUBOX_HEIGTH_MIN, 826 MENUBOX_HEIGTH_MIN,
832 MENUBOX_WIDTH_MIN, 827 MENUBOX_WIDTH_MIN,
833 CHECKLIST_HEIGTH_MIN); 828 CHECKLIST_HEIGTH_MIN);
@@ -868,26 +863,26 @@ static void conf_string(struct menu *menu)
868 863
869 switch (sym_get_type(menu->sym)) { 864 switch (sym_get_type(menu->sym)) {
870 case S_INT: 865 case S_INT:
871 heading = _(inputbox_instructions_int); 866 heading = inputbox_instructions_int;
872 break; 867 break;
873 case S_HEX: 868 case S_HEX:
874 heading = _(inputbox_instructions_hex); 869 heading = inputbox_instructions_hex;
875 break; 870 break;
876 case S_STRING: 871 case S_STRING:
877 heading = _(inputbox_instructions_string); 872 heading = inputbox_instructions_string;
878 break; 873 break;
879 default: 874 default:
880 heading = _("Internal mconf error!"); 875 heading = "Internal mconf error!";
881 } 876 }
882 dialog_clear(); 877 dialog_clear();
883 res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), 878 res = dialog_inputbox(prompt ? prompt : "Main Menu",
884 heading, 10, 75, 879 heading, 10, 75,
885 sym_get_string_value(menu->sym)); 880 sym_get_string_value(menu->sym));
886 switch (res) { 881 switch (res) {
887 case 0: 882 case 0:
888 if (sym_set_string_value(menu->sym, dialog_input_result)) 883 if (sym_set_string_value(menu->sym, dialog_input_result))
889 return; 884 return;
890 show_textbox(NULL, _("You have made an invalid entry."), 5, 43); 885 show_textbox(NULL, "You have made an invalid entry.", 5, 43);
891 break; 886 break;
892 case 1: 887 case 1:
893 show_help(menu); 888 show_help(menu);
@@ -915,10 +910,10 @@ static void conf_load(void)
915 sym_set_change_count(1); 910 sym_set_change_count(1);
916 return; 911 return;
917 } 912 }
918 show_textbox(NULL, _("File does not exist!"), 5, 38); 913 show_textbox(NULL, "File does not exist!", 5, 38);
919 break; 914 break;
920 case 1: 915 case 1:
921 show_helptext(_("Load Alternate Configuration"), load_config_help); 916 show_helptext("Load Alternate Configuration", load_config_help);
922 break; 917 break;
923 case KEY_ESC: 918 case KEY_ESC:
924 return; 919 return;
@@ -941,10 +936,10 @@ static void conf_save(void)
941 set_config_filename(dialog_input_result); 936 set_config_filename(dialog_input_result);
942 return; 937 return;
943 } 938 }
944 show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); 939 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
945 break; 940 break;
946 case 1: 941 case 1:
947 show_helptext(_("Save Alternate Configuration"), save_config_help); 942 show_helptext("Save Alternate Configuration", save_config_help);
948 break; 943 break;
949 case KEY_ESC: 944 case KEY_ESC:
950 return; 945 return;
@@ -961,8 +956,8 @@ static int handle_exit(void)
961 dialog_clear(); 956 dialog_clear();
962 if (conf_get_changed()) 957 if (conf_get_changed())
963 res = dialog_yesno(NULL, 958 res = dialog_yesno(NULL,
964 _("Do you wish to save your new configuration?\n" 959 "Do you wish to save your new configuration?\n"
965 "(Press <ESC><ESC> to continue kernel configuration.)"), 960 "(Press <ESC><ESC> to continue kernel configuration.)",
966 6, 60); 961 6, 60);
967 else 962 else
968 res = -1; 963 res = -1;
@@ -972,26 +967,27 @@ static int handle_exit(void)
972 switch (res) { 967 switch (res) {
973 case 0: 968 case 0:
974 if (conf_write(filename)) { 969 if (conf_write(filename)) {
975 fprintf(stderr, _("\n\n" 970 fprintf(stderr, "\n\n"
976 "Error while writing of the configuration.\n" 971 "Error while writing of the configuration.\n"
977 "Your configuration changes were NOT saved." 972 "Your configuration changes were NOT saved."
978 "\n\n")); 973 "\n\n");
979 return 1; 974 return 1;
980 } 975 }
976 conf_write_autoconf(0);
981 /* fall through */ 977 /* fall through */
982 case -1: 978 case -1:
983 if (!silent) 979 if (!silent)
984 printf(_("\n\n" 980 printf("\n\n"
985 "*** End of the configuration.\n" 981 "*** End of the configuration.\n"
986 "*** Execute 'make' to start the build or try 'make help'." 982 "*** Execute 'make' to start the build or try 'make help'."
987 "\n\n")); 983 "\n\n");
988 res = 0; 984 res = 0;
989 break; 985 break;
990 default: 986 default:
991 if (!silent) 987 if (!silent)
992 fprintf(stderr, _("\n\n" 988 fprintf(stderr, "\n\n"
993 "Your configuration changes were NOT saved." 989 "Your configuration changes were NOT saved."
994 "\n\n")); 990 "\n\n");
995 if (res != KEY_ESC) 991 if (res != KEY_ESC)
996 res = 0; 992 res = 0;
997 } 993 }
@@ -1009,10 +1005,6 @@ int main(int ac, char **av)
1009 char *mode; 1005 char *mode;
1010 int res; 1006 int res;
1011 1007
1012 setlocale(LC_ALL, "");
1013 bindtextdomain(PACKAGE, LOCALEDIR);
1014 textdomain(PACKAGE);
1015
1016 signal(SIGINT, sig_handler); 1008 signal(SIGINT, sig_handler);
1017 1009
1018 if (ac > 1 && strcmp(av[1], "-s") == 0) { 1010 if (ac > 1 && strcmp(av[1], "-s") == 0) {
@@ -1031,8 +1023,8 @@ int main(int ac, char **av)
1031 } 1023 }
1032 1024
1033 if (init_dialog(NULL)) { 1025 if (init_dialog(NULL)) {
1034 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); 1026 fprintf(stderr, "Your display is too small to run Menuconfig!\n");
1035 fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); 1027 fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
1036 return 1; 1028 return 1;
1037 } 1029 }
1038 1030
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 36cd3e1f1c28..4cf15d449c05 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -212,10 +212,7 @@ void menu_add_option(int token, char *arg)
212 sym_defconfig_list = current_entry->sym; 212 sym_defconfig_list = current_entry->sym;
213 else if (sym_defconfig_list != current_entry->sym) 213 else if (sym_defconfig_list != current_entry->sym)
214 zconf_error("trying to redefine defconfig symbol"); 214 zconf_error("trying to redefine defconfig symbol");
215 sym_defconfig_list->flags |= SYMBOL_AUTO; 215 sym_defconfig_list->flags |= SYMBOL_NO_WRITE;
216 break;
217 case T_OPT_ENV:
218 prop_add_env(arg);
219 break; 216 break;
220 case T_OPT_ALLNOCONFIG_Y: 217 case T_OPT_ALLNOCONFIG_Y:
221 current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; 218 current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
@@ -711,7 +708,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
711 struct menu *submenu[8], *menu, *location = NULL; 708 struct menu *submenu[8], *menu, *location = NULL;
712 struct jump_key *jump = NULL; 709 struct jump_key *jump = NULL;
713 710
714 str_printf(r, _("Prompt: %s\n"), _(prop->text)); 711 str_printf(r, "Prompt: %s\n", prop->text);
715 menu = prop->menu->parent; 712 menu = prop->menu->parent;
716 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { 713 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
717 bool accessible = menu_is_visible(menu); 714 bool accessible = menu_is_visible(menu);
@@ -744,16 +741,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
744 } 741 }
745 742
746 if (i > 0) { 743 if (i > 0) {
747 str_printf(r, _(" Location:\n")); 744 str_printf(r, " Location:\n");
748 for (j = 4; --i >= 0; j += 2) { 745 for (j = 4; --i >= 0; j += 2) {
749 menu = submenu[i]; 746 menu = submenu[i];
750 if (jump && menu == location) 747 if (jump && menu == location)
751 jump->offset = strlen(r->s); 748 jump->offset = strlen(r->s);
752 str_printf(r, "%*c-> %s", j, ' ', 749 str_printf(r, "%*c-> %s", j, ' ',
753 _(menu_get_prompt(menu))); 750 menu_get_prompt(menu));
754 if (menu->sym) { 751 if (menu->sym) {
755 str_printf(r, " (%s [=%s])", menu->sym->name ? 752 str_printf(r, " (%s [=%s])", menu->sym->name ?
756 menu->sym->name : _("<choice>"), 753 menu->sym->name : "<choice>",
757 sym_get_string_value(menu->sym)); 754 sym_get_string_value(menu->sym));
758 } 755 }
759 str_append(r, "\n"); 756 str_append(r, "\n");
@@ -817,27 +814,27 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
817 814
818 prop = get_symbol_prop(sym); 815 prop = get_symbol_prop(sym);
819 if (prop) { 816 if (prop) {
820 str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, 817 str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
821 prop->menu->lineno); 818 prop->menu->lineno);
822 if (!expr_is_yes(prop->visible.expr)) { 819 if (!expr_is_yes(prop->visible.expr)) {
823 str_append(r, _(" Depends on: ")); 820 str_append(r, " Depends on: ");
824 expr_gstr_print(prop->visible.expr, r); 821 expr_gstr_print(prop->visible.expr, r);
825 str_append(r, "\n"); 822 str_append(r, "\n");
826 } 823 }
827 } 824 }
828 825
829 get_symbol_props_str(r, sym, P_SELECT, _(" Selects: ")); 826 get_symbol_props_str(r, sym, P_SELECT, " Selects: ");
830 if (sym->rev_dep.expr) { 827 if (sym->rev_dep.expr) {
831 str_append(r, _(" Selected by: ")); 828 expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n");
832 expr_gstr_print_revdep(sym->rev_dep.expr, r); 829 expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n");
833 str_append(r, "\n"); 830 expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n");
834 } 831 }
835 832
836 get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: ")); 833 get_symbol_props_str(r, sym, P_IMPLY, " Implies: ");
837 if (sym->implied.expr) { 834 if (sym->implied.expr) {
838 str_append(r, _(" Implied by: ")); 835 expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n");
839 expr_gstr_print_revdep(sym->implied.expr, r); 836 expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n");
840 str_append(r, "\n"); 837 expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n");
841 } 838 }
842 839
843 str_append(r, "\n\n"); 840 str_append(r, "\n\n");
@@ -852,7 +849,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
852 for (i = 0; sym_arr && (sym = sym_arr[i]); i++) 849 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
853 get_symbol_str(&res, sym, head); 850 get_symbol_str(&res, sym, head);
854 if (!i) 851 if (!i)
855 str_append(&res, _("No matches found.\n")); 852 str_append(&res, "No matches found.\n");
856 return res; 853 return res;
857} 854}
858 855
@@ -867,7 +864,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
867 str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); 864 str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
868 help_text = menu_get_help(menu); 865 help_text = menu_get_help(menu);
869 } 866 }
870 str_printf(help, "%s\n", _(help_text)); 867 str_printf(help, "%s\n", help_text);
871 if (sym) 868 if (sym)
872 get_symbol_str(help, sym, NULL); 869 get_symbol_str(help, sym, NULL);
873} 870}
diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh
index 67d131447631..0ef906499646 100755
--- a/scripts/kconfig/merge_config.sh
+++ b/scripts/kconfig/merge_config.sh
@@ -33,12 +33,15 @@ usage() {
33 echo " -n use allnoconfig instead of alldefconfig" 33 echo " -n use allnoconfig instead of alldefconfig"
34 echo " -r list redundant entries when merging fragments" 34 echo " -r list redundant entries when merging fragments"
35 echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead." 35 echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead."
36 echo
37 echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with \$CONFIG_ environment variable."
36} 38}
37 39
38RUNMAKE=true 40RUNMAKE=true
39ALLTARGET=alldefconfig 41ALLTARGET=alldefconfig
40WARNREDUN=false 42WARNREDUN=false
41OUTPUT=. 43OUTPUT=.
44CONFIG_PREFIX=${CONFIG_-CONFIG_}
42 45
43while true; do 46while true; do
44 case $1 in 47 case $1 in
@@ -99,7 +102,9 @@ if [ ! -r "$INITFILE" ]; then
99fi 102fi
100 103
101MERGE_LIST=$* 104MERGE_LIST=$*
102SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" 105SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p"
106SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p"
107
103TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) 108TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
104 109
105echo "Using $INITFILE as base" 110echo "Using $INITFILE as base"
@@ -112,7 +117,7 @@ for MERGE_FILE in $MERGE_LIST ; do
112 echo "The merge file '$MERGE_FILE' does not exist. Exit." >&2 117 echo "The merge file '$MERGE_FILE' does not exist. Exit." >&2
113 exit 1 118 exit 1
114 fi 119 fi
115 CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE) 120 CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE)
116 121
117 for CFG in $CFG_LIST ; do 122 for CFG in $CFG_LIST ; do
118 grep -q -w $CFG $TMP_FILE || continue 123 grep -q -w $CFG $TMP_FILE || continue
@@ -155,7 +160,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
155 160
156 161
157# Check all specified config values took (might have missed-dependency issues) 162# Check all specified config values took (might have missed-dependency issues)
158for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do 163for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do
159 164
160 REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) 165 REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
161 ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG") 166 ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG")
diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh
new file mode 100644
index 000000000000..001559ef0a60
--- /dev/null
+++ b/scripts/kconfig/nconf-cfg.sh
@@ -0,0 +1,47 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4PKG="ncursesw menuw panelw"
5PKG2="ncurses menu panel"
6
7if [ -n "$(command -v pkg-config)" ]; then
8 if pkg-config --exists $PKG; then
9 echo cflags=\"$(pkg-config --cflags $PKG)\"
10 echo libs=\"$(pkg-config --libs $PKG)\"
11 exit 0
12 fi
13
14 if pkg-config --exists $PKG2; then
15 echo cflags=\"$(pkg-config --cflags $PKG2)\"
16 echo libs=\"$(pkg-config --libs $PKG2)\"
17 exit 0
18 fi
19fi
20
21# Check the default paths in case pkg-config is not installed.
22# (Even if it is installed, some distributions such as openSUSE cannot
23# find ncurses by pkg-config.)
24if [ -f /usr/include/ncursesw/ncurses.h ]; then
25 echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
26 echo libs=\"-lncursesw -lmenuw -lpanelw\"
27 exit 0
28fi
29
30if [ -f /usr/include/ncurses/ncurses.h ]; then
31 echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncurses\"
32 echo libs=\"-lncurses -lmenu -lpanel\"
33 exit 0
34fi
35
36if [ -f /usr/include/ncurses.h ]; then
37 echo cflags=\"-D_GNU_SOURCE\"
38 echo libs=\"-lncurses -lmenu -lpanel\"
39 exit 0
40fi
41
42echo >&2 "*"
43echo >&2 "* Unable to find the ncurses package."
44echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
45echo >&2 "* depending on your distribution)."
46echo >&2 "*"
47exit 1
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 003114779815..1ef232ae5ab9 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -15,7 +15,7 @@
15#include "nconf.h" 15#include "nconf.h"
16#include <ctype.h> 16#include <ctype.h>
17 17
18static const char nconf_global_help[] = N_( 18static const char nconf_global_help[] =
19"Help windows\n" 19"Help windows\n"
20"------------\n" 20"------------\n"
21"o Global help: Unless in a data entry window, pressing <F1> will give \n" 21"o Global help: Unless in a data entry window, pressing <F1> will give \n"
@@ -130,8 +130,8 @@ static const char nconf_global_help[] = N_(
130"\n" 130"\n"
131"Note that this mode can eventually be a little more CPU expensive than\n" 131"Note that this mode can eventually be a little more CPU expensive than\n"
132"the default mode, especially with a larger number of unfolded submenus.\n" 132"the default mode, especially with a larger number of unfolded submenus.\n"
133"\n"), 133"\n",
134menu_no_f_instructions[] = N_( 134menu_no_f_instructions[] =
135"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 135"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
136"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" 136"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
137"\n" 137"\n"
@@ -147,8 +147,8 @@ menu_no_f_instructions[] = N_(
147"You do not have function keys support.\n" 147"You do not have function keys support.\n"
148"Press <1> instead of <F1>, <2> instead of <F2>, etc.\n" 148"Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
149"For verbose global help use key <1>.\n" 149"For verbose global help use key <1>.\n"
150"For help related to the current menu entry press <?> or <h>.\n"), 150"For help related to the current menu entry press <?> or <h>.\n",
151menu_instructions[] = N_( 151menu_instructions[] =
152"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 152"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
153"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" 153"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
154"\n" 154"\n"
@@ -163,30 +163,30 @@ menu_instructions[] = N_(
163"\n" 163"\n"
164"Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n" 164"Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
165"For verbose global help press <F1>.\n" 165"For verbose global help press <F1>.\n"
166"For help related to the current menu entry press <?> or <h>.\n"), 166"For help related to the current menu entry press <?> or <h>.\n",
167radiolist_instructions[] = N_( 167radiolist_instructions[] =
168"Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n" 168"Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
169"with <Space>.\n" 169"with <Space>.\n"
170"For help related to the current entry press <?> or <h>.\n" 170"For help related to the current entry press <?> or <h>.\n"
171"For global help press <F1>.\n"), 171"For global help press <F1>.\n",
172inputbox_instructions_int[] = N_( 172inputbox_instructions_int[] =
173"Please enter a decimal value.\n" 173"Please enter a decimal value.\n"
174"Fractions will not be accepted.\n" 174"Fractions will not be accepted.\n"
175"Press <Enter> to apply, <Esc> to cancel."), 175"Press <Enter> to apply, <Esc> to cancel.",
176inputbox_instructions_hex[] = N_( 176inputbox_instructions_hex[] =
177"Please enter a hexadecimal value.\n" 177"Please enter a hexadecimal value.\n"
178"Press <Enter> to apply, <Esc> to cancel."), 178"Press <Enter> to apply, <Esc> to cancel.",
179inputbox_instructions_string[] = N_( 179inputbox_instructions_string[] =
180"Please enter a string value.\n" 180"Please enter a string value.\n"
181"Press <Enter> to apply, <Esc> to cancel."), 181"Press <Enter> to apply, <Esc> to cancel.",
182setmod_text[] = N_( 182setmod_text[] =
183"This feature depends on another feature which has been configured as a\n" 183"This feature depends on another feature which has been configured as a\n"
184"module. As a result, the current feature will be built as a module too."), 184"module. As a result, the current feature will be built as a module too.",
185load_config_text[] = N_( 185load_config_text[] =
186"Enter the name of the configuration file you wish to load.\n" 186"Enter the name of the configuration file you wish to load.\n"
187"Accept the name shown to restore the configuration you last\n" 187"Accept the name shown to restore the configuration you last\n"
188"retrieved. Leave empty to abort."), 188"retrieved. Leave empty to abort.",
189load_config_help[] = N_( 189load_config_help[] =
190"For various reasons, one may wish to keep several different\n" 190"For various reasons, one may wish to keep several different\n"
191"configurations available on a single machine.\n" 191"configurations available on a single machine.\n"
192"\n" 192"\n"
@@ -194,11 +194,11 @@ load_config_help[] = N_(
194"default one, entering its name here will allow you to load and modify\n" 194"default one, entering its name here will allow you to load and modify\n"
195"that configuration.\n" 195"that configuration.\n"
196"\n" 196"\n"
197"Leave empty to abort.\n"), 197"Leave empty to abort.\n",
198save_config_text[] = N_( 198save_config_text[] =
199"Enter a filename to which this configuration should be saved\n" 199"Enter a filename to which this configuration should be saved\n"
200"as an alternate. Leave empty to abort."), 200"as an alternate. Leave empty to abort.",
201save_config_help[] = N_( 201save_config_help[] =
202"For various reasons, one may wish to keep several different\n" 202"For various reasons, one may wish to keep several different\n"
203"configurations available on a single machine.\n" 203"configurations available on a single machine.\n"
204"\n" 204"\n"
@@ -206,8 +206,8 @@ save_config_help[] = N_(
206"and use the current configuration as an alternate to whatever\n" 206"and use the current configuration as an alternate to whatever\n"
207"configuration options you have selected at that time.\n" 207"configuration options you have selected at that time.\n"
208"\n" 208"\n"
209"Leave empty to abort.\n"), 209"Leave empty to abort.\n",
210search_help[] = N_( 210search_help[] =
211"Search for symbols (configuration variable names CONFIG_*) and display\n" 211"Search for symbols (configuration variable names CONFIG_*) and display\n"
212"their relations. Regular expressions are supported.\n" 212"their relations. Regular expressions are supported.\n"
213"Example: Search for \"^FOO\".\n" 213"Example: Search for \"^FOO\".\n"
@@ -244,7 +244,7 @@ search_help[] = N_(
244"USB => find all symbols containing USB\n" 244"USB => find all symbols containing USB\n"
245"^USB => find all symbols starting with USB\n" 245"^USB => find all symbols starting with USB\n"
246"USB$ => find all symbols ending with USB\n" 246"USB$ => find all symbols ending with USB\n"
247"\n"); 247"\n";
248 248
249struct mitem { 249struct mitem {
250 char str[256]; 250 char str[256];
@@ -388,7 +388,7 @@ static void print_function_line(void)
388static void handle_f1(int *key, struct menu *current_item) 388static void handle_f1(int *key, struct menu *current_item)
389{ 389{
390 show_scroll_win(main_window, 390 show_scroll_win(main_window,
391 _("Global help"), _(nconf_global_help)); 391 "Global help", nconf_global_help);
392 return; 392 return;
393} 393}
394 394
@@ -403,8 +403,8 @@ static void handle_f2(int *key, struct menu *current_item)
403static void handle_f3(int *key, struct menu *current_item) 403static void handle_f3(int *key, struct menu *current_item)
404{ 404{
405 show_scroll_win(main_window, 405 show_scroll_win(main_window,
406 _("Short help"), 406 "Short help",
407 _(current_instructions)); 407 current_instructions);
408 return; 408 return;
409} 409}
410 410
@@ -412,7 +412,7 @@ static void handle_f3(int *key, struct menu *current_item)
412static void handle_f4(int *key, struct menu *current_item) 412static void handle_f4(int *key, struct menu *current_item)
413{ 413{
414 int res = btn_dialog(main_window, 414 int res = btn_dialog(main_window,
415 _("Show all symbols?"), 415 "Show all symbols?",
416 2, 416 2,
417 " <Show All> ", 417 " <Show All> ",
418 "<Don't show all>"); 418 "<Don't show all>");
@@ -653,8 +653,8 @@ static int do_exit(void)
653 return 0; 653 return 0;
654 } 654 }
655 res = btn_dialog(main_window, 655 res = btn_dialog(main_window,
656 _("Do you wish to save your new configuration?\n" 656 "Do you wish to save your new configuration?\n"
657 "<ESC> to cancel and resume nconfig."), 657 "<ESC> to cancel and resume nconfig.",
658 2, 658 2,
659 " <save> ", 659 " <save> ",
660 "<don't save>"); 660 "<don't save>");
@@ -670,15 +670,16 @@ static int do_exit(void)
670 if (res) 670 if (res)
671 btn_dialog( 671 btn_dialog(
672 main_window, 672 main_window,
673 _("Error during writing of configuration.\n" 673 "Error during writing of configuration.\n"
674 "Your configuration changes were NOT saved."), 674 "Your configuration changes were NOT saved.",
675 1, 675 1,
676 "<OK>"); 676 "<OK>");
677 conf_write_autoconf(0);
677 break; 678 break;
678 default: 679 default:
679 btn_dialog( 680 btn_dialog(
680 main_window, 681 main_window,
681 _("Your configuration changes were NOT saved."), 682 "Your configuration changes were NOT saved.",
682 1, 683 1,
683 "<OK>"); 684 "<OK>");
684 break; 685 break;
@@ -697,12 +698,12 @@ static void search_conf(void)
697 int dres; 698 int dres;
698 699
699 title = str_new(); 700 title = str_new();
700 str_printf( &title, _("Enter (sub)string or regexp to search for " 701 str_printf( &title, "Enter (sub)string or regexp to search for "
701 "(with or without \"%s\")"), CONFIG_); 702 "(with or without \"%s\")", CONFIG_);
702 703
703again: 704again:
704 dres = dialog_inputbox(main_window, 705 dres = dialog_inputbox(main_window,
705 _("Search Configuration Parameter"), 706 "Search Configuration Parameter",
706 str_get(&title), 707 str_get(&title),
707 "", &dialog_input_result, &dialog_input_result_len); 708 "", &dialog_input_result, &dialog_input_result_len);
708 switch (dres) { 709 switch (dres) {
@@ -710,7 +711,7 @@ again:
710 break; 711 break;
711 case 1: 712 case 1:
712 show_scroll_win(main_window, 713 show_scroll_win(main_window,
713 _("Search Configuration"), search_help); 714 "Search Configuration", search_help);
714 goto again; 715 goto again;
715 default: 716 default:
716 str_free(&title); 717 str_free(&title);
@@ -726,7 +727,7 @@ again:
726 res = get_relations_str(sym_arr, NULL); 727 res = get_relations_str(sym_arr, NULL);
727 free(sym_arr); 728 free(sym_arr);
728 show_scroll_win(main_window, 729 show_scroll_win(main_window,
729 _("Search Results"), str_get(&res)); 730 "Search Results", str_get(&res));
730 str_free(&res); 731 str_free(&res);
731 str_free(&title); 732 str_free(&title);
732} 733}
@@ -754,7 +755,7 @@ static void build_conf(struct menu *menu)
754 switch (ptype) { 755 switch (ptype) {
755 case P_MENU: 756 case P_MENU:
756 child_count++; 757 child_count++;
757 prompt = _(prompt); 758 prompt = prompt;
758 if (single_menu_mode) { 759 if (single_menu_mode) {
759 item_make(menu, 'm', 760 item_make(menu, 'm',
760 "%s%*c%s", 761 "%s%*c%s",
@@ -775,7 +776,7 @@ static void build_conf(struct menu *menu)
775 item_make(menu, ':', 776 item_make(menu, ':',
776 " %*c*** %s ***", 777 " %*c*** %s ***",
777 indent + 1, ' ', 778 indent + 1, ' ',
778 _(prompt)); 779 prompt);
779 } 780 }
780 break; 781 break;
781 default: 782 default:
@@ -783,7 +784,7 @@ static void build_conf(struct menu *menu)
783 child_count++; 784 child_count++;
784 item_make(menu, ':', "---%*c%s", 785 item_make(menu, ':', "---%*c%s",
785 indent + 1, ' ', 786 indent + 1, ' ',
786 _(prompt)); 787 prompt);
787 } 788 }
788 } 789 }
789 } else 790 } else
@@ -829,11 +830,11 @@ static void build_conf(struct menu *menu)
829 } 830 }
830 831
831 item_add_str("%*c%s", indent + 1, 832 item_add_str("%*c%s", indent + 1,
832 ' ', _(menu_get_prompt(menu))); 833 ' ', menu_get_prompt(menu));
833 if (val == yes) { 834 if (val == yes) {
834 if (def_menu) { 835 if (def_menu) {
835 item_add_str(" (%s)", 836 item_add_str(" (%s)",
836 _(menu_get_prompt(def_menu))); 837 menu_get_prompt(def_menu));
837 item_add_str(" --->"); 838 item_add_str(" --->");
838 if (def_menu->list) { 839 if (def_menu->list) {
839 indent += 2; 840 indent += 2;
@@ -847,7 +848,7 @@ static void build_conf(struct menu *menu)
847 if (menu == current_menu) { 848 if (menu == current_menu) {
848 item_make(menu, ':', 849 item_make(menu, ':',
849 "---%*c%s", indent + 1, 850 "---%*c%s", indent + 1,
850 ' ', _(menu_get_prompt(menu))); 851 ' ', menu_get_prompt(menu));
851 goto conf_childs; 852 goto conf_childs;
852 } 853 }
853 child_count++; 854 child_count++;
@@ -894,17 +895,17 @@ static void build_conf(struct menu *menu)
894 if (tmp < 0) 895 if (tmp < 0)
895 tmp = 0; 896 tmp = 0;
896 item_add_str("%*c%s%s", tmp, ' ', 897 item_add_str("%*c%s%s", tmp, ' ',
897 _(menu_get_prompt(menu)), 898 menu_get_prompt(menu),
898 (sym_has_value(sym) || 899 (sym_has_value(sym) ||
899 !sym_is_changable(sym)) ? "" : 900 !sym_is_changable(sym)) ? "" :
900 _(" (NEW)")); 901 " (NEW)");
901 goto conf_childs; 902 goto conf_childs;
902 } 903 }
903 } 904 }
904 item_add_str("%*c%s%s", indent + 1, ' ', 905 item_add_str("%*c%s%s", indent + 1, ' ',
905 _(menu_get_prompt(menu)), 906 menu_get_prompt(menu),
906 (sym_has_value(sym) || !sym_is_changable(sym)) ? 907 (sym_has_value(sym) || !sym_is_changable(sym)) ?
907 "" : _(" (NEW)")); 908 "" : " (NEW)");
908 if (menu->prompt && menu->prompt->type == P_MENU) { 909 if (menu->prompt && menu->prompt->type == P_MENU) {
909 item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); 910 item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
910 return; 911 return;
@@ -1086,8 +1087,8 @@ static void conf(struct menu *menu)
1086 if (!child_count) 1087 if (!child_count)
1087 break; 1088 break;
1088 1089
1089 show_menu(prompt ? _(prompt) : _("Main Menu"), 1090 show_menu(prompt ? prompt : "Main Menu",
1090 _(menu_instructions), 1091 menu_instructions,
1091 current_index, &last_top_row); 1092 current_index, &last_top_row);
1092 keypad((menu_win(curses_menu)), TRUE); 1093 keypad((menu_win(curses_menu)), TRUE);
1093 while (!global_exit) { 1094 while (!global_exit) {
@@ -1210,12 +1211,9 @@ static void conf(struct menu *menu)
1210 } 1211 }
1211} 1212}
1212 1213
1213static void conf_message_callback(const char *fmt, va_list ap) 1214static void conf_message_callback(const char *s)
1214{ 1215{
1215 char buf[1024]; 1216 btn_dialog(main_window, s, 1, "<OK>");
1216
1217 vsnprintf(buf, sizeof(buf), fmt, ap);
1218 btn_dialog(main_window, buf, 1, "<OK>");
1219} 1217}
1220 1218
1221static void show_help(struct menu *menu) 1219static void show_help(struct menu *menu)
@@ -1227,13 +1225,13 @@ static void show_help(struct menu *menu)
1227 1225
1228 help = str_new(); 1226 help = str_new();
1229 menu_get_ext_help(menu, &help); 1227 menu_get_ext_help(menu, &help);
1230 show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); 1228 show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help));
1231 str_free(&help); 1229 str_free(&help);
1232} 1230}
1233 1231
1234static void conf_choice(struct menu *menu) 1232static void conf_choice(struct menu *menu)
1235{ 1233{
1236 const char *prompt = _(menu_get_prompt(menu)); 1234 const char *prompt = menu_get_prompt(menu);
1237 struct menu *child = NULL; 1235 struct menu *child = NULL;
1238 struct symbol *active; 1236 struct symbol *active;
1239 int selected_index = 0; 1237 int selected_index = 0;
@@ -1256,13 +1254,13 @@ static void conf_choice(struct menu *menu)
1256 1254
1257 if (child->sym == sym_get_choice_value(menu->sym)) 1255 if (child->sym == sym_get_choice_value(menu->sym))
1258 item_make(child, ':', "<X> %s", 1256 item_make(child, ':', "<X> %s",
1259 _(menu_get_prompt(child))); 1257 menu_get_prompt(child));
1260 else if (child->sym) 1258 else if (child->sym)
1261 item_make(child, ':', " %s", 1259 item_make(child, ':', " %s",
1262 _(menu_get_prompt(child))); 1260 menu_get_prompt(child));
1263 else 1261 else
1264 item_make(child, ':', "*** %s ***", 1262 item_make(child, ':', "*** %s ***",
1265 _(menu_get_prompt(child))); 1263 menu_get_prompt(child));
1266 1264
1267 if (child->sym == active){ 1265 if (child->sym == active){
1268 last_top_row = top_row(curses_menu); 1266 last_top_row = top_row(curses_menu);
@@ -1270,8 +1268,8 @@ static void conf_choice(struct menu *menu)
1270 } 1268 }
1271 i++; 1269 i++;
1272 } 1270 }
1273 show_menu(prompt ? _(prompt) : _("Choice Menu"), 1271 show_menu(prompt ? prompt : "Choice Menu",
1274 _(radiolist_instructions), 1272 radiolist_instructions,
1275 selected_index, 1273 selected_index,
1276 &last_top_row); 1274 &last_top_row);
1277 while (!global_exit) { 1275 while (!global_exit) {
@@ -1358,19 +1356,19 @@ static void conf_string(struct menu *menu)
1358 1356
1359 switch (sym_get_type(menu->sym)) { 1357 switch (sym_get_type(menu->sym)) {
1360 case S_INT: 1358 case S_INT:
1361 heading = _(inputbox_instructions_int); 1359 heading = inputbox_instructions_int;
1362 break; 1360 break;
1363 case S_HEX: 1361 case S_HEX:
1364 heading = _(inputbox_instructions_hex); 1362 heading = inputbox_instructions_hex;
1365 break; 1363 break;
1366 case S_STRING: 1364 case S_STRING:
1367 heading = _(inputbox_instructions_string); 1365 heading = inputbox_instructions_string;
1368 break; 1366 break;
1369 default: 1367 default:
1370 heading = _("Internal nconf error!"); 1368 heading = "Internal nconf error!";
1371 } 1369 }
1372 res = dialog_inputbox(main_window, 1370 res = dialog_inputbox(main_window,
1373 prompt ? _(prompt) : _("Main Menu"), 1371 prompt ? prompt : "Main Menu",
1374 heading, 1372 heading,
1375 sym_get_string_value(menu->sym), 1373 sym_get_string_value(menu->sym),
1376 &dialog_input_result, 1374 &dialog_input_result,
@@ -1381,7 +1379,7 @@ static void conf_string(struct menu *menu)
1381 dialog_input_result)) 1379 dialog_input_result))
1382 return; 1380 return;
1383 btn_dialog(main_window, 1381 btn_dialog(main_window,
1384 _("You have made an invalid entry."), 0); 1382 "You have made an invalid entry.", 0);
1385 break; 1383 break;
1386 case 1: 1384 case 1:
1387 show_help(menu); 1385 show_help(menu);
@@ -1410,11 +1408,11 @@ static void conf_load(void)
1410 sym_set_change_count(1); 1408 sym_set_change_count(1);
1411 return; 1409 return;
1412 } 1410 }
1413 btn_dialog(main_window, _("File does not exist!"), 0); 1411 btn_dialog(main_window, "File does not exist!", 0);
1414 break; 1412 break;
1415 case 1: 1413 case 1:
1416 show_scroll_win(main_window, 1414 show_scroll_win(main_window,
1417 _("Load Alternate Configuration"), 1415 "Load Alternate Configuration",
1418 load_config_help); 1416 load_config_help);
1419 break; 1417 break;
1420 case KEY_EXIT: 1418 case KEY_EXIT:
@@ -1441,13 +1439,13 @@ static void conf_save(void)
1441 set_config_filename(dialog_input_result); 1439 set_config_filename(dialog_input_result);
1442 return; 1440 return;
1443 } 1441 }
1444 btn_dialog(main_window, _("Can't create file! " 1442 btn_dialog(main_window, "Can't create file! "
1445 "Probably a nonexistent directory."), 1443 "Probably a nonexistent directory.",
1446 1, "<OK>"); 1444 1, "<OK>");
1447 break; 1445 break;
1448 case 1: 1446 case 1:
1449 show_scroll_win(main_window, 1447 show_scroll_win(main_window,
1450 _("Save Alternate Configuration"), 1448 "Save Alternate Configuration",
1451 save_config_help); 1449 save_config_help);
1452 break; 1450 break;
1453 case KEY_EXIT: 1451 case KEY_EXIT:
@@ -1480,10 +1478,6 @@ int main(int ac, char **av)
1480 int lines, columns; 1478 int lines, columns;
1481 char *mode; 1479 char *mode;
1482 1480
1483 setlocale(LC_ALL, "");
1484 bindtextdomain(PACKAGE, LOCALEDIR);
1485 textdomain(PACKAGE);
1486
1487 if (ac > 1 && strcmp(av[1], "-s") == 0) { 1481 if (ac > 1 && strcmp(av[1], "-s") == 0) {
1488 /* Silence conf_read() until the real callback is set up */ 1482 /* Silence conf_read() until the real callback is set up */
1489 conf_set_message_callback(NULL); 1483 conf_set_message_callback(NULL);
@@ -1541,8 +1535,8 @@ int main(int ac, char **av)
1541 /* check for KEY_FUNC(1) */ 1535 /* check for KEY_FUNC(1) */
1542 if (has_key(KEY_F(1)) == FALSE) { 1536 if (has_key(KEY_F(1)) == FALSE) {
1543 show_scroll_win(main_window, 1537 show_scroll_win(main_window,
1544 _("Instructions"), 1538 "Instructions",
1545 _(menu_no_f_instructions)); 1539 menu_no_f_instructions);
1546 } 1540 }
1547 1541
1548 conf_set_message_callback(conf_message_callback); 1542 conf_set_message_callback(conf_message_callback);
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
index 0d5261705ef5..2b9e19f603c4 100644
--- a/scripts/kconfig/nconf.h
+++ b/scripts/kconfig/nconf.h
@@ -14,8 +14,7 @@
14#include <stdlib.h> 14#include <stdlib.h>
15#include <string.h> 15#include <string.h>
16#include <unistd.h> 16#include <unistd.h>
17#include <locale.h> 17#include <ncurses.h>
18#include <curses.h>
19#include <menu.h> 18#include <menu.h>
20#include <panel.h> 19#include <panel.h>
21#include <form.h> 20#include <form.h>
@@ -24,8 +23,6 @@
24#include <time.h> 23#include <time.h>
25#include <sys/time.h> 24#include <sys/time.h>
26 25
27#include "ncurses.h"
28
29#define max(a, b) ({\ 26#define max(a, b) ({\
30 typeof(a) _a = a;\ 27 typeof(a) _a = a;\
31 typeof(b) _b = b;\ 28 typeof(b) _b = b;\
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
new file mode 100644
index 000000000000..5ca2df790d3c
--- /dev/null
+++ b/scripts/kconfig/preprocess.c
@@ -0,0 +1,572 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
4
5#include <stdarg.h>
6#include <stdbool.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include "list.h"
12
13#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
14
15static char *expand_string_with_args(const char *in, int argc, char *argv[]);
16
17static void __attribute__((noreturn)) pperror(const char *format, ...)
18{
19 va_list ap;
20
21 fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
22 va_start(ap, format);
23 vfprintf(stderr, format, ap);
24 va_end(ap);
25 fprintf(stderr, "\n");
26
27 exit(1);
28}
29
30/*
31 * Environment variables
32 */
33static LIST_HEAD(env_list);
34
35struct env {
36 char *name;
37 char *value;
38 struct list_head node;
39};
40
41static void env_add(const char *name, const char *value)
42{
43 struct env *e;
44
45 e = xmalloc(sizeof(*e));
46 e->name = xstrdup(name);
47 e->value = xstrdup(value);
48
49 list_add_tail(&e->node, &env_list);
50}
51
52static void env_del(struct env *e)
53{
54 list_del(&e->node);
55 free(e->name);
56 free(e->value);
57 free(e);
58}
59
60/* The returned pointer must be freed when done */
61static char *env_expand(const char *name)
62{
63 struct env *e;
64 const char *value;
65
66 if (!*name)
67 return NULL;
68
69 list_for_each_entry(e, &env_list, node) {
70 if (!strcmp(name, e->name))
71 return xstrdup(e->value);
72 }
73
74 value = getenv(name);
75 if (!value)
76 return NULL;
77
78 /*
79 * We need to remember all referenced environment variables.
80 * They will be written out to include/config/auto.conf.cmd
81 */
82 env_add(name, value);
83
84 return xstrdup(value);
85}
86
87void env_write_dep(FILE *f, const char *autoconfig_name)
88{
89 struct env *e, *tmp;
90
91 list_for_each_entry_safe(e, tmp, &env_list, node) {
92 fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
93 fprintf(f, "%s: FORCE\n", autoconfig_name);
94 fprintf(f, "endif\n");
95 env_del(e);
96 }
97}
98
99/*
100 * Built-in functions
101 */
102struct function {
103 const char *name;
104 unsigned int min_args;
105 unsigned int max_args;
106 char *(*func)(int argc, char *argv[]);
107};
108
109static char *do_error_if(int argc, char *argv[])
110{
111 if (!strcmp(argv[0], "y"))
112 pperror("%s", argv[1]);
113
114 return NULL;
115}
116
117static char *do_filename(int argc, char *argv[])
118{
119 return xstrdup(current_file->name);
120}
121
122static char *do_info(int argc, char *argv[])
123{
124 printf("%s\n", argv[0]);
125
126 return xstrdup("");
127}
128
129static char *do_lineno(int argc, char *argv[])
130{
131 char buf[16];
132
133 sprintf(buf, "%d", yylineno);
134
135 return xstrdup(buf);
136}
137
138static char *do_shell(int argc, char *argv[])
139{
140 FILE *p;
141 char buf[256];
142 char *cmd;
143 size_t nread;
144 int i;
145
146 cmd = argv[0];
147
148 p = popen(cmd, "r");
149 if (!p) {
150 perror(cmd);
151 exit(1);
152 }
153
154 nread = fread(buf, 1, sizeof(buf), p);
155 if (nread == sizeof(buf))
156 nread--;
157
158 /* remove trailing new lines */
159 while (nread > 0 && buf[nread - 1] == '\n')
160 nread--;
161
162 buf[nread] = 0;
163
164 /* replace a new line with a space */
165 for (i = 0; i < nread; i++) {
166 if (buf[i] == '\n')
167 buf[i] = ' ';
168 }
169
170 if (pclose(p) == -1) {
171 perror(cmd);
172 exit(1);
173 }
174
175 return xstrdup(buf);
176}
177
178static char *do_warning_if(int argc, char *argv[])
179{
180 if (!strcmp(argv[0], "y"))
181 fprintf(stderr, "%s:%d: %s\n",
182 current_file->name, yylineno, argv[1]);
183
184 return xstrdup("");
185}
186
187static const struct function function_table[] = {
188 /* Name MIN MAX Function */
189 { "error-if", 2, 2, do_error_if },
190 { "filename", 0, 0, do_filename },
191 { "info", 1, 1, do_info },
192 { "lineno", 0, 0, do_lineno },
193 { "shell", 1, 1, do_shell },
194 { "warning-if", 2, 2, do_warning_if },
195};
196
197#define FUNCTION_MAX_ARGS 16
198
199static char *function_expand(const char *name, int argc, char *argv[])
200{
201 const struct function *f;
202 int i;
203
204 for (i = 0; i < ARRAY_SIZE(function_table); i++) {
205 f = &function_table[i];
206 if (strcmp(f->name, name))
207 continue;
208
209 if (argc < f->min_args)
210 pperror("too few function arguments passed to '%s'",
211 name);
212
213 if (argc > f->max_args)
214 pperror("too many function arguments passed to '%s'",
215 name);
216
217 return f->func(argc, argv);
218 }
219
220 return NULL;
221}
222
223/*
224 * Variables (and user-defined functions)
225 */
226static LIST_HEAD(variable_list);
227
228struct variable {
229 char *name;
230 char *value;
231 enum variable_flavor flavor;
232 int exp_count;
233 struct list_head node;
234};
235
236static struct variable *variable_lookup(const char *name)
237{
238 struct variable *v;
239
240 list_for_each_entry(v, &variable_list, node) {
241 if (!strcmp(name, v->name))
242 return v;
243 }
244
245 return NULL;
246}
247
248static char *variable_expand(const char *name, int argc, char *argv[])
249{
250 struct variable *v;
251 char *res;
252
253 v = variable_lookup(name);
254 if (!v)
255 return NULL;
256
257 if (argc == 0 && v->exp_count)
258 pperror("Recursive variable '%s' references itself (eventually)",
259 name);
260
261 if (v->exp_count > 1000)
262 pperror("Too deep recursive expansion");
263
264 v->exp_count++;
265
266 if (v->flavor == VAR_RECURSIVE)
267 res = expand_string_with_args(v->value, argc, argv);
268 else
269 res = xstrdup(v->value);
270
271 v->exp_count--;
272
273 return res;
274}
275
276void variable_add(const char *name, const char *value,
277 enum variable_flavor flavor)
278{
279 struct variable *v;
280 char *new_value;
281 bool append = false;
282
283 v = variable_lookup(name);
284 if (v) {
285 /* For defined variables, += inherits the existing flavor */
286 if (flavor == VAR_APPEND) {
287 flavor = v->flavor;
288 append = true;
289 } else {
290 free(v->value);
291 }
292 } else {
293 /* For undefined variables, += assumes the recursive flavor */
294 if (flavor == VAR_APPEND)
295 flavor = VAR_RECURSIVE;
296
297 v = xmalloc(sizeof(*v));
298 v->name = xstrdup(name);
299 v->exp_count = 0;
300 list_add_tail(&v->node, &variable_list);
301 }
302
303 v->flavor = flavor;
304
305 if (flavor == VAR_SIMPLE)
306 new_value = expand_string(value);
307 else
308 new_value = xstrdup(value);
309
310 if (append) {
311 v->value = xrealloc(v->value,
312 strlen(v->value) + strlen(new_value) + 2);
313 strcat(v->value, " ");
314 strcat(v->value, new_value);
315 free(new_value);
316 } else {
317 v->value = new_value;
318 }
319}
320
321static void variable_del(struct variable *v)
322{
323 list_del(&v->node);
324 free(v->name);
325 free(v->value);
326 free(v);
327}
328
329void variable_all_del(void)
330{
331 struct variable *v, *tmp;
332
333 list_for_each_entry_safe(v, tmp, &variable_list, node)
334 variable_del(v);
335}
336
337/*
338 * Evaluate a clause with arguments. argc/argv are arguments from the upper
339 * function call.
340 *
341 * Returned string must be freed when done
342 */
343static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
344{
345 char *tmp, *name, *res, *endptr, *prev, *p;
346 int new_argc = 0;
347 char *new_argv[FUNCTION_MAX_ARGS];
348 int nest = 0;
349 int i;
350 unsigned long n;
351
352 tmp = xstrndup(str, len);
353
354 /*
355 * If variable name is '1', '2', etc. It is generally an argument
356 * from a user-function call (i.e. local-scope variable). If not
357 * available, then look-up global-scope variables.
358 */
359 n = strtoul(tmp, &endptr, 10);
360 if (!*endptr && n > 0 && n <= argc) {
361 res = xstrdup(argv[n - 1]);
362 goto free_tmp;
363 }
364
365 prev = p = tmp;
366
367 /*
368 * Split into tokens
369 * The function name and arguments are separated by a comma.
370 * For example, if the function call is like this:
371 * $(foo,$(x),$(y))
372 *
373 * The input string for this helper should be:
374 * foo,$(x),$(y)
375 *
376 * and split into:
377 * new_argv[0] = 'foo'
378 * new_argv[1] = '$(x)'
379 * new_argv[2] = '$(y)'
380 */
381 while (*p) {
382 if (nest == 0 && *p == ',') {
383 *p = 0;
384 if (new_argc >= FUNCTION_MAX_ARGS)
385 pperror("too many function arguments");
386 new_argv[new_argc++] = prev;
387 prev = p + 1;
388 } else if (*p == '(') {
389 nest++;
390 } else if (*p == ')') {
391 nest--;
392 }
393
394 p++;
395 }
396 new_argv[new_argc++] = prev;
397
398 /*
399 * Shift arguments
400 * new_argv[0] represents a function name or a variable name. Put it
401 * into 'name', then shift the rest of the arguments. This simplifies
402 * 'const' handling.
403 */
404 name = expand_string_with_args(new_argv[0], argc, argv);
405 new_argc--;
406 for (i = 0; i < new_argc; i++)
407 new_argv[i] = expand_string_with_args(new_argv[i + 1],
408 argc, argv);
409
410 /* Search for variables */
411 res = variable_expand(name, new_argc, new_argv);
412 if (res)
413 goto free;
414
415 /* Look for built-in functions */
416 res = function_expand(name, new_argc, new_argv);
417 if (res)
418 goto free;
419
420 /* Last, try environment variable */
421 if (new_argc == 0) {
422 res = env_expand(name);
423 if (res)
424 goto free;
425 }
426
427 res = xstrdup("");
428free:
429 for (i = 0; i < new_argc; i++)
430 free(new_argv[i]);
431 free(name);
432free_tmp:
433 free(tmp);
434
435 return res;
436}
437
438/*
439 * Expand a string that follows '$'
440 *
441 * For example, if the input string is
442 * ($(FOO)$($(BAR)))$(BAZ)
443 * this helper evaluates
444 * $($(FOO)$($(BAR)))
445 * and returns a new string containing the expansion (note that the string is
446 * recursively expanded), also advancing 'str' to point to the next character
447 * after the corresponding closing parenthesis, in this case, *str will be
448 * $(BAR)
449 */
450static char *expand_dollar_with_args(const char **str, int argc, char *argv[])
451{
452 const char *p = *str;
453 const char *q;
454 int nest = 0;
455
456 /*
457 * In Kconfig, variable/function references always start with "$(".
458 * Neither single-letter variables as in $A nor curly braces as in ${CC}
459 * are supported. '$' not followed by '(' loses its special meaning.
460 */
461 if (*p != '(') {
462 *str = p;
463 return xstrdup("$");
464 }
465
466 p++;
467 q = p;
468 while (*q) {
469 if (*q == '(') {
470 nest++;
471 } else if (*q == ')') {
472 if (nest-- == 0)
473 break;
474 }
475 q++;
476 }
477
478 if (!*q)
479 pperror("unterminated reference to '%s': missing ')'", p);
480
481 /* Advance 'str' to after the expanded initial portion of the string */
482 *str = q + 1;
483
484 return eval_clause(p, q - p, argc, argv);
485}
486
487char *expand_dollar(const char **str)
488{
489 return expand_dollar_with_args(str, 0, NULL);
490}
491
492static char *__expand_string(const char **str, bool (*is_end)(char c),
493 int argc, char *argv[])
494{
495 const char *in, *p;
496 char *expansion, *out;
497 size_t in_len, out_len;
498
499 out = xmalloc(1);
500 *out = 0;
501 out_len = 1;
502
503 p = in = *str;
504
505 while (1) {
506 if (*p == '$') {
507 in_len = p - in;
508 p++;
509 expansion = expand_dollar_with_args(&p, argc, argv);
510 out_len += in_len + strlen(expansion);
511 out = xrealloc(out, out_len);
512 strncat(out, in, in_len);
513 strcat(out, expansion);
514 free(expansion);
515 in = p;
516 continue;
517 }
518
519 if (is_end(*p))
520 break;
521
522 p++;
523 }
524
525 in_len = p - in;
526 out_len += in_len;
527 out = xrealloc(out, out_len);
528 strncat(out, in, in_len);
529
530 /* Advance 'str' to the end character */
531 *str = p;
532
533 return out;
534}
535
536static bool is_end_of_str(char c)
537{
538 return !c;
539}
540
541/*
542 * Expand variables and functions in the given string. Undefined variables
543 * expand to an empty string.
544 * The returned string must be freed when done.
545 */
546static char *expand_string_with_args(const char *in, int argc, char *argv[])
547{
548 return __expand_string(&in, is_end_of_str, argc, argv);
549}
550
551char *expand_string(const char *in)
552{
553 return expand_string_with_args(in, 0, NULL);
554}
555
556static bool is_end_of_token(char c)
557{
558 /* Why are '.' and '/' valid characters for symbols? */
559 return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/');
560}
561
562/*
563 * Expand variables in a token. The parsing stops when a token separater
564 * (in most cases, it is a whitespace) is encountered. 'str' is updated to
565 * point to the next character.
566 *
567 * The returned string must be freed when done.
568 */
569char *expand_one_token(const char **str)
570{
571 return __expand_string(str, is_end_of_token, 0, NULL);
572}
diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh
new file mode 100755
index 000000000000..02ccc0ae1031
--- /dev/null
+++ b/scripts/kconfig/qconf-cfg.sh
@@ -0,0 +1,32 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4PKG="Qt5Core Qt5Gui Qt5Widgets"
5PKG2="QtCore QtGui"
6
7if [ -z "$(command -v pkg-config)" ]; then
8 echo >&2 "*"
9 echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it."
10 echo >&2 "*"
11 exit 1
12fi
13
14if pkg-config --exists $PKG; then
15 echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\"
16 echo libs=\"$(pkg-config --libs $PKG)\"
17 echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\"
18 exit 0
19fi
20
21if pkg-config --exists $PKG2; then
22 echo cflags=\"$(pkg-config --cflags $PKG2)\"
23 echo libs=\"$(pkg-config --libs $PKG2)\"
24 echo moc=\"$(pkg-config --variable=moc_location QtCore)\"
25 exit 0
26fi
27
28echo >&2 "*"
29echo >&2 "* Could not find Qt via pkg-config."
30echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"
31echo >&2 "*"
32exit 1
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index ae6c72546411..ef4310f2558b 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -34,10 +34,6 @@
34#include "qconf.moc" 34#include "qconf.moc"
35#include "images.c" 35#include "images.c"
36 36
37#ifdef _
38# undef _
39# define _ qgettext
40#endif
41 37
42static QApplication *configApp; 38static QApplication *configApp;
43static ConfigSettings *configSettings; 39static ConfigSettings *configSettings;
@@ -46,12 +42,7 @@ QAction *ConfigMainWindow::saveAction;
46 42
47static inline QString qgettext(const char* str) 43static inline QString qgettext(const char* str)
48{ 44{
49 return QString::fromLocal8Bit(gettext(str)); 45 return QString::fromLocal8Bit(str);
50}
51
52static inline QString qgettext(const QString& str)
53{
54 return QString::fromLocal8Bit(gettext(str.toLatin1()));
55} 46}
56 47
57ConfigSettings::ConfigSettings() 48ConfigSettings::ConfigSettings()
@@ -127,7 +118,7 @@ void ConfigItem::updateMenu(void)
127 118
128 sym = menu->sym; 119 sym = menu->sym;
129 prop = menu->prompt; 120 prop = menu->prompt;
130 prompt = _(menu_get_prompt(menu)); 121 prompt = qgettext(menu_get_prompt(menu));
131 122
132 if (prop) switch (prop->type) { 123 if (prop) switch (prop->type) {
133 case P_MENU: 124 case P_MENU:
@@ -216,7 +207,7 @@ void ConfigItem::updateMenu(void)
216 break; 207 break;
217 } 208 }
218 if (!sym_has_value(sym) && visible) 209 if (!sym_has_value(sym) && visible)
219 prompt += _(" (NEW)"); 210 prompt += " (NEW)";
220set_prompt: 211set_prompt:
221 setText(promptColIdx, prompt); 212 setText(promptColIdx, prompt);
222} 213}
@@ -327,7 +318,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
327 setVerticalScrollMode(ScrollPerPixel); 318 setVerticalScrollMode(ScrollPerPixel);
328 setHorizontalScrollMode(ScrollPerPixel); 319 setHorizontalScrollMode(ScrollPerPixel);
329 320
330 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value")); 321 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
331 322
332 connect(this, SIGNAL(itemSelectionChanged(void)), 323 connect(this, SIGNAL(itemSelectionChanged(void)),
333 SLOT(updateSelection(void))); 324 SLOT(updateSelection(void)));
@@ -883,7 +874,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
883 QAction *action; 874 QAction *action;
884 875
885 headerPopup = new QMenu(this); 876 headerPopup = new QMenu(this);
886 action = new QAction(_("Show Name"), this); 877 action = new QAction("Show Name", this);
887 action->setCheckable(true); 878 action->setCheckable(true);
888 connect(action, SIGNAL(toggled(bool)), 879 connect(action, SIGNAL(toggled(bool)),
889 parent(), SLOT(setShowName(bool))); 880 parent(), SLOT(setShowName(bool)));
@@ -891,7 +882,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
891 action, SLOT(setOn(bool))); 882 action, SLOT(setOn(bool)));
892 action->setChecked(showName); 883 action->setChecked(showName);
893 headerPopup->addAction(action); 884 headerPopup->addAction(action);
894 action = new QAction(_("Show Range"), this); 885 action = new QAction("Show Range", this);
895 action->setCheckable(true); 886 action->setCheckable(true);
896 connect(action, SIGNAL(toggled(bool)), 887 connect(action, SIGNAL(toggled(bool)),
897 parent(), SLOT(setShowRange(bool))); 888 parent(), SLOT(setShowRange(bool)));
@@ -899,7 +890,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
899 action, SLOT(setOn(bool))); 890 action, SLOT(setOn(bool)));
900 action->setChecked(showRange); 891 action->setChecked(showRange);
901 headerPopup->addAction(action); 892 headerPopup->addAction(action);
902 action = new QAction(_("Show Data"), this); 893 action = new QAction("Show Data", this);
903 action->setCheckable(true); 894 action->setCheckable(true);
904 connect(action, SIGNAL(toggled(bool)), 895 connect(action, SIGNAL(toggled(bool)),
905 parent(), SLOT(setShowData(bool))); 896 parent(), SLOT(setShowData(bool)));
@@ -1086,7 +1077,7 @@ void ConfigInfoView::menuInfo(void)
1086 if (sym) { 1077 if (sym) {
1087 if (_menu->prompt) { 1078 if (_menu->prompt) {
1088 head += "<big><b>"; 1079 head += "<big><b>";
1089 head += print_filter(_(_menu->prompt->text)); 1080 head += print_filter(_menu->prompt->text);
1090 head += "</b></big>"; 1081 head += "</b></big>";
1091 if (sym->name) { 1082 if (sym->name) {
1092 head += " ("; 1083 head += " (";
@@ -1117,7 +1108,7 @@ void ConfigInfoView::menuInfo(void)
1117 str_free(&help_gstr); 1108 str_free(&help_gstr);
1118 } else if (_menu->prompt) { 1109 } else if (_menu->prompt) {
1119 head += "<big><b>"; 1110 head += "<big><b>";
1120 head += print_filter(_(_menu->prompt->text)); 1111 head += print_filter(_menu->prompt->text);
1121 head += "</b></big><br><br>"; 1112 head += "</b></big><br><br>";
1122 if (showDebug()) { 1113 if (showDebug()) {
1123 if (_menu->prompt->visible.expr) { 1114 if (_menu->prompt->visible.expr) {
@@ -1152,13 +1143,12 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
1152 case P_PROMPT: 1143 case P_PROMPT:
1153 case P_MENU: 1144 case P_MENU:
1154 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu); 1145 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1155 debug += print_filter(_(prop->text)); 1146 debug += print_filter(prop->text);
1156 debug += "</a><br>"; 1147 debug += "</a><br>";
1157 break; 1148 break;
1158 case P_DEFAULT: 1149 case P_DEFAULT:
1159 case P_SELECT: 1150 case P_SELECT:
1160 case P_RANGE: 1151 case P_RANGE:
1161 case P_ENV:
1162 debug += prop_get_type_name(prop->type); 1152 debug += prop_get_type_name(prop->type);
1163 debug += ": "; 1153 debug += ": ";
1164 expr_print(prop->expr, expr_print_help, &debug, E_NONE); 1154 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
@@ -1234,7 +1224,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
1234QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) 1224QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
1235{ 1225{
1236 QMenu* popup = Parent::createStandardContextMenu(pos); 1226 QMenu* popup = Parent::createStandardContextMenu(pos);
1237 QAction* action = new QAction(_("Show Debug Info"), popup); 1227 QAction* action = new QAction("Show Debug Info", popup);
1238 action->setCheckable(true); 1228 action->setCheckable(true);
1239 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); 1229 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1240 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); 1230 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1261,11 +1251,11 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
1261 QHBoxLayout* layout2 = new QHBoxLayout(0); 1251 QHBoxLayout* layout2 = new QHBoxLayout(0);
1262 layout2->setContentsMargins(0, 0, 0, 0); 1252 layout2->setContentsMargins(0, 0, 0, 0);
1263 layout2->setSpacing(6); 1253 layout2->setSpacing(6);
1264 layout2->addWidget(new QLabel(_("Find:"), this)); 1254 layout2->addWidget(new QLabel("Find:", this));
1265 editField = new QLineEdit(this); 1255 editField = new QLineEdit(this);
1266 connect(editField, SIGNAL(returnPressed()), SLOT(search())); 1256 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1267 layout2->addWidget(editField); 1257 layout2->addWidget(editField);
1268 searchButton = new QPushButton(_("Search"), this); 1258 searchButton = new QPushButton("Search", this);
1269 searchButton->setAutoDefault(false); 1259 searchButton->setAutoDefault(false);
1270 connect(searchButton, SIGNAL(clicked()), SLOT(search())); 1260 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1271 layout2->addWidget(searchButton); 1261 layout2->addWidget(searchButton);
@@ -1387,44 +1377,44 @@ ConfigMainWindow::ConfigMainWindow(void)
1387 toolBar = new QToolBar("Tools", this); 1377 toolBar = new QToolBar("Tools", this);
1388 addToolBar(toolBar); 1378 addToolBar(toolBar);
1389 1379
1390 backAction = new QAction(QPixmap(xpm_back), _("Back"), this); 1380 backAction = new QAction(QPixmap(xpm_back), "Back", this);
1391 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); 1381 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1392 backAction->setEnabled(false); 1382 backAction->setEnabled(false);
1393 QAction *quitAction = new QAction(_("&Quit"), this); 1383 QAction *quitAction = new QAction("&Quit", this);
1394 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); 1384 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1395 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); 1385 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1396 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this); 1386 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
1397 loadAction->setShortcut(Qt::CTRL + Qt::Key_L); 1387 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1398 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); 1388 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1399 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this); 1389 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
1400 saveAction->setShortcut(Qt::CTRL + Qt::Key_S); 1390 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1401 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); 1391 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1402 conf_set_changed_callback(conf_changed); 1392 conf_set_changed_callback(conf_changed);
1403 // Set saveAction's initial state 1393 // Set saveAction's initial state
1404 conf_changed(); 1394 conf_changed();
1405 QAction *saveAsAction = new QAction(_("Save &As..."), this); 1395 QAction *saveAsAction = new QAction("Save &As...", this);
1406 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs())); 1396 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
1407 QAction *searchAction = new QAction(_("&Find"), this); 1397 QAction *searchAction = new QAction("&Find", this);
1408 searchAction->setShortcut(Qt::CTRL + Qt::Key_F); 1398 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1409 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig())); 1399 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
1410 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this); 1400 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
1411 singleViewAction->setCheckable(true); 1401 singleViewAction->setCheckable(true);
1412 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView())); 1402 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
1413 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this); 1403 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
1414 splitViewAction->setCheckable(true); 1404 splitViewAction->setCheckable(true);
1415 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView())); 1405 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
1416 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this); 1406 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
1417 fullViewAction->setCheckable(true); 1407 fullViewAction->setCheckable(true);
1418 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView())); 1408 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
1419 1409
1420 QAction *showNameAction = new QAction(_("Show Name"), this); 1410 QAction *showNameAction = new QAction("Show Name", this);
1421 showNameAction->setCheckable(true); 1411 showNameAction->setCheckable(true);
1422 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); 1412 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1423 showNameAction->setChecked(configView->showName()); 1413 showNameAction->setChecked(configView->showName());
1424 QAction *showRangeAction = new QAction(_("Show Range"), this); 1414 QAction *showRangeAction = new QAction("Show Range", this);
1425 showRangeAction->setCheckable(true); 1415 showRangeAction->setCheckable(true);
1426 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); 1416 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1427 QAction *showDataAction = new QAction(_("Show Data"), this); 1417 QAction *showDataAction = new QAction("Show Data", this);
1428 showDataAction->setCheckable(true); 1418 showDataAction->setCheckable(true);
1429 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); 1419 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1430 1420
@@ -1435,21 +1425,21 @@ ConfigMainWindow::ConfigMainWindow(void)
1435 connect(optGroup, SIGNAL(triggered(QAction *)), menuView, 1425 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
1436 SLOT(setOptionMode(QAction *))); 1426 SLOT(setOptionMode(QAction *)));
1437 1427
1438 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup); 1428 configView->showNormalAction = new QAction("Show Normal Options", optGroup);
1439 configView->showAllAction = new QAction(_("Show All Options"), optGroup); 1429 configView->showAllAction = new QAction("Show All Options", optGroup);
1440 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup); 1430 configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
1441 configView->showNormalAction->setCheckable(true); 1431 configView->showNormalAction->setCheckable(true);
1442 configView->showAllAction->setCheckable(true); 1432 configView->showAllAction->setCheckable(true);
1443 configView->showPromptAction->setCheckable(true); 1433 configView->showPromptAction->setCheckable(true);
1444 1434
1445 QAction *showDebugAction = new QAction( _("Show Debug Info"), this); 1435 QAction *showDebugAction = new QAction("Show Debug Info", this);
1446 showDebugAction->setCheckable(true); 1436 showDebugAction->setCheckable(true);
1447 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); 1437 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1448 showDebugAction->setChecked(helpText->showDebug()); 1438 showDebugAction->setChecked(helpText->showDebug());
1449 1439
1450 QAction *showIntroAction = new QAction( _("Introduction"), this); 1440 QAction *showIntroAction = new QAction("Introduction", this);
1451 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro())); 1441 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
1452 QAction *showAboutAction = new QAction( _("About"), this); 1442 QAction *showAboutAction = new QAction("About", this);
1453 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout())); 1443 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
1454 1444
1455 // init tool bar 1445 // init tool bar
@@ -1463,7 +1453,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1463 toolBar->addAction(fullViewAction); 1453 toolBar->addAction(fullViewAction);
1464 1454
1465 // create config menu 1455 // create config menu
1466 QMenu* config = menu->addMenu(_("&File")); 1456 QMenu* config = menu->addMenu("&File");
1467 config->addAction(loadAction); 1457 config->addAction(loadAction);
1468 config->addAction(saveAction); 1458 config->addAction(saveAction);
1469 config->addAction(saveAsAction); 1459 config->addAction(saveAsAction);
@@ -1471,11 +1461,11 @@ ConfigMainWindow::ConfigMainWindow(void)
1471 config->addAction(quitAction); 1461 config->addAction(quitAction);
1472 1462
1473 // create edit menu 1463 // create edit menu
1474 QMenu* editMenu = menu->addMenu(_("&Edit")); 1464 QMenu* editMenu = menu->addMenu("&Edit");
1475 editMenu->addAction(searchAction); 1465 editMenu->addAction(searchAction);
1476 1466
1477 // create options menu 1467 // create options menu
1478 QMenu* optionMenu = menu->addMenu(_("&Option")); 1468 QMenu* optionMenu = menu->addMenu("&Option");
1479 optionMenu->addAction(showNameAction); 1469 optionMenu->addAction(showNameAction);
1480 optionMenu->addAction(showRangeAction); 1470 optionMenu->addAction(showRangeAction);
1481 optionMenu->addAction(showDataAction); 1471 optionMenu->addAction(showDataAction);
@@ -1486,7 +1476,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1486 1476
1487 // create help menu 1477 // create help menu
1488 menu->addSeparator(); 1478 menu->addSeparator();
1489 QMenu* helpMenu = menu->addMenu(_("&Help")); 1479 QMenu* helpMenu = menu->addMenu("&Help");
1490 helpMenu->addAction(showIntroAction); 1480 helpMenu->addAction(showIntroAction);
1491 helpMenu->addAction(showAboutAction); 1481 helpMenu->addAction(showAboutAction);
1492 1482
@@ -1534,16 +1524,18 @@ void ConfigMainWindow::loadConfig(void)
1534 if (s.isNull()) 1524 if (s.isNull())
1535 return; 1525 return;
1536 if (conf_read(QFile::encodeName(s))) 1526 if (conf_read(QFile::encodeName(s)))
1537 QMessageBox::information(this, "qconf", _("Unable to load configuration!")); 1527 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1538 ConfigView::updateListAll(); 1528 ConfigView::updateListAll();
1539} 1529}
1540 1530
1541bool ConfigMainWindow::saveConfig(void) 1531bool ConfigMainWindow::saveConfig(void)
1542{ 1532{
1543 if (conf_write(NULL)) { 1533 if (conf_write(NULL)) {
1544 QMessageBox::information(this, "qconf", _("Unable to save configuration!")); 1534 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1545 return false; 1535 return false;
1546 } 1536 }
1537 conf_write_autoconf(0);
1538
1547 return true; 1539 return true;
1548} 1540}
1549 1541
@@ -1723,11 +1715,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
1723 e->accept(); 1715 e->accept();
1724 return; 1716 return;
1725 } 1717 }
1726 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning, 1718 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1727 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); 1719 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1728 mb.setButtonText(QMessageBox::Yes, _("&Save Changes")); 1720 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1729 mb.setButtonText(QMessageBox::No, _("&Discard Changes")); 1721 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1730 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit")); 1722 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1731 switch (mb.exec()) { 1723 switch (mb.exec()) {
1732 case QMessageBox::Yes: 1724 case QMessageBox::Yes:
1733 if (saveConfig()) 1725 if (saveConfig())
@@ -1746,7 +1738,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
1746 1738
1747void ConfigMainWindow::showIntro(void) 1739void ConfigMainWindow::showIntro(void)
1748{ 1740{
1749 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n" 1741 static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
1750 "For each option, a blank box indicates the feature is disabled, a check\n" 1742 "For each option, a blank box indicates the feature is disabled, a check\n"
1751 "indicates it is enabled, and a dot indicates that it is to be compiled\n" 1743 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1752 "as a module. Clicking on the box will cycle through the three states.\n\n" 1744 "as a module. Clicking on the box will cycle through the three states.\n\n"
@@ -1756,16 +1748,16 @@ void ConfigMainWindow::showIntro(void)
1756 "options must be enabled to support the option you are interested in, you can\n" 1748 "options must be enabled to support the option you are interested in, you can\n"
1757 "still view the help of a grayed-out option.\n\n" 1749 "still view the help of a grayed-out option.\n\n"
1758 "Toggling Show Debug Info under the Options menu will show the dependencies,\n" 1750 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1759 "which you can then match by examining other options.\n\n"); 1751 "which you can then match by examining other options.\n\n";
1760 1752
1761 QMessageBox::information(this, "qconf", str); 1753 QMessageBox::information(this, "qconf", str);
1762} 1754}
1763 1755
1764void ConfigMainWindow::showAbout(void) 1756void ConfigMainWindow::showAbout(void)
1765{ 1757{
1766 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n" 1758 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1767 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n" 1759 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
1768 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"); 1760 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1769 1761
1770 QMessageBox::information(this, "qconf", str); 1762 QMessageBox::information(this, "qconf", str);
1771} 1763}
@@ -1826,7 +1818,7 @@ static const char *progname;
1826 1818
1827static void usage(void) 1819static void usage(void)
1828{ 1820{
1829 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname); 1821 printf("%s [-s] <config>\n", progname);
1830 exit(0); 1822 exit(0);
1831} 1823}
1832 1824
@@ -1835,9 +1827,6 @@ int main(int ac, char** av)
1835 ConfigMainWindow* v; 1827 ConfigMainWindow* v;
1836 const char *name; 1828 const char *name;
1837 1829
1838 bindtextdomain(PACKAGE, LOCALEDIR);
1839 textdomain(PACKAGE);
1840
1841 progname = av[0]; 1830 progname = av[0];
1842 configApp = new QApplication(ac, av); 1831 configApp = new QApplication(ac, av);
1843 if (ac > 1 && av[1][0] == '-') { 1832 if (ac > 1 && av[1][0] == '-') {
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index a2e83ab17de3..4686531e2f8c 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -165,10 +165,10 @@ sub read_kconfig {
165 my $last_source = ""; 165 my $last_source = "";
166 166
167 # Check for any environment variables used 167 # Check for any environment variables used
168 while ($source =~ /\$(\w+)/ && $last_source ne $source) { 168 while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) {
169 my $env = $1; 169 my $env = $1;
170 $last_source = $source; 170 $last_source = $source;
171 $source =~ s/\$$env/$ENV{$env}/; 171 $source =~ s/\$\($env\)/$ENV{$env}/;
172 } 172 }
173 173
174 open(my $kinfile, '<', $source) || die "Can't open $kconfig"; 174 open(my $kinfile, '<', $source) || die "Can't open $kconfig";
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 2220bc4b051b..703b9b899ee9 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list;
33struct symbol *modules_sym; 33struct symbol *modules_sym;
34tristate modules_val; 34tristate modules_val;
35 35
36struct expr *sym_env_list;
37
38static void sym_add_default(struct symbol *sym, const char *def)
39{
40 struct property *prop = prop_alloc(P_DEFAULT, sym);
41
42 prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
43}
44
45void sym_init(void)
46{
47 struct symbol *sym;
48 struct utsname uts;
49 static bool inited = false;
50
51 if (inited)
52 return;
53 inited = true;
54
55 uname(&uts);
56
57 sym = sym_lookup("UNAME_RELEASE", 0);
58 sym->type = S_STRING;
59 sym->flags |= SYMBOL_AUTO;
60 sym_add_default(sym, uts.release);
61}
62
63enum symbol_type sym_get_type(struct symbol *sym) 36enum symbol_type sym_get_type(struct symbol *sym)
64{ 37{
65 enum symbol_type type = sym->type; 38 enum symbol_type type = sym->type;
@@ -103,15 +76,6 @@ struct property *sym_get_choice_prop(struct symbol *sym)
103 return NULL; 76 return NULL;
104} 77}
105 78
106struct property *sym_get_env_prop(struct symbol *sym)
107{
108 struct property *prop;
109
110 for_all_properties(sym, prop, P_ENV)
111 return prop;
112 return NULL;
113}
114
115static struct property *sym_get_default_prop(struct symbol *sym) 79static struct property *sym_get_default_prop(struct symbol *sym)
116{ 80{
117 struct property *prop; 81 struct property *prop;
@@ -243,7 +207,7 @@ static void sym_calc_visibility(struct symbol *sym)
243 tri = yes; 207 tri = yes;
244 if (sym->dir_dep.expr) 208 if (sym->dir_dep.expr)
245 tri = expr_calc_value(sym->dir_dep.expr); 209 tri = expr_calc_value(sym->dir_dep.expr);
246 if (tri == mod) 210 if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
247 tri = yes; 211 tri = yes;
248 if (sym->dir_dep.tri != tri) { 212 if (sym->dir_dep.tri != tri) {
249 sym->dir_dep.tri = tri; 213 sym->dir_dep.tri = tri;
@@ -333,6 +297,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
333 return def_sym; 297 return def_sym;
334} 298}
335 299
300static void sym_warn_unmet_dep(struct symbol *sym)
301{
302 struct gstr gs = str_new();
303
304 str_printf(&gs,
305 "\nWARNING: unmet direct dependencies detected for %s\n",
306 sym->name);
307 str_printf(&gs,
308 " Depends on [%c]: ",
309 sym->dir_dep.tri == mod ? 'm' : 'n');
310 expr_gstr_print(sym->dir_dep.expr, &gs);
311 str_printf(&gs, "\n");
312
313 expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
314 " Selected by [y]:\n");
315 expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
316 " Selected by [m]:\n");
317
318 fputs(str_get(&gs), stderr);
319}
320
336void sym_calc_value(struct symbol *sym) 321void sym_calc_value(struct symbol *sym)
337{ 322{
338 struct symbol_value newval, oldval; 323 struct symbol_value newval, oldval;
@@ -403,9 +388,10 @@ void sym_calc_value(struct symbol *sym)
403 if (!sym_is_choice(sym)) { 388 if (!sym_is_choice(sym)) {
404 prop = sym_get_default_prop(sym); 389 prop = sym_get_default_prop(sym);
405 if (prop) { 390 if (prop) {
406 sym->flags |= SYMBOL_WRITE;
407 newval.tri = EXPR_AND(expr_calc_value(prop->expr), 391 newval.tri = EXPR_AND(expr_calc_value(prop->expr),
408 prop->visible.tri); 392 prop->visible.tri);
393 if (newval.tri != no)
394 sym->flags |= SYMBOL_WRITE;
409 } 395 }
410 if (sym->implied.tri != no) { 396 if (sym->implied.tri != no) {
411 sym->flags |= SYMBOL_WRITE; 397 sym->flags |= SYMBOL_WRITE;
@@ -413,18 +399,8 @@ void sym_calc_value(struct symbol *sym)
413 } 399 }
414 } 400 }
415 calc_newval: 401 calc_newval:
416 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { 402 if (sym->dir_dep.tri < sym->rev_dep.tri)
417 struct expr *e; 403 sym_warn_unmet_dep(sym);
418 e = expr_simplify_unmet_dep(sym->rev_dep.expr,
419 sym->dir_dep.expr);
420 fprintf(stderr, "warning: (");
421 expr_fprint(e, stderr);
422 fprintf(stderr, ") selects %s which has unmet direct dependencies (",
423 sym->name);
424 expr_fprint(sym->dir_dep.expr, stderr);
425 fprintf(stderr, ")\n");
426 expr_free(e);
427 }
428 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); 404 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
429 } 405 }
430 if (newval.tri == mod && 406 if (newval.tri == mod &&
@@ -478,7 +454,7 @@ void sym_calc_value(struct symbol *sym)
478 } 454 }
479 } 455 }
480 456
481 if (sym->flags & SYMBOL_AUTO) 457 if (sym->flags & SYMBOL_NO_WRITE)
482 sym->flags &= ~SYMBOL_WRITE; 458 sym->flags &= ~SYMBOL_WRITE;
483 459
484 if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) 460 if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
@@ -894,59 +870,6 @@ struct symbol *sym_find(const char *name)
894 return symbol; 870 return symbol;
895} 871}
896 872
897/*
898 * Expand symbol's names embedded in the string given in argument. Symbols'
899 * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
900 * the empty string.
901 */
902char *sym_expand_string_value(const char *in)
903{
904 const char *src;
905 char *res;
906 size_t reslen;
907
908 /*
909 * Note: 'in' might come from a token that's about to be
910 * freed, so make sure to always allocate a new string
911 */
912 reslen = strlen(in) + 1;
913 res = xmalloc(reslen);
914 res[0] = '\0';
915
916 while ((src = strchr(in, '$'))) {
917 char *p, name[SYMBOL_MAXLENGTH];
918 const char *symval = "";
919 struct symbol *sym;
920 size_t newlen;
921
922 strncat(res, in, src - in);
923 src++;
924
925 p = name;
926 while (isalnum(*src) || *src == '_')
927 *p++ = *src++;
928 *p = '\0';
929
930 sym = sym_find(name);
931 if (sym != NULL) {
932 sym_calc_value(sym);
933 symval = sym_get_string_value(sym);
934 }
935
936 newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
937 if (newlen > reslen) {
938 reslen = newlen;
939 res = xrealloc(res, reslen);
940 }
941
942 strcat(res, symval);
943 in = src;
944 }
945 strcat(res, in);
946
947 return res;
948}
949
950const char *sym_escape_string_value(const char *in) 873const char *sym_escape_string_value(const char *in)
951{ 874{
952 const char *p; 875 const char *p;
@@ -1088,7 +1011,7 @@ static struct dep_stack {
1088 struct dep_stack *prev, *next; 1011 struct dep_stack *prev, *next;
1089 struct symbol *sym; 1012 struct symbol *sym;
1090 struct property *prop; 1013 struct property *prop;
1091 struct expr *expr; 1014 struct expr **expr;
1092} *check_top; 1015} *check_top;
1093 1016
1094static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) 1017static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
@@ -1153,31 +1076,42 @@ static void sym_check_print_recursive(struct symbol *last_sym)
1153 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", 1076 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
1154 prop->file->name, prop->lineno); 1077 prop->file->name, prop->lineno);
1155 1078
1156 if (stack->expr) { 1079 if (sym_is_choice(sym)) {
1157 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", 1080 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
1158 prop->file->name, prop->lineno, 1081 menu->file->name, menu->lineno,
1082 sym->name ? sym->name : "<choice>",
1083 next_sym->name ? next_sym->name : "<choice>");
1084 } else if (sym_is_choice_value(sym)) {
1085 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
1086 menu->file->name, menu->lineno,
1159 sym->name ? sym->name : "<choice>", 1087 sym->name ? sym->name : "<choice>",
1160 prop_get_type_name(prop->type),
1161 next_sym->name ? next_sym->name : "<choice>"); 1088 next_sym->name ? next_sym->name : "<choice>");
1162 } else if (stack->prop) { 1089 } else if (stack->expr == &sym->dir_dep.expr) {
1163 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", 1090 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
1164 prop->file->name, prop->lineno, 1091 prop->file->name, prop->lineno,
1165 sym->name ? sym->name : "<choice>", 1092 sym->name ? sym->name : "<choice>",
1166 next_sym->name ? next_sym->name : "<choice>"); 1093 next_sym->name ? next_sym->name : "<choice>");
1167 } else if (sym_is_choice(sym)) { 1094 } else if (stack->expr == &sym->rev_dep.expr) {
1168 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", 1095 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
1169 menu->file->name, menu->lineno, 1096 prop->file->name, prop->lineno,
1170 sym->name ? sym->name : "<choice>", 1097 sym->name ? sym->name : "<choice>",
1171 next_sym->name ? next_sym->name : "<choice>"); 1098 next_sym->name ? next_sym->name : "<choice>");
1172 } else if (sym_is_choice_value(sym)) { 1099 } else if (stack->expr == &sym->implied.expr) {
1173 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", 1100 fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
1174 menu->file->name, menu->lineno, 1101 prop->file->name, prop->lineno,
1102 sym->name ? sym->name : "<choice>",
1103 next_sym->name ? next_sym->name : "<choice>");
1104 } else if (stack->expr) {
1105 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
1106 prop->file->name, prop->lineno,
1175 sym->name ? sym->name : "<choice>", 1107 sym->name ? sym->name : "<choice>",
1108 prop_get_type_name(prop->type),
1176 next_sym->name ? next_sym->name : "<choice>"); 1109 next_sym->name ? next_sym->name : "<choice>");
1177 } else { 1110 } else {
1178 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", 1111 fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
1179 prop->file->name, prop->lineno, 1112 prop->file->name, prop->lineno,
1180 sym->name ? sym->name : "<choice>", 1113 sym->name ? sym->name : "<choice>",
1114 prop_get_type_name(prop->type),
1181 next_sym->name ? next_sym->name : "<choice>"); 1115 next_sym->name ? next_sym->name : "<choice>");
1182 } 1116 }
1183 } 1117 }
@@ -1234,12 +1168,26 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
1234 1168
1235 dep_stack_insert(&stack, sym); 1169 dep_stack_insert(&stack, sym);
1236 1170
1171 stack.expr = &sym->dir_dep.expr;
1172 sym2 = sym_check_expr_deps(sym->dir_dep.expr);
1173 if (sym2)
1174 goto out;
1175
1176 stack.expr = &sym->rev_dep.expr;
1237 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 1177 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
1238 if (sym2) 1178 if (sym2)
1239 goto out; 1179 goto out;
1240 1180
1181 stack.expr = &sym->implied.expr;
1182 sym2 = sym_check_expr_deps(sym->implied.expr);
1183 if (sym2)
1184 goto out;
1185
1186 stack.expr = NULL;
1187
1241 for (prop = sym->prop; prop; prop = prop->next) { 1188 for (prop = sym->prop; prop; prop = prop->next) {
1242 if (prop->type == P_CHOICE || prop->type == P_SELECT) 1189 if (prop->type == P_CHOICE || prop->type == P_SELECT ||
1190 prop->type == P_IMPLY)
1243 continue; 1191 continue;
1244 stack.prop = prop; 1192 stack.prop = prop;
1245 sym2 = sym_check_expr_deps(prop->visible.expr); 1193 sym2 = sym_check_expr_deps(prop->visible.expr);
@@ -1247,7 +1195,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
1247 break; 1195 break;
1248 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 1196 if (prop->type != P_DEFAULT || sym_is_choice(sym))
1249 continue; 1197 continue;
1250 stack.expr = prop->expr; 1198 stack.expr = &prop->expr;
1251 sym2 = sym_check_expr_deps(prop->expr); 1199 sym2 = sym_check_expr_deps(prop->expr);
1252 if (sym2) 1200 if (sym2)
1253 break; 1201 break;
@@ -1325,9 +1273,6 @@ struct symbol *sym_check_deps(struct symbol *sym)
1325 sym->flags &= ~SYMBOL_CHECK; 1273 sym->flags &= ~SYMBOL_CHECK;
1326 } 1274 }
1327 1275
1328 if (sym2 && sym2 == sym)
1329 sym2 = NULL;
1330
1331 return sym2; 1276 return sym2;
1332} 1277}
1333 1278
@@ -1366,8 +1311,6 @@ const char *prop_get_type_name(enum prop_type type)
1366 switch (type) { 1311 switch (type) {
1367 case P_PROMPT: 1312 case P_PROMPT:
1368 return "prompt"; 1313 return "prompt";
1369 case P_ENV:
1370 return "env";
1371 case P_COMMENT: 1314 case P_COMMENT:
1372 return "comment"; 1315 return "comment";
1373 case P_MENU: 1316 case P_MENU:
@@ -1389,32 +1332,3 @@ const char *prop_get_type_name(enum prop_type type)
1389 } 1332 }
1390 return "unknown"; 1333 return "unknown";
1391} 1334}
1392
1393static void prop_add_env(const char *env)
1394{
1395 struct symbol *sym, *sym2;
1396 struct property *prop;
1397 char *p;
1398
1399 sym = current_entry->sym;
1400 sym->flags |= SYMBOL_AUTO;
1401 for_all_properties(sym, prop, P_ENV) {
1402 sym2 = prop_get_symbol(prop);
1403 if (strcmp(sym2->name, env))
1404 menu_warn(current_entry, "redefining environment symbol from %s",
1405 sym2->name);
1406 return;
1407 }
1408
1409 prop = prop_alloc(P_ENV, sym);
1410 prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
1411
1412 sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
1413 sym_env_list->right.sym = sym;
1414
1415 p = getenv(env);
1416 if (p)
1417 sym_add_default(sym, p);
1418 else
1419 menu_warn(current_entry, "environment variable %s undefined", env);
1420}
diff --git a/scripts/kconfig/tests/auto_submenu/Kconfig b/scripts/kconfig/tests/auto_submenu/Kconfig
new file mode 100644
index 000000000000..c17bf2caa7e6
--- /dev/null
+++ b/scripts/kconfig/tests/auto_submenu/Kconfig
@@ -0,0 +1,50 @@
1config A
2 bool "A"
3 default y
4
5config A0
6 bool "A0"
7 depends on A
8 default y
9 help
10 This depends on A, so should be a submenu of A.
11
12config A0_0
13 bool "A1_0"
14 depends on A0
15 help
16 Submenus are created recursively.
17 This should be a submenu of A0.
18
19config A1
20 bool "A1"
21 depends on A
22 default y
23 help
24 This should line up with A0.
25
26choice
27 prompt "choice"
28 depends on A1
29 help
30 Choice should become a submenu as well.
31
32config A1_0
33 bool "A1_0"
34
35config A1_1
36 bool "A1_1"
37
38endchoice
39
40config B
41 bool "B"
42 help
43 This is independent of A.
44
45config C
46 bool "C"
47 depends on A
48 help
49 This depends on A, but not a consecutive item, so can/should not
50 be a submenu.
diff --git a/scripts/kconfig/tests/auto_submenu/__init__.py b/scripts/kconfig/tests/auto_submenu/__init__.py
new file mode 100644
index 000000000000..32e79b85faeb
--- /dev/null
+++ b/scripts/kconfig/tests/auto_submenu/__init__.py
@@ -0,0 +1,12 @@
1"""
2Create submenu for symbols that depend on the preceding one.
3
4If a symbols has dependency on the preceding symbol, the menu entry
5should become the submenu of the preceding one, and displayed with
6deeper indentation.
7"""
8
9
10def test(conf):
11 assert conf.oldaskconfig() == 0
12 assert conf.stdout_contains('expected_stdout')
diff --git a/scripts/kconfig/tests/auto_submenu/expected_stdout b/scripts/kconfig/tests/auto_submenu/expected_stdout
new file mode 100644
index 000000000000..bf5236f39a56
--- /dev/null
+++ b/scripts/kconfig/tests/auto_submenu/expected_stdout
@@ -0,0 +1,10 @@
1A (A) [Y/n/?] (NEW)
2 A0 (A0) [Y/n/?] (NEW)
3 A1_0 (A0_0) [N/y/?] (NEW)
4 A1 (A1) [Y/n/?] (NEW)
5 choice
6 > 1. A1_0 (A1_0) (NEW)
7 2. A1_1 (A1_1) (NEW)
8 choice[1-2?]:
9B (B) [N/y/?] (NEW)
10C (C) [N/y/?] (NEW)
diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig
new file mode 100644
index 000000000000..cc60e9ce2c03
--- /dev/null
+++ b/scripts/kconfig/tests/choice/Kconfig
@@ -0,0 +1,54 @@
1config MODULES
2 bool "Enable loadable module support"
3 option modules
4 default y
5
6choice
7 prompt "boolean choice"
8 default BOOL_CHOICE1
9
10config BOOL_CHOICE0
11 bool "choice 0"
12
13config BOOL_CHOICE1
14 bool "choice 1"
15
16endchoice
17
18choice
19 prompt "optional boolean choice"
20 optional
21 default OPT_BOOL_CHOICE1
22
23config OPT_BOOL_CHOICE0
24 bool "choice 0"
25
26config OPT_BOOL_CHOICE1
27 bool "choice 1"
28
29endchoice
30
31choice
32 prompt "tristate choice"
33 default TRI_CHOICE1
34
35config TRI_CHOICE0
36 tristate "choice 0"
37
38config TRI_CHOICE1
39 tristate "choice 1"
40
41endchoice
42
43choice
44 prompt "optional tristate choice"
45 optional
46 default OPT_TRI_CHOICE1
47
48config OPT_TRI_CHOICE0
49 tristate "choice 0"
50
51config OPT_TRI_CHOICE1
52 tristate "choice 1"
53
54endchoice
diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py
new file mode 100644
index 000000000000..9edcc5262134
--- /dev/null
+++ b/scripts/kconfig/tests/choice/__init__.py
@@ -0,0 +1,40 @@
1"""
2Basic choice tests.
3
4The handling of 'choice' is a bit complicated part in Kconfig.
5
6The behavior of 'y' choice is intuitive. If choice values are tristate,
7the choice can be 'm' where each value can be enabled independently.
8Also, if a choice is marked as 'optional', the whole choice can be
9invisible.
10"""
11
12
13def test_oldask0(conf):
14 assert conf.oldaskconfig() == 0
15 assert conf.stdout_contains('oldask0_expected_stdout')
16
17
18def test_oldask1(conf):
19 assert conf.oldaskconfig('oldask1_config') == 0
20 assert conf.stdout_contains('oldask1_expected_stdout')
21
22
23def test_allyes(conf):
24 assert conf.allyesconfig() == 0
25 assert conf.config_contains('allyes_expected_config')
26
27
28def test_allmod(conf):
29 assert conf.allmodconfig() == 0
30 assert conf.config_contains('allmod_expected_config')
31
32
33def test_allno(conf):
34 assert conf.allnoconfig() == 0
35 assert conf.config_contains('allno_expected_config')
36
37
38def test_alldef(conf):
39 assert conf.alldefconfig() == 0
40 assert conf.config_contains('alldef_expected_config')
diff --git a/scripts/kconfig/tests/choice/alldef_expected_config b/scripts/kconfig/tests/choice/alldef_expected_config
new file mode 100644
index 000000000000..7a754bf4be94
--- /dev/null
+++ b/scripts/kconfig/tests/choice/alldef_expected_config
@@ -0,0 +1,5 @@
1CONFIG_MODULES=y
2# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y
4# CONFIG_TRI_CHOICE0 is not set
5# CONFIG_TRI_CHOICE1 is not set
diff --git a/scripts/kconfig/tests/choice/allmod_expected_config b/scripts/kconfig/tests/choice/allmod_expected_config
new file mode 100644
index 000000000000..f1f5dcdb7923
--- /dev/null
+++ b/scripts/kconfig/tests/choice/allmod_expected_config
@@ -0,0 +1,9 @@
1CONFIG_MODULES=y
2# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y
4# CONFIG_OPT_BOOL_CHOICE0 is not set
5CONFIG_OPT_BOOL_CHOICE1=y
6CONFIG_TRI_CHOICE0=m
7CONFIG_TRI_CHOICE1=m
8CONFIG_OPT_TRI_CHOICE0=m
9CONFIG_OPT_TRI_CHOICE1=m
diff --git a/scripts/kconfig/tests/choice/allno_expected_config b/scripts/kconfig/tests/choice/allno_expected_config
new file mode 100644
index 000000000000..b88ee7a43136
--- /dev/null
+++ b/scripts/kconfig/tests/choice/allno_expected_config
@@ -0,0 +1,5 @@
1# CONFIG_MODULES is not set
2# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y
4# CONFIG_TRI_CHOICE0 is not set
5CONFIG_TRI_CHOICE1=y
diff --git a/scripts/kconfig/tests/choice/allyes_expected_config b/scripts/kconfig/tests/choice/allyes_expected_config
new file mode 100644
index 000000000000..e5a062a1157c
--- /dev/null
+++ b/scripts/kconfig/tests/choice/allyes_expected_config
@@ -0,0 +1,9 @@
1CONFIG_MODULES=y
2# CONFIG_BOOL_CHOICE0 is not set
3CONFIG_BOOL_CHOICE1=y
4# CONFIG_OPT_BOOL_CHOICE0 is not set
5CONFIG_OPT_BOOL_CHOICE1=y
6# CONFIG_TRI_CHOICE0 is not set
7CONFIG_TRI_CHOICE1=y
8# CONFIG_OPT_TRI_CHOICE0 is not set
9CONFIG_OPT_TRI_CHOICE1=y
diff --git a/scripts/kconfig/tests/choice/oldask0_expected_stdout b/scripts/kconfig/tests/choice/oldask0_expected_stdout
new file mode 100644
index 000000000000..b251bba9698b
--- /dev/null
+++ b/scripts/kconfig/tests/choice/oldask0_expected_stdout
@@ -0,0 +1,10 @@
1Enable loadable module support (MODULES) [Y/n/?] (NEW)
2boolean choice
3 1. choice 0 (BOOL_CHOICE0) (NEW)
4> 2. choice 1 (BOOL_CHOICE1) (NEW)
5choice[1-2?]:
6optional boolean choice [N/y/?] (NEW)
7tristate choice [M/y/?] (NEW)
8 choice 0 (TRI_CHOICE0) [N/m/?] (NEW)
9 choice 1 (TRI_CHOICE1) [N/m/?] (NEW)
10optional tristate choice [N/m/y/?] (NEW)
diff --git a/scripts/kconfig/tests/choice/oldask1_config b/scripts/kconfig/tests/choice/oldask1_config
new file mode 100644
index 000000000000..b67bfe3c641f
--- /dev/null
+++ b/scripts/kconfig/tests/choice/oldask1_config
@@ -0,0 +1,2 @@
1# CONFIG_MODULES is not set
2CONFIG_OPT_BOOL_CHOICE0=y
diff --git a/scripts/kconfig/tests/choice/oldask1_expected_stdout b/scripts/kconfig/tests/choice/oldask1_expected_stdout
new file mode 100644
index 000000000000..c2125e9bf96a
--- /dev/null
+++ b/scripts/kconfig/tests/choice/oldask1_expected_stdout
@@ -0,0 +1,15 @@
1Enable loadable module support (MODULES) [N/y/?]
2boolean choice
3 1. choice 0 (BOOL_CHOICE0) (NEW)
4> 2. choice 1 (BOOL_CHOICE1) (NEW)
5choice[1-2?]:
6optional boolean choice [Y/n/?] (NEW)
7optional boolean choice
8> 1. choice 0 (OPT_BOOL_CHOICE0)
9 2. choice 1 (OPT_BOOL_CHOICE1) (NEW)
10choice[1-2?]:
11tristate choice
12 1. choice 0 (TRI_CHOICE0) (NEW)
13> 2. choice 1 (TRI_CHOICE1) (NEW)
14choice[1-2?]:
15optional tristate choice [N/y/?]
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig
new file mode 100644
index 000000000000..11ac25c26040
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig
@@ -0,0 +1,19 @@
1config MODULES
2 def_bool y
3 option modules
4
5config DEP
6 tristate
7 default m
8
9choice
10 prompt "Tristate Choice"
11
12config CHOICE0
13 tristate "Choice 0"
14
15config CHOICE1
16 tristate "Choice 1"
17 depends on DEP
18
19endchoice
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py
new file mode 100644
index 000000000000..f8d728c7b101
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py
@@ -0,0 +1,15 @@
1"""
2Hide tristate choice values with mod dependency in y choice.
3
4If tristate choice values depend on symbols set to 'm', they should be
5hidden when the choice containing them is changed from 'm' to 'y'
6(i.e. exclusive choice).
7
8Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074
9"""
10
11
12def test(conf):
13 assert conf.oldaskconfig('config', 'y') == 0
14 assert conf.config_contains('expected_config')
15 assert conf.stdout_contains('expected_stdout')
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/config b/scripts/kconfig/tests/choice_value_with_m_dep/config
new file mode 100644
index 000000000000..3a126b7a2546
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/config
@@ -0,0 +1,2 @@
1CONFIG_CHOICE0=m
2CONFIG_CHOICE1=m
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_config b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config
new file mode 100644
index 000000000000..4d07b449540e
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config
@@ -0,0 +1,3 @@
1CONFIG_MODULES=y
2CONFIG_DEP=m
3CONFIG_CHOICE0=y
diff --git a/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout
new file mode 100644
index 000000000000..2b50ab65c86a
--- /dev/null
+++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout
@@ -0,0 +1,4 @@
1Tristate Choice [M/y/?] y
2Tristate Choice
3> 1. Choice 0 (CHOICE0)
4choice[1]: 1
diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py
new file mode 100644
index 000000000000..0345ef6e3273
--- /dev/null
+++ b/scripts/kconfig/tests/conftest.py
@@ -0,0 +1,291 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
4#
5
6"""
7Kconfig unit testing framework.
8
9This provides fixture functions commonly used from test files.
10"""
11
12import os
13import pytest
14import shutil
15import subprocess
16import tempfile
17
18CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf'))
19
20
21class Conf:
22 """Kconfig runner and result checker.
23
24 This class provides methods to run text-based interface of Kconfig
25 (scripts/kconfig/conf) and retrieve the resulted configuration,
26 stdout, and stderr. It also provides methods to compare those
27 results with expectations.
28 """
29
30 def __init__(self, request):
31 """Create a new Conf instance.
32
33 request: object to introspect the requesting test module
34 """
35 # the directory of the test being run
36 self._test_dir = os.path.dirname(str(request.fspath))
37
38 # runners
39 def _run_conf(self, mode, dot_config=None, out_file='.config',
40 interactive=False, in_keys=None, extra_env={}):
41 """Run text-based Kconfig executable and save the result.
42
43 mode: input mode option (--oldaskconfig, --defconfig=<file> etc.)
44 dot_config: .config file to use for configuration base
45 out_file: file name to contain the output config data
46 interactive: flag to specify the interactive mode
47 in_keys: key inputs for interactive modes
48 extra_env: additional environments
49 returncode: exit status of the Kconfig executable
50 """
51 command = [CONF_PATH, mode, 'Kconfig']
52
53 # Override 'srctree' environment to make the test as the top directory
54 extra_env['srctree'] = self._test_dir
55
56 # Run Kconfig in a temporary directory.
57 # This directory is automatically removed when done.
58 with tempfile.TemporaryDirectory() as temp_dir:
59
60 # if .config is given, copy it to the working directory
61 if dot_config:
62 shutil.copyfile(os.path.join(self._test_dir, dot_config),
63 os.path.join(temp_dir, '.config'))
64
65 ps = subprocess.Popen(command,
66 stdin=subprocess.PIPE,
67 stdout=subprocess.PIPE,
68 stderr=subprocess.PIPE,
69 cwd=temp_dir,
70 env=dict(os.environ, **extra_env))
71
72 # If input key sequence is given, feed it to stdin.
73 if in_keys:
74 ps.stdin.write(in_keys.encode('utf-8'))
75
76 while ps.poll() is None:
77 # For interactive modes such as oldaskconfig, oldconfig,
78 # send 'Enter' key until the program finishes.
79 if interactive:
80 ps.stdin.write(b'\n')
81
82 self.retcode = ps.returncode
83 self.stdout = ps.stdout.read().decode()
84 self.stderr = ps.stderr.read().decode()
85
86 # Retrieve the resulted config data only when .config is supposed
87 # to exist. If the command fails, the .config does not exist.
88 # 'listnewconfig' does not produce .config in the first place.
89 if self.retcode == 0 and out_file:
90 with open(os.path.join(temp_dir, out_file)) as f:
91 self.config = f.read()
92 else:
93 self.config = None
94
95 # Logging:
96 # Pytest captures the following information by default. In failure
97 # of tests, the captured log will be displayed. This will be useful to
98 # figure out what has happened.
99
100 print("[command]\n{}\n".format(' '.join(command)))
101
102 print("[retcode]\n{}\n".format(self.retcode))
103
104 print("[stdout]")
105 print(self.stdout)
106
107 print("[stderr]")
108 print(self.stderr)
109
110 if self.config is not None:
111 print("[output for '{}']".format(out_file))
112 print(self.config)
113
114 return self.retcode
115
116 def oldaskconfig(self, dot_config=None, in_keys=None):
117 """Run oldaskconfig.
118
119 dot_config: .config file to use for configuration base (optional)
120 in_key: key inputs (optional)
121 returncode: exit status of the Kconfig executable
122 """
123 return self._run_conf('--oldaskconfig', dot_config=dot_config,
124 interactive=True, in_keys=in_keys)
125
126 def oldconfig(self, dot_config=None, in_keys=None):
127 """Run oldconfig.
128
129 dot_config: .config file to use for configuration base (optional)
130 in_key: key inputs (optional)
131 returncode: exit status of the Kconfig executable
132 """
133 return self._run_conf('--oldconfig', dot_config=dot_config,
134 interactive=True, in_keys=in_keys)
135
136 def olddefconfig(self, dot_config=None):
137 """Run olddefconfig.
138
139 dot_config: .config file to use for configuration base (optional)
140 returncode: exit status of the Kconfig executable
141 """
142 return self._run_conf('--olddefconfig', dot_config=dot_config)
143
144 def defconfig(self, defconfig):
145 """Run defconfig.
146
147 defconfig: defconfig file for input
148 returncode: exit status of the Kconfig executable
149 """
150 defconfig_path = os.path.join(self._test_dir, defconfig)
151 return self._run_conf('--defconfig={}'.format(defconfig_path))
152
153 def _allconfig(self, mode, all_config):
154 if all_config:
155 all_config_path = os.path.join(self._test_dir, all_config)
156 extra_env = {'KCONFIG_ALLCONFIG': all_config_path}
157 else:
158 extra_env = {}
159
160 return self._run_conf('--{}config'.format(mode), extra_env=extra_env)
161
162 def allyesconfig(self, all_config=None):
163 """Run allyesconfig.
164
165 all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
166 returncode: exit status of the Kconfig executable
167 """
168 return self._allconfig('allyes', all_config)
169
170 def allmodconfig(self, all_config=None):
171 """Run allmodconfig.
172
173 all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
174 returncode: exit status of the Kconfig executable
175 """
176 return self._allconfig('allmod', all_config)
177
178 def allnoconfig(self, all_config=None):
179 """Run allnoconfig.
180
181 all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
182 returncode: exit status of the Kconfig executable
183 """
184 return self._allconfig('allno', all_config)
185
186 def alldefconfig(self, all_config=None):
187 """Run alldefconfig.
188
189 all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
190 returncode: exit status of the Kconfig executable
191 """
192 return self._allconfig('alldef', all_config)
193
194 def randconfig(self, all_config=None):
195 """Run randconfig.
196
197 all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
198 returncode: exit status of the Kconfig executable
199 """
200 return self._allconfig('rand', all_config)
201
202 def savedefconfig(self, dot_config):
203 """Run savedefconfig.
204
205 dot_config: .config file for input
206 returncode: exit status of the Kconfig executable
207 """
208 return self._run_conf('--savedefconfig', out_file='defconfig')
209
210 def listnewconfig(self, dot_config=None):
211 """Run listnewconfig.
212
213 dot_config: .config file to use for configuration base (optional)
214 returncode: exit status of the Kconfig executable
215 """
216 return self._run_conf('--listnewconfig', dot_config=dot_config,
217 out_file=None)
218
219 # checkers
220 def _read_and_compare(self, compare, expected):
221 """Compare the result with expectation.
222
223 compare: function to compare the result with expectation
224 expected: file that contains the expected data
225 """
226 with open(os.path.join(self._test_dir, expected)) as f:
227 expected_data = f.read()
228 return compare(self, expected_data)
229
230 def _contains(self, attr, expected):
231 return self._read_and_compare(
232 lambda s, e: getattr(s, attr).find(e) >= 0,
233 expected)
234
235 def _matches(self, attr, expected):
236 return self._read_and_compare(lambda s, e: getattr(s, attr) == e,
237 expected)
238
239 def config_contains(self, expected):
240 """Check if resulted configuration contains expected data.
241
242 expected: file that contains the expected data
243 returncode: True if result contains the expected data, False otherwise
244 """
245 return self._contains('config', expected)
246
247 def config_matches(self, expected):
248 """Check if resulted configuration exactly matches expected data.
249
250 expected: file that contains the expected data
251 returncode: True if result matches the expected data, False otherwise
252 """
253 return self._matches('config', expected)
254
255 def stdout_contains(self, expected):
256 """Check if resulted stdout contains expected data.
257
258 expected: file that contains the expected data
259 returncode: True if result contains the expected data, False otherwise
260 """
261 return self._contains('stdout', expected)
262
263 def stdout_matches(self, expected):
264 """Check if resulted stdout exactly matches expected data.
265
266 expected: file that contains the expected data
267 returncode: True if result matches the expected data, False otherwise
268 """
269 return self._matches('stdout', expected)
270
271 def stderr_contains(self, expected):
272 """Check if resulted stderr contains expected data.
273
274 expected: file that contains the expected data
275 returncode: True if result contains the expected data, False otherwise
276 """
277 return self._contains('stderr', expected)
278
279 def stderr_matches(self, expected):
280 """Check if resulted stderr exactly matches expected data.
281
282 expected: file that contains the expected data
283 returncode: True if result matches the expected data, False otherwise
284 """
285 return self._matches('stderr', expected)
286
287
288@pytest.fixture(scope="module")
289def conf(request):
290 """Create a Conf instance and provide it to test functions."""
291 return Conf(request)
diff --git a/scripts/kconfig/tests/err_recursive_dep/Kconfig b/scripts/kconfig/tests/err_recursive_dep/Kconfig
new file mode 100644
index 000000000000..ebdb3ffd8717
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_dep/Kconfig
@@ -0,0 +1,63 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# depends on itself
4
5config A
6 bool "A"
7 depends on A
8
9# select itself
10
11config B
12 bool
13 select B
14
15# depends on each other
16
17config C1
18 bool "C1"
19 depends on C2
20
21config C2
22 bool "C2"
23 depends on C1
24
25# depends on and select
26
27config D1
28 bool "D1"
29 depends on D2
30 select D2
31
32config D2
33 bool
34
35# depends on and imply
36
37config E1
38 bool "E1"
39 depends on E2
40 imply E2
41
42config E2
43 bool "E2"
44
45# property
46
47config F1
48 bool "F1"
49 default F2
50
51config F2
52 bool "F2"
53 depends on F1
54
55# menu
56
57menu "menu depending on its content"
58 depends on G
59
60config G
61 bool "G"
62
63endmenu
diff --git a/scripts/kconfig/tests/err_recursive_dep/__init__.py b/scripts/kconfig/tests/err_recursive_dep/__init__.py
new file mode 100644
index 000000000000..5f3821b43ce6
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_dep/__init__.py
@@ -0,0 +1,10 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Detect recursive dependency error.
4
5Recursive dependency should be treated as an error.
6"""
7
8def test(conf):
9 assert conf.oldaskconfig() == 1
10 assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr
new file mode 100644
index 000000000000..84679b104655
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_dep/expected_stderr
@@ -0,0 +1,38 @@
1Kconfig:11:error: recursive dependency detected!
2Kconfig:11: symbol B is selected by B
3For a resolution refer to Documentation/kbuild/kconfig-language.txt
4subsection "Kconfig recursive dependency limitations"
5
6Kconfig:5:error: recursive dependency detected!
7Kconfig:5: symbol A depends on A
8For a resolution refer to Documentation/kbuild/kconfig-language.txt
9subsection "Kconfig recursive dependency limitations"
10
11Kconfig:17:error: recursive dependency detected!
12Kconfig:17: symbol C1 depends on C2
13Kconfig:21: symbol C2 depends on C1
14For a resolution refer to Documentation/kbuild/kconfig-language.txt
15subsection "Kconfig recursive dependency limitations"
16
17Kconfig:32:error: recursive dependency detected!
18Kconfig:32: symbol D2 is selected by D1
19Kconfig:27: symbol D1 depends on D2
20For a resolution refer to Documentation/kbuild/kconfig-language.txt
21subsection "Kconfig recursive dependency limitations"
22
23Kconfig:37:error: recursive dependency detected!
24Kconfig:37: symbol E1 depends on E2
25Kconfig:42: symbol E2 is implied by E1
26For a resolution refer to Documentation/kbuild/kconfig-language.txt
27subsection "Kconfig recursive dependency limitations"
28
29Kconfig:60:error: recursive dependency detected!
30Kconfig:60: symbol G depends on G
31For a resolution refer to Documentation/kbuild/kconfig-language.txt
32subsection "Kconfig recursive dependency limitations"
33
34Kconfig:51:error: recursive dependency detected!
35Kconfig:51: symbol F2 depends on F1
36Kconfig:49: symbol F1 default value contains F2
37For a resolution refer to Documentation/kbuild/kconfig-language.txt
38subsection "Kconfig recursive dependency limitations"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig
new file mode 100644
index 000000000000..0e4c8750ab65
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig
@@ -0,0 +1 @@
source "Kconfig.inc1"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1
new file mode 100644
index 000000000000..00e408d653fc
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1
@@ -0,0 +1,4 @@
1
2
3
4source "Kconfig.inc2"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2
new file mode 100644
index 000000000000..349ea2db15dc
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2
@@ -0,0 +1,3 @@
1
2
3source "Kconfig.inc3"
diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3 b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3
new file mode 100644
index 000000000000..0e4c8750ab65
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc3
@@ -0,0 +1 @@
source "Kconfig.inc1"
diff --git a/scripts/kconfig/tests/err_recursive_inc/__init__.py b/scripts/kconfig/tests/err_recursive_inc/__init__.py
new file mode 100644
index 000000000000..0e4c839c54aa
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/__init__.py
@@ -0,0 +1,10 @@
1"""
2Detect recursive inclusion error.
3
4If recursive inclusion is detected, it should fail with error messages.
5"""
6
7
8def test(conf):
9 assert conf.oldaskconfig() != 0
10 assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/err_recursive_inc/expected_stderr b/scripts/kconfig/tests/err_recursive_inc/expected_stderr
new file mode 100644
index 000000000000..6b582eee2176
--- /dev/null
+++ b/scripts/kconfig/tests/err_recursive_inc/expected_stderr
@@ -0,0 +1,6 @@
1Recursive inclusion detected.
2Inclusion path:
3 current file : Kconfig.inc1
4 included from: Kconfig.inc3:1
5 included from: Kconfig.inc2:3
6 included from: Kconfig.inc1:4
diff --git a/scripts/kconfig/tests/inter_choice/Kconfig b/scripts/kconfig/tests/inter_choice/Kconfig
new file mode 100644
index 000000000000..e44449f075df
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/Kconfig
@@ -0,0 +1,23 @@
1config MODULES
2 def_bool y
3 option modules
4
5choice
6 prompt "Choice"
7
8config CHOICE_VAL0
9 tristate "Choice 0"
10
11config CHOIVE_VAL1
12 tristate "Choice 1"
13
14endchoice
15
16choice
17 prompt "Another choice"
18 depends on CHOICE_VAL0
19
20config DUMMY
21 bool "dummy"
22
23endchoice
diff --git a/scripts/kconfig/tests/inter_choice/__init__.py b/scripts/kconfig/tests/inter_choice/__init__.py
new file mode 100644
index 000000000000..5c7fc365ed40
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/__init__.py
@@ -0,0 +1,14 @@
1"""
2Do not affect user-assigned choice value by another choice.
3
4Handling of state flags for choices is complecated. In old days,
5the defconfig result of a choice could be affected by another choice
6if those choices interact by 'depends on', 'select', etc.
7
8Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a
9"""
10
11
12def test(conf):
13 assert conf.defconfig('defconfig') == 0
14 assert conf.config_contains('expected_config')
diff --git a/scripts/kconfig/tests/inter_choice/defconfig b/scripts/kconfig/tests/inter_choice/defconfig
new file mode 100644
index 000000000000..162c4148e2a5
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/defconfig
@@ -0,0 +1 @@
CONFIG_CHOICE_VAL0=y
diff --git a/scripts/kconfig/tests/inter_choice/expected_config b/scripts/kconfig/tests/inter_choice/expected_config
new file mode 100644
index 000000000000..5dceefb054e3
--- /dev/null
+++ b/scripts/kconfig/tests/inter_choice/expected_config
@@ -0,0 +1,4 @@
1CONFIG_MODULES=y
2CONFIG_CHOICE_VAL0=y
3# CONFIG_CHOIVE_VAL1 is not set
4CONFIG_DUMMY=y
diff --git a/scripts/kconfig/tests/new_choice_with_dep/Kconfig b/scripts/kconfig/tests/new_choice_with_dep/Kconfig
new file mode 100644
index 000000000000..53ef1b86e7bf
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/Kconfig
@@ -0,0 +1,37 @@
1config A
2 bool "A"
3 help
4 This is a new symbol.
5
6choice
7 prompt "Choice ?"
8 depends on A
9 help
10 "depends on A" has been newly added.
11
12config CHOICE_B
13 bool "Choice B"
14
15config CHOICE_C
16 bool "Choice C"
17 help
18 This is a new symbol, so should be asked.
19
20endchoice
21
22choice
23 prompt "Choice2 ?"
24
25config CHOICE_D
26 bool "Choice D"
27
28config CHOICE_E
29 bool "Choice E"
30
31config CHOICE_F
32 bool "Choice F"
33 depends on A
34 help
35 This is a new symbol, so should be asked.
36
37endchoice
diff --git a/scripts/kconfig/tests/new_choice_with_dep/__init__.py b/scripts/kconfig/tests/new_choice_with_dep/__init__.py
new file mode 100644
index 000000000000..f0e0ead0f32f
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/__init__.py
@@ -0,0 +1,14 @@
1"""
2Ask new choice values when they become visible.
3
4If new choice values are added with new dependency, and they become
5visible during user configuration, oldconfig should recognize them
6as (NEW), and ask the user for choice.
7
8Related Linux commit: 5d09598d488f081e3be23f885ed65cbbe2d073b5
9"""
10
11
12def test(conf):
13 assert conf.oldconfig('config', 'y') == 0
14 assert conf.stdout_contains('expected_stdout')
diff --git a/scripts/kconfig/tests/new_choice_with_dep/config b/scripts/kconfig/tests/new_choice_with_dep/config
new file mode 100644
index 000000000000..47ef95d567fd
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/config
@@ -0,0 +1,3 @@
1CONFIG_CHOICE_B=y
2# CONFIG_CHOICE_D is not set
3CONFIG_CHOICE_E=y
diff --git a/scripts/kconfig/tests/new_choice_with_dep/expected_stdout b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout
new file mode 100644
index 000000000000..74dc0bcb22bc
--- /dev/null
+++ b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout
@@ -0,0 +1,10 @@
1A (A) [N/y/?] (NEW) y
2 Choice ?
3 > 1. Choice B (CHOICE_B)
4 2. Choice C (CHOICE_C) (NEW)
5 choice[1-2?]:
6Choice2 ?
7 1. Choice D (CHOICE_D)
8> 2. Choice E (CHOICE_E)
9 3. Choice F (CHOICE_F) (NEW)
10choice[1-3?]:
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig
new file mode 100644
index 000000000000..c00b8fe54f45
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig
@@ -0,0 +1,14 @@
1config A
2 bool "A"
3
4choice
5 prompt "Choice ?"
6 depends on A
7
8config CHOICE_B
9 bool "Choice B"
10
11config CHOICE_C
12 bool "Choice C"
13
14endchoice
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py
new file mode 100644
index 000000000000..207261b0fe00
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py
@@ -0,0 +1,19 @@
1"""
2Do not write choice values to .config if the dependency is unmet.
3
4"# CONFIG_... is not set" should not be written into the .config file
5for symbols with unmet dependency.
6
7This was not working correctly for choice values because choice needs
8a bit different symbol computation.
9
10This checks that no unneeded "# COFIG_... is not set" is contained in
11the .config file.
12
13Related Linux commit: cb67ab2cd2b8abd9650292c986c79901e3073a59
14"""
15
16
17def test(conf):
18 assert conf.oldaskconfig('config', 'n') == 0
19 assert conf.config_matches('expected_config')
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/config b/scripts/kconfig/tests/no_write_if_dep_unmet/config
new file mode 100644
index 000000000000..abd280e2f616
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/config
@@ -0,0 +1 @@
CONFIG_A=y
diff --git a/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
new file mode 100644
index 000000000000..473228810c35
--- /dev/null
+++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config
@@ -0,0 +1,5 @@
1#
2# Automatically generated file; DO NOT EDIT.
3# Main menu
4#
5# CONFIG_A is not set
diff --git a/scripts/kconfig/tests/preprocess/builtin_func/Kconfig b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig
new file mode 100644
index 000000000000..baa328827911
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/builtin_func/Kconfig
@@ -0,0 +1,27 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# 'info' prints the argument to stdout.
4$(info,hello world 0)
5
6# 'warning-if', if the first argument is y, sends the second argument to stderr,
7# and the message is prefixed with the current file name and line number.
8$(warning-if,y,hello world 1)
9
10# 'error-if' is similar, but it terminates the parsing immediately.
11# The following is just no-op since the first argument is not y.
12$(error-if,n,this should not be printed)
13
14# Shorthand
15warning = $(warning-if,y,$(1))
16
17# 'shell' executes a command, and returns its stdout.
18$(warning,$(shell,echo hello world 3))
19
20# Every newline in the output is replaced with a space,
21# but any trailing newlines are deleted.
22$(warning,$(shell,printf 'hello\nworld\n\n4\n\n\n'))
23
24# 'filename' is expanded to the currently parsed file name,
25# 'lineno' to the line number.
26$(warning,filename=$(filename))
27$(warning,lineno=$(lineno))
diff --git a/scripts/kconfig/tests/preprocess/builtin_func/__init__.py b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py
new file mode 100644
index 000000000000..2e53ba08fca1
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/builtin_func/__init__.py
@@ -0,0 +1,9 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Built-in function tests.
4"""
5
6def test(conf):
7 assert conf.oldaskconfig() == 0
8 assert conf.stdout_contains('expected_stdout')
9 assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr
new file mode 100644
index 000000000000..33ea9ca38400
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stderr
@@ -0,0 +1,5 @@
1Kconfig:8: hello world 1
2Kconfig:18: hello world 3
3Kconfig:22: hello world 4
4Kconfig:26: filename=Kconfig
5Kconfig:27: lineno=27
diff --git a/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout
new file mode 100644
index 000000000000..82de3a7e97de
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/builtin_func/expected_stdout
@@ -0,0 +1 @@
hello world 0
diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig
new file mode 100644
index 000000000000..6838997c23ba
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/circular_expansion/Kconfig
@@ -0,0 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0
2
3X = $(Y)
4Y = $(X)
5$(info $(X))
diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py
new file mode 100644
index 000000000000..419bda3e075c
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/circular_expansion/__init__.py
@@ -0,0 +1,11 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Detect circular variable expansion.
4
5If a recursively expanded variable references itself (eventually),
6it should fail with an error message.
7"""
8
9def test(conf):
10 assert conf.oldaskconfig() != 0
11 assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr
new file mode 100644
index 000000000000..cde68fa989d0
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/circular_expansion/expected_stderr
@@ -0,0 +1 @@
Kconfig:5: Recursive variable 'X' references itself (eventually)
diff --git a/scripts/kconfig/tests/preprocess/escape/Kconfig b/scripts/kconfig/tests/preprocess/escape/Kconfig
new file mode 100644
index 000000000000..4e3f44445544
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/escape/Kconfig
@@ -0,0 +1,44 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# Shorthand
4warning = $(warning-if,y,$(1))
5
6# You can not pass commas directly to a function since they are treated as
7# delimiters. You can use the following trick to do so.
8comma := ,
9$(warning,hello$(comma) world)
10
11# Like Make, single quotes, double quotes, spaces are treated verbatim.
12# The following prints the text as-is.
13$(warning, ' " '" ' ''' "'")
14
15# Unlike Make, '$' has special meaning only when it is followed by '('.
16# No need to escape '$' itself.
17$(warning,$)
18$(warning,$$)
19$ := 1
20$(warning,$($))
21
22# You need a trick to escape '$' followed by '('
23# The following should print "$(X)". It should not be expanded further.
24dollar := $
25$(warning,$(dollar)(X))
26
27# You need a trick to treat unbalanced parentheses.
28# The following should print "(".
29left_paren := (
30$(warning,$(left_paren))
31
32# A simple expanded should not be expanded multiple times.
33# The following should print "$(X)". It should not be expanded further.
34Y := $(dollar)(X)
35$(warning,$(Y))
36
37# The following should print "$(X)" as well.
38Y = $(dollar)(X)
39$(warning,$(Y))
40
41# The following should print "$(".
42# It should not be emit "unterminated reference" error.
43unterminated := $(dollar)(
44$(warning,$(unterminated))
diff --git a/scripts/kconfig/tests/preprocess/escape/__init__.py b/scripts/kconfig/tests/preprocess/escape/__init__.py
new file mode 100644
index 000000000000..7ee8e747f546
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/escape/__init__.py
@@ -0,0 +1,8 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Escape sequence tests.
4"""
5
6def test(conf):
7 assert conf.oldaskconfig() == 0
8 assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/preprocess/escape/expected_stderr b/scripts/kconfig/tests/preprocess/escape/expected_stderr
new file mode 100644
index 000000000000..1c00957ddaa9
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/escape/expected_stderr
@@ -0,0 +1,10 @@
1Kconfig:9: hello, world
2Kconfig:13: ' " '" ' ''' "'"
3Kconfig:17: $
4Kconfig:18: $$
5Kconfig:20: 1
6Kconfig:25: $(X)
7Kconfig:30: (
8Kconfig:35: $(X)
9Kconfig:39: $(X)
10Kconfig:44: $(
diff --git a/scripts/kconfig/tests/preprocess/variable/Kconfig b/scripts/kconfig/tests/preprocess/variable/Kconfig
new file mode 100644
index 000000000000..9ce2f95cbd24
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/variable/Kconfig
@@ -0,0 +1,53 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# Shorthand
4warning = $(warning-if,y,$(1))
5
6# Simply expanded variable.
7X := 1
8SIMPLE := $(X)
9X := 2
10$(warning,SIMPLE = $(SIMPLE))
11
12# Recursively expanded variable.
13X := 1
14RECURSIVE = $(X)
15X := 2
16$(warning,RECURSIVE = $(RECURSIVE))
17
18# Append something to a simply expanded variable.
19Y := 3
20SIMPLE += $(Y)
21Y := 4
22$(warning,SIMPLE = $(SIMPLE))
23
24# Append something to a recursively expanded variable.
25Y := 3
26RECURSIVE += $(Y)
27Y := 4
28$(warning,RECURSIVE = $(RECURSIVE))
29
30# Use += operator to an undefined variable.
31# This works as a recursively expanded variable.
32Y := 3
33UNDEFINED_VARIABLE += $(Y)
34Y := 4
35$(warning,UNDEFINED_VARIABLE = $(UNDEFINED_VARIABLE))
36
37# You can use variable references for the lefthand side of assignment statement.
38X := A
39Y := B
40$(X)$(Y) := 5
41$(warning,AB = $(AB))
42
43# User-defined function.
44greeting = $(1), my name is $(2).
45$(warning,$(greeting,Hello,John))
46
47# The number of arguments is not checked for user-defined functions.
48# If some arguments are optional, it is useful to pass fewer parameters.
49# $(2) will be blank in this case.
50$(warning,$(greeting,Hello))
51
52# Unreferenced parameters are just ignored.
53$(warning,$(greeting,Hello,John,ignored,ignored))
diff --git a/scripts/kconfig/tests/preprocess/variable/__init__.py b/scripts/kconfig/tests/preprocess/variable/__init__.py
new file mode 100644
index 000000000000..e88b1708d6d4
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/variable/__init__.py
@@ -0,0 +1,8 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Variable and user-defined function tests.
4"""
5
6def test(conf):
7 assert conf.oldaskconfig() == 0
8 assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/preprocess/variable/expected_stderr b/scripts/kconfig/tests/preprocess/variable/expected_stderr
new file mode 100644
index 000000000000..a4841c3fdff5
--- /dev/null
+++ b/scripts/kconfig/tests/preprocess/variable/expected_stderr
@@ -0,0 +1,9 @@
1Kconfig:10: SIMPLE = 1
2Kconfig:16: RECURSIVE = 2
3Kconfig:22: SIMPLE = 1 3
4Kconfig:28: RECURSIVE = 2 4
5Kconfig:35: UNDEFINED_VARIABLE = 4
6Kconfig:41: AB = 5
7Kconfig:45: Hello, my name is John.
8Kconfig:50: Hello, my name is .
9Kconfig:53: Hello, my name is John.
diff --git a/scripts/kconfig/tests/pytest.ini b/scripts/kconfig/tests/pytest.ini
new file mode 100644
index 000000000000..85d7ce8e448b
--- /dev/null
+++ b/scripts/kconfig/tests/pytest.ini
@@ -0,0 +1,7 @@
1[pytest]
2addopts = --verbose
3
4# Pytest requires that test files have unique names, because pytest imports
5# them as top-level modules. It is silly to prefix or suffix a test file with
6# the directory name that contains it. Use __init__.py for all test files.
7python_files = __init__.py
diff --git a/scripts/kconfig/tests/rand_nested_choice/Kconfig b/scripts/kconfig/tests/rand_nested_choice/Kconfig
new file mode 100644
index 000000000000..c591d512929f
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/Kconfig
@@ -0,0 +1,33 @@
1choice
2 prompt "choice"
3
4config A
5 bool "A"
6
7config B
8 bool "B"
9
10if B
11choice
12 prompt "sub choice"
13
14config C
15 bool "C"
16
17config D
18 bool "D"
19
20if D
21choice
22 prompt "subsub choice"
23
24config E
25 bool "E"
26
27endchoice
28endif # D
29
30endchoice
31endif # B
32
33endchoice
diff --git a/scripts/kconfig/tests/rand_nested_choice/__init__.py b/scripts/kconfig/tests/rand_nested_choice/__init__.py
new file mode 100644
index 000000000000..e729a4e85218
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/__init__.py
@@ -0,0 +1,16 @@
1"""
2Set random values recursively in nested choices.
3
4Kconfig can create a choice-in-choice structure by using 'if' statement.
5randconfig should correctly set random choice values.
6
7Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29
8"""
9
10
11def test(conf):
12 for i in range(20):
13 assert conf.randconfig() == 0
14 assert (conf.config_contains('expected_stdout0') or
15 conf.config_contains('expected_stdout1') or
16 conf.config_contains('expected_stdout2'))
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0
new file mode 100644
index 000000000000..05450f3d4eb5
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0
@@ -0,0 +1,2 @@
1CONFIG_A=y
2# CONFIG_B is not set
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1
new file mode 100644
index 000000000000..37ab29584157
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1
@@ -0,0 +1,4 @@
1# CONFIG_A is not set
2CONFIG_B=y
3CONFIG_C=y
4# CONFIG_D is not set
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2
new file mode 100644
index 000000000000..849ff47e9848
--- /dev/null
+++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2
@@ -0,0 +1,5 @@
1# CONFIG_A is not set
2CONFIG_B=y
3# CONFIG_C is not set
4CONFIG_D=y
5CONFIG_E=y
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index c6f6e21b809f..d999683bb2a7 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -14,69 +14,21 @@
14struct file *file_lookup(const char *name) 14struct file *file_lookup(const char *name)
15{ 15{
16 struct file *file; 16 struct file *file;
17 char *file_name = sym_expand_string_value(name);
18 17
19 for (file = file_list; file; file = file->next) { 18 for (file = file_list; file; file = file->next) {
20 if (!strcmp(name, file->name)) { 19 if (!strcmp(name, file->name)) {
21 free(file_name);
22 return file; 20 return file;
23 } 21 }
24 } 22 }
25 23
26 file = xmalloc(sizeof(*file)); 24 file = xmalloc(sizeof(*file));
27 memset(file, 0, sizeof(*file)); 25 memset(file, 0, sizeof(*file));
28 file->name = file_name; 26 file->name = xstrdup(name);
29 file->next = file_list; 27 file->next = file_list;
30 file_list = file; 28 file_list = file;
31 return file; 29 return file;
32} 30}
33 31
34/* write a dependency file as used by kbuild to track dependencies */
35int file_write_dep(const char *name)
36{
37 struct symbol *sym, *env_sym;
38 struct expr *e;
39 struct file *file;
40 FILE *out;
41
42 if (!name)
43 name = ".kconfig.d";
44 out = fopen("..config.tmp", "w");
45 if (!out)
46 return 1;
47 fprintf(out, "deps_config := \\\n");
48 for (file = file_list; file; file = file->next) {
49 if (file->next)
50 fprintf(out, "\t%s \\\n", file->name);
51 else
52 fprintf(out, "\t%s\n", file->name);
53 }
54 fprintf(out, "\n%s: \\\n"
55 "\t$(deps_config)\n\n", conf_get_autoconfig_name());
56
57 expr_list_for_each_sym(sym_env_list, e, sym) {
58 struct property *prop;
59 const char *value;
60
61 prop = sym_get_env_prop(sym);
62 env_sym = prop_get_symbol(prop);
63 if (!env_sym)
64 continue;
65 value = getenv(env_sym->name);
66 if (!value)
67 value = "";
68 fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
69 fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());
70 fprintf(out, "endif\n");
71 }
72
73 fprintf(out, "\n$(deps_config): ;\n");
74 fclose(out);
75 rename("..config.tmp", name);
76 return 0;
77}
78
79
80/* Allocate initial growable string */ 32/* Allocate initial growable string */
81struct gstr str_new(void) 33struct gstr str_new(void)
82{ 34{
@@ -165,3 +117,14 @@ char *xstrdup(const char *s)
165 fprintf(stderr, "Out of memory.\n"); 117 fprintf(stderr, "Out of memory.\n");
166 exit(1); 118 exit(1);
167} 119}
120
121char *xstrndup(const char *s, size_t n)
122{
123 char *p;
124
125 p = strndup(s, n);
126 if (p)
127 return p;
128 fprintf(stderr, "Out of memory.\n");
129 exit(1);
130}
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 88b650eb9cc9..25bd2b89fe3f 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -1,13 +1,13 @@
1%option nostdinit noyywrap never-interactive full ecs 1%option nostdinit noyywrap never-interactive full ecs
2%option 8bit nodefault perf-report perf-report 2%option 8bit nodefault yylineno
3%option noinput 3%x COMMAND HELP STRING PARAM ASSIGN_VAL
4%x COMMAND HELP STRING PARAM
5%{ 4%{
6/* 5/*
7 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 6 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
8 * Released under the terms of the GNU GPL v2.0. 7 * Released under the terms of the GNU GPL v2.0.
9 */ 8 */
10 9
10#include <assert.h>
11#include <limits.h> 11#include <limits.h>
12#include <stdio.h> 12#include <stdio.h>
13#include <stdlib.h> 13#include <stdlib.h>
@@ -35,6 +35,8 @@ struct buffer *current_buf;
35 35
36static int last_ts, first_ts; 36static int last_ts, first_ts;
37 37
38static char *expand_token(const char *in, size_t n);
39static void append_expanded_string(const char *in);
38static void zconf_endhelp(void); 40static void zconf_endhelp(void);
39static void zconf_endfile(void); 41static void zconf_endfile(void);
40 42
@@ -83,7 +85,6 @@ n [A-Za-z0-9_-]
83 85
84[ \t]*#.*\n | 86[ \t]*#.*\n |
85[ \t]*\n { 87[ \t]*\n {
86 current_file->lineno++;
87 return T_EOL; 88 return T_EOL;
88} 89}
89[ \t]*#.* 90[ \t]*#.*
@@ -102,25 +103,45 @@ n [A-Za-z0-9_-]
102<COMMAND>{ 103<COMMAND>{
103 {n}+ { 104 {n}+ {
104 const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); 105 const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
105 BEGIN(PARAM);
106 current_pos.file = current_file; 106 current_pos.file = current_file;
107 current_pos.lineno = current_file->lineno; 107 current_pos.lineno = yylineno;
108 if (id && id->flags & TF_COMMAND) { 108 if (id && id->flags & TF_COMMAND) {
109 BEGIN(PARAM);
109 yylval.id = id; 110 yylval.id = id;
110 return id->token; 111 return id->token;
111 } 112 }
112 alloc_string(yytext, yyleng); 113 alloc_string(yytext, yyleng);
113 yylval.string = text; 114 yylval.string = text;
114 return T_WORD; 115 return T_VARIABLE;
116 }
117 ({n}|$)+ {
118 /* this token includes at least one '$' */
119 yylval.string = expand_token(yytext, yyleng);
120 if (strlen(yylval.string))
121 return T_VARIABLE;
122 free(yylval.string);
115 } 123 }
124 "=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; }
125 ":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; }
126 "+=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; }
127 [[:blank:]]+
116 . warn_ignored_character(*yytext); 128 . warn_ignored_character(*yytext);
117 \n { 129 \n {
118 BEGIN(INITIAL); 130 BEGIN(INITIAL);
119 current_file->lineno++;
120 return T_EOL; 131 return T_EOL;
121 } 132 }
122} 133}
123 134
135<ASSIGN_VAL>{
136 [^[:blank:]\n]+.* {
137 alloc_string(yytext, yyleng);
138 yylval.string = text;
139 return T_ASSIGN_VAL;
140 }
141 \n { BEGIN(INITIAL); return T_EOL; }
142 .
143}
144
124<PARAM>{ 145<PARAM>{
125 "&&" return T_AND; 146 "&&" return T_AND;
126 "||" return T_OR; 147 "||" return T_OR;
@@ -138,7 +159,7 @@ n [A-Za-z0-9_-]
138 new_string(); 159 new_string();
139 BEGIN(STRING); 160 BEGIN(STRING);
140 } 161 }
141 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; 162 \n BEGIN(INITIAL); return T_EOL;
142 ({n}|[/.])+ { 163 ({n}|[/.])+ {
143 const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); 164 const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
144 if (id && id->flags & TF_PARAM) { 165 if (id && id->flags & TF_PARAM) {
@@ -149,8 +170,15 @@ n [A-Za-z0-9_-]
149 yylval.string = text; 170 yylval.string = text;
150 return T_WORD; 171 return T_WORD;
151 } 172 }
173 ({n}|[/.$])+ {
174 /* this token includes at least one '$' */
175 yylval.string = expand_token(yytext, yyleng);
176 if (strlen(yylval.string))
177 return T_WORD;
178 free(yylval.string);
179 }
152 #.* /* comment */ 180 #.* /* comment */
153 \\\n current_file->lineno++; 181 \\\n ;
154 [[:blank:]]+ 182 [[:blank:]]+
155 . warn_ignored_character(*yytext); 183 . warn_ignored_character(*yytext);
156 <<EOF>> { 184 <<EOF>> {
@@ -159,12 +187,13 @@ n [A-Za-z0-9_-]
159} 187}
160 188
161<STRING>{ 189<STRING>{
162 [^'"\\\n]+/\n { 190 "$".* append_expanded_string(yytext);
191 [^$'"\\\n]+/\n {
163 append_string(yytext, yyleng); 192 append_string(yytext, yyleng);
164 yylval.string = text; 193 yylval.string = text;
165 return T_WORD_QUOTE; 194 return T_WORD_QUOTE;
166 } 195 }
167 [^'"\\\n]+ { 196 [^$'"\\\n]+ {
168 append_string(yytext, yyleng); 197 append_string(yytext, yyleng);
169 } 198 }
170 \\.?/\n { 199 \\.?/\n {
@@ -187,7 +216,6 @@ n [A-Za-z0-9_-]
187 fprintf(stderr, 216 fprintf(stderr,
188 "%s:%d:warning: multi-line strings not supported\n", 217 "%s:%d:warning: multi-line strings not supported\n",
189 zconf_curname(), zconf_lineno()); 218 zconf_curname(), zconf_lineno());
190 current_file->lineno++;
191 BEGIN(INITIAL); 219 BEGIN(INITIAL);
192 return T_EOL; 220 return T_EOL;
193 } 221 }
@@ -220,12 +248,10 @@ n [A-Za-z0-9_-]
220 } 248 }
221 } 249 }
222 [ \t]*\n/[^ \t\n] { 250 [ \t]*\n/[^ \t\n] {
223 current_file->lineno++;
224 zconf_endhelp(); 251 zconf_endhelp();
225 return T_HELPTEXT; 252 return T_HELPTEXT;
226 } 253 }
227 [ \t]*\n { 254 [ \t]*\n {
228 current_file->lineno++;
229 append_string("\n", 1); 255 append_string("\n", 1);
230 } 256 }
231 [^ \t\n].* { 257 [^ \t\n].* {
@@ -254,6 +280,58 @@ n [A-Za-z0-9_-]
254} 280}
255 281
256%% 282%%
283static char *expand_token(const char *in, size_t n)
284{
285 char *out;
286 int c;
287 char c2;
288 const char *rest, *end;
289
290 new_string();
291 append_string(in, n);
292
293 /* get the whole line because we do not know the end of token. */
294 while ((c = input()) != EOF) {
295 if (c == '\n') {
296 unput(c);
297 break;
298 }
299 c2 = c;
300 append_string(&c2, 1);
301 }
302
303 rest = text;
304 out = expand_one_token(&rest);
305
306 /* push back unused characters to the input stream */
307 end = rest + strlen(rest);
308 while (end > rest)
309 unput(*--end);
310
311 free(text);
312
313 return out;
314}
315
316static void append_expanded_string(const char *str)
317{
318 const char *end;
319 char *res;
320
321 str++;
322
323 res = expand_dollar(&str);
324
325 /* push back unused characters to the input stream */
326 end = str + strlen(str);
327 while (end > str)
328 unput(*--end);
329
330 append_string(res, strlen(res));
331
332 free(res);
333}
334
257void zconf_starthelp(void) 335void zconf_starthelp(void)
258{ 336{
259 new_string(); 337 new_string();
@@ -304,7 +382,7 @@ void zconf_initscan(const char *name)
304 memset(current_buf, 0, sizeof(*current_buf)); 382 memset(current_buf, 0, sizeof(*current_buf));
305 383
306 current_file = file_lookup(name); 384 current_file = file_lookup(name);
307 current_file->lineno = 1; 385 yylineno = 1;
308} 386}
309 387
310void zconf_nextfile(const char *name) 388void zconf_nextfile(const char *name)
@@ -325,24 +403,26 @@ void zconf_nextfile(const char *name)
325 buf->parent = current_buf; 403 buf->parent = current_buf;
326 current_buf = buf; 404 current_buf = buf;
327 405
328 for (iter = current_file->parent; iter; iter = iter->parent ) { 406 current_file->lineno = yylineno;
329 if (!strcmp(current_file->name,iter->name) ) { 407 file->parent = current_file;
408
409 for (iter = current_file; iter; iter = iter->parent) {
410 if (!strcmp(iter->name, file->name)) {
330 fprintf(stderr, 411 fprintf(stderr,
331 "%s:%d: recursive inclusion detected. " 412 "Recursive inclusion detected.\n"
332 "Inclusion path:\n current file : '%s'\n", 413 "Inclusion path:\n"
333 zconf_curname(), zconf_lineno(), 414 " current file : %s\n", file->name);
334 zconf_curname()); 415 iter = file;
335 iter = current_file;
336 do { 416 do {
337 iter = iter->parent; 417 iter = iter->parent;
338 fprintf(stderr, " included from: '%s:%d'\n", 418 fprintf(stderr, " included from: %s:%d\n",
339 iter->name, iter->lineno - 1); 419 iter->name, iter->lineno - 1);
340 } while (strcmp(iter->name, current_file->name)); 420 } while (strcmp(iter->name, file->name));
341 exit(1); 421 exit(1);
342 } 422 }
343 } 423 }
344 file->lineno = 1; 424
345 file->parent = current_file; 425 yylineno = 1;
346 current_file = file; 426 current_file = file;
347} 427}
348 428
@@ -351,6 +431,8 @@ static void zconf_endfile(void)
351 struct buffer *parent; 431 struct buffer *parent;
352 432
353 current_file = current_file->parent; 433 current_file = current_file->parent;
434 if (current_file)
435 yylineno = current_file->lineno;
354 436
355 parent = current_buf->parent; 437 parent = current_buf->parent;
356 if (parent) { 438 if (parent) {
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index ad6305b0f40c..22fceb264cf5 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
31static struct menu *current_menu, *current_entry; 31static struct menu *current_menu, *current_entry;
32 32
33%} 33%}
34%expect 32 34%expect 30
35 35
36%union 36%union
37{ 37{
@@ -41,6 +41,7 @@ static struct menu *current_menu, *current_entry;
41 struct expr *expr; 41 struct expr *expr;
42 struct menu *menu; 42 struct menu *menu;
43 const struct kconf_id *id; 43 const struct kconf_id *id;
44 enum variable_flavor flavor;
44} 45}
45 46
46%token <id>T_MAINMENU 47%token <id>T_MAINMENU
@@ -77,6 +78,9 @@ static struct menu *current_menu, *current_entry;
77%token T_CLOSE_PAREN 78%token T_CLOSE_PAREN
78%token T_OPEN_PAREN 79%token T_OPEN_PAREN
79%token T_EOL 80%token T_EOL
81%token <string> T_VARIABLE
82%token <flavor> T_ASSIGN
83%token <string> T_ASSIGN_VAL
80 84
81%left T_OR 85%left T_OR
82%left T_AND 86%left T_AND
@@ -92,7 +96,7 @@ static struct menu *current_menu, *current_entry;
92%type <id> end 96%type <id> end
93%type <id> option_name 97%type <id> option_name
94%type <menu> if_entry menu_entry choice_entry 98%type <menu> if_entry menu_entry choice_entry
95%type <string> symbol_option_arg word_opt 99%type <string> symbol_option_arg word_opt assign_val
96 100
97%destructor { 101%destructor {
98 fprintf(stderr, "%s:%d: missing end statement for this entry\n", 102 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -109,28 +113,15 @@ static struct menu *current_menu, *current_entry;
109%% 113%%
110input: nl start | start; 114input: nl start | start;
111 115
112start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list; 116start: mainmenu_stmt stmt_list | stmt_list;
113 117
114/* mainmenu entry */ 118/* mainmenu entry */
115 119
116mainmenu_stmt: T_MAINMENU prompt nl 120mainmenu_stmt: T_MAINMENU prompt T_EOL
117{ 121{
118 menu_add_prompt(P_MENU, $2, NULL); 122 menu_add_prompt(P_MENU, $2, NULL);
119}; 123};
120 124
121/* Default main menu, if there's no mainmenu entry */
122
123no_mainmenu_stmt: /* empty */
124{
125 /*
126 * Hack: Keep the main menu title on the heap so we can safely free it
127 * later regardless of whether it comes from the 'prompt' in
128 * mainmenu_stmt or here
129 */
130 menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
131};
132
133
134stmt_list: 125stmt_list:
135 /* empty */ 126 /* empty */
136 | stmt_list common_stmt 127 | stmt_list common_stmt
@@ -156,6 +147,7 @@ common_stmt:
156 | config_stmt 147 | config_stmt
157 | menuconfig_stmt 148 | menuconfig_stmt
158 | source_stmt 149 | source_stmt
150 | assignment_stmt
159; 151;
160 152
161option_error: 153option_error:
@@ -273,7 +265,7 @@ symbol_option_arg:
273choice: T_CHOICE word_opt T_EOL 265choice: T_CHOICE word_opt T_EOL
274{ 266{
275 struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); 267 struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
276 sym->flags |= SYMBOL_AUTO; 268 sym->flags |= SYMBOL_NO_WRITE;
277 menu_add_entry(sym); 269 menu_add_entry(sym);
278 menu_add_expr(P_CHOICE, NULL, NULL); 270 menu_add_expr(P_CHOICE, NULL, NULL);
279 free($2); 271 free($2);
@@ -345,7 +337,7 @@ choice_block:
345 337
346/* if entry */ 338/* if entry */
347 339
348if_entry: T_IF expr nl 340if_entry: T_IF expr T_EOL
349{ 341{
350 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 342 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
351 menu_add_entry(NULL); 343 menu_add_entry(NULL);
@@ -524,31 +516,42 @@ symbol: nonconst_symbol
524word_opt: /* empty */ { $$ = NULL; } 516word_opt: /* empty */ { $$ = NULL; }
525 | T_WORD 517 | T_WORD
526 518
519/* assignment statement */
520
521assignment_stmt: T_VARIABLE T_ASSIGN assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); }
522
523assign_val:
524 /* empty */ { $$ = xstrdup(""); };
525 | T_ASSIGN_VAL
526;
527
527%% 528%%
528 529
529void conf_parse(const char *name) 530void conf_parse(const char *name)
530{ 531{
531 const char *tmp;
532 struct symbol *sym; 532 struct symbol *sym;
533 int i; 533 int i;
534 534
535 zconf_initscan(name); 535 zconf_initscan(name);
536 536
537 sym_init();
538 _menu_init(); 537 _menu_init();
539 538
540 if (getenv("ZCONF_DEBUG")) 539 if (getenv("ZCONF_DEBUG"))
541 yydebug = 1; 540 yydebug = 1;
542 yyparse(); 541 yyparse();
542
543 /* Variables are expanded in the parse phase. We can free them here. */
544 variable_all_del();
545
543 if (yynerrs) 546 if (yynerrs)
544 exit(1); 547 exit(1);
545 if (!modules_sym) 548 if (!modules_sym)
546 modules_sym = sym_find( "n" ); 549 modules_sym = sym_find( "n" );
547 550
548 tmp = rootmenu.prompt->text; 551 if (!menu_has_prompt(&rootmenu)) {
549 rootmenu.prompt->text = _(rootmenu.prompt->text); 552 current_entry = &rootmenu;
550 rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); 553 menu_add_prompt(P_MENU, "Main menu", NULL);
551 free((char*)tmp); 554 }
552 555
553 menu_finalize(&rootmenu); 556 menu_finalize(&rootmenu);
554 for_all_symbols(i, sym) { 557 for_all_symbols(i, sym) {
@@ -714,6 +717,10 @@ static void print_symbol(FILE *out, struct menu *menu)
714 print_quoted_string(out, prop->text); 717 print_quoted_string(out, prop->text);
715 fputc('\n', out); 718 fputc('\n', out);
716 break; 719 break;
720 case P_SYMBOL:
721 fputs( " symbol ", out);
722 fprintf(out, "%s\n", prop->sym->name);
723 break;
717 default: 724 default:
718 fprintf(out, " unknown prop %d!\n", prop->type); 725 fprintf(out, " unknown prop %d!\n", prop->type);
719 break; 726 break;
@@ -780,3 +787,4 @@ void zconfdump(FILE *out)
780#include "expr.c" 787#include "expr.c"
781#include "symbol.c" 788#include "symbol.c"
782#include "menu.c" 789#include "menu.c"
790#include "preprocess.c"
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index fee8952037b1..ffbe901a37b5 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1,4 +1,5 @@
1#!/usr/bin/env perl 1#!/usr/bin/env perl
2# SPDX-License-Identifier: GPL-2.0
2 3
3use warnings; 4use warnings;
4use strict; 5use strict;
@@ -328,13 +329,15 @@ my $lineprefix="";
328use constant { 329use constant {
329 STATE_NORMAL => 0, # normal code 330 STATE_NORMAL => 0, # normal code
330 STATE_NAME => 1, # looking for function name 331 STATE_NAME => 1, # looking for function name
331 STATE_FIELD => 2, # scanning field start 332 STATE_BODY_MAYBE => 2, # body - or maybe more description
332 STATE_PROTO => 3, # scanning prototype 333 STATE_BODY => 3, # the body of the comment
333 STATE_DOCBLOCK => 4, # documentation block 334 STATE_PROTO => 4, # scanning prototype
334 STATE_INLINE => 5, # gathering documentation outside main block 335 STATE_DOCBLOCK => 5, # documentation block
336 STATE_INLINE => 6, # gathering documentation outside main block
335}; 337};
336my $state; 338my $state;
337my $in_doc_sect; 339my $in_doc_sect;
340my $leading_space;
338 341
339# Inline documentation state 342# Inline documentation state
340use constant { 343use constant {
@@ -363,7 +366,7 @@ my $doc_sect = $doc_com .
363my $doc_content = $doc_com_body . '(.*)'; 366my $doc_content = $doc_com_body . '(.*)';
364my $doc_block = $doc_com . 'DOC:\s*(.*)?'; 367my $doc_block = $doc_com . 'DOC:\s*(.*)?';
365my $doc_inline_start = '^\s*/\*\*\s*$'; 368my $doc_inline_start = '^\s*/\*\*\s*$';
366my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; 369my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)';
367my $doc_inline_end = '^\s*\*/\s*$'; 370my $doc_inline_end = '^\s*\*/\s*$';
368my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; 371my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$';
369my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; 372my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;';
@@ -553,10 +556,9 @@ sub output_highlight {
553 } 556 }
554 if ($line eq ""){ 557 if ($line eq ""){
555 if (! $output_preformatted) { 558 if (! $output_preformatted) {
556 print $lineprefix, local_unescape($blankline); 559 print $lineprefix, $blankline;
557 } 560 }
558 } else { 561 } else {
559 $line =~ s/\\\\\\/\&/g;
560 if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { 562 if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
561 print "\\&$line"; 563 print "\\&$line";
562 } else { 564 } else {
@@ -747,17 +749,73 @@ sub output_blockhead_rst(%) {
747 } 749 }
748} 750}
749 751
750sub output_highlight_rst { 752#
751 my $contents = join "\n",@_; 753# Apply the RST highlights to a sub-block of text.
752 my $line; 754#
753 755sub highlight_block($) {
754 # undo the evil effects of xml_escape() earlier 756 # The dohighlight kludge requires the text be called $contents
755 $contents = xml_unescape($contents); 757 my $contents = shift;
756
757 eval $dohighlight; 758 eval $dohighlight;
758 die $@ if $@; 759 die $@ if $@;
760 return $contents;
761}
759 762
760 foreach $line (split "\n", $contents) { 763#
764# Regexes used only here.
765#
766my $sphinx_literal = '^[^.].*::$';
767my $sphinx_cblock = '^\.\.\ +code-block::';
768
769sub output_highlight_rst {
770 my $input = join "\n",@_;
771 my $output = "";
772 my $line;
773 my $in_literal = 0;
774 my $litprefix;
775 my $block = "";
776
777 foreach $line (split "\n",$input) {
778 #
779 # If we're in a literal block, see if we should drop out
780 # of it. Otherwise pass the line straight through unmunged.
781 #
782 if ($in_literal) {
783 if (! ($line =~ /^\s*$/)) {
784 #
785 # If this is the first non-blank line in a literal
786 # block we need to figure out what the proper indent is.
787 #
788 if ($litprefix eq "") {
789 $line =~ /^(\s*)/;
790 $litprefix = '^' . $1;
791 $output .= $line . "\n";
792 } elsif (! ($line =~ /$litprefix/)) {
793 $in_literal = 0;
794 } else {
795 $output .= $line . "\n";
796 }
797 } else {
798 $output .= $line . "\n";
799 }
800 }
801 #
802 # Not in a literal block (or just dropped out)
803 #
804 if (! $in_literal) {
805 $block .= $line . "\n";
806 if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) {
807 $in_literal = 1;
808 $litprefix = "";
809 $output .= highlight_block($block);
810 $block = ""
811 }
812 }
813 }
814
815 if ($block) {
816 $output .= highlight_block($block);
817 }
818 foreach $line (split "\n", $output) {
761 print $lineprefix . $line . "\n"; 819 print $lineprefix . $line . "\n";
762 } 820 }
763} 821}
@@ -1004,7 +1062,7 @@ sub dump_struct($$) {
1004 my $x = shift; 1062 my $x = shift;
1005 my $file = shift; 1063 my $file = shift;
1006 1064
1007 if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) { 1065 if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}/) {
1008 my $decl_type = $1; 1066 my $decl_type = $1;
1009 $declaration_name = $2; 1067 $declaration_name = $2;
1010 my $members = $3; 1068 my $members = $3;
@@ -1062,7 +1120,7 @@ sub dump_struct($$) {
1062 # Handle bitmaps 1120 # Handle bitmaps
1063 $arg =~ s/:\s*\d+\s*//g; 1121 $arg =~ s/:\s*\d+\s*//g;
1064 # Handle arrays 1122 # Handle arrays
1065 $arg =~ s/\[\S+\]//g; 1123 $arg =~ s/\[.*\]//g;
1066 # The type may have multiple words, 1124 # The type may have multiple words,
1067 # and multiple IDs can be defined, like: 1125 # and multiple IDs can be defined, like:
1068 # const struct foo, *bar, foobar 1126 # const struct foo, *bar, foobar
@@ -1090,20 +1148,20 @@ sub dump_struct($$) {
1090 } 1148 }
1091 } 1149 }
1092 } 1150 }
1093 $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)}([^\{\}\;]*)\;/$newmember/; 1151 $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/$newmember/;
1094 } 1152 }
1095 1153
1096 # Ignore other nested elements, like enums 1154 # Ignore other nested elements, like enums
1097 $members =~ s/({[^\{\}]*})//g; 1155 $members =~ s/(\{[^\{\}]*\})//g;
1098 1156
1099 create_parameterlist($members, ';', $file, $declaration_name); 1157 create_parameterlist($members, ';', $file, $declaration_name);
1100 check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); 1158 check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual);
1101 1159
1102 # Adjust declaration for better display 1160 # Adjust declaration for better display
1103 $declaration =~ s/([{;])/$1\n/g; 1161 $declaration =~ s/([\{;])/$1\n/g;
1104 $declaration =~ s/}\s+;/};/g; 1162 $declaration =~ s/\}\s+;/};/g;
1105 # Better handle inlined enums 1163 # Better handle inlined enums
1106 do {} while ($declaration =~ s/(enum\s+{[^}]+),([^\n])/$1,\n$2/); 1164 do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/);
1107 1165
1108 my @def_args = split /\n/, $declaration; 1166 my @def_args = split /\n/, $declaration;
1109 my $level = 1; 1167 my $level = 1;
@@ -1113,12 +1171,12 @@ sub dump_struct($$) {
1113 $clause =~ s/\s+$//; 1171 $clause =~ s/\s+$//;
1114 $clause =~ s/\s+/ /; 1172 $clause =~ s/\s+/ /;
1115 next if (!$clause); 1173 next if (!$clause);
1116 $level-- if ($clause =~ m/(})/ && $level > 1); 1174 $level-- if ($clause =~ m/(\})/ && $level > 1);
1117 if (!($clause =~ m/^\s*#/)) { 1175 if (!($clause =~ m/^\s*#/)) {
1118 $declaration .= "\t" x $level; 1176 $declaration .= "\t" x $level;
1119 } 1177 }
1120 $declaration .= "\t" . $clause . "\n"; 1178 $declaration .= "\t" . $clause . "\n";
1121 $level++ if ($clause =~ m/({)/ && !($clause =~m/}/)); 1179 $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/));
1122 } 1180 }
1123 output_declaration($declaration_name, 1181 output_declaration($declaration_name,
1124 'struct', 1182 'struct',
@@ -1186,7 +1244,7 @@ sub dump_enum($$) {
1186 # strip #define macros inside enums 1244 # strip #define macros inside enums
1187 $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; 1245 $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos;
1188 1246
1189 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { 1247 if ($x =~ /enum\s+(\w+)\s*\{(.*)\}/) {
1190 $declaration_name = $1; 1248 $declaration_name = $1;
1191 my $members = $2; 1249 my $members = $2;
1192 my %_members; 1250 my %_members;
@@ -1422,8 +1480,6 @@ sub push_parameter($$$$) {
1422 } 1480 }
1423 } 1481 }
1424 1482
1425 $param = xml_escape($param);
1426
1427 # strip spaces from $param so that it is one continuous string 1483 # strip spaces from $param so that it is one continuous string
1428 # on @parameterlist; 1484 # on @parameterlist;
1429 # this fixes a problem where check_sections() cannot find 1485 # this fixes a problem where check_sections() cannot find
@@ -1522,6 +1578,7 @@ sub dump_function($$) {
1522 $prototype =~ s/__meminit +//; 1578 $prototype =~ s/__meminit +//;
1523 $prototype =~ s/__must_check +//; 1579 $prototype =~ s/__must_check +//;
1524 $prototype =~ s/__weak +//; 1580 $prototype =~ s/__weak +//;
1581 $prototype =~ s/__sched +//;
1525 my $define = $prototype =~ s/^#\s*define\s+//; #ak added 1582 my $define = $prototype =~ s/^#\s*define\s+//; #ak added
1526 $prototype =~ s/__attribute__\s*\(\( 1583 $prototype =~ s/__attribute__\s*\(\(
1527 (?: 1584 (?:
@@ -1728,7 +1785,7 @@ sub process_proto_type($$) {
1728 } 1785 }
1729 1786
1730 while (1) { 1787 while (1) {
1731 if ( $x =~ /([^{};]*)([{};])(.*)/ ) { 1788 if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) {
1732 if( length $prototype ) { 1789 if( length $prototype ) {
1733 $prototype .= " " 1790 $prototype .= " "
1734 } 1791 }
@@ -1748,47 +1805,6 @@ sub process_proto_type($$) {
1748 } 1805 }
1749} 1806}
1750 1807
1751# xml_escape: replace <, >, and & in the text stream;
1752#
1753# however, formatting controls that are generated internally/locally in the
1754# kernel-doc script are not escaped here; instead, they begin life like
1755# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings
1756# are converted to their mnemonic-expected output, without the 4 * '\' & ':',
1757# just before actual output; (this is done by local_unescape())
1758sub xml_escape($) {
1759 my $text = shift;
1760 if ($output_mode eq "man") {
1761 return $text;
1762 }
1763 $text =~ s/\&/\\\\\\amp;/g;
1764 $text =~ s/\</\\\\\\lt;/g;
1765 $text =~ s/\>/\\\\\\gt;/g;
1766 return $text;
1767}
1768
1769# xml_unescape: reverse the effects of xml_escape
1770sub xml_unescape($) {
1771 my $text = shift;
1772 if ($output_mode eq "man") {
1773 return $text;
1774 }
1775 $text =~ s/\\\\\\amp;/\&/g;
1776 $text =~ s/\\\\\\lt;/</g;
1777 $text =~ s/\\\\\\gt;/>/g;
1778 return $text;
1779}
1780
1781# convert local escape strings to html
1782# local escape strings look like: '\\\\menmonic:' (that's 4 backslashes)
1783sub local_unescape($) {
1784 my $text = shift;
1785 if ($output_mode eq "man") {
1786 return $text;
1787 }
1788 $text =~ s/\\\\\\\\lt:/</g;
1789 $text =~ s/\\\\\\\\gt:/>/g;
1790 return $text;
1791}
1792 1808
1793sub map_filename($) { 1809sub map_filename($) {
1794 my $file; 1810 my $file;
@@ -1826,15 +1842,291 @@ sub process_export_file($) {
1826 close(IN); 1842 close(IN);
1827} 1843}
1828 1844
1829sub process_file($) { 1845#
1830 my $file; 1846# Parsers for the various processing states.
1847#
1848# STATE_NORMAL: looking for the /** to begin everything.
1849#
1850sub process_normal() {
1851 if (/$doc_start/o) {
1852 $state = STATE_NAME; # next line is always the function name
1853 $in_doc_sect = 0;
1854 $declaration_start_line = $. + 1;
1855 }
1856}
1857
1858#
1859# STATE_NAME: Looking for the "name - description" line
1860#
1861sub process_name($$) {
1862 my $file = shift;
1831 my $identifier; 1863 my $identifier;
1832 my $func;
1833 my $descr; 1864 my $descr;
1834 my $in_purpose = 0; 1865
1866 if (/$doc_block/o) {
1867 $state = STATE_DOCBLOCK;
1868 $contents = "";
1869 $new_start_line = $. + 1;
1870
1871 if ( $1 eq "" ) {
1872 $section = $section_intro;
1873 } else {
1874 $section = $1;
1875 }
1876 }
1877 elsif (/$doc_decl/o) {
1878 $identifier = $1;
1879 if (/\s*([\w\s]+?)(\(\))?\s*-/) {
1880 $identifier = $1;
1881 }
1882
1883 $state = STATE_BODY;
1884 # if there's no @param blocks need to set up default section
1885 # here
1886 $contents = "";
1887 $section = $section_default;
1888 $new_start_line = $. + 1;
1889 if (/-(.*)/) {
1890 # strip leading/trailing/multiple spaces
1891 $descr= $1;
1892 $descr =~ s/^\s*//;
1893 $descr =~ s/\s*$//;
1894 $descr =~ s/\s+/ /g;
1895 $declaration_purpose = $descr;
1896 $state = STATE_BODY_MAYBE;
1897 } else {
1898 $declaration_purpose = "";
1899 }
1900
1901 if (($declaration_purpose eq "") && $verbose) {
1902 print STDERR "${file}:$.: warning: missing initial short description on line:\n";
1903 print STDERR $_;
1904 ++$warnings;
1905 }
1906
1907 if ($identifier =~ m/^struct\b/) {
1908 $decl_type = 'struct';
1909 } elsif ($identifier =~ m/^union\b/) {
1910 $decl_type = 'union';
1911 } elsif ($identifier =~ m/^enum\b/) {
1912 $decl_type = 'enum';
1913 } elsif ($identifier =~ m/^typedef\b/) {
1914 $decl_type = 'typedef';
1915 } else {
1916 $decl_type = 'function';
1917 }
1918
1919 if ($verbose) {
1920 print STDERR "${file}:$.: info: Scanning doc for $identifier\n";
1921 }
1922 } else {
1923 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
1924 " - I thought it was a doc line\n";
1925 ++$warnings;
1926 $state = STATE_NORMAL;
1927 }
1928}
1929
1930
1931#
1932# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment.
1933#
1934sub process_body($$) {
1935 my $file = shift;
1936
1937 if (/$doc_sect/i) { # case insensitive for supported section names
1938 $newsection = $1;
1939 $newcontents = $2;
1940
1941 # map the supported section names to the canonical names
1942 if ($newsection =~ m/^description$/i) {
1943 $newsection = $section_default;
1944 } elsif ($newsection =~ m/^context$/i) {
1945 $newsection = $section_context;
1946 } elsif ($newsection =~ m/^returns?$/i) {
1947 $newsection = $section_return;
1948 } elsif ($newsection =~ m/^\@return$/) {
1949 # special: @return is a section, not a param description
1950 $newsection = $section_return;
1951 }
1952
1953 if (($contents ne "") && ($contents ne "\n")) {
1954 if (!$in_doc_sect && $verbose) {
1955 print STDERR "${file}:$.: warning: contents before sections\n";
1956 ++$warnings;
1957 }
1958 dump_section($file, $section, $contents);
1959 $section = $section_default;
1960 }
1961
1962 $in_doc_sect = 1;
1963 $state = STATE_BODY;
1964 $contents = $newcontents;
1965 $new_start_line = $.;
1966 while (substr($contents, 0, 1) eq " ") {
1967 $contents = substr($contents, 1);
1968 }
1969 if ($contents ne "") {
1970 $contents .= "\n";
1971 }
1972 $section = $newsection;
1973 $leading_space = undef;
1974 } elsif (/$doc_end/) {
1975 if (($contents ne "") && ($contents ne "\n")) {
1976 dump_section($file, $section, $contents);
1977 $section = $section_default;
1978 $contents = "";
1979 }
1980 # look for doc_com + <text> + doc_end:
1981 if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
1982 print STDERR "${file}:$.: warning: suspicious ending line: $_";
1983 ++$warnings;
1984 }
1985
1986 $prototype = "";
1987 $state = STATE_PROTO;
1988 $brcount = 0;
1989 } elsif (/$doc_content/) {
1990 # miguel-style comment kludge, look for blank lines after
1991 # @parameter line to signify start of description
1992 if ($1 eq "") {
1993 if ($section =~ m/^@/ || $section eq $section_context) {
1994 dump_section($file, $section, $contents);
1995 $section = $section_default;
1996 $contents = "";
1997 $new_start_line = $.;
1998 } else {
1999 $contents .= "\n";
2000 }
2001 $state = STATE_BODY;
2002 } elsif ($state == STATE_BODY_MAYBE) {
2003 # Continued declaration purpose
2004 chomp($declaration_purpose);
2005 $declaration_purpose .= " " . $1;
2006 $declaration_purpose =~ s/\s+/ /g;
2007 } else {
2008 my $cont = $1;
2009 if ($section =~ m/^@/ || $section eq $section_context) {
2010 if (!defined $leading_space) {
2011 if ($cont =~ m/^(\s+)/) {
2012 $leading_space = $1;
2013 } else {
2014 $leading_space = "";
2015 }
2016 }
2017 $cont =~ s/^$leading_space//;
2018 }
2019 $contents .= $cont . "\n";
2020 }
2021 } else {
2022 # i dont know - bad line? ignore.
2023 print STDERR "${file}:$.: warning: bad line: $_";
2024 ++$warnings;
2025 }
2026}
2027
2028
2029#
2030# STATE_PROTO: reading a function/whatever prototype.
2031#
2032sub process_proto($$) {
2033 my $file = shift;
2034
2035 if (/$doc_inline_oneline/) {
2036 $section = $1;
2037 $contents = $2;
2038 if ($contents ne "") {
2039 $contents .= "\n";
2040 dump_section($file, $section, $contents);
2041 $section = $section_default;
2042 $contents = "";
2043 }
2044 } elsif (/$doc_inline_start/) {
2045 $state = STATE_INLINE;
2046 $inline_doc_state = STATE_INLINE_NAME;
2047 } elsif ($decl_type eq 'function') {
2048 process_proto_function($_, $file);
2049 } else {
2050 process_proto_type($_, $file);
2051 }
2052}
2053
2054#
2055# STATE_DOCBLOCK: within a DOC: block.
2056#
2057sub process_docblock($$) {
2058 my $file = shift;
2059
2060 if (/$doc_end/) {
2061 dump_doc_section($file, $section, $contents);
2062 $section = $section_default;
2063 $contents = "";
2064 $function = "";
2065 %parameterdescs = ();
2066 %parametertypes = ();
2067 @parameterlist = ();
2068 %sections = ();
2069 @sectionlist = ();
2070 $prototype = "";
2071 $state = STATE_NORMAL;
2072 } elsif (/$doc_content/) {
2073 if ( $1 eq "" ) {
2074 $contents .= $blankline;
2075 } else {
2076 $contents .= $1 . "\n";
2077 }
2078 }
2079}
2080
2081#
2082# STATE_INLINE: docbook comments within a prototype.
2083#
2084sub process_inline($$) {
2085 my $file = shift;
2086
2087 # First line (state 1) needs to be a @parameter
2088 if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) {
2089 $section = $1;
2090 $contents = $2;
2091 $new_start_line = $.;
2092 if ($contents ne "") {
2093 while (substr($contents, 0, 1) eq " ") {
2094 $contents = substr($contents, 1);
2095 }
2096 $contents .= "\n";
2097 }
2098 $inline_doc_state = STATE_INLINE_TEXT;
2099 # Documentation block end */
2100 } elsif (/$doc_inline_end/) {
2101 if (($contents ne "") && ($contents ne "\n")) {
2102 dump_section($file, $section, $contents);
2103 $section = $section_default;
2104 $contents = "";
2105 }
2106 $state = STATE_PROTO;
2107 $inline_doc_state = STATE_INLINE_NA;
2108 # Regular text
2109 } elsif (/$doc_content/) {
2110 if ($inline_doc_state == STATE_INLINE_TEXT) {
2111 $contents .= $1 . "\n";
2112 # nuke leading blank lines
2113 if ($contents =~ /^\s*$/) {
2114 $contents = "";
2115 }
2116 } elsif ($inline_doc_state == STATE_INLINE_NAME) {
2117 $inline_doc_state = STATE_INLINE_ERROR;
2118 print STDERR "${file}:$.: warning: ";
2119 print STDERR "Incorrect use of kernel-doc format: $_";
2120 ++$warnings;
2121 }
2122 }
2123}
2124
2125
2126sub process_file($) {
2127 my $file;
1835 my $initial_section_counter = $section_counter; 2128 my $initial_section_counter = $section_counter;
1836 my ($orig_file) = @_; 2129 my ($orig_file) = @_;
1837 my $leading_space;
1838 2130
1839 $file = map_filename($orig_file); 2131 $file = map_filename($orig_file);
1840 2132
@@ -1853,250 +2145,23 @@ sub process_file($) {
1853 } 2145 }
1854 # Replace tabs by spaces 2146 # Replace tabs by spaces
1855 while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; 2147 while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {};
2148 # Hand this line to the appropriate state handler
1856 if ($state == STATE_NORMAL) { 2149 if ($state == STATE_NORMAL) {
1857 if (/$doc_start/o) { 2150 process_normal();
1858 $state = STATE_NAME; # next line is always the function name 2151 } elsif ($state == STATE_NAME) {
1859 $in_doc_sect = 0; 2152 process_name($file, $_);
1860 $declaration_start_line = $. + 1; 2153 } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) {
1861 } 2154 process_body($file, $_);
1862 } elsif ($state == STATE_NAME) {# this line is the function name (always)
1863 if (/$doc_block/o) {
1864 $state = STATE_DOCBLOCK;
1865 $contents = "";
1866 $new_start_line = $. + 1;
1867
1868 if ( $1 eq "" ) {
1869 $section = $section_intro;
1870 } else {
1871 $section = $1;
1872 }
1873 }
1874 elsif (/$doc_decl/o) {
1875 $identifier = $1;
1876 if (/\s*([\w\s]+?)\s*-/) {
1877 $identifier = $1;
1878 }
1879
1880 $state = STATE_FIELD;
1881 # if there's no @param blocks need to set up default section
1882 # here
1883 $contents = "";
1884 $section = $section_default;
1885 $new_start_line = $. + 1;
1886 if (/-(.*)/) {
1887 # strip leading/trailing/multiple spaces
1888 $descr= $1;
1889 $descr =~ s/^\s*//;
1890 $descr =~ s/\s*$//;
1891 $descr =~ s/\s+/ /g;
1892 $declaration_purpose = xml_escape($descr);
1893 $in_purpose = 1;
1894 } else {
1895 $declaration_purpose = "";
1896 }
1897
1898 if (($declaration_purpose eq "") && $verbose) {
1899 print STDERR "${file}:$.: warning: missing initial short description on line:\n";
1900 print STDERR $_;
1901 ++$warnings;
1902 }
1903
1904 if ($identifier =~ m/^struct/) {
1905 $decl_type = 'struct';
1906 } elsif ($identifier =~ m/^union/) {
1907 $decl_type = 'union';
1908 } elsif ($identifier =~ m/^enum/) {
1909 $decl_type = 'enum';
1910 } elsif ($identifier =~ m/^typedef/) {
1911 $decl_type = 'typedef';
1912 } else {
1913 $decl_type = 'function';
1914 }
1915
1916 if ($verbose) {
1917 print STDERR "${file}:$.: info: Scanning doc for $identifier\n";
1918 }
1919 } else {
1920 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
1921 " - I thought it was a doc line\n";
1922 ++$warnings;
1923 $state = STATE_NORMAL;
1924 }
1925 } elsif ($state == STATE_FIELD) { # look for head: lines, and include content
1926 if (/$doc_sect/i) { # case insensitive for supported section names
1927 $newsection = $1;
1928 $newcontents = $2;
1929
1930 # map the supported section names to the canonical names
1931 if ($newsection =~ m/^description$/i) {
1932 $newsection = $section_default;
1933 } elsif ($newsection =~ m/^context$/i) {
1934 $newsection = $section_context;
1935 } elsif ($newsection =~ m/^returns?$/i) {
1936 $newsection = $section_return;
1937 } elsif ($newsection =~ m/^\@return$/) {
1938 # special: @return is a section, not a param description
1939 $newsection = $section_return;
1940 }
1941
1942 if (($contents ne "") && ($contents ne "\n")) {
1943 if (!$in_doc_sect && $verbose) {
1944 print STDERR "${file}:$.: warning: contents before sections\n";
1945 ++$warnings;
1946 }
1947 dump_section($file, $section, xml_escape($contents));
1948 $section = $section_default;
1949 }
1950
1951 $in_doc_sect = 1;
1952 $in_purpose = 0;
1953 $contents = $newcontents;
1954 $new_start_line = $.;
1955 while (substr($contents, 0, 1) eq " ") {
1956 $contents = substr($contents, 1);
1957 }
1958 if ($contents ne "") {
1959 $contents .= "\n";
1960 }
1961 $section = $newsection;
1962 $leading_space = undef;
1963 } elsif (/$doc_end/) {
1964 if (($contents ne "") && ($contents ne "\n")) {
1965 dump_section($file, $section, xml_escape($contents));
1966 $section = $section_default;
1967 $contents = "";
1968 }
1969 # look for doc_com + <text> + doc_end:
1970 if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
1971 print STDERR "${file}:$.: warning: suspicious ending line: $_";
1972 ++$warnings;
1973 }
1974
1975 $prototype = "";
1976 $state = STATE_PROTO;
1977 $brcount = 0;
1978# print STDERR "end of doc comment, looking for prototype\n";
1979 } elsif (/$doc_content/) {
1980 # miguel-style comment kludge, look for blank lines after
1981 # @parameter line to signify start of description
1982 if ($1 eq "") {
1983 if ($section =~ m/^@/ || $section eq $section_context) {
1984 dump_section($file, $section, xml_escape($contents));
1985 $section = $section_default;
1986 $contents = "";
1987 $new_start_line = $.;
1988 } else {
1989 $contents .= "\n";
1990 }
1991 $in_purpose = 0;
1992 } elsif ($in_purpose == 1) {
1993 # Continued declaration purpose
1994 chomp($declaration_purpose);
1995 $declaration_purpose .= " " . xml_escape($1);
1996 $declaration_purpose =~ s/\s+/ /g;
1997 } else {
1998 my $cont = $1;
1999 if ($section =~ m/^@/ || $section eq $section_context) {
2000 if (!defined $leading_space) {
2001 if ($cont =~ m/^(\s+)/) {
2002 $leading_space = $1;
2003 } else {
2004 $leading_space = "";
2005 }
2006 }
2007
2008 $cont =~ s/^$leading_space//;
2009 }
2010 $contents .= $cont . "\n";
2011 }
2012 } else {
2013 # i dont know - bad line? ignore.
2014 print STDERR "${file}:$.: warning: bad line: $_";
2015 ++$warnings;
2016 }
2017 } elsif ($state == STATE_INLINE) { # scanning for inline parameters 2155 } elsif ($state == STATE_INLINE) { # scanning for inline parameters
2018 # First line (state 1) needs to be a @parameter 2156 process_inline($file, $_);
2019 if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { 2157 } elsif ($state == STATE_PROTO) {
2020 $section = $1; 2158 process_proto($file, $_);
2021 $contents = $2;
2022 $new_start_line = $.;
2023 if ($contents ne "") {
2024 while (substr($contents, 0, 1) eq " ") {
2025 $contents = substr($contents, 1);
2026 }
2027 $contents .= "\n";
2028 }
2029 $inline_doc_state = STATE_INLINE_TEXT;
2030 # Documentation block end */
2031 } elsif (/$doc_inline_end/) {
2032 if (($contents ne "") && ($contents ne "\n")) {
2033 dump_section($file, $section, xml_escape($contents));
2034 $section = $section_default;
2035 $contents = "";
2036 }
2037 $state = STATE_PROTO;
2038 $inline_doc_state = STATE_INLINE_NA;
2039 # Regular text
2040 } elsif (/$doc_content/) {
2041 if ($inline_doc_state == STATE_INLINE_TEXT) {
2042 $contents .= $1 . "\n";
2043 # nuke leading blank lines
2044 if ($contents =~ /^\s*$/) {
2045 $contents = "";
2046 }
2047 } elsif ($inline_doc_state == STATE_INLINE_NAME) {
2048 $inline_doc_state = STATE_INLINE_ERROR;
2049 print STDERR "${file}:$.: warning: ";
2050 print STDERR "Incorrect use of kernel-doc format: $_";
2051 ++$warnings;
2052 }
2053 }
2054 } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype)
2055 if (/$doc_inline_oneline/) {
2056 $section = $1;
2057 $contents = $2;
2058 if ($contents ne "") {
2059 $contents .= "\n";
2060 dump_section($file, $section, xml_escape($contents));
2061 $section = $section_default;
2062 $contents = "";
2063 }
2064 } elsif (/$doc_inline_start/) {
2065 $state = STATE_INLINE;
2066 $inline_doc_state = STATE_INLINE_NAME;
2067 } elsif ($decl_type eq 'function') {
2068 process_proto_function($_, $file);
2069 } else {
2070 process_proto_type($_, $file);
2071 }
2072 } elsif ($state == STATE_DOCBLOCK) { 2159 } elsif ($state == STATE_DOCBLOCK) {
2073 if (/$doc_end/) 2160 process_docblock($file, $_);
2074 {
2075 dump_doc_section($file, $section, xml_escape($contents));
2076 $section = $section_default;
2077 $contents = "";
2078 $function = "";
2079 %parameterdescs = ();
2080 %parametertypes = ();
2081 @parameterlist = ();
2082 %sections = ();
2083 @sectionlist = ();
2084 $prototype = "";
2085 $state = STATE_NORMAL;
2086 }
2087 elsif (/$doc_content/)
2088 {
2089 if ( $1 eq "" )
2090 {
2091 $contents .= $blankline;
2092 }
2093 else
2094 {
2095 $contents .= $1 . "\n";
2096 }
2097 }
2098 } 2161 }
2099 } 2162 }
2163
2164 # Make sure we got something interesting.
2100 if ($initial_section_counter == $section_counter) { 2165 if ($initial_section_counter == $section_counter) {
2101 if ($output_mode ne "none") { 2166 if ($output_mode ne "none") {
2102 print STDERR "${file}:1: warning: no structured comments found\n"; 2167 print STDERR "${file}:1: warning: no structured comments found\n";
diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl
index bc5788000018..6a897788f5a7 100755
--- a/scripts/leaking_addresses.pl
+++ b/scripts/leaking_addresses.pl
@@ -3,15 +3,20 @@
3# (c) 2017 Tobin C. Harding <me@tobin.cc> 3# (c) 2017 Tobin C. Harding <me@tobin.cc>
4# Licensed under the terms of the GNU GPL License version 2 4# Licensed under the terms of the GNU GPL License version 2
5# 5#
6# leaking_addresses.pl: Scan 64 bit kernel for potential leaking addresses. 6# leaking_addresses.pl: Scan the kernel for potential leaking addresses.
7# - Scans dmesg output. 7# - Scans dmesg output.
8# - Walks directory tree and parses each file (for each directory in @DIRS). 8# - Walks directory tree and parses each file (for each directory in @DIRS).
9# 9#
10# Use --debug to output path before parsing, this is useful to find files that 10# Use --debug to output path before parsing, this is useful to find files that
11# cause the script to choke. 11# cause the script to choke.
12
12# 13#
13# You may like to set kptr_restrict=2 before running script 14# When the system is idle it is likely that most files under /proc/PID will be
14# (see Documentation/sysctl/kernel.txt). 15# identical for various processes. Scanning _all_ the PIDs under /proc is
16# unnecessary and implies that we are thoroughly scanning /proc. This is _not_
17# the case because there may be ways userspace can trigger creation of /proc
18# files that leak addresses but were not present during a scan. For these two
19# reasons we exclude all PID directories under /proc except '1/'
15 20
16use warnings; 21use warnings;
17use strict; 22use strict;
@@ -22,9 +27,10 @@ use Cwd 'abs_path';
22use Term::ANSIColor qw(:constants); 27use Term::ANSIColor qw(:constants);
23use Getopt::Long qw(:config no_auto_abbrev); 28use Getopt::Long qw(:config no_auto_abbrev);
24use Config; 29use Config;
30use bigint qw/hex/;
31use feature 'state';
25 32
26my $P = $0; 33my $P = $0;
27my $V = '0.01';
28 34
29# Directories to scan. 35# Directories to scan.
30my @DIRS = ('/proc', '/sys'); 36my @DIRS = ('/proc', '/sys');
@@ -32,10 +38,9 @@ my @DIRS = ('/proc', '/sys');
32# Timer for parsing each file, in seconds. 38# Timer for parsing each file, in seconds.
33my $TIMEOUT = 10; 39my $TIMEOUT = 10;
34 40
35# Script can only grep for kernel addresses on the following architectures. If 41# Kernel addresses vary by architecture. We can only auto-detect the following
36# your architecture is not listed here and has a grep'able kernel address please 42# architectures (using `uname -m`). (flag --32-bit overrides auto-detection.)
37# consider submitting a patch. 43my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64', 'x86');
38my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64');
39 44
40# Command line options. 45# Command line options.
41my $help = 0; 46my $help = 0;
@@ -43,46 +48,34 @@ my $debug = 0;
43my $raw = 0; 48my $raw = 0;
44my $output_raw = ""; # Write raw results to file. 49my $output_raw = ""; # Write raw results to file.
45my $input_raw = ""; # Read raw results from file instead of scanning. 50my $input_raw = ""; # Read raw results from file instead of scanning.
46
47my $suppress_dmesg = 0; # Don't show dmesg in output. 51my $suppress_dmesg = 0; # Don't show dmesg in output.
48my $squash_by_path = 0; # Summary report grouped by absolute path. 52my $squash_by_path = 0; # Summary report grouped by absolute path.
49my $squash_by_filename = 0; # Summary report grouped by filename. 53my $squash_by_filename = 0; # Summary report grouped by filename.
50 54my $kernel_config_file = ""; # Kernel configuration file.
51# Do not parse these files (absolute path). 55my $opt_32bit = 0; # Scan 32-bit kernel.
52my @skip_parse_files_abs = ('/proc/kmsg', 56my $page_offset_32bit = 0; # Page offset for 32-bit kernel.
53 '/proc/kcore', 57
54 '/proc/fs/ext4/sdb1/mb_groups', 58# Skip these absolute paths.
55 '/proc/1/fd/3', 59my @skip_abs = (
56 '/sys/firmware/devicetree', 60 '/proc/kmsg',
57 '/proc/device-tree', 61 '/proc/device-tree',
58 '/sys/kernel/debug/tracing/trace_pipe', 62 '/proc/1/syscall',
59 '/sys/kernel/security/apparmor/revision'); 63 '/sys/firmware/devicetree',
60 64 '/sys/kernel/debug/tracing/trace_pipe',
61# Do not parse these files under any subdirectory. 65 '/sys/kernel/security/apparmor/revision');
62my @skip_parse_files_any = ('0', 66
63 '1', 67# Skip these under any subdirectory.
64 '2', 68my @skip_any = (
65 'pagemap', 69 'pagemap',
66 'events', 70 'events',
67 'access', 71 'access',
68 'registers', 72 'registers',
69 'snapshot_raw', 73 'snapshot_raw',
70 'trace_pipe_raw', 74 'trace_pipe_raw',
71 'ptmx', 75 'ptmx',
72 'trace_pipe'); 76 'trace_pipe',
73 77 'fd',
74# Do not walk these directories (absolute path). 78 'usbmon');
75my @skip_walk_dirs_abs = ();
76
77# Do not walk these directories under any subdirectory.
78my @skip_walk_dirs_any = ('self',
79 'thread-self',
80 'cwd',
81 'fd',
82 'usbmon',
83 'stderr',
84 'stdin',
85 'stdout');
86 79
87sub help 80sub help
88{ 81{
@@ -91,31 +84,22 @@ sub help
91 print << "EOM"; 84 print << "EOM";
92 85
93Usage: $P [OPTIONS] 86Usage: $P [OPTIONS]
94Version: $V
95 87
96Options: 88Options:
97 89
98 -o, --output-raw=<file> Save results for future processing. 90 -o, --output-raw=<file> Save results for future processing.
99 -i, --input-raw=<file> Read results from file instead of scanning. 91 -i, --input-raw=<file> Read results from file instead of scanning.
100 --raw Show raw results (default). 92 --raw Show raw results (default).
101 --suppress-dmesg Do not show dmesg results. 93 --suppress-dmesg Do not show dmesg results.
102 --squash-by-path Show one result per unique path. 94 --squash-by-path Show one result per unique path.
103 --squash-by-filename Show one result per unique filename. 95 --squash-by-filename Show one result per unique filename.
104 -d, --debug Display debugging output. 96 --kernel-config-file=<file> Kernel configuration file (e.g /boot/config)
105 -h, --help, --version Display this help and exit. 97 --32-bit Scan 32-bit kernel.
106 98 --page-offset-32-bit=o Page offset (for 32-bit kernel 0xABCD1234).
107Examples: 99 -d, --debug Display debugging output.
108 100 -h, --help, --version Display this help and exit.
109 # Scan kernel and dump raw results.
110 $0
111
112 # Scan kernel and save results to file.
113 $0 --output-raw scan.out
114 101
115 # View summary report. 102Scans the running kernel for potential leaking addresses.
116 $0 --input-raw scan.out --squash-by-filename
117
118Scans the running (64 bit) kernel for potential leaking addresses.
119 103
120EOM 104EOM
121 exit($exitcode); 105 exit($exitcode);
@@ -131,6 +115,9 @@ GetOptions(
131 'squash-by-path' => \$squash_by_path, 115 'squash-by-path' => \$squash_by_path,
132 'squash-by-filename' => \$squash_by_filename, 116 'squash-by-filename' => \$squash_by_filename,
133 'raw' => \$raw, 117 'raw' => \$raw,
118 'kernel-config-file=s' => \$kernel_config_file,
119 '32-bit' => \$opt_32bit,
120 'page-offset-32-bit=o' => \$page_offset_32bit,
134) or help(1); 121) or help(1);
135 122
136help(0) if ($help); 123help(0) if ($help);
@@ -146,16 +133,19 @@ if (!$input_raw and ($squash_by_path or $squash_by_filename)) {
146 exit(128); 133 exit(128);
147} 134}
148 135
149if (!is_supported_architecture()) { 136if (!(is_supported_architecture() or $opt_32bit or $page_offset_32bit)) {
150 printf "\nScript does not support your architecture, sorry.\n"; 137 printf "\nScript does not support your architecture, sorry.\n";
151 printf "\nCurrently we support: \n\n"; 138 printf "\nCurrently we support: \n\n";
152 foreach(@SUPPORTED_ARCHITECTURES) { 139 foreach(@SUPPORTED_ARCHITECTURES) {
153 printf "\t%s\n", $_; 140 printf "\t%s\n", $_;
154 } 141 }
142 printf("\n");
143
144 printf("If you are running a 32-bit architecture you may use:\n");
145 printf("\n\t--32-bit or --page-offset-32-bit=<page offset>\n\n");
155 146
156 my $archname = $Config{archname}; 147 my $archname = `uname -m`;
157 printf "\n\$ perl -MConfig -e \'print \"\$Config{archname}\\n\"\'\n"; 148 printf("Machine hardware name (`uname -m`): %s\n", $archname);
158 printf "%s\n", $archname;
159 149
160 exit(129); 150 exit(129);
161} 151}
@@ -177,49 +167,183 @@ sub dprint
177 167
178sub is_supported_architecture 168sub is_supported_architecture
179{ 169{
180 return (is_x86_64() or is_ppc64()); 170 return (is_x86_64() or is_ppc64() or is_ix86_32());
181} 171}
182 172
183sub is_x86_64 173sub is_32bit
184{ 174{
185 my $archname = $Config{archname}; 175 # Allow --32-bit or --page-offset-32-bit to override
186 176 if ($opt_32bit or $page_offset_32bit) {
187 if ($archname =~ m/x86_64/) {
188 return 1; 177 return 1;
189 } 178 }
190 return 0; 179
180 return is_ix86_32();
181}
182
183sub is_ix86_32
184{
185 state $arch = `uname -m`;
186
187 chomp $arch;
188 if ($arch =~ m/i[3456]86/) {
189 return 1;
190 }
191 return 0;
192}
193
194sub is_arch
195{
196 my ($desc) = @_;
197 my $arch = `uname -m`;
198
199 chomp $arch;
200 if ($arch eq $desc) {
201 return 1;
202 }
203 return 0;
204}
205
206sub is_x86_64
207{
208 state $is = is_arch('x86_64');
209 return $is;
191} 210}
192 211
193sub is_ppc64 212sub is_ppc64
194{ 213{
195 my $archname = $Config{archname}; 214 state $is = is_arch('ppc64');
215 return $is;
216}
196 217
197 if ($archname =~ m/powerpc/ and $archname =~ m/64/) { 218# Gets config option value from kernel config file.
198 return 1; 219# Returns "" on error or if config option not found.
220sub get_kernel_config_option
221{
222 my ($option) = @_;
223 my $value = "";
224 my $tmp_file = "";
225 my @config_files;
226
227 # Allow --kernel-config-file to override.
228 if ($kernel_config_file ne "") {
229 @config_files = ($kernel_config_file);
230 } elsif (-R "/proc/config.gz") {
231 my $tmp_file = "/tmp/tmpkconf";
232
233 if (system("gunzip < /proc/config.gz > $tmp_file")) {
234 dprint "$0: system(gunzip < /proc/config.gz) failed\n";
235 return "";
236 } else {
237 @config_files = ($tmp_file);
238 }
239 } else {
240 my $file = '/boot/config-' . `uname -r`;
241 chomp $file;
242 @config_files = ($file, '/boot/config');
199 } 243 }
200 return 0; 244
245 foreach my $file (@config_files) {
246 dprint("parsing config file: %s\n", $file);
247 $value = option_from_file($option, $file);
248 if ($value ne "") {
249 last;
250 }
251 }
252
253 if ($tmp_file ne "") {
254 system("rm -f $tmp_file");
255 }
256
257 return $value;
258}
259
260# Parses $file and returns kernel configuration option value.
261sub option_from_file
262{
263 my ($option, $file) = @_;
264 my $str = "";
265 my $val = "";
266
267 open(my $fh, "<", $file) or return "";
268 while (my $line = <$fh> ) {
269 if ($line =~ /^$option/) {
270 ($str, $val) = split /=/, $line;
271 chomp $val;
272 last;
273 }
274 }
275
276 close $fh;
277 return $val;
201} 278}
202 279
203sub is_false_positive 280sub is_false_positive
204{ 281{
205 my ($match) = @_; 282 my ($match) = @_;
206 283
284 if (is_32bit()) {
285 return is_false_positive_32bit($match);
286 }
287
288 # 64 bit false positives.
289
207 if ($match =~ '\b(0x)?(f|F){16}\b' or 290 if ($match =~ '\b(0x)?(f|F){16}\b' or
208 $match =~ '\b(0x)?0{16}\b') { 291 $match =~ '\b(0x)?0{16}\b') {
209 return 1; 292 return 1;
210 } 293 }
211 294
212 if (is_x86_64) { 295 if (is_x86_64() and is_in_vsyscall_memory_region($match)) {
213 # vsyscall memory region, we should probably check against a range here. 296 return 1;
214 if ($match =~ '\bf{10}600000\b' or
215 $match =~ '\bf{10}601000\b') {
216 return 1;
217 }
218 } 297 }
219 298
220 return 0; 299 return 0;
221} 300}
222 301
302sub is_false_positive_32bit
303{
304 my ($match) = @_;
305 state $page_offset = get_page_offset();
306
307 if ($match =~ '\b(0x)?(f|F){8}\b') {
308 return 1;
309 }
310
311 if (hex($match) < $page_offset) {
312 return 1;
313 }
314
315 return 0;
316}
317
318# returns integer value
319sub get_page_offset
320{
321 my $page_offset;
322 my $default_offset = 0xc0000000;
323
324 # Allow --page-offset-32bit to override.
325 if ($page_offset_32bit != 0) {
326 return $page_offset_32bit;
327 }
328
329 $page_offset = get_kernel_config_option('CONFIG_PAGE_OFFSET');
330 if (!$page_offset) {
331 return $default_offset;
332 }
333 return $page_offset;
334}
335
336sub is_in_vsyscall_memory_region
337{
338 my ($match) = @_;
339
340 my $hex = hex($match);
341 my $region_min = hex("0xffffffffff600000");
342 my $region_max = hex("0xffffffffff601000");
343
344 return ($hex >= $region_min and $hex <= $region_max);
345}
346
223# True if argument potentially contains a kernel address. 347# True if argument potentially contains a kernel address.
224sub may_leak_address 348sub may_leak_address
225{ 349{
@@ -238,14 +362,8 @@ sub may_leak_address
238 return 0; 362 return 0;
239 } 363 }
240 364
241 # One of these is guaranteed to be true. 365 $address_re = get_address_re();
242 if (is_x86_64()) { 366 while ($line =~ /($address_re)/g) {
243 $address_re = '\b(0x)?ffff[[:xdigit:]]{12}\b';
244 } elsif (is_ppc64()) {
245 $address_re = '\b(0x)?[89abcdef]00[[:xdigit:]]{13}\b';
246 }
247
248 while (/($address_re)/g) {
249 if (!is_false_positive($1)) { 367 if (!is_false_positive($1)) {
250 return 1; 368 return 1;
251 } 369 }
@@ -254,6 +372,31 @@ sub may_leak_address
254 return 0; 372 return 0;
255} 373}
256 374
375sub get_address_re
376{
377 if (is_ppc64()) {
378 return '\b(0x)?[89abcdef]00[[:xdigit:]]{13}\b';
379 } elsif (is_32bit()) {
380 return '\b(0x)?[[:xdigit:]]{8}\b';
381 }
382
383 return get_x86_64_re();
384}
385
386sub get_x86_64_re
387{
388 # We handle page table levels but only if explicitly configured using
389 # CONFIG_PGTABLE_LEVELS. If config file parsing fails or config option
390 # is not found we default to using address regular expression suitable
391 # for 4 page table levels.
392 state $ptl = get_kernel_config_option('CONFIG_PGTABLE_LEVELS');
393
394 if ($ptl == 5) {
395 return '\b(0x)?ff[[:xdigit:]]{14}\b';
396 }
397 return '\b(0x)?ffff[[:xdigit:]]{12}\b';
398}
399
257sub parse_dmesg 400sub parse_dmesg
258{ 401{
259 open my $cmd, '-|', 'dmesg'; 402 open my $cmd, '-|', 'dmesg';
@@ -268,26 +411,20 @@ sub parse_dmesg
268# True if we should skip this path. 411# True if we should skip this path.
269sub skip 412sub skip
270{ 413{
271 my ($path, $paths_abs, $paths_any) = @_; 414 my ($path) = @_;
272 415
273 foreach (@$paths_abs) { 416 foreach (@skip_abs) {
274 return 1 if (/^$path$/); 417 return 1 if (/^$path$/);
275 } 418 }
276 419
277 my($filename, $dirs, $suffix) = fileparse($path); 420 my($filename, $dirs, $suffix) = fileparse($path);
278 foreach (@$paths_any) { 421 foreach (@skip_any) {
279 return 1 if (/^$filename$/); 422 return 1 if (/^$filename$/);
280 } 423 }
281 424
282 return 0; 425 return 0;
283} 426}
284 427
285sub skip_parse
286{
287 my ($path) = @_;
288 return skip($path, \@skip_parse_files_abs, \@skip_parse_files_any);
289}
290
291sub timed_parse_file 428sub timed_parse_file
292{ 429{
293 my ($file) = @_; 430 my ($file) = @_;
@@ -313,11 +450,9 @@ sub parse_file
313 return; 450 return;
314 } 451 }
315 452
316 if (skip_parse($file)) { 453 if (! -T $file) {
317 dprint "skipping file: $file\n";
318 return; 454 return;
319 } 455 }
320 dprint "parsing: $file\n";
321 456
322 open my $fh, "<", $file or return; 457 open my $fh, "<", $file or return;
323 while ( <$fh> ) { 458 while ( <$fh> ) {
@@ -328,12 +463,14 @@ sub parse_file
328 close $fh; 463 close $fh;
329} 464}
330 465
331 466# Checks if the actual path name is leaking a kernel address.
332# True if we should skip walking this directory. 467sub check_path_for_leaks
333sub skip_walk
334{ 468{
335 my ($path) = @_; 469 my ($path) = @_;
336 return skip($path, \@skip_walk_dirs_abs, \@skip_walk_dirs_any) 470
471 if (may_leak_address($path)) {
472 printf("Path name may contain address: $path\n");
473 }
337} 474}
338 475
339# Recursively walk directory tree. 476# Recursively walk directory tree.
@@ -342,7 +479,6 @@ sub walk
342 my @dirs = @_; 479 my @dirs = @_;
343 480
344 while (my $pwd = shift @dirs) { 481 while (my $pwd = shift @dirs) {
345 next if (skip_walk($pwd));
346 next if (!opendir(DIR, $pwd)); 482 next if (!opendir(DIR, $pwd));
347 my @files = readdir(DIR); 483 my @files = readdir(DIR);
348 closedir(DIR); 484 closedir(DIR);
@@ -353,11 +489,21 @@ sub walk
353 my $path = "$pwd/$file"; 489 my $path = "$pwd/$file";
354 next if (-l $path); 490 next if (-l $path);
355 491
492 # skip /proc/PID except /proc/1
493 next if (($path =~ /^\/proc\/[0-9]+$/) &&
494 ($path !~ /^\/proc\/1$/));
495
496 next if (skip($path));
497
498 check_path_for_leaks($path);
499
356 if (-d $path) { 500 if (-d $path) {
357 push @dirs, $path; 501 push @dirs, $path;
358 } else { 502 next;
359 timed_parse_file($path);
360 } 503 }
504
505 dprint "parsing: $path\n";
506 timed_parse_file($path);
361 } 507 }
362 } 508 }
363} 509}
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index be56a1153014..c8cf45362bd6 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -4,7 +4,7 @@
4# link vmlinux 4# link vmlinux
5# 5#
6# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and 6# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and
7# $(KBUILD_VMLINUX_MAIN) and $(KBUILD_VMLINUX_LIBS). Most are built-in.o files 7# $(KBUILD_VMLINUX_MAIN) and $(KBUILD_VMLINUX_LIBS). Most are built-in.a files
8# from top-level directories in the kernel tree, others are specified in 8# from top-level directories in the kernel tree, others are specified in
9# arch/$(ARCH)/Makefile. Ordering when linking is important, and 9# arch/$(ARCH)/Makefile. Ordering when linking is important, and
10# $(KBUILD_VMLINUX_INIT) must be first. $(KBUILD_VMLINUX_LIBS) are archives 10# $(KBUILD_VMLINUX_INIT) must be first. $(KBUILD_VMLINUX_LIBS) are archives
@@ -18,7 +18,7 @@
18# | +--< init/version.o + more 18# | +--< init/version.o + more
19# | 19# |
20# +--< $(KBUILD_VMLINUX_MAIN) 20# +--< $(KBUILD_VMLINUX_MAIN)
21# | +--< drivers/built-in.o mm/built-in.o + more 21# | +--< drivers/built-in.a mm/built-in.a + more
22# | 22# |
23# +--< $(KBUILD_VMLINUX_LIBS) 23# +--< $(KBUILD_VMLINUX_LIBS)
24# | +--< lib/lib.a + more 24# | +--< lib/lib.a + more
@@ -51,17 +51,15 @@ info()
51# 51#
52# Traditional incremental style of link does not require this step 52# Traditional incremental style of link does not require this step
53# 53#
54# built-in.o output file 54# built-in.a output file
55# 55#
56archive_builtin() 56archive_builtin()
57{ 57{
58 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 58 info AR built-in.a
59 info AR built-in.o 59 rm -f built-in.a;
60 rm -f built-in.o; 60 ${AR} rcsTP${KBUILD_ARFLAGS} built-in.a \
61 ${AR} rcsTP${KBUILD_ARFLAGS} built-in.o \ 61 ${KBUILD_VMLINUX_INIT} \
62 ${KBUILD_VMLINUX_INIT} \ 62 ${KBUILD_VMLINUX_MAIN}
63 ${KBUILD_VMLINUX_MAIN}
64 fi
65} 63}
66 64
67# Link of vmlinux.o used for section mismatch analysis 65# Link of vmlinux.o used for section mismatch analysis
@@ -70,21 +68,14 @@ modpost_link()
70{ 68{
71 local objects 69 local objects
72 70
73 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 71 objects="--whole-archive \
74 objects="--whole-archive \ 72 built-in.a \
75 built-in.o \ 73 --no-whole-archive \
76 --no-whole-archive \ 74 --start-group \
77 --start-group \ 75 ${KBUILD_VMLINUX_LIBS} \
78 ${KBUILD_VMLINUX_LIBS} \ 76 --end-group"
79 --end-group" 77
80 else 78 ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
81 objects="${KBUILD_VMLINUX_INIT} \
82 --start-group \
83 ${KBUILD_VMLINUX_MAIN} \
84 ${KBUILD_VMLINUX_LIBS} \
85 --end-group"
86 fi
87 ${LD} ${LDFLAGS} -r -o ${1} ${objects}
88} 79}
89 80
90# Link of vmlinux 81# Link of vmlinux
@@ -96,46 +87,28 @@ vmlinux_link()
96 local objects 87 local objects
97 88
98 if [ "${SRCARCH}" != "um" ]; then 89 if [ "${SRCARCH}" != "um" ]; then
99 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 90 objects="--whole-archive \
100 objects="--whole-archive \ 91 built-in.a \
101 built-in.o \ 92 --no-whole-archive \
102 --no-whole-archive \ 93 --start-group \
103 --start-group \ 94 ${KBUILD_VMLINUX_LIBS} \
104 ${KBUILD_VMLINUX_LIBS} \ 95 --end-group \
105 --end-group \ 96 ${1}"
106 ${1}" 97
107 else 98 ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
108 objects="${KBUILD_VMLINUX_INIT} \
109 --start-group \
110 ${KBUILD_VMLINUX_MAIN} \
111 ${KBUILD_VMLINUX_LIBS} \
112 --end-group \
113 ${1}"
114 fi
115
116 ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
117 -T ${lds} ${objects} 99 -T ${lds} ${objects}
118 else 100 else
119 if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then 101 objects="-Wl,--whole-archive \
120 objects="-Wl,--whole-archive \ 102 built-in.a \
121 built-in.o \ 103 -Wl,--no-whole-archive \
122 -Wl,--no-whole-archive \ 104 -Wl,--start-group \
123 -Wl,--start-group \ 105 ${KBUILD_VMLINUX_LIBS} \
124 ${KBUILD_VMLINUX_LIBS} \ 106 -Wl,--end-group \
125 -Wl,--end-group \ 107 ${1}"
126 ${1}" 108
127 else 109 ${CC} ${CFLAGS_vmlinux} -o ${2} \
128 objects="${KBUILD_VMLINUX_INIT} \ 110 -Wl,-T,${lds} \
129 -Wl,--start-group \ 111 ${objects} \
130 ${KBUILD_VMLINUX_MAIN} \
131 ${KBUILD_VMLINUX_LIBS} \
132 -Wl,--end-group \
133 ${1}"
134 fi
135
136 ${CC} ${CFLAGS_vmlinux} -o ${2} \
137 -Wl,-T,${lds} \
138 ${objects} \
139 -lutil -lrt -lpthread 112 -lutil -lrt -lpthread
140 rm -f linux 113 rm -f linux
141 fi 114 fi
@@ -148,10 +121,6 @@ kallsyms()
148 info KSYM ${2} 121 info KSYM ${2}
149 local kallsymopt; 122 local kallsymopt;
150 123
151 if [ -n "${CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX}" ]; then
152 kallsymopt="${kallsymopt} --symbol-prefix=_"
153 fi
154
155 if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then 124 if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
156 kallsymopt="${kallsymopt} --all-symbols" 125 kallsymopt="${kallsymopt} --all-symbols"
157 fi 126 fi
@@ -191,7 +160,7 @@ cleanup()
191 rm -f .tmp_System.map 160 rm -f .tmp_System.map
192 rm -f .tmp_kallsyms* 161 rm -f .tmp_kallsyms*
193 rm -f .tmp_vmlinux* 162 rm -f .tmp_vmlinux*
194 rm -f built-in.o 163 rm -f built-in.a
195 rm -f System.map 164 rm -f System.map
196 rm -f vmlinux 165 rm -f vmlinux
197 rm -f vmlinux.o 166 rm -f vmlinux.o
@@ -296,8 +265,8 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then
296 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o 265 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o
297 266
298 # step 3 267 # step 3
299 size1=$(stat -c "%s" .tmp_kallsyms1.o) 268 size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" .tmp_kallsyms1.o)
300 size2=$(stat -c "%s" .tmp_kallsyms2.o) 269 size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" .tmp_kallsyms2.o)
301 270
302 if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then 271 if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
303 kallsymso=.tmp_kallsyms3.o 272 kallsymso=.tmp_kallsyms3.o
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index e19d6565f245..412f13fdff52 100755
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -6,31 +6,20 @@
6 6
7# Usage 7# Usage
8# $1 - Kernel src directory 8# $1 - Kernel src directory
9# $2 - Output directory
10# $3 - version
11# $4 - patchlevel
12 9
13
14test ! -r $2/Makefile -o -O $2/Makefile || exit 0
15# Only overwrite automatically generated Makefiles 10# Only overwrite automatically generated Makefiles
16# (so we do not overwrite kernel Makefile) 11# (so we do not overwrite kernel Makefile)
17if test -e $2/Makefile && ! grep -q Automatically $2/Makefile 12if test -e Makefile && ! grep -q Automatically Makefile
18then 13then
19 exit 0 14 exit 0
20fi 15fi
21if [ "${quiet}" != "silent_" ]; then 16if [ "${quiet}" != "silent_" ]; then
22 echo " GEN $2/Makefile" 17 echo " GEN Makefile"
23fi 18fi
24 19
25cat << EOF > $2/Makefile 20cat << EOF > Makefile
26# Automatically generated by $0: don't edit 21# Automatically generated by $0: don't edit
27 22
28VERSION = $3
29PATCHLEVEL = $4
30
31lastword = \$(word \$(words \$(1)),\$(1))
32makedir := \$(dir \$(call lastword,\$(MAKEFILE_LIST)))
33
34ifeq ("\$(origin V)", "command line") 23ifeq ("\$(origin V)", "command line")
35VERBOSE := \$(V) 24VERBOSE := \$(V)
36endif 25endif
@@ -38,15 +27,12 @@ ifneq (\$(VERBOSE),1)
38Q := @ 27Q := @
39endif 28endif
40 29
41MAKEARGS := -C $1
42MAKEARGS += O=\$(if \$(patsubst /%,,\$(makedir)),\$(CURDIR)/)\$(patsubst %/,%,\$(makedir))
43
44MAKEFLAGS += --no-print-directory 30MAKEFLAGS += --no-print-directory
45 31
46.PHONY: __sub-make \$(MAKECMDGOALS) 32.PHONY: __sub-make \$(MAKECMDGOALS)
47 33
48__sub-make: 34__sub-make:
49 \$(Q)\$(MAKE) \$(MAKEARGS) \$(MAKECMDGOALS) 35 \$(Q)\$(MAKE) -C $1 O=\$(CURDIR) \$(MAKECMDGOALS)
50 36
51\$(filter-out __sub-make, \$(MAKECMDGOALS)): __sub-make 37\$(filter-out __sub-make, \$(MAKECMDGOALS)): __sub-make
52 @: 38 @:
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
index 42c5d50f2bcc..a5b4af47987a 100644
--- a/scripts/mod/Makefile
+++ b/scripts/mod/Makefile
@@ -4,6 +4,8 @@ OBJECT_FILES_NON_STANDARD := y
4hostprogs-y := modpost mk_elfconfig 4hostprogs-y := modpost mk_elfconfig
5always := $(hostprogs-y) empty.o 5always := $(hostprogs-y) empty.o
6 6
7CFLAGS_REMOVE_empty.o := $(ASM_MACRO_FLAGS)
8
7modpost-objs := modpost.o file2alias.o sumversion.o 9modpost-objs := modpost.o file2alias.o sumversion.o
8 10
9devicetable-offsets-file := devicetable-offsets.h 11devicetable-offsets-file := devicetable-offsets.h
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index 9fad6afe4c41..293004499b4d 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -139,6 +139,9 @@ int main(void)
139 DEVID(hv_vmbus_device_id); 139 DEVID(hv_vmbus_device_id);
140 DEVID_FIELD(hv_vmbus_device_id, guid); 140 DEVID_FIELD(hv_vmbus_device_id, guid);
141 141
142 DEVID(rpmsg_device_id);
143 DEVID_FIELD(rpmsg_device_id, name);
144
142 DEVID(i2c_device_id); 145 DEVID(i2c_device_id);
143 DEVID_FIELD(i2c_device_id, name); 146 DEVID_FIELD(i2c_device_id, name);
144 147
@@ -218,5 +221,9 @@ int main(void)
218 DEVID_FIELD(tb_service_id, protocol_version); 221 DEVID_FIELD(tb_service_id, protocol_version);
219 DEVID_FIELD(tb_service_id, protocol_revision); 222 DEVID_FIELD(tb_service_id, protocol_revision);
220 223
224 DEVID(typec_device_id);
225 DEVID_FIELD(typec_device_id, svid);
226 DEVID_FIELD(typec_device_id, mode);
227
221 return 0; 228 return 0;
222} 229}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index b9beeaa4695b..28a61665bb9c 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -95,12 +95,20 @@ extern struct devtable *__start___devtable[], *__stop___devtable[];
95 */ 95 */
96#define DEF_FIELD(m, devid, f) \ 96#define DEF_FIELD(m, devid, f) \
97 typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f)) 97 typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f))
98
99/* Define a variable v that holds the address of field f of struct devid
100 * based at address m. Due to the way typeof works, for a field of type
101 * T[N] the variable has type T(*)[N], _not_ T*.
102 */
103#define DEF_FIELD_ADDR_VAR(m, devid, f, v) \
104 typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f)
105
98/* Define a variable f that holds the address of field f of struct devid 106/* Define a variable f that holds the address of field f of struct devid
99 * based at address m. Due to the way typeof works, for a field of type 107 * based at address m. Due to the way typeof works, for a field of type
100 * T[N] the variable has type T(*)[N], _not_ T*. 108 * T[N] the variable has type T(*)[N], _not_ T*.
101 */ 109 */
102#define DEF_FIELD_ADDR(m, devid, f) \ 110#define DEF_FIELD_ADDR(m, devid, f) \
103 typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) 111 DEF_FIELD_ADDR_VAR(m, devid, f, f)
104 112
105/* Add a table entry. We test function type matches while we're here. */ 113/* Add a table entry. We test function type matches while we're here. */
106#define ADD_TO_DEVTABLE(device_id, type, function) \ 114#define ADD_TO_DEVTABLE(device_id, type, function) \
@@ -644,7 +652,7 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
644 652
645 for (i = 0; i < count; i++) { 653 for (i = 0; i < count; i++) {
646 unsigned int j; 654 unsigned int j;
647 DEF_FIELD_ADDR(symval + i*id_size, pnp_card_device_id, devs); 655 DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs);
648 656
649 for (j = 0; j < PNP_MAX_DEVICES; j++) { 657 for (j = 0; j < PNP_MAX_DEVICES; j++) {
650 const char *id = (char *)(*devs)[j].id; 658 const char *id = (char *)(*devs)[j].id;
@@ -656,10 +664,13 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
656 664
657 /* find duplicate, already added value */ 665 /* find duplicate, already added value */
658 for (i2 = 0; i2 < i && !dup; i2++) { 666 for (i2 = 0; i2 < i && !dup; i2++) {
659 DEF_FIELD_ADDR(symval + i2*id_size, pnp_card_device_id, devs); 667 DEF_FIELD_ADDR_VAR(symval + i2 * id_size,
668 pnp_card_device_id,
669 devs, devs_dup);
660 670
661 for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { 671 for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) {
662 const char *id2 = (char *)(*devs)[j2].id; 672 const char *id2 =
673 (char *)(*devs_dup)[j2].id;
663 674
664 if (!id2[0]) 675 if (!id2[0])
665 break; 676 break;
@@ -944,6 +955,17 @@ static int do_vmbus_entry(const char *filename, void *symval,
944} 955}
945ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry); 956ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry);
946 957
958/* Looks like: rpmsg:S */
959static int do_rpmsg_entry(const char *filename, void *symval,
960 char *alias)
961{
962 DEF_FIELD_ADDR(symval, rpmsg_device_id, name);
963 sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name);
964
965 return 1;
966}
967ADD_TO_DEVTABLE("rpmsg", rpmsg_device_id, do_rpmsg_entry);
968
947/* Looks like: i2c:S */ 969/* Looks like: i2c:S */
948static int do_i2c_entry(const char *filename, void *symval, 970static int do_i2c_entry(const char *filename, void *symval,
949 char *alias) 971 char *alias)
@@ -1341,6 +1363,19 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias)
1341} 1363}
1342ADD_TO_DEVTABLE("tbsvc", tb_service_id, do_tbsvc_entry); 1364ADD_TO_DEVTABLE("tbsvc", tb_service_id, do_tbsvc_entry);
1343 1365
1366/* Looks like: typec:idNmN */
1367static int do_typec_entry(const char *filename, void *symval, char *alias)
1368{
1369 DEF_FIELD(symval, typec_device_id, svid);
1370 DEF_FIELD(symval, typec_device_id, mode);
1371
1372 sprintf(alias, "typec:id%04X", svid);
1373 ADD(alias, "m", mode != TYPEC_ANY_MODE, mode);
1374
1375 return 1;
1376}
1377ADD_TO_DEVTABLE("typec", typec_device_id, do_typec_entry);
1378
1344/* Does namelen bytes of name exactly match the symbol? */ 1379/* Does namelen bytes of name exactly match the symbol? */
1345static bool sym_is(const char *name, unsigned namelen, const char *symbol) 1380static bool sym_is(const char *name, unsigned namelen, const char *symbol)
1346{ 1381{
@@ -1391,11 +1426,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
1391 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) 1426 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
1392 return; 1427 return;
1393 1428
1394 /* All our symbols are of form <prefix>__mod_<name>__<identifier>_device_table. */ 1429 /* All our symbols are of form __mod_<name>__<identifier>_device_table. */
1395 name = strstr(symname, "__mod_"); 1430 if (strncmp(symname, "__mod_", strlen("__mod_")))
1396 if (!name)
1397 return; 1431 return;
1398 name += strlen("__mod_"); 1432 name = symname + strlen("__mod_");
1399 namelen = strlen(name); 1433 namelen = strlen(name);
1400 if (namelen < strlen("_device_table")) 1434 if (namelen < strlen("_device_table"))
1401 return; 1435 return;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 9917f928d0fd..0d998c54564d 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -19,9 +19,7 @@
19#include <stdbool.h> 19#include <stdbool.h>
20#include <errno.h> 20#include <errno.h>
21#include "modpost.h" 21#include "modpost.h"
22#include "../../include/generated/autoconf.h"
23#include "../../include/linux/license.h" 22#include "../../include/linux/license.h"
24#include "../../include/linux/export.h"
25 23
26/* Are we using CONFIG_MODVERSIONS? */ 24/* Are we using CONFIG_MODVERSIONS? */
27static int modversions = 0; 25static int modversions = 0;
@@ -123,7 +121,7 @@ void *do_nofail(void *ptr, const char *expr)
123/* A list of all modules we processed */ 121/* A list of all modules we processed */
124static struct module *modules; 122static struct module *modules;
125 123
126static struct module *find_module(char *modname) 124static struct module *find_module(const char *modname)
127{ 125{
128 struct module *mod; 126 struct module *mod;
129 127
@@ -591,35 +589,32 @@ static void parse_elf_finish(struct elf_info *info)
591static int ignore_undef_symbol(struct elf_info *info, const char *symname) 589static int ignore_undef_symbol(struct elf_info *info, const char *symname)
592{ 590{
593 /* ignore __this_module, it will be resolved shortly */ 591 /* ignore __this_module, it will be resolved shortly */
594 if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0) 592 if (strcmp(symname, "__this_module") == 0)
595 return 1; 593 return 1;
596 /* ignore global offset table */ 594 /* ignore global offset table */
597 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) 595 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
598 return 1; 596 return 1;
599 if (info->hdr->e_machine == EM_PPC) 597 if (info->hdr->e_machine == EM_PPC)
600 /* Special register function linked on all modules during final link of .ko */ 598 /* Special register function linked on all modules during final link of .ko */
601 if (strncmp(symname, "_restgpr_", sizeof("_restgpr_") - 1) == 0 || 599 if (strstarts(symname, "_restgpr_") ||
602 strncmp(symname, "_savegpr_", sizeof("_savegpr_") - 1) == 0 || 600 strstarts(symname, "_savegpr_") ||
603 strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || 601 strstarts(symname, "_rest32gpr_") ||
604 strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0 || 602 strstarts(symname, "_save32gpr_") ||
605 strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 || 603 strstarts(symname, "_restvr_") ||
606 strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0) 604 strstarts(symname, "_savevr_"))
607 return 1; 605 return 1;
608 if (info->hdr->e_machine == EM_PPC64) 606 if (info->hdr->e_machine == EM_PPC64)
609 /* Special register function linked on all modules during final link of .ko */ 607 /* Special register function linked on all modules during final link of .ko */
610 if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 || 608 if (strstarts(symname, "_restgpr0_") ||
611 strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0 || 609 strstarts(symname, "_savegpr0_") ||
612 strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 || 610 strstarts(symname, "_restvr_") ||
613 strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0 || 611 strstarts(symname, "_savevr_") ||
614 strcmp(symname, ".TOC.") == 0) 612 strcmp(symname, ".TOC.") == 0)
615 return 1; 613 return 1;
616 /* Do not ignore this symbol */ 614 /* Do not ignore this symbol */
617 return 0; 615 return 0;
618} 616}
619 617
620#define CRC_PFX VMLINUX_SYMBOL_STR(__crc_)
621#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_)
622
623static void handle_modversions(struct module *mod, struct elf_info *info, 618static void handle_modversions(struct module *mod, struct elf_info *info,
624 Elf_Sym *sym, const char *symname) 619 Elf_Sym *sym, const char *symname)
625{ 620{
@@ -628,13 +623,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
628 bool is_crc = false; 623 bool is_crc = false;
629 624
630 if ((!is_vmlinux(mod->name) || mod->is_dot_o) && 625 if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
631 strncmp(symname, "__ksymtab", 9) == 0) 626 strstarts(symname, "__ksymtab"))
632 export = export_from_secname(info, get_secindex(info, sym)); 627 export = export_from_secname(info, get_secindex(info, sym));
633 else 628 else
634 export = export_from_sec(info, get_secindex(info, sym)); 629 export = export_from_sec(info, get_secindex(info, sym));
635 630
636 /* CRC'd symbol */ 631 /* CRC'd symbol */
637 if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 632 if (strstarts(symname, "__crc_")) {
638 is_crc = true; 633 is_crc = true;
639 crc = (unsigned int) sym->st_value; 634 crc = (unsigned int) sym->st_value;
640 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) { 635 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) {
@@ -647,13 +642,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
647 info->sechdrs[sym->st_shndx].sh_addr : 0); 642 info->sechdrs[sym->st_shndx].sh_addr : 0);
648 crc = *crcp; 643 crc = *crcp;
649 } 644 }
650 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 645 sym_update_crc(symname + strlen("__crc_"), mod, crc,
651 export); 646 export);
652 } 647 }
653 648
654 switch (sym->st_shndx) { 649 switch (sym->st_shndx) {
655 case SHN_COMMON: 650 case SHN_COMMON:
656 if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) { 651 if (strstarts(symname, "__gnu_lto_")) {
657 /* Should warn here, but modpost runs before the linker */ 652 /* Should warn here, but modpost runs before the linker */
658 } else 653 } else
659 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); 654 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
@@ -677,7 +672,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
677 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) 672 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
678 break; 673 break;
679 if (symname[0] == '.') { 674 if (symname[0] == '.') {
680 char *munged = strdup(symname); 675 char *munged = NOFAIL(strdup(symname));
681 munged[0] = '_'; 676 munged[0] = '_';
682 munged[1] = toupper(munged[1]); 677 munged[1] = toupper(munged[1]);
683 symname = munged; 678 symname = munged;
@@ -685,15 +680,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
685 } 680 }
686#endif 681#endif
687 682
688#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
689 if (symname[0] != '_')
690 break;
691 else
692 symname++;
693#endif
694 if (is_crc) { 683 if (is_crc) {
695 const char *e = is_vmlinux(mod->name) ?"":".ko"; 684 const char *e = is_vmlinux(mod->name) ?"":".ko";
696 warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", symname + strlen(CRC_PFX), mod->name, e); 685 warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n",
686 symname + strlen("__crc_"), mod->name, e);
697 } 687 }
698 mod->unres = alloc_symbol(symname, 688 mod->unres = alloc_symbol(symname,
699 ELF_ST_BIND(sym->st_info) == STB_WEAK, 689 ELF_ST_BIND(sym->st_info) == STB_WEAK,
@@ -701,13 +691,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
701 break; 691 break;
702 default: 692 default:
703 /* All exported symbols */ 693 /* All exported symbols */
704 if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 694 if (strstarts(symname, "__ksymtab_")) {
705 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, 695 sym_add_exported(symname + strlen("__ksymtab_"), mod,
706 export); 696 export);
707 } 697 }
708 if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0) 698 if (strcmp(symname, "init_module") == 0)
709 mod->has_init = 1; 699 mod->has_init = 1;
710 if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0) 700 if (strcmp(symname, "cleanup_module") == 0)
711 mod->has_cleanup = 1; 701 mod->has_cleanup = 1;
712 break; 702 break;
713 } 703 }
@@ -734,16 +724,17 @@ static char *next_string(char *string, unsigned long *secsize)
734 return string; 724 return string;
735} 725}
736 726
737static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len, 727static char *get_next_modinfo(struct elf_info *info, const char *tag,
738 const char *tag, char *info) 728 char *prev)
739{ 729{
740 char *p; 730 char *p;
741 unsigned int taglen = strlen(tag); 731 unsigned int taglen = strlen(tag);
742 unsigned long size = modinfo_len; 732 char *modinfo = info->modinfo;
733 unsigned long size = info->modinfo_len;
743 734
744 if (info) { 735 if (prev) {
745 size -= info - (char *)modinfo; 736 size -= prev - modinfo;
746 modinfo = next_string(info, &size); 737 modinfo = next_string(prev, &size);
747 } 738 }
748 739
749 for (p = modinfo; p; p = next_string(p, &size)) { 740 for (p = modinfo; p; p = next_string(p, &size)) {
@@ -753,11 +744,10 @@ static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
753 return NULL; 744 return NULL;
754} 745}
755 746
756static char *get_modinfo(void *modinfo, unsigned long modinfo_len, 747static char *get_modinfo(struct elf_info *info, const char *tag)
757 const char *tag)
758 748
759{ 749{
760 return get_next_modinfo(modinfo, modinfo_len, tag, NULL); 750 return get_next_modinfo(info, tag, NULL);
761} 751}
762 752
763/** 753/**
@@ -840,8 +830,7 @@ static const char *const section_white_list[] =
840 ".debug*", 830 ".debug*",
841 ".cranges", /* sh64 */ 831 ".cranges", /* sh64 */
842 ".zdebug*", /* Compressed debug sections. */ 832 ".zdebug*", /* Compressed debug sections. */
843 ".GCC-command-line", /* mn10300 */ 833 ".GCC.command.line", /* record-gcc-switches */
844 ".GCC.command.line", /* record-gcc-switches, non mn10300 */
845 ".mdebug*", /* alpha, score, mips etc. */ 834 ".mdebug*", /* alpha, score, mips etc. */
846 ".pdr", /* alpha, score, mips etc. */ 835 ".pdr", /* alpha, score, mips etc. */
847 ".stab*", 836 ".stab*",
@@ -1104,8 +1093,8 @@ static const struct sectioncheck *section_mismatch(
1104 /* 1093 /*
1105 * The target section could be the SHT_NUL section when we're 1094 * The target section could be the SHT_NUL section when we're
1106 * handling relocations to un-resolved symbols, trying to match it 1095 * handling relocations to un-resolved symbols, trying to match it
1107 * doesn't make much sense and causes build failures on parisc and 1096 * doesn't make much sense and causes build failures on parisc
1108 * mn10300 architectures. 1097 * architectures.
1109 */ 1098 */
1110 if (*tosec == '\0') 1099 if (*tosec == '\0')
1111 return NULL; 1100 return NULL;
@@ -1182,13 +1171,13 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
1182 /* Check for pattern 1 */ 1171 /* Check for pattern 1 */
1183 if (match(tosec, init_data_sections) && 1172 if (match(tosec, init_data_sections) &&
1184 match(fromsec, data_sections) && 1173 match(fromsec, data_sections) &&
1185 (strncmp(fromsym, "__param", strlen("__param")) == 0)) 1174 strstarts(fromsym, "__param"))
1186 return 0; 1175 return 0;
1187 1176
1188 /* Check for pattern 1a */ 1177 /* Check for pattern 1a */
1189 if (strcmp(tosec, ".init.text") == 0 && 1178 if (strcmp(tosec, ".init.text") == 0 &&
1190 match(fromsec, data_sections) && 1179 match(fromsec, data_sections) &&
1191 (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0)) 1180 strstarts(fromsym, "__param_ops_"))
1192 return 0; 1181 return 0;
1193 1182
1194 /* Check for pattern 2 */ 1183 /* Check for pattern 2 */
@@ -1329,7 +1318,7 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1329static char *sec2annotation(const char *s) 1318static char *sec2annotation(const char *s)
1330{ 1319{
1331 if (match(s, init_exit_sections)) { 1320 if (match(s, init_exit_sections)) {
1332 char *p = malloc(20); 1321 char *p = NOFAIL(malloc(20));
1333 char *r = p; 1322 char *r = p;
1334 1323
1335 *p++ = '_'; 1324 *p++ = '_';
@@ -1349,7 +1338,7 @@ static char *sec2annotation(const char *s)
1349 strcat(p, " "); 1338 strcat(p, " ");
1350 return r; 1339 return r;
1351 } else { 1340 } else {
1352 return strdup(""); 1341 return NOFAIL(strdup(""));
1353 } 1342 }
1354} 1343}
1355 1344
@@ -1543,8 +1532,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
1543 from = find_elf_symbol2(elf, r->r_offset, fromsec); 1532 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1544 fromsym = sym_name(elf, from); 1533 fromsym = sym_name(elf, from);
1545 1534
1546 if (!strncmp(fromsym, "reference___initcall", 1535 if (strstarts(fromsym, "reference___initcall"))
1547 sizeof("reference___initcall")-1))
1548 return; 1536 return;
1549 1537
1550 tosec = sec_name(elf, get_secindex(elf, sym)); 1538 tosec = sec_name(elf, get_secindex(elf, sym));
@@ -1941,7 +1929,7 @@ static char *remove_dot(char *s)
1941 return s; 1929 return s;
1942} 1930}
1943 1931
1944static void read_symbols(char *modname) 1932static void read_symbols(const char *modname)
1945{ 1933{
1946 const char *symname; 1934 const char *symname;
1947 char *version; 1935 char *version;
@@ -1962,7 +1950,7 @@ static void read_symbols(char *modname)
1962 mod->skip = 1; 1950 mod->skip = 1;
1963 } 1951 }
1964 1952
1965 license = get_modinfo(info.modinfo, info.modinfo_len, "license"); 1953 license = get_modinfo(&info, "license");
1966 if (!license && !is_vmlinux(modname)) 1954 if (!license && !is_vmlinux(modname))
1967 warn("modpost: missing MODULE_LICENSE() in %s\n" 1955 warn("modpost: missing MODULE_LICENSE() in %s\n"
1968 "see include/linux/module.h for " 1956 "see include/linux/module.h for "
@@ -1974,8 +1962,7 @@ static void read_symbols(char *modname)
1974 mod->gpl_compatible = 0; 1962 mod->gpl_compatible = 0;
1975 break; 1963 break;
1976 } 1964 }
1977 license = get_next_modinfo(info.modinfo, info.modinfo_len, 1965 license = get_next_modinfo(&info, "license", license);
1978 "license", license);
1979 } 1966 }
1980 1967
1981 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { 1968 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
@@ -1984,11 +1971,10 @@ static void read_symbols(char *modname)
1984 handle_modversions(mod, &info, sym, symname); 1971 handle_modversions(mod, &info, sym, symname);
1985 handle_moddevtable(mod, &info, sym, symname); 1972 handle_moddevtable(mod, &info, sym, symname);
1986 } 1973 }
1987 if (!is_vmlinux(modname) || 1974 if (!is_vmlinux(modname) || vmlinux_section_warnings)
1988 (is_vmlinux(modname) && vmlinux_section_warnings))
1989 check_sec_ref(mod, modname, &info); 1975 check_sec_ref(mod, modname, &info);
1990 1976
1991 version = get_modinfo(info.modinfo, info.modinfo_len, "version"); 1977 version = get_modinfo(&info, "version");
1992 if (version) 1978 if (version)
1993 maybe_frob_rcs_version(modname, version, info.modinfo, 1979 maybe_frob_rcs_version(modname, version, info.modinfo,
1994 version - (char *)info.hdr); 1980 version - (char *)info.hdr);
@@ -2050,7 +2036,7 @@ void buf_write(struct buffer *buf, const char *s, int len)
2050{ 2036{
2051 if (buf->size - buf->pos < len) { 2037 if (buf->size - buf->pos < len) {
2052 buf->size += len + SZ; 2038 buf->size += len + SZ;
2053 buf->p = realloc(buf->p, buf->size); 2039 buf->p = NOFAIL(realloc(buf->p, buf->size));
2054 } 2040 }
2055 strncpy(buf->p + buf->pos, s, len); 2041 strncpy(buf->p + buf->pos, s, len);
2056 buf->pos += len; 2042 buf->pos += len;
@@ -2139,10 +2125,13 @@ static int check_modname_len(struct module *mod)
2139 **/ 2125 **/
2140static void add_header(struct buffer *b, struct module *mod) 2126static void add_header(struct buffer *b, struct module *mod)
2141{ 2127{
2128 buf_printf(b, "#include <linux/build-salt.h>\n");
2142 buf_printf(b, "#include <linux/module.h>\n"); 2129 buf_printf(b, "#include <linux/module.h>\n");
2143 buf_printf(b, "#include <linux/vermagic.h>\n"); 2130 buf_printf(b, "#include <linux/vermagic.h>\n");
2144 buf_printf(b, "#include <linux/compiler.h>\n"); 2131 buf_printf(b, "#include <linux/compiler.h>\n");
2145 buf_printf(b, "\n"); 2132 buf_printf(b, "\n");
2133 buf_printf(b, "BUILD_SALT;\n");
2134 buf_printf(b, "\n");
2146 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); 2135 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
2147 buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); 2136 buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
2148 buf_printf(b, "\n"); 2137 buf_printf(b, "\n");
@@ -2175,9 +2164,7 @@ static void add_retpoline(struct buffer *b)
2175 2164
2176static void add_staging_flag(struct buffer *b, const char *name) 2165static void add_staging_flag(struct buffer *b, const char *name)
2177{ 2166{
2178 static const char *staging_dir = "drivers/staging"; 2167 if (strstarts(name, "drivers/staging"))
2179
2180 if (strncmp(staging_dir, name, strlen(staging_dir)) == 0)
2181 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); 2168 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
2182} 2169}
2183 2170
@@ -2231,7 +2218,7 @@ static int add_versions(struct buffer *b, struct module *mod)
2231 err = 1; 2218 err = 1;
2232 break; 2219 break;
2233 } 2220 }
2234 buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n", 2221 buf_printf(b, "\t{ %#8x, \"%s\" },\n",
2235 s->crc, s->name); 2222 s->crc, s->name);
2236 } 2223 }
2237 2224
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
index 944418da9fe3..0f6dcb4011a8 100644
--- a/scripts/mod/sumversion.c
+++ b/scripts/mod/sumversion.c
@@ -330,14 +330,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
330 goto out; 330 goto out;
331 } 331 }
332 332
333 /* There will be a line like so: 333 /* Sum all files in the same dir or subdirs. */
334 deps_drivers/net/dummy.o := \
335 drivers/net/dummy.c \
336 $(wildcard include/config/net/fastroute.h) \
337 include/linux/module.h \
338
339 Sum all files in the same dir or subdirs.
340 */
341 while ((line = get_next_line(&pos, file, flen)) != NULL) { 334 while ((line = get_next_line(&pos, file, flen)) != NULL) {
342 char* p = line; 335 char* p = line;
343 336
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index 729c547fc9e1..6135574a6f39 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -164,7 +164,7 @@ sub linux_objects
164 s:^\./::; 164 s:^\./::;
165 if (/.*\.o$/ && 165 if (/.*\.o$/ &&
166 ! ( 166 ! (
167 m:/built-in.o$: 167 m:/built-in.a$:
168 || m:arch/x86/vdso/: 168 || m:arch/x86/vdso/:
169 || m:arch/x86/boot/: 169 || m:arch/x86/boot/:
170 || m:arch/ia64/ia32/ia32.o$: 170 || m:arch/ia64/ia32/ia32.o$:
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index 9fbcf5ed0ca7..73503ebce632 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -24,6 +24,7 @@
24# Remove hyphens since they have special meaning in RPM filenames 24# Remove hyphens since they have special meaning in RPM filenames
25KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) 25KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE))
26KDEB_SOURCENAME ?= linux-$(KERNELRELEASE) 26KDEB_SOURCENAME ?= linux-$(KERNELRELEASE)
27KBUILD_PKG_ROOTCMD ?="fakeroot -u"
27export KDEB_SOURCENAME 28export KDEB_SOURCENAME
28# Include only those top-level files that are needed by make, plus the GPL copy 29# Include only those top-level files that are needed by make, plus the GPL copy
29TAR_CONTENT := $(KBUILD_ALLDIRS) .config .scmversion Makefile \ 30TAR_CONTENT := $(KBUILD_ALLDIRS) .config .scmversion Makefile \
@@ -66,35 +67,20 @@ binrpm-pkg: FORCE
66 67
67clean-files += $(objtree)/*.spec 68clean-files += $(objtree)/*.spec
68 69
69# Deb target
70# ---------------------------------------------------------------------------
71quiet_cmd_builddeb = BUILDDEB
72 cmd_builddeb = set -e; \
73 test `id -u` = 0 || \
74 test -n "$(KBUILD_PKG_ROOTCMD)" || { \
75 which fakeroot >/dev/null 2>&1 && \
76 KBUILD_PKG_ROOTCMD="fakeroot -u"; \
77 } || { \
78 echo; \
79 echo "builddeb must be run as root (or using fakeroot)."; \
80 echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \
81 echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \
82 echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \
83 false; \
84 } && \
85 \
86 $$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \
87 $(srctree)/scripts/package/builddeb $@
88
89deb-pkg: FORCE 70deb-pkg: FORCE
90 $(MAKE) clean 71 $(MAKE) clean
72 $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian
91 $(call cmd,src_tar,$(KDEB_SOURCENAME)) 73 $(call cmd,src_tar,$(KDEB_SOURCENAME))
92 $(MAKE) KBUILD_SRC= 74 origversion=$$(dpkg-parsechangelog -SVersion |sed 's/-[^-]*$$//');\
93 +$(call cmd,builddeb) 75 mv $(KDEB_SOURCENAME).tar.gz ../$(KDEB_SOURCENAME)_$${origversion}.orig.tar.gz
76 +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) -i.git -us -uc
94 77
95bindeb-pkg: FORCE 78bindeb-pkg: FORCE
96 $(MAKE) KBUILD_SRC= 79 $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian
97 +$(call cmd,builddeb) 80 +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) -b -nc -uc
81
82intdeb-pkg: FORCE
83 +$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb
98 84
99clean-dirs += $(objtree)/debian/ 85clean-dirs += $(objtree)/debian/
100 86
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 13fabb1f81db..f43a274f4f1d 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -30,67 +30,11 @@ create_package() {
30 chmod -R a+rX "$pdir" 30 chmod -R a+rX "$pdir"
31 31
32 # Create the package 32 # Create the package
33 dpkg-gencontrol $forcearch -Vkernel:debarch="${debarch}" -p$pname -P"$pdir" 33 dpkg-gencontrol -p$pname -P"$pdir"
34 dpkg --build "$pdir" .. 34 dpkg --build "$pdir" ..
35} 35}
36 36
37set_debarch() {
38 # Attempt to find the correct Debian architecture
39 case "$UTS_MACHINE" in
40 i386|ia64|alpha)
41 debarch="$UTS_MACHINE" ;;
42 x86_64)
43 debarch=amd64 ;;
44 sparc*)
45 debarch=sparc ;;
46 s390*)
47 debarch=s390$(grep -q CONFIG_64BIT=y $KCONFIG_CONFIG && echo x || true) ;;
48 ppc*)
49 debarch=$(grep -q CPU_LITTLE_ENDIAN=y $KCONFIG_CONFIG && echo ppc64el || echo powerpc) ;;
50 parisc*)
51 debarch=hppa ;;
52 mips*)
53 debarch=mips$(grep -q CPU_LITTLE_ENDIAN=y $KCONFIG_CONFIG && echo el || true) ;;
54 aarch64|arm64)
55 debarch=arm64 ;;
56 arm*)
57 if grep -q CONFIG_AEABI=y $KCONFIG_CONFIG; then
58 if grep -q CONFIG_VFP=y $KCONFIG_CONFIG; then
59 debarch=armhf
60 else
61 debarch=armel
62 fi
63 else
64 debarch=arm
65 fi
66 ;;
67 *)
68 debarch=$(dpkg --print-architecture)
69 echo "" >&2
70 echo "** ** ** WARNING ** ** **" >&2
71 echo "" >&2
72 echo "Your architecture doesn't have its equivalent" >&2
73 echo "Debian userspace architecture defined!" >&2
74 echo "Falling back to using your current userspace instead!" >&2
75 echo "Please add support for $UTS_MACHINE to ${0} ..." >&2
76 echo "" >&2
77 esac
78 if [ -n "$KBUILD_DEBARCH" ] ; then
79 debarch="$KBUILD_DEBARCH"
80 fi
81 forcearch="-DArchitecture=$debarch"
82
83}
84
85# Some variables and settings used throughout the script
86version=$KERNELRELEASE 37version=$KERNELRELEASE
87revision=$(cat .version)
88if [ -n "$KDEB_PKGVERSION" ]; then
89 packageversion=$KDEB_PKGVERSION
90else
91 packageversion=$version-$revision
92fi
93sourcename=$KDEB_SOURCENAME
94tmpdir="$objtree/debian/tmp" 38tmpdir="$objtree/debian/tmp"
95kernel_headers_dir="$objtree/debian/hdrtmp" 39kernel_headers_dir="$objtree/debian/hdrtmp"
96libc_headers_dir="$objtree/debian/headertmp" 40libc_headers_dir="$objtree/debian/headertmp"
@@ -99,9 +43,6 @@ packagename=linux-image-$version
99kernel_headers_packagename=linux-headers-$version 43kernel_headers_packagename=linux-headers-$version
100libc_headers_packagename=linux-libc-dev 44libc_headers_packagename=linux-libc-dev
101dbg_packagename=$packagename-dbg 45dbg_packagename=$packagename-dbg
102debarch=
103forcearch=
104set_debarch
105 46
106if [ "$ARCH" = "um" ] ; then 47if [ "$ARCH" = "um" ] ; then
107 packagename=user-mode-linux-$version 48 packagename=user-mode-linux-$version
@@ -140,11 +81,11 @@ else
140 cp System.map "$tmpdir/boot/System.map-$version" 81 cp System.map "$tmpdir/boot/System.map-$version"
141 cp $KCONFIG_CONFIG "$tmpdir/boot/config-$version" 82 cp $KCONFIG_CONFIG "$tmpdir/boot/config-$version"
142fi 83fi
143cp "$($MAKE -s image_name)" "$tmpdir/$installed_image_path" 84cp "$($MAKE -s -f $srctree/Makefile image_name)" "$tmpdir/$installed_image_path"
144 85
145if grep -q "^CONFIG_OF=y" $KCONFIG_CONFIG ; then 86if grep -q "^CONFIG_OF_EARLY_FLATTREE=y" $KCONFIG_CONFIG ; then
146 # Only some architectures with OF support have this target 87 # Only some architectures with OF support have this target
147 if grep -q dtbs_install "${srctree}/arch/$SRCARCH/Makefile"; then 88 if [ -d "${srctree}/arch/$SRCARCH/boot/dts" ]; then
148 $MAKE KBUILD_SRC= INSTALL_DTBS_PATH="$tmpdir/usr/lib/$packagename" dtbs_install 89 $MAKE KBUILD_SRC= INSTALL_DTBS_PATH="$tmpdir/usr/lib/$packagename" dtbs_install
149 fi 90 fi
150fi 91fi
@@ -212,105 +153,6 @@ EOF
212 chmod 755 "$tmpdir/DEBIAN/$script" 153 chmod 755 "$tmpdir/DEBIAN/$script"
213done 154done
214 155
215# Try to determine maintainer and email values
216if [ -n "$DEBEMAIL" ]; then
217 email=$DEBEMAIL
218elif [ -n "$EMAIL" ]; then
219 email=$EMAIL
220else
221 email=$(id -nu)@$(hostname -f 2>/dev/null || hostname)
222fi
223if [ -n "$DEBFULLNAME" ]; then
224 name=$DEBFULLNAME
225elif [ -n "$NAME" ]; then
226 name=$NAME
227else
228 name="Anonymous"
229fi
230maintainer="$name <$email>"
231
232# Try to determine distribution
233if [ -n "$KDEB_CHANGELOG_DIST" ]; then
234 distribution=$KDEB_CHANGELOG_DIST
235# In some cases lsb_release returns the codename as n/a, which breaks dpkg-parsechangelog
236elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ] && [ "$distribution" != "n/a" ]; then
237 : # nothing to do in this case
238else
239 distribution="unstable"
240 echo >&2 "Using default distribution of 'unstable' in the changelog"
241 echo >&2 "Install lsb-release or set \$KDEB_CHANGELOG_DIST explicitly"
242fi
243
244# Generate a simple changelog template
245cat <<EOF > debian/changelog
246$sourcename ($packageversion) $distribution; urgency=low
247
248 * Custom built Linux kernel.
249
250 -- $maintainer $(date -R)
251EOF
252
253# Generate copyright file
254cat <<EOF > debian/copyright
255This is a packacked upstream version of the Linux kernel.
256
257The sources may be found at most Linux archive sites, including:
258https://www.kernel.org/pub/linux/kernel
259
260Copyright: 1991 - 2017 Linus Torvalds and others.
261
262The git repository for mainline kernel development is at:
263git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
264
265 This program is free software; you can redistribute it and/or modify
266 it under the terms of the GNU General Public License as published by
267 the Free Software Foundation; version 2 dated June, 1991.
268
269On Debian GNU/Linux systems, the complete text of the GNU General Public
270License version 2 can be found in \`/usr/share/common-licenses/GPL-2'.
271EOF
272
273
274build_depends="bc, kmod, cpio "
275
276# Generate a control file
277cat <<EOF > debian/control
278Source: $sourcename
279Section: kernel
280Priority: optional
281Maintainer: $maintainer
282Build-Depends: $build_depends
283Homepage: http://www.kernel.org/
284EOF
285
286if [ "$ARCH" = "um" ]; then
287 cat <<EOF >> debian/control
288
289Package: $packagename
290Architecture: any
291Description: User Mode Linux kernel, version $version
292 User-mode Linux is a port of the Linux kernel to its own system call
293 interface. It provides a kind of virtual machine, which runs Linux
294 as a user process under another Linux kernel. This is useful for
295 kernel development, sandboxes, jails, experimentation, and
296 many other things.
297 .
298 This package contains the Linux kernel, modules and corresponding other
299 files, version: $version.
300EOF
301
302else
303 cat <<EOF >> debian/control
304
305Package: $packagename
306Architecture: any
307Description: Linux kernel, version $version
308 This package contains the Linux kernel, modules and corresponding other
309 files, version: $version.
310EOF
311
312fi
313
314# Build kernel header package 156# Build kernel header package
315(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles" 157(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
316(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles" 158(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles"
@@ -331,27 +173,6 @@ mkdir -p "$destdir"
331ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" 173ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build"
332rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" 174rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
333 175
334cat <<EOF >> debian/control
335
336Package: $kernel_headers_packagename
337Architecture: any
338Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch}
339 This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch}
340 .
341 This is useful for people who need to build external modules
342EOF
343
344cat <<EOF >> debian/control
345
346Package: $libc_headers_packagename
347Section: devel
348Provides: linux-kernel-headers
349Architecture: any
350Description: Linux support headers for userspace development
351 This package provides userspaces headers from the Linux kernel. These headers
352 are used by the installed headers for GNU glibc and other system libraries.
353EOF
354
355if [ "$ARCH" != "um" ]; then 176if [ "$ARCH" != "um" ]; then
356 create_package "$kernel_headers_packagename" "$kernel_headers_dir" 177 create_package "$kernel_headers_packagename" "$kernel_headers_dir"
357 create_package "$libc_headers_packagename" "$libc_headers_dir" 178 create_package "$libc_headers_packagename" "$libc_headers_dir"
@@ -370,47 +191,7 @@ if [ -n "$BUILD_DEBUG" ] ; then
370 ln -s ../lib/modules/$version/vmlinux $dbg_dir/usr/lib/debug/boot/vmlinux-$version 191 ln -s ../lib/modules/$version/vmlinux $dbg_dir/usr/lib/debug/boot/vmlinux-$version
371 # kdump-tools 192 # kdump-tools
372 ln -s lib/modules/$version/vmlinux $dbg_dir/usr/lib/debug/vmlinux-$version 193 ln -s lib/modules/$version/vmlinux $dbg_dir/usr/lib/debug/vmlinux-$version
373
374 cat <<EOF >> debian/control
375
376Package: $dbg_packagename
377Section: debug
378Architecture: any
379Description: Linux kernel debugging symbols for $version
380 This package will come in handy if you need to debug the kernel. It provides
381 all the necessary debug symbols for the kernel and its modules.
382EOF
383
384 create_package "$dbg_packagename" "$dbg_dir" 194 create_package "$dbg_packagename" "$dbg_dir"
385fi 195fi
386 196
387if [ "x$1" = "xdeb-pkg" ]
388then
389 cat <<EOF > debian/rules
390#!/usr/bin/make -f
391
392build:
393 \$(MAKE)
394
395binary-arch:
396 \$(MAKE) KDEB_SOURCENAME=${sourcename} KDEB_PKGVERSION=${packageversion} bindeb-pkg
397
398clean:
399 rm -rf debian/*tmp debian/files
400 mv debian/ debian.backup # debian/ might be cleaned away
401 \$(MAKE) clean
402 mv debian.backup debian
403
404binary: binary-arch
405EOF
406 mv ${sourcename}.tar.gz ../${sourcename}_${version}.orig.tar.gz
407 tar caf ../${sourcename}_${packageversion}.debian.tar.gz debian/{copyright,rules,changelog,control}
408 dpkg-source -cdebian/control -ldebian/changelog --format="3.0 (custom)" --target-format="3.0 (quilt)" \
409 -b / ../${sourcename}_${version}.orig.tar.gz ../${sourcename}_${packageversion}.debian.tar.gz
410 mv ${sourcename}_${packageversion}*dsc ..
411 dpkg-genchanges -Vkernel:debarch="${debarch}" > ../${sourcename}_${packageversion}_${debarch}.changes
412else
413 dpkg-genchanges -b -Vkernel:debarch="${debarch}" > ../${sourcename}_${packageversion}_${debarch}.changes
414fi
415
416exit 0 197exit 0
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index e8cc72a51b32..d624a07a4e77 100755
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -84,10 +84,6 @@ case "${ARCH}" in
84 [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" 84 [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
85 [ -f "${objtree}/lifimage" ] && cp -v -- "${objtree}/lifimage" "${tmpdir}/boot/lifimage-${KERNELRELEASE}" 85 [ -f "${objtree}/lifimage" ] && cp -v -- "${objtree}/lifimage" "${tmpdir}/boot/lifimage-${KERNELRELEASE}"
86 ;; 86 ;;
87 vax)
88 [ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS"
89 [ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk"
90 ;;
91 mips) 87 mips)
92 if [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.bin" ]; then 88 if [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.bin" ]; then
93 cp -v -- "${objtree}/arch/mips/boot/compressed/vmlinux.bin" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" 89 cp -v -- "${objtree}/arch/mips/boot/compressed/vmlinux.bin" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
@@ -109,6 +105,14 @@ case "${ARCH}" in
109 cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" 105 cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
110 fi 106 fi
111 ;; 107 ;;
108 arm64)
109 for i in Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo ; do
110 if [ -f "${objtree}/arch/arm64/boot/${i}" ] ; then
111 cp -v -- "${objtree}/arch/arm64/boot/${i}" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
112 break
113 fi
114 done
115 ;;
112 *) 116 *)
113 [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}" 117 [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}"
114 echo "" >&2 118 echo "" >&2
diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
new file mode 100755
index 000000000000..edcad61fe3cd
--- /dev/null
+++ b/scripts/package/mkdebian
@@ -0,0 +1,223 @@
1#!/bin/sh
2#
3# Copyright 2003 Wichert Akkerman <wichert@wiggy.net>
4#
5# Simple script to generate a debian/ directory for a Linux kernel.
6
7set -e
8
9is_enabled() {
10 grep -q "^CONFIG_$1=y" $KCONFIG_CONFIG
11}
12
13if_enabled_echo() {
14 if is_enabled "$1"; then
15 echo -n "$2"
16 elif [ $# -ge 3 ]; then
17 echo -n "$3"
18 fi
19}
20
21set_debarch() {
22 if [ -n "$KBUILD_DEBARCH" ] ; then
23 debarch="$KBUILD_DEBARCH"
24 return
25 fi
26
27 # Attempt to find the correct Debian architecture
28 case "$UTS_MACHINE" in
29 i386|ia64|alpha|m68k|riscv*)
30 debarch="$UTS_MACHINE" ;;
31 x86_64)
32 debarch=amd64 ;;
33 sparc*)
34 debarch=sparc$(if_enabled_echo 64BIT 64) ;;
35 s390*)
36 debarch=s390x ;;
37 ppc*)
38 if is_enabled 64BIT; then
39 debarch=ppc64$(if_enabled_echo CPU_LITTLE_ENDIAN el)
40 else
41 debarch=powerpc$(if_enabled_echo SPE spe)
42 fi
43 ;;
44 parisc*)
45 debarch=hppa ;;
46 mips*)
47 if is_enabled CPU_LITTLE_ENDIAN; then
48 debarch=mips$(if_enabled_echo 64BIT 64)$(if_enabled_echo CPU_MIPSR6 r6)el
49 elif is_enabled CPU_MIPSR6; then
50 debarch=mips$(if_enabled_echo 64BIT 64)r6
51 else
52 debarch=mips
53 fi
54 ;;
55 aarch64|arm64)
56 debarch=arm64 ;;
57 arm*)
58 if is_enabled AEABI; then
59 debarch=arm$(if_enabled_echo VFP hf el)
60 else
61 debarch=arm
62 fi
63 ;;
64 openrisc)
65 debarch=or1k ;;
66 sh)
67 if is_enabled CPU_SH3; then
68 debarch=sh3$(if_enabled_echo CPU_BIG_ENDIAN eb)
69 elif is_enabled CPU_SH4; then
70 debarch=sh4$(if_enabled_echo CPU_BIG_ENDIAN eb)
71 fi
72 ;;
73 esac
74 if [ -z "$debarch" ]; then
75 debarch=$(dpkg-architecture -qDEB_HOST_ARCH)
76 echo "" >&2
77 echo "** ** ** WARNING ** ** **" >&2
78 echo "" >&2
79 echo "Your architecture doesn't have its equivalent" >&2
80 echo "Debian userspace architecture defined!" >&2
81 echo "Falling back to the current host architecture ($debarch)." >&2
82 echo "Please add support for $UTS_MACHINE to ${0} ..." >&2
83 echo "" >&2
84 fi
85}
86
87# Some variables and settings used throughout the script
88version=$KERNELRELEASE
89if [ -n "$KDEB_PKGVERSION" ]; then
90 packageversion=$KDEB_PKGVERSION
91 revision=${packageversion##*-}
92else
93 revision=$(cat .version 2>/dev/null||echo 1)
94 packageversion=$version-$revision
95fi
96sourcename=$KDEB_SOURCENAME
97packagename=linux-image-$version
98kernel_headers_packagename=linux-headers-$version
99dbg_packagename=$packagename-dbg
100debarch=
101set_debarch
102
103if [ "$ARCH" = "um" ] ; then
104 packagename=user-mode-linux-$version
105fi
106
107email=${DEBEMAIL-$EMAIL}
108
109# use email string directly if it contains <email>
110if echo $email | grep -q '<.*>'; then
111 maintainer=$email
112else
113 # or construct the maintainer string
114 user=${KBUILD_BUILD_USER-$(id -nu)}
115 name=${DEBFULLNAME-$user}
116 if [ -z "$email" ]; then
117 buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)}
118 email="$user@$buildhost"
119 fi
120 maintainer="$name <$email>"
121fi
122
123# Try to determine distribution
124if [ -n "$KDEB_CHANGELOG_DIST" ]; then
125 distribution=$KDEB_CHANGELOG_DIST
126# In some cases lsb_release returns the codename as n/a, which breaks dpkg-parsechangelog
127elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ] && [ "$distribution" != "n/a" ]; then
128 : # nothing to do in this case
129else
130 distribution="unstable"
131 echo >&2 "Using default distribution of 'unstable' in the changelog"
132 echo >&2 "Install lsb-release or set \$KDEB_CHANGELOG_DIST explicitly"
133fi
134
135mkdir -p debian/
136echo $debarch > debian/arch
137
138# Generate a simple changelog template
139cat <<EOF > debian/changelog
140$sourcename ($packageversion) $distribution; urgency=low
141
142 * Custom built Linux kernel.
143
144 -- $maintainer $(date -R)
145EOF
146
147# Generate copyright file
148cat <<EOF > debian/copyright
149This is a packacked upstream version of the Linux kernel.
150
151The sources may be found at most Linux archive sites, including:
152https://www.kernel.org/pub/linux/kernel
153
154Copyright: 1991 - 2018 Linus Torvalds and others.
155
156The git repository for mainline kernel development is at:
157git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
158
159 This program is free software; you can redistribute it and/or modify
160 it under the terms of the GNU General Public License as published by
161 the Free Software Foundation; version 2 dated June, 1991.
162
163On Debian GNU/Linux systems, the complete text of the GNU General Public
164License version 2 can be found in \`/usr/share/common-licenses/GPL-2'.
165EOF
166
167# Generate a control file
168cat <<EOF > debian/control
169Source: $sourcename
170Section: kernel
171Priority: optional
172Maintainer: $maintainer
173Build-Depends: bc, kmod, cpio
174Homepage: http://www.kernel.org/
175
176Package: $packagename
177Architecture: $debarch
178Description: Linux kernel, version $version
179 This package contains the Linux kernel, modules and corresponding other
180 files, version: $version.
181
182Package: $kernel_headers_packagename
183Architecture: $debarch
184Description: Linux kernel headers for $version on $debarch
185 This package provides kernel header files for $version on $debarch
186 .
187 This is useful for people who need to build external modules
188
189Package: linux-libc-dev
190Section: devel
191Provides: linux-kernel-headers
192Architecture: $debarch
193Description: Linux support headers for userspace development
194 This package provides userspaces headers from the Linux kernel. These headers
195 are used by the installed headers for GNU glibc and other system libraries.
196
197Package: $dbg_packagename
198Section: debug
199Architecture: $debarch
200Description: Linux kernel debugging symbols for $version
201 This package will come in handy if you need to debug the kernel. It provides
202 all the necessary debug symbols for the kernel and its modules.
203EOF
204
205cat <<EOF > debian/rules
206#!$(command -v $MAKE) -f
207
208build:
209 \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} \
210 KBUILD_BUILD_VERSION=${revision} KBUILD_SRC=
211
212binary-arch:
213 \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} \
214 KBUILD_BUILD_VERSION=${revision} KBUILD_SRC= intdeb-pkg
215
216clean:
217 rm -rf debian/*tmp debian/files
218 \$(MAKE) clean
219
220binary: binary-arch
221EOF
222
223exit 0
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 61427c6f2209..009147d4718e 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -12,6 +12,7 @@
12# how we were called determines which rpms we build and how we build them 12# how we were called determines which rpms we build and how we build them
13if [ "$1" = prebuilt ]; then 13if [ "$1" = prebuilt ]; then
14 S=DEL 14 S=DEL
15 MAKE="$MAKE -f $srctree/Makefile"
15else 16else
16 S= 17 S=
17fi 18fi
@@ -78,19 +79,19 @@ $S %prep
78$S %setup -q 79$S %setup -q
79$S 80$S
80$S %build 81$S %build
81$S make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release} 82$S $MAKE %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}
82$S 83$S
83 %install 84 %install
84 mkdir -p %{buildroot}/boot 85 mkdir -p %{buildroot}/boot
85 %ifarch ia64 86 %ifarch ia64
86 mkdir -p %{buildroot}/boot/efi 87 mkdir -p %{buildroot}/boot/efi
87 cp \$(make image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE 88 cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
88 ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ 89 ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/
89 %else 90 %else
90 cp \$(make image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE 91 cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
91 %endif 92 %endif
92$M make %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} KBUILD_SRC= modules_install 93$M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install
93 make %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr KBUILD_SRC= headers_install 94 $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
94 cp System.map %{buildroot}/boot/System.map-$KERNELRELEASE 95 cp System.map %{buildroot}/boot/System.map-$KERNELRELEASE
95 cp .config %{buildroot}/boot/config-$KERNELRELEASE 96 cp .config %{buildroot}/boot/config-$KERNELRELEASE
96 bzip2 -9 --keep vmlinux 97 bzip2 -9 --keep vmlinux
@@ -118,6 +119,8 @@ $S$M ln -sf /usr/src/kernels/$KERNELRELEASE source
118 %preun 119 %preun
119 if [ -x /sbin/new-kernel-pkg ]; then 120 if [ -x /sbin/new-kernel-pkg ]; then
120 new-kernel-pkg --remove $KERNELRELEASE --rminitrd --initrdfile=/boot/initramfs-$KERNELRELEASE.img 121 new-kernel-pkg --remove $KERNELRELEASE --rminitrd --initrdfile=/boot/initramfs-$KERNELRELEASE.img
122 elif [ -x /usr/bin/kernel-install ]; then
123 kernel-install remove $KERNELRELEASE
121 fi 124 fi
122 125
123 %postun 126 %postun
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 16e086dcc567..895c40e8679f 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -33,20 +33,6 @@
33#include <string.h> 33#include <string.h>
34#include <unistd.h> 34#include <unistd.h>
35 35
36/*
37 * glibc synced up and added the metag number but didn't add the relocations.
38 * Work around this in a crude manner for now.
39 */
40#ifndef EM_METAG
41#define EM_METAG 174
42#endif
43#ifndef R_METAG_ADDR32
44#define R_METAG_ADDR32 2
45#endif
46#ifndef R_METAG_NONE
47#define R_METAG_NONE 3
48#endif
49
50#ifndef EM_AARCH64 36#ifndef EM_AARCH64
51#define EM_AARCH64 183 37#define EM_AARCH64 183
52#define R_AARCH64_NONE 0 38#define R_AARCH64_NONE 0
@@ -514,7 +500,7 @@ do_file(char const *const fname)
514 gpfx = 0; 500 gpfx = 0;
515 switch (w2(ehdr->e_machine)) { 501 switch (w2(ehdr->e_machine)) {
516 default: 502 default:
517 fprintf(stderr, "unrecognized e_machine %d %s\n", 503 fprintf(stderr, "unrecognized e_machine %u %s\n",
518 w2(ehdr->e_machine), fname); 504 w2(ehdr->e_machine), fname);
519 fail_file(); 505 fail_file();
520 break; 506 break;
@@ -538,12 +524,6 @@ do_file(char const *const fname)
538 gpfx = '_'; 524 gpfx = '_';
539 break; 525 break;
540 case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; 526 case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
541 case EM_METAG: reltype = R_METAG_ADDR32;
542 altmcount = "_mcount_wrapper";
543 rel_type_nop = R_METAG_NONE;
544 /* We happen to have the same requirement as MIPS */
545 is_fake_mcount32 = MIPS32_is_fake_mcount;
546 break;
547 case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; 527 case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break;
548 case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; 528 case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break;
549 case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; 529 case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break;
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
index b9897e2be404..2e7793735e14 100644
--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -441,7 +441,7 @@ static unsigned find_secsym_ndx(unsigned const txtndx,
441 return symp - sym0; 441 return symp - sym0;
442 } 442 }
443 } 443 }
444 fprintf(stderr, "Cannot find symbol for section %d: %s.\n", 444 fprintf(stderr, "Cannot find symbol for section %u: %s.\n",
445 txtndx, txtname); 445 txtndx, txtname);
446 fail_file(); 446 fail_file();
447} 447}
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 2033af758173..f599031260d5 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -266,13 +266,29 @@ if ($arch eq "x86_64") {
266 $objcopy .= " -O elf32-sh-linux"; 266 $objcopy .= " -O elf32-sh-linux";
267 267
268} elsif ($arch eq "powerpc") { 268} elsif ($arch eq "powerpc") {
269 my $ldemulation;
270
269 $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)"; 271 $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
270 # See comment in the sparc64 section for why we use '\w'. 272 # See comment in the sparc64 section for why we use '\w'.
271 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?\\w*?)>:"; 273 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?\\w*?)>:";
272 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$"; 274 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
273 275
276 if ($endian eq "big") {
277 $cc .= " -mbig-endian ";
278 $ld .= " -EB ";
279 $ldemulation = "ppc"
280 } else {
281 $cc .= " -mlittle-endian ";
282 $ld .= " -EL ";
283 $ldemulation = "lppc"
284 }
274 if ($bits == 64) { 285 if ($bits == 64) {
275 $type = ".quad"; 286 $type = ".quad";
287 $cc .= " -m64 ";
288 $ld .= " -m elf64".$ldemulation." ";
289 } else {
290 $cc .= " -m32 ";
291 $ld .= " -m elf32".$ldemulation." ";
276 } 292 }
277 293
278} elsif ($arch eq "arm") { 294} elsif ($arch eq "arm") {
@@ -368,14 +384,14 @@ if ($arch eq "x86_64") {
368} elsif ($arch eq "microblaze") { 384} elsif ($arch eq "microblaze") {
369 # Microblaze calls '_mcount' instead of plain 'mcount'. 385 # Microblaze calls '_mcount' instead of plain 'mcount'.
370 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; 386 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
371} elsif ($arch eq "blackfin") { 387} elsif ($arch eq "riscv") {
372 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; 388 $function_regex = "^([0-9a-fA-F]+)\\s+<([^.0-9][0-9a-zA-Z_\\.]+)>:";
373 $mcount_adjust = -4; 389 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL\\s_mcount\$";
374} elsif ($arch eq "tilegx" || $arch eq "tile") {
375 # Default to the newer TILE-Gx architecture if only "tile" is given.
376 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
377 $type = ".quad"; 390 $type = ".quad";
378 $alignment = 8; 391 $alignment = 2;
392} elsif ($arch eq "nds32") {
393 $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$";
394 $alignment = 2;
379} else { 395} else {
380 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; 396 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
381} 397}
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index ffe8179f5d41..073fe7537f6c 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -124,7 +124,6 @@ int main(int argc, char *argv[])
124 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); 124 fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
125 fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); 125 fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
126 fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); 126 fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
127 fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n");
128 127
129 fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); 128 fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
130 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); 129 fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py
new file mode 100755
index 000000000000..839e190bbd7a
--- /dev/null
+++ b/scripts/spdxcheck.py
@@ -0,0 +1,285 @@
1#!/usr/bin/env python
2# SPDX-License-Identifier: GPL-2.0
3# Copyright Thomas Gleixner <tglx@linutronix.de>
4
5from argparse import ArgumentParser
6from ply import lex, yacc
7import locale
8import traceback
9import sys
10import git
11import re
12import os
13
14class ParserException(Exception):
15 def __init__(self, tok, txt):
16 self.tok = tok
17 self.txt = txt
18
19class SPDXException(Exception):
20 def __init__(self, el, txt):
21 self.el = el
22 self.txt = txt
23
24class SPDXdata(object):
25 def __init__(self):
26 self.license_files = 0
27 self.exception_files = 0
28 self.licenses = [ ]
29 self.exceptions = { }
30
31# Read the spdx data from the LICENSES directory
32def read_spdxdata(repo):
33
34 # The subdirectories of LICENSES in the kernel source
35 license_dirs = [ "preferred", "other", "exceptions" ]
36 lictree = repo.head.commit.tree['LICENSES']
37
38 spdx = SPDXdata()
39
40 for d in license_dirs:
41 for el in lictree[d].traverse():
42 if not os.path.isfile(el.path):
43 continue
44
45 exception = None
46 for l in open(el.path).readlines():
47 if l.startswith('Valid-License-Identifier:'):
48 lid = l.split(':')[1].strip().upper()
49 if lid in spdx.licenses:
50 raise SPDXException(el, 'Duplicate License Identifier: %s' %lid)
51 else:
52 spdx.licenses.append(lid)
53
54 elif l.startswith('SPDX-Exception-Identifier:'):
55 exception = l.split(':')[1].strip().upper()
56 spdx.exceptions[exception] = []
57
58 elif l.startswith('SPDX-Licenses:'):
59 for lic in l.split(':')[1].upper().strip().replace(' ', '').replace('\t', '').split(','):
60 if not lic in spdx.licenses:
61 raise SPDXException(None, 'Exception %s missing license %s' %(ex, lic))
62 spdx.exceptions[exception].append(lic)
63
64 elif l.startswith("License-Text:"):
65 if exception:
66 if not len(spdx.exceptions[exception]):
67 raise SPDXException(el, 'Exception %s is missing SPDX-Licenses' %excid)
68 spdx.exception_files += 1
69 else:
70 spdx.license_files += 1
71 break
72 return spdx
73
74class id_parser(object):
75
76 reserved = [ 'AND', 'OR', 'WITH' ]
77 tokens = [ 'LPAR', 'RPAR', 'ID', 'EXC' ] + reserved
78
79 precedence = ( ('nonassoc', 'AND', 'OR'), )
80
81 t_ignore = ' \t'
82
83 def __init__(self, spdx):
84 self.spdx = spdx
85 self.lasttok = None
86 self.lastid = None
87 self.lexer = lex.lex(module = self, reflags = re.UNICODE)
88 # Initialize the parser. No debug file and no parser rules stored on disk
89 # The rules are small enough to be generated on the fly
90 self.parser = yacc.yacc(module = self, write_tables = False, debug = False)
91 self.lines_checked = 0
92 self.checked = 0
93 self.spdx_valid = 0
94 self.spdx_errors = 0
95 self.curline = 0
96 self.deepest = 0
97
98 # Validate License and Exception IDs
99 def validate(self, tok):
100 id = tok.value.upper()
101 if tok.type == 'ID':
102 if not id in self.spdx.licenses:
103 raise ParserException(tok, 'Invalid License ID')
104 self.lastid = id
105 elif tok.type == 'EXC':
106 if id not in self.spdx.exceptions:
107 raise ParserException(tok, 'Invalid Exception ID')
108 if self.lastid not in self.spdx.exceptions[id]:
109 raise ParserException(tok, 'Exception not valid for license %s' %self.lastid)
110 self.lastid = None
111 elif tok.type != 'WITH':
112 self.lastid = None
113
114 # Lexer functions
115 def t_RPAR(self, tok):
116 r'\)'
117 self.lasttok = tok.type
118 return tok
119
120 def t_LPAR(self, tok):
121 r'\('
122 self.lasttok = tok.type
123 return tok
124
125 def t_ID(self, tok):
126 r'[A-Za-z.0-9\-+]+'
127
128 if self.lasttok == 'EXC':
129 print(tok)
130 raise ParserException(tok, 'Missing parentheses')
131
132 tok.value = tok.value.strip()
133 val = tok.value.upper()
134
135 if val in self.reserved:
136 tok.type = val
137 elif self.lasttok == 'WITH':
138 tok.type = 'EXC'
139
140 self.lasttok = tok.type
141 self.validate(tok)
142 return tok
143
144 def t_error(self, tok):
145 raise ParserException(tok, 'Invalid token')
146
147 def p_expr(self, p):
148 '''expr : ID
149 | ID WITH EXC
150 | expr AND expr
151 | expr OR expr
152 | LPAR expr RPAR'''
153 pass
154
155 def p_error(self, p):
156 if not p:
157 raise ParserException(None, 'Unfinished license expression')
158 else:
159 raise ParserException(p, 'Syntax error')
160
161 def parse(self, expr):
162 self.lasttok = None
163 self.lastid = None
164 self.parser.parse(expr, lexer = self.lexer)
165
166 def parse_lines(self, fd, maxlines, fname):
167 self.checked += 1
168 self.curline = 0
169 try:
170 for line in fd:
171 line = line.decode(locale.getpreferredencoding(False), errors='ignore')
172 self.curline += 1
173 if self.curline > maxlines:
174 break
175 self.lines_checked += 1
176 if line.find("SPDX-License-Identifier:") < 0:
177 continue
178 expr = line.split(':')[1].replace('*/', '').strip()
179 self.parse(expr)
180 self.spdx_valid += 1
181 #
182 # Should we check for more SPDX ids in the same file and
183 # complain if there are any?
184 #
185 break
186
187 except ParserException as pe:
188 if pe.tok:
189 col = line.find(expr) + pe.tok.lexpos
190 tok = pe.tok.value
191 sys.stdout.write('%s: %d:%d %s: %s\n' %(fname, self.curline, col, pe.txt, tok))
192 else:
193 sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, col, pe.txt))
194 self.spdx_errors += 1
195
196def scan_git_tree(tree):
197 for el in tree.traverse():
198 # Exclude stuff which would make pointless noise
199 # FIXME: Put this somewhere more sensible
200 if el.path.startswith("LICENSES"):
201 continue
202 if el.path.find("license-rules.rst") >= 0:
203 continue
204 if not os.path.isfile(el.path):
205 continue
206 with open(el.path, 'rb') as fd:
207 parser.parse_lines(fd, args.maxlines, el.path)
208
209def scan_git_subtree(tree, path):
210 for p in path.strip('/').split('/'):
211 tree = tree[p]
212 scan_git_tree(tree)
213
214if __name__ == '__main__':
215
216 ap = ArgumentParser(description='SPDX expression checker')
217 ap.add_argument('path', nargs='*', help='Check path or file. If not given full git tree scan. For stdin use "-"')
218 ap.add_argument('-m', '--maxlines', type=int, default=15,
219 help='Maximum number of lines to scan in a file. Default 15')
220 ap.add_argument('-v', '--verbose', action='store_true', help='Verbose statistics output')
221 args = ap.parse_args()
222
223 # Sanity check path arguments
224 if '-' in args.path and len(args.path) > 1:
225 sys.stderr.write('stdin input "-" must be the only path argument\n')
226 sys.exit(1)
227
228 try:
229 # Use git to get the valid license expressions
230 repo = git.Repo(os.getcwd())
231 assert not repo.bare
232
233 # Initialize SPDX data
234 spdx = read_spdxdata(repo)
235
236 # Initilize the parser
237 parser = id_parser(spdx)
238
239 except SPDXException as se:
240 if se.el:
241 sys.stderr.write('%s: %s\n' %(se.el.path, se.txt))
242 else:
243 sys.stderr.write('%s\n' %se.txt)
244 sys.exit(1)
245
246 except Exception as ex:
247 sys.stderr.write('FAIL: %s\n' %ex)
248 sys.stderr.write('%s\n' %traceback.format_exc())
249 sys.exit(1)
250
251 try:
252 if len(args.path) and args.path[0] == '-':
253 parser.parse_lines(sys.stdin, args.maxlines, '-')
254 else:
255 if args.path:
256 for p in args.path:
257 if os.path.isfile(p):
258 parser.parse_lines(open(p), args.maxlines, p)
259 elif os.path.isdir(p):
260 scan_git_subtree(repo.head.reference.commit.tree, p)
261 else:
262 sys.stderr.write('path %s does not exist\n' %p)
263 sys.exit(1)
264 else:
265 # Full git tree scan
266 scan_git_tree(repo.head.commit.tree)
267
268 if args.verbose:
269 sys.stderr.write('\n')
270 sys.stderr.write('License files: %12d\n' %spdx.license_files)
271 sys.stderr.write('Exception files: %12d\n' %spdx.exception_files)
272 sys.stderr.write('License IDs %12d\n' %len(spdx.licenses))
273 sys.stderr.write('Exception IDs %12d\n' %len(spdx.exceptions))
274 sys.stderr.write('\n')
275 sys.stderr.write('Files checked: %12d\n' %parser.checked)
276 sys.stderr.write('Lines checked: %12d\n' %parser.lines_checked)
277 sys.stderr.write('Files with SPDX: %12d\n' %parser.spdx_valid)
278 sys.stderr.write('Files with errors: %12d\n' %parser.spdx_errors)
279
280 sys.exit(0)
281
282 except Exception as ex:
283 sys.stderr.write('FAIL: %s\n' %ex)
284 sys.stderr.write('%s\n' %traceback.format_exc())
285 sys.exit(1)
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
index 9a058cff49d4..517d0c3f83df 100644
--- a/scripts/spelling.txt
+++ b/scripts/spelling.txt
@@ -10,6 +10,8 @@
10abandonning||abandoning 10abandonning||abandoning
11abigious||ambiguous 11abigious||ambiguous
12abitrate||arbitrate 12abitrate||arbitrate
13abord||abort
14aboslute||absolute
13abov||above 15abov||above
14abreviated||abbreviated 16abreviated||abbreviated
15absense||absence 17absense||absence
@@ -25,6 +27,7 @@ accessable||accessible
25accesss||access 27accesss||access
26accidentaly||accidentally 28accidentaly||accidentally
27accidentually||accidentally 29accidentually||accidentally
30acclerated||accelerated
28accoding||according 31accoding||according
29accomodate||accommodate 32accomodate||accommodate
30accomodates||accommodates 33accomodates||accommodates
@@ -58,12 +61,15 @@ addres||address
58adddress||address 61adddress||address
59addreses||addresses 62addreses||addresses
60addresss||address 63addresss||address
64addrress||address
61aditional||additional 65aditional||additional
62aditionally||additionally 66aditionally||additionally
63aditionaly||additionally 67aditionaly||additionally
64adminstrative||administrative 68adminstrative||administrative
65adress||address 69adress||address
66adresses||addresses 70adresses||addresses
71adrresses||addresses
72advertisment||advertisement
67adviced||advised 73adviced||advised
68afecting||affecting 74afecting||affecting
69againt||against 75againt||against
@@ -100,6 +106,7 @@ alue||value
100ambigious||ambiguous 106ambigious||ambiguous
101amoung||among 107amoung||among
102amout||amount 108amout||amount
109amplifer||amplifier
103an union||a union 110an union||a union
104an user||a user 111an user||a user
105an userspace||a userspace 112an userspace||a userspace
@@ -145,11 +152,15 @@ assistent||assistant
145assocation||association 152assocation||association
146associcated||associated 153associcated||associated
147assotiated||associated 154assotiated||associated
155asssert||assert
148assum||assume 156assum||assume
149assumtpion||assumption 157assumtpion||assumption
150asuming||assuming 158asuming||assuming
151asycronous||asynchronous 159asycronous||asynchronous
152asynchnous||asynchronous 160asynchnous||asynchronous
161asynchromous||asynchronous
162asymetric||asymmetric
163asymmeric||asymmetric
153atomatically||automatically 164atomatically||automatically
154atomicly||atomically 165atomicly||atomically
155atempt||attempt 166atempt||attempt
@@ -172,6 +183,7 @@ avaible||available
172availabe||available 183availabe||available
173availabled||available 184availabled||available
174availablity||availability 185availablity||availability
186availaible||available
175availale||available 187availale||available
176availavility||availability 188availavility||availability
177availble||available 189availble||available
@@ -206,8 +218,11 @@ borad||board
206boundry||boundary 218boundry||boundary
207brievely||briefly 219brievely||briefly
208broadcat||broadcast 220broadcat||broadcast
221bufufer||buffer
209cacluated||calculated 222cacluated||calculated
223caculate||calculate
210caculation||calculation 224caculation||calculation
225cadidate||candidate
211calender||calendar 226calender||calendar
212calescing||coalescing 227calescing||coalescing
213calle||called 228calle||called
@@ -221,12 +236,14 @@ capabilty||capability
221capabitilies||capabilities 236capabitilies||capabilities
222capatibilities||capabilities 237capatibilities||capabilities
223capapbilities||capabilities 238capapbilities||capabilities
239caputure||capture
224carefuly||carefully 240carefuly||carefully
225cariage||carriage 241cariage||carriage
226catagory||category 242catagory||category
227cehck||check 243cehck||check
228challange||challenge 244challange||challenge
229challanges||challenges 245challanges||challenges
246chache||cache
230chanell||channel 247chanell||channel
231changable||changeable 248changable||changeable
232chanined||chained 249chanined||chained
@@ -240,6 +257,7 @@ charaters||characters
240charcter||character 257charcter||character
241chcek||check 258chcek||check
242chck||check 259chck||check
260checksumed||checksummed
243checksuming||checksumming 261checksuming||checksumming
244childern||children 262childern||children
245childs||children 263childs||children
@@ -292,8 +310,10 @@ comunication||communication
292conbination||combination 310conbination||combination
293conditionaly||conditionally 311conditionaly||conditionally
294conected||connected 312conected||connected
313conector||connector
295connecetd||connected 314connecetd||connected
296configuartion||configuration 315configuartion||configuration
316configuation||configuration
297configuratoin||configuration 317configuratoin||configuration
298configuraton||configuration 318configuraton||configuration
299configuretion||configuration 319configuretion||configuration
@@ -315,6 +335,7 @@ continous||continuous
315continously||continuously 335continously||continuously
316continueing||continuing 336continueing||continuing
317contraints||constraints 337contraints||constraints
338contruct||construct
318contol||control 339contol||control
319contoller||controller 340contoller||controller
320controled||controlled 341controled||controlled
@@ -343,6 +364,7 @@ dafault||default
343deafult||default 364deafult||default
344deamon||daemon 365deamon||daemon
345decompres||decompress 366decompres||decompress
367decsribed||described
346decription||description 368decription||description
347dectected||detected 369dectected||detected
348defailt||default 370defailt||default
@@ -379,6 +401,7 @@ desctiptor||descriptor
379desriptor||descriptor 401desriptor||descriptor
380desriptors||descriptors 402desriptors||descriptors
381destionation||destination 403destionation||destination
404destoried||destroyed
382destory||destroy 405destory||destroy
383destoryed||destroyed 406destoryed||destroyed
384destorys||destroys 407destorys||destroys
@@ -400,22 +423,30 @@ didnt||didn't
400diferent||different 423diferent||different
401differrence||difference 424differrence||difference
402diffrent||different 425diffrent||different
426differenciate||differentiate
403diffrentiate||differentiate 427diffrentiate||differentiate
404difinition||definition 428difinition||definition
405dimesions||dimensions 429dimesions||dimensions
406diplay||display 430diplay||display
431directon||direction
407direectly||directly 432direectly||directly
433diregard||disregard
408disassocation||disassociation 434disassocation||disassociation
409disapear||disappear 435disapear||disappear
410disapeared||disappeared 436disapeared||disappeared
411disappared||disappeared 437disappared||disappeared
438disbale||disable
439disbaled||disabled
412disble||disable 440disble||disable
413disbled||disabled 441disbled||disabled
414disconnet||disconnect 442disconnet||disconnect
415discontinous||discontinuous 443discontinous||discontinuous
444disharge||discharge
416dispertion||dispersion 445dispertion||dispersion
417dissapears||disappears 446dissapears||disappears
418distiction||distinction 447distiction||distinction
448divisable||divisible
449divsiors||divisors
419docuentation||documentation 450docuentation||documentation
420documantation||documentation 451documantation||documentation
421documentaion||documentation 452documentaion||documentation
@@ -427,6 +458,7 @@ downlad||download
427downlads||downloads 458downlads||downloads
428druing||during 459druing||during
429dynmaic||dynamic 460dynmaic||dynamic
461eanable||enable
430easilly||easily 462easilly||easily
431ecspecially||especially 463ecspecially||especially
432edditable||editable 464edditable||editable
@@ -484,9 +516,12 @@ exprimental||experimental
484extened||extended 516extened||extended
485extensability||extensibility 517extensability||extensibility
486extention||extension 518extention||extension
519extenstion||extension
487extracter||extractor 520extracter||extractor
521faield||failed
488falied||failed 522falied||failed
489faild||failed 523faild||failed
524failer||failure
490faill||fail 525faill||fail
491failied||failed 526failied||failed
492faillure||failure 527faillure||failure
@@ -520,6 +555,7 @@ forseeable||foreseeable
520forse||force 555forse||force
521fortan||fortran 556fortan||fortran
522forwardig||forwarding 557forwardig||forwarding
558frambuffer||framebuffer
523framming||framing 559framming||framing
524framwork||framework 560framwork||framework
525frequncy||frequency 561frequncy||frequency
@@ -527,6 +563,7 @@ frome||from
527fucntion||function 563fucntion||function
528fuction||function 564fuction||function
529fuctions||functions 565fuctions||functions
566funcation||function
530funcion||function 567funcion||function
531functionallity||functionality 568functionallity||functionality
532functionaly||functionally 569functionaly||functionally
@@ -540,6 +577,7 @@ futrue||future
540gaurenteed||guaranteed 577gaurenteed||guaranteed
541generiously||generously 578generiously||generously
542genereate||generate 579genereate||generate
580genereted||generated
543genric||generic 581genric||generic
544globel||global 582globel||global
545grabing||grabbing 583grabing||grabbing
@@ -553,6 +591,7 @@ guarentee||guarantee
553halfs||halves 591halfs||halves
554hander||handler 592hander||handler
555handfull||handful 593handfull||handful
594hanlde||handle
556hanled||handled 595hanled||handled
557happend||happened 596happend||happened
558harware||hardware 597harware||hardware
@@ -561,6 +600,7 @@ helpfull||helpful
561hybernate||hibernate 600hybernate||hibernate
562hierachy||hierarchy 601hierachy||hierarchy
563hierarchie||hierarchy 602hierarchie||hierarchy
603homogenous||homogeneous
564howver||however 604howver||however
565hsould||should 605hsould||should
566hypervior||hypervisor 606hypervior||hypervisor
@@ -568,6 +608,8 @@ hypter||hyper
568identidier||identifier 608identidier||identifier
569iligal||illegal 609iligal||illegal
570illigal||illegal 610illigal||illegal
611illgal||illegal
612iomaped||iomapped
571imblance||imbalance 613imblance||imbalance
572immeadiately||immediately 614immeadiately||immediately
573immedaite||immediate 615immedaite||immediate
@@ -618,12 +660,15 @@ initation||initiation
618initators||initiators 660initators||initiators
619initialiazation||initialization 661initialiazation||initialization
620initializiation||initialization 662initializiation||initialization
663initialze||initialize
621initialzed||initialized 664initialzed||initialized
622initilization||initialization 665initilization||initialization
623initilize||initialize 666initilize||initialize
624inofficial||unofficial 667inofficial||unofficial
668inrerface||interface
625insititute||institute 669insititute||institute
626instal||install 670instal||install
671instanciate||instantiate
627instanciated||instantiated 672instanciated||instantiated
628inteface||interface 673inteface||interface
629integreated||integrated 674integreated||integrated
@@ -657,6 +702,7 @@ intregral||integral
657intrrupt||interrupt 702intrrupt||interrupt
658intterrupt||interrupt 703intterrupt||interrupt
659intuative||intuitive 704intuative||intuitive
705inavlid||invalid
660invaid||invalid 706invaid||invalid
661invald||invalid 707invald||invalid
662invalde||invalid 708invalde||invalid
@@ -683,6 +729,7 @@ langauge||language
683langugage||language 729langugage||language
684lauch||launch 730lauch||launch
685layed||laid 731layed||laid
732legnth||length
686leightweight||lightweight 733leightweight||lightweight
687lengh||length 734lengh||length
688lenght||length 735lenght||length
@@ -696,6 +743,7 @@ licenceing||licencing
696loggging||logging 743loggging||logging
697loggin||login 744loggin||login
698logile||logfile 745logile||logfile
746loobpack||loopback
699loosing||losing 747loosing||losing
700losted||lost 748losted||lost
701machinary||machinery 749machinary||machinery
@@ -703,6 +751,7 @@ maintainance||maintenance
703maintainence||maintenance 751maintainence||maintenance
704maintan||maintain 752maintan||maintain
705makeing||making 753makeing||making
754mailformed||malformed
706malplaced||misplaced 755malplaced||misplaced
707malplace||misplace 756malplace||misplace
708managable||manageable 757managable||manageable
@@ -710,6 +759,7 @@ managment||management
710mangement||management 759mangement||management
711manoeuvering||maneuvering 760manoeuvering||maneuvering
712mappping||mapping 761mappping||mapping
762matchs||matches
713mathimatical||mathematical 763mathimatical||mathematical
714mathimatic||mathematic 764mathimatic||mathematic
715mathimatics||mathematics 765mathimatics||mathematics
@@ -725,6 +775,7 @@ messsage||message
725messsages||messages 775messsages||messages
726micropone||microphone 776micropone||microphone
727microprocesspr||microprocessor 777microprocesspr||microprocessor
778migrateable||migratable
728milliseonds||milliseconds 779milliseonds||milliseconds
729minium||minimum 780minium||minimum
730minimam||minimum 781minimam||minimum
@@ -741,6 +792,7 @@ missmatch||mismatch
741miximum||maximum 792miximum||maximum
742mmnemonic||mnemonic 793mmnemonic||mnemonic
743mnay||many 794mnay||many
795modfiy||modify
744modulues||modules 796modulues||modules
745momery||memory 797momery||memory
746memomry||memory 798memomry||memory
@@ -777,6 +829,7 @@ notifed||notified
777numebr||number 829numebr||number
778numner||number 830numner||number
779obtaion||obtain 831obtaion||obtain
832obusing||abusing
780occassionally||occasionally 833occassionally||occasionally
781occationally||occasionally 834occationally||occasionally
782occurance||occurrence 835occurance||occurrence
@@ -787,6 +840,7 @@ occure||occurred
787occured||occurred 840occured||occurred
788occuring||occurring 841occuring||occurring
789offet||offset 842offet||offset
843offloded||offloaded
790omited||omitted 844omited||omitted
791omiting||omitting 845omiting||omitting
792omitt||omit 846omitt||omit
@@ -829,6 +883,7 @@ parametes||parameters
829parametised||parametrised 883parametised||parametrised
830paramter||parameter 884paramter||parameter
831paramters||parameters 885paramters||parameters
886parmaters||parameters
832particuarly||particularly 887particuarly||particularly
833particularily||particularly 888particularily||particularly
834partiton||partition 889partiton||partition
@@ -837,6 +892,7 @@ passin||passing
837pathes||paths 892pathes||paths
838pecularities||peculiarities 893pecularities||peculiarities
839peformance||performance 894peformance||performance
895peforming||performing
840peice||piece 896peice||piece
841pendantic||pedantic 897pendantic||pedantic
842peprocessor||preprocessor 898peprocessor||preprocessor
@@ -846,6 +902,7 @@ peroid||period
846persistance||persistence 902persistance||persistence
847persistant||persistent 903persistant||persistent
848plalform||platform 904plalform||platform
905platfoem||platform
849platfrom||platform 906platfrom||platform
850plattform||platform 907plattform||platform
851pleaes||please 908pleaes||please
@@ -858,6 +915,7 @@ posible||possible
858positon||position 915positon||position
859possibilites||possibilities 916possibilites||possibilities
860powerfull||powerful 917powerfull||powerful
918preamle||preamble
861preample||preamble 919preample||preamble
862preapre||prepare 920preapre||prepare
863preceeded||preceded 921preceeded||preceded
@@ -870,6 +928,7 @@ prefered||preferred
870prefferably||preferably 928prefferably||preferably
871premption||preemption 929premption||preemption
872prepaired||prepared 930prepaired||prepared
931preperation||preparation
873pressre||pressure 932pressre||pressure
874primative||primitive 933primative||primitive
875princliple||principle 934princliple||principle
@@ -935,6 +994,7 @@ recommanded||recommended
935recyle||recycle 994recyle||recycle
936redircet||redirect 995redircet||redirect
937redirectrion||redirection 996redirectrion||redirection
997redundacy||redundancy
938reename||rename 998reename||rename
939refcounf||refcount 999refcounf||refcount
940refence||reference 1000refence||reference
@@ -945,6 +1005,7 @@ refernces||references
945refernnce||reference 1005refernnce||reference
946refrence||reference 1006refrence||reference
947registerd||registered 1007registerd||registered
1008registeration||registration
948registeresd||registered 1009registeresd||registered
949registerred||registered 1010registerred||registered
950registes||registers 1011registes||registers
@@ -973,7 +1034,9 @@ requirment||requirement
973requred||required 1034requred||required
974requried||required 1035requried||required
975requst||request 1036requst||request
1037reregisteration||reregistration
976reseting||resetting 1038reseting||resetting
1039reseverd||reserved
977resizeable||resizable 1040resizeable||resizable
978resouce||resource 1041resouce||resource
979resouces||resources 1042resouces||resources
@@ -982,6 +1045,7 @@ responce||response
982ressizes||resizes 1045ressizes||resizes
983ressource||resource 1046ressource||resource
984ressources||resources 1047ressources||resources
1048restesting||retesting
985retransmited||retransmitted 1049retransmited||retransmitted
986retreived||retrieved 1050retreived||retrieved
987retreive||retrieve 1051retreive||retrieve
@@ -1006,6 +1070,7 @@ sacrifying||sacrificing
1006safly||safely 1070safly||safely
1007safty||safety 1071safty||safety
1008savable||saveable 1072savable||saveable
1073scaleing||scaling
1009scaned||scanned 1074scaned||scanned
1010scaning||scanning 1075scaning||scanning
1011scarch||search 1076scarch||search
@@ -1014,6 +1079,8 @@ searchs||searches
1014secquence||sequence 1079secquence||sequence
1015secund||second 1080secund||second
1016segement||segment 1081segement||segment
1082semaphone||semaphore
1083senario||scenario
1017senarios||scenarios 1084senarios||scenarios
1018sentivite||sensitive 1085sentivite||sensitive
1019separatly||separately 1086separatly||separately
@@ -1025,9 +1092,13 @@ seperate||separate
1025seperatly||separately 1092seperatly||separately
1026seperator||separator 1093seperator||separator
1027sepperate||separate 1094sepperate||separate
1095seqeunce||sequence
1096seqeuncer||sequencer
1097seqeuencer||sequencer
1028sequece||sequence 1098sequece||sequence
1029sequencial||sequential 1099sequencial||sequential
1030serveral||several 1100serveral||several
1101servive||service
1031setts||sets 1102setts||sets
1032settting||setting 1103settting||setting
1033shotdown||shutdown 1104shotdown||shutdown
@@ -1073,6 +1144,7 @@ standartization||standardization
1073standart||standard 1144standart||standard
1074staticly||statically 1145staticly||statically
1075stoped||stopped 1146stoped||stopped
1147stoping||stopping
1076stoppped||stopped 1148stoppped||stopped
1077straming||streaming 1149straming||streaming
1078struc||struct 1150struc||struct
@@ -1085,6 +1157,7 @@ subdirectoires||subdirectories
1085suble||subtle 1157suble||subtle
1086substract||subtract 1158substract||subtract
1087submition||submission 1159submition||submission
1160suceed||succeed
1088succesfully||successfully 1161succesfully||successfully
1089succesful||successful 1162succesful||successful
1090successed||succeeded 1163successed||succeeded
@@ -1108,6 +1181,7 @@ surpressed||suppressed
1108surpresses||suppresses 1181surpresses||suppresses
1109susbsystem||subsystem 1182susbsystem||subsystem
1110suspeneded||suspended 1183suspeneded||suspended
1184suspsend||suspend
1111suspicously||suspiciously 1185suspicously||suspiciously
1112swaping||swapping 1186swaping||swapping
1113switchs||switches 1187switchs||switches
@@ -1122,6 +1196,7 @@ swtich||switch
1122symetric||symmetric 1196symetric||symmetric
1123synax||syntax 1197synax||syntax
1124synchonized||synchronized 1198synchonized||synchronized
1199synchronuously||synchronously
1125syncronize||synchronize 1200syncronize||synchronize
1126syncronized||synchronized 1201syncronized||synchronized
1127syncronizing||synchronizing 1202syncronizing||synchronizing
@@ -1130,11 +1205,14 @@ syste||system
1130sytem||system 1205sytem||system
1131sythesis||synthesis 1206sythesis||synthesis
1132taht||that 1207taht||that
1208tansmit||transmit
1133targetted||targeted 1209targetted||targeted
1134targetting||targeting 1210targetting||targeting
1211taskelt||tasklet
1135teh||the 1212teh||the
1136temorary||temporary 1213temorary||temporary
1137temproarily||temporarily 1214temproarily||temporarily
1215thead||thread
1138therfore||therefore 1216therfore||therefore
1139thier||their 1217thier||their
1140threds||threads 1218threds||threads
@@ -1143,11 +1221,14 @@ thresold||threshold
1143throught||through 1221throught||through
1144troughput||throughput 1222troughput||throughput
1145thses||these 1223thses||these
1224tiggers||triggers
1146tiggered||triggered 1225tiggered||triggered
1147tipically||typically 1226tipically||typically
1227timeing||timing
1148timout||timeout 1228timout||timeout
1149tmis||this 1229tmis||this
1150torerable||tolerable 1230torerable||tolerable
1231traking||tracking
1151tramsmitted||transmitted 1232tramsmitted||transmitted
1152tramsmit||transmit 1233tramsmit||transmit
1153tranasction||transaction 1234tranasction||transaction
@@ -1162,6 +1243,7 @@ transormed||transformed
1162trasfer||transfer 1243trasfer||transfer
1163trasmission||transmission 1244trasmission||transmission
1164treshold||threshold 1245treshold||threshold
1246trigerred||triggered
1165trigerring||triggering 1247trigerring||triggering
1166trun||turn 1248trun||turn
1167tunning||tuning 1249tunning||tuning
@@ -1169,6 +1251,8 @@ ture||true
1169tyep||type 1251tyep||type
1170udpate||update 1252udpate||update
1171uesd||used 1253uesd||used
1254uknown||unknown
1255usupported||unsupported
1172uncommited||uncommitted 1256uncommited||uncommitted
1173unconditionaly||unconditionally 1257unconditionaly||unconditionally
1174underun||underrun 1258underun||underrun
@@ -1181,11 +1265,14 @@ unexpeted||unexpected
1181unexpexted||unexpected 1265unexpexted||unexpected
1182unfortunatelly||unfortunately 1266unfortunatelly||unfortunately
1183unifiy||unify 1267unifiy||unify
1268uniterrupted||uninterrupted
1184unintialized||uninitialized 1269unintialized||uninitialized
1185unkmown||unknown 1270unkmown||unknown
1186unknonw||unknown 1271unknonw||unknown
1187unknow||unknown 1272unknow||unknown
1188unkown||unknown 1273unkown||unknown
1274unamed||unnamed
1275uneeded||unneeded
1189unneded||unneeded 1276unneded||unneeded
1190unneccecary||unnecessary 1277unneccecary||unnecessary
1191unneccesary||unnecessary 1278unneccesary||unnecessary
@@ -1210,6 +1297,7 @@ usefull||useful
1210usege||usage 1297usege||usage
1211usera||users 1298usera||users
1212usualy||usually 1299usualy||usually
1300usupported||unsupported
1213utilites||utilities 1301utilites||utilities
1214utillities||utilities 1302utillities||utilities
1215utilties||utilities 1303utilties||utilities
@@ -1233,7 +1321,9 @@ virtaul||virtual
1233virtiual||virtual 1321virtiual||virtual
1234visiters||visitors 1322visiters||visitors
1235vitual||virtual 1323vitual||virtual
1324vunerable||vulnerable
1236wakeus||wakeups 1325wakeus||wakeups
1326wathdog||watchdog
1237wating||waiting 1327wating||waiting
1238wiat||wait 1328wiat||wait
1239wether||whether 1329wether||whether
diff --git a/scripts/split-man.pl b/scripts/split-man.pl
new file mode 100755
index 000000000000..c3db607ee9ec
--- /dev/null
+++ b/scripts/split-man.pl
@@ -0,0 +1,28 @@
1#!/usr/bin/perl
2# SPDX-License-Identifier: GPL-2.0
3#
4# Author: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
5#
6# Produce manpages from kernel-doc.
7# See Documentation/doc-guide/kernel-doc.rst for instructions
8
9if ($#ARGV < 0) {
10 die "where do I put the results?\n";
11}
12
13mkdir $ARGV[0],0777;
14$state = 0;
15while (<STDIN>) {
16 if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) {
17 if ($state == 1) { close OUT }
18 $state = 1;
19 $fn = "$ARGV[0]/$1.9";
20 print STDERR "Creating $fn\n";
21 open OUT, ">$fn" or die "can't open $fn: $!\n";
22 print OUT $_;
23 } elsif ($state != 0) {
24 print OUT $_;
25 }
26}
27
28close OUT;
diff --git a/scripts/subarch.include b/scripts/subarch.include
new file mode 100644
index 000000000000..650682821126
--- /dev/null
+++ b/scripts/subarch.include
@@ -0,0 +1,13 @@
1# SUBARCH tells the usermode build what the underlying arch is. That is set
2# first, and if a usermode build is happening, the "ARCH=um" on the command
3# line overrides the setting of ARCH below. If a native build is happening,
4# then ARCH is assigned, getting whatever value it gets normally, and
5# SUBARCH is subsequently ignored.
6
7SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
8 -e s/sun4u/sparc64/ \
9 -e s/arm.*/arm/ -e s/sa110/arm/ \
10 -e s/s390x/s390/ -e s/parisc64/parisc/ \
11 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
12 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
13 -e s/riscv.*/riscv/)
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 78e546ff689c..4fa070f9231a 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -28,20 +28,11 @@ fi
28# ignore userspace tools 28# ignore userspace tools
29ignore="$ignore ( -path ${tree}tools ) -prune -o" 29ignore="$ignore ( -path ${tree}tools ) -prune -o"
30 30
31# Find all available archs
32find_all_archs()
33{
34 ALLSOURCE_ARCHS=""
35 for arch in `ls ${tree}arch`; do
36 ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
37 done
38}
39
40# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH 31# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
41if [ "${ALLSOURCE_ARCHS}" = "" ]; then 32if [ "${ALLSOURCE_ARCHS}" = "" ]; then
42 ALLSOURCE_ARCHS=${SRCARCH} 33 ALLSOURCE_ARCHS=${SRCARCH}
43elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then 34elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
44 find_all_archs 35 ALLSOURCE_ARCHS=$(find ${tree}arch/ -mindepth 1 -maxdepth 1 -type d -printf '%f ')
45fi 36fi
46 37
47# find sources in arch/$ARCH 38# find sources in arch/$ARCH
@@ -161,6 +152,7 @@ regex_asm=(
161) 152)
162regex_c=( 153regex_c=(
163 '/^SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/sys_\1/' 154 '/^SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/sys_\1/'
155 '/^BPF_CALL_[0-9](\([[:alnum:]_]*\).*/\1/'
164 '/^COMPAT_SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/compat_sys_\1/' 156 '/^COMPAT_SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/compat_sys_\1/'
165 '/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1/' 157 '/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1/'
166 '/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1_rcuidle/' 158 '/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
@@ -188,9 +180,9 @@ regex_c=(
188 '/\<CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/ClearPage\1/' 180 '/\<CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/ClearPage\1/'
189 '/\<__CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/__ClearPage\1/' 181 '/\<__CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/__ClearPage\1/'
190 '/\<TESTCLEARFLAG_FALSE(\([[:alnum:]_]*\).*/TestClearPage\1/' 182 '/\<TESTCLEARFLAG_FALSE(\([[:alnum:]_]*\).*/TestClearPage\1/'
191 '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/Page\1/' 183 '/^PAGE_TYPE_OPS(\([[:alnum:]_]*\).*/Page\1/'
192 '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__SetPage\1/' 184 '/^PAGE_TYPE_OPS(\([[:alnum:]_]*\).*/__SetPage\1/'
193 '/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/' 185 '/^PAGE_TYPE_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/'
194 '/^TASK_PFA_TEST([^,]*, *\([[:alnum:]_]*\))/task_\1/' 186 '/^TASK_PFA_TEST([^,]*, *\([[:alnum:]_]*\))/task_\1/'
195 '/^TASK_PFA_SET([^,]*, *\([[:alnum:]_]*\))/task_set_\1/' 187 '/^TASK_PFA_SET([^,]*, *\([[:alnum:]_]*\))/task_set_\1/'
196 '/^TASK_PFA_CLEAR([^,]*, *\([[:alnum:]_]*\))/task_clear_\1/' 188 '/^TASK_PFA_CLEAR([^,]*, *\([[:alnum:]_]*\))/task_clear_\1/'
@@ -211,7 +203,7 @@ regex_c=(
211 '/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/' 203 '/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/'
212 '/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/' 204 '/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/'
213 '/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/' 205 '/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/'
214 '/\<DEFINE_HASHTABLE(\([[:alnum:]_]*\)/\1/v/' 206 '/\<\(DEFINE\|DECLARE\)_HASHTABLE(\([[:alnum:]_]*\)/\2/v/'
215) 207)
216regex_kconfig=( 208regex_kconfig=(
217 '/^[[:blank:]]*\(menu\|\)config[[:blank:]]\+\([[:alnum:]_]\+\)/\2/' 209 '/^[[:blank:]]*\(menu\|\)config[[:blank:]]\+\([[:alnum:]_]\+\)/\2/'
@@ -254,7 +246,7 @@ exuberant()
254{ 246{
255 setup_regex exuberant asm c 247 setup_regex exuberant asm c
256 all_target_sources | xargs $1 -a \ 248 all_target_sources | xargs $1 -a \
257 -I __initdata,__exitdata,__initconst, \ 249 -I __initdata,__exitdata,__initconst,__ro_after_init \
258 -I __initdata_memblock \ 250 -I __initdata_memblock \
259 -I __refdata,__attribute,__maybe_unused,__always_unused \ 251 -I __refdata,__attribute,__maybe_unused,__always_unused \
260 -I __acquires,__releases,__deprecated \ 252 -I __acquires,__releases,__deprecated \
diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py
index db40fa04cd51..9b6dd4f36335 100755
--- a/scripts/tracing/draw_functrace.py
+++ b/scripts/tracing/draw_functrace.py
@@ -123,7 +123,7 @@ def main():
123 tree = tree.getParent(caller) 123 tree = tree.getParent(caller)
124 tree = tree.calls(callee, calltime) 124 tree = tree.calls(callee, calltime)
125 125
126 print CallTree.ROOT 126 print(CallTree.ROOT)
127 127
128if __name__ == "__main__": 128if __name__ == "__main__":
129 main() 129 main()
diff --git a/scripts/ver_linux b/scripts/ver_linux
index 545ec7388eb7..a6c728db05ce 100755
--- a/scripts/ver_linux
+++ b/scripts/ver_linux
@@ -13,28 +13,28 @@ BEGIN {
13 system("uname -a") 13 system("uname -a")
14 printf("\n") 14 printf("\n")
15 15
16 printversion("GNU C", version("gcc -dumpversion 2>&1")) 16 printversion("GNU C", version("gcc -dumpversion"))
17 printversion("GNU Make", version("make --version 2>&1")) 17 printversion("GNU Make", version("make --version"))
18 printversion("Binutils", version("ld -v 2>&1")) 18 printversion("Binutils", version("ld -v"))
19 printversion("Util-linux", version("mount --version 2>&1")) 19 printversion("Util-linux", version("mount --version"))
20 printversion("Mount", version("mount --version 2>&1")) 20 printversion("Mount", version("mount --version"))
21 printversion("Module-init-tools", version("depmod -V 2>&1")) 21 printversion("Module-init-tools", version("depmod -V"))
22 printversion("E2fsprogs", version("tune2fs 2>&1")) 22 printversion("E2fsprogs", version("tune2fs"))
23 printversion("Jfsutils", version("fsck.jfs -V 2>&1")) 23 printversion("Jfsutils", version("fsck.jfs -V"))
24 printversion("Reiserfsprogs", version("reiserfsck -V 2>&1")) 24 printversion("Reiserfsprogs", version("reiserfsck -V"))
25 printversion("Reiser4fsprogs", version("fsck.reiser4 -V 2>&1")) 25 printversion("Reiser4fsprogs", version("fsck.reiser4 -V"))
26 printversion("Xfsprogs", version("xfs_db -V 2>&1")) 26 printversion("Xfsprogs", version("xfs_db -V"))
27 printversion("Pcmciautils", version("pccardctl -V 2>&1")) 27 printversion("Pcmciautils", version("pccardctl -V"))
28 printversion("Pcmcia-cs", version("cardmgr -V 2>&1")) 28 printversion("Pcmcia-cs", version("cardmgr -V"))
29 printversion("Quota-tools", version("quota -V 2>&1")) 29 printversion("Quota-tools", version("quota -V"))
30 printversion("PPP", version("pppd --version 2>&1")) 30 printversion("PPP", version("pppd --version"))
31 printversion("Isdn4k-utils", version("isdnctrl 2>&1")) 31 printversion("Isdn4k-utils", version("isdnctrl"))
32 printversion("Nfs-utils", version("showmount --version 2>&1")) 32 printversion("Nfs-utils", version("showmount --version"))
33 33
34 if (system("test -r /proc/self/maps") == 0) { 34 while (getline <"/proc/self/maps" > 0) {
35 while (getline <"/proc/self/maps" > 0) { 35 if (/libc.*\.so$/) {
36 n = split($0, procmaps, "/") 36 n = split($0, procmaps, "/")
37 if (/libc.*so$/ && match(procmaps[n], /[0-9]+([.]?[0-9]+)+/)) { 37 if (match(procmaps[n], /[0-9]+([.]?[0-9]+)+/)) {
38 ver = substr(procmaps[n], RSTART, RLENGTH) 38 ver = substr(procmaps[n], RSTART, RLENGTH)
39 printversion("Linux C Library", ver) 39 printversion("Linux C Library", ver)
40 break 40 break
@@ -42,7 +42,7 @@ BEGIN {
42 } 42 }
43 } 43 }
44 44
45 printversion("Dynamic linker (ldd)", version("ldd --version 2>&1")) 45 printversion("Dynamic linker (ldd)", version("ldd --version"))
46 46
47 while ("ldconfig -p 2>/dev/null" | getline > 0) { 47 while ("ldconfig -p 2>/dev/null" | getline > 0) {
48 if (/(libg|stdc)[+]+\.so/) { 48 if (/(libg|stdc)[+]+\.so/) {
@@ -50,30 +50,27 @@ BEGIN {
50 break 50 break
51 } 51 }
52 } 52 }
53 if (system("test -r " libcpp) == 0) 53 printversion("Linux C++ Library", version("readlink " libcpp))
54 printversion("Linux C++ Library", version("readlink " libcpp)) 54 printversion("Procps", version("ps --version"))
55 printversion("Net-tools", version("ifconfig --version"))
56 printversion("Kbd", version("loadkeys -V"))
57 printversion("Console-tools", version("loadkeys -V"))
58 printversion("Oprofile", version("oprofiled --version"))
59 printversion("Sh-utils", version("expr --v"))
60 printversion("Udev", version("udevadm --version"))
61 printversion("Wireless-tools", version("iwconfig --version"))
55 62
56 printversion("Procps", version("ps --version 2>&1")) 63 while ("sort /proc/modules" | getline > 0) {
57 printversion("Net-tools", version("ifconfig --version 2>&1")) 64 mods = mods sep $1
58 printversion("Kbd", version("loadkeys -V 2>&1")) 65 sep = " "
59 printversion("Console-tools", version("loadkeys -V 2>&1"))
60 printversion("Oprofile", version("oprofiled --version 2>&1"))
61 printversion("Sh-utils", version("expr --v 2>&1"))
62 printversion("Udev", version("udevadm --version 2>&1"))
63 printversion("Wireless-tools", version("iwconfig --version 2>&1"))
64
65 if (system("test -r /proc/modules") == 0) {
66 while ("sort /proc/modules" | getline > 0) {
67 mods = mods sep $1
68 sep = " "
69 }
70 printversion("Modules Loaded", mods)
71 } 66 }
67 printversion("Modules Loaded", mods)
72} 68}
73 69
74function version(cmd, ver) { 70function version(cmd, ver) {
71 cmd = cmd " 2>&1"
75 while (cmd | getline > 0) { 72 while (cmd | getline > 0) {
76 if (!/ver_linux/ && match($0, /[0-9]+([.]?[0-9]+)+/)) { 73 if (match($0, /[0-9]+([.]?[0-9]+)+/)) {
77 ver = substr($0, RSTART, RLENGTH) 74 ver = substr($0, RSTART, RLENGTH)
78 break 75 break
79 } 76 }