diff options
Diffstat (limited to 'scripts')
104 files changed, 2605 insertions, 5916 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 065324a..cce31ee 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -237,9 +237,7 @@ cc-ldoption = $(call try-run-cached,\ # ld-option # Usage: LDFLAGS += $(call ld-option, -X) -ld-option = $(call try-run-cached,\ - $(CC) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -x c /dev/null -c -o "$$TMPO"; \ - $(LD) $(LDFLAGS) $(1) "$$TMPO" -o "$$TMP",$(1),$(2)) +ld-option = $(call try-run-cached, $(LD) $(LDFLAGS) $(1) -v,$(1),$(2)) # ar-option # Usage: KBUILD_ARFLAGS := $(call ar-option,D) @@ -368,7 +366,7 @@ ksym_dep_filter = \ $(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \ boot*|build*|cpp_its_S|*cpp_lds_S|dtc|host*|vdso*) : ;; \ *) echo "Don't know how to preprocess $(1)" >&2; false ;; \ - esac | tr ";" "\n" | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' + esac | tr ";" "\n" | sed -n 's/^.*=== __KSYM_\(.*\) ===.*$$/_\1/p' cmd_and_fixdep = \ $(echo-cmd) $(cmd_$(1)); \ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 4f2b25d..77cce68 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -73,11 +73,11 @@ endif ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) lib-target := $(obj)/lib.a -obj-y += $(obj)/lib-ksyms.o +real-obj-y += $(obj)/lib-ksyms.o endif -ifneq ($(strip $(obj-y) $(need-builtin)),) -builtin-target := $(obj)/built-in.o +ifneq ($(strip $(real-obj-y) $(need-builtin)),) +builtin-target := $(obj)/built-in.a endif modorder-target := $(obj)/modules.order @@ -104,7 +104,7 @@ ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< ; endif -# Do section mismatch analysis for each module/built-in.o +# Do section mismatch analysis for each module/built-in.a ifdef CONFIG_DEBUG_SECTION_MISMATCH cmd_secanalysis = ; scripts/mod/modpost $@ endif @@ -119,29 +119,17 @@ modkern_cflags = \ $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL)) quiet_modtag := $(empty) $(empty) -$(real-objs-m) : part-of-module := y -$(real-objs-m:.o=.i) : part-of-module := y -$(real-objs-m:.o=.s) : part-of-module := y -$(real-objs-m:.o=.lst): part-of-module := y +$(real-obj-m) : part-of-module := y +$(real-obj-m:.o=.i) : part-of-module := y +$(real-obj-m:.o=.s) : part-of-module := y +$(real-obj-m:.o=.lst): part-of-module := y -$(real-objs-m) : quiet_modtag := [M] -$(real-objs-m:.o=.i) : quiet_modtag := [M] -$(real-objs-m:.o=.s) : quiet_modtag := [M] -$(real-objs-m:.o=.lst): quiet_modtag := [M] +$(real-obj-m) : quiet_modtag := [M] +$(real-obj-m:.o=.i) : quiet_modtag := [M] +$(real-obj-m:.o=.s) : quiet_modtag := [M] +$(real-obj-m:.o=.lst): quiet_modtag := [M] -$(obj-m) : quiet_modtag := [M] - -# Default for not multi-part modules -modname = $(basetarget) - -$(multi-objs-m) : modname = $(modname-multi) -$(multi-objs-m:.o=.i) : modname = $(modname-multi) -$(multi-objs-m:.o=.s) : modname = $(modname-multi) -$(multi-objs-m:.o=.lst) : modname = $(modname-multi) -$(multi-objs-y) : modname = $(modname-multi) -$(multi-objs-y:.o=.i) : modname = $(modname-multi) -$(multi-objs-y:.o=.s) : modname = $(modname-multi) -$(multi-objs-y:.o=.lst) : modname = $(modname-multi) +$(obj-m) : quiet_modtag := [M] quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< @@ -314,7 +302,7 @@ endef # List module undefined symbols (or empty line if not enabled) ifdef CONFIG_TRIM_UNUSED_KSYMS -cmd_undef_syms = $(NM) $@ | sed -n 's/^ \+U //p' | xargs echo +cmd_undef_syms = $(NM) $@ | sed -n 's/^ *U //p' | xargs echo else cmd_undef_syms = echo endif @@ -345,8 +333,8 @@ $(obj)/%.lst: $(src)/%.c FORCE modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) -$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) -$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) +$(real-obj-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) +$(real-obj-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) # .S file exports must have their C prototypes defined in asm/asm-prototypes.h # or a file that it includes, in order to get versioned symbols. We build a @@ -424,7 +412,7 @@ endif $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE $(call if_changed_rule,as_o_S) -targets += $(real-objs-y) $(real-objs-m) $(lib-y) +targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y) targets += $(extra-y) $(MAKECMDGOALS) $(always) # Linker scripts preprocessor (.lds.S -> .lds) @@ -458,24 +446,16 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ; # ifdef builtin-target -ifdef CONFIG_THIN_ARCHIVES - cmd_make_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) - cmd_make_empty_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) - quiet_cmd_link_o_target = AR $@ -else - cmd_make_builtin = $(LD) $(ld_flags) -r -o - cmd_make_empty_builtin = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) - quiet_cmd_link_o_target = LD $@ -endif - -# If the list of objects to link is empty, just create an empty built-in.o -cmd_link_o_target = $(if $(strip $(obj-y)),\ - $(cmd_make_builtin) $@ $(filter $(obj-y), $^) \ - $(cmd_secanalysis),\ - $(cmd_make_empty_builtin) $@) +# built-in.a archives are made with no symbol table or index which +# makes them small and fast, but unable to be used by the linker. +# scripts/link-vmlinux.sh builds an aggregate built-in.a with a symbol +# table and index. +quiet_cmd_ar_builtin = AR $@ + cmd_ar_builtin = rm -f $@; \ + $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(filter $(real-obj-y), $^) -$(builtin-target): $(obj-y) FORCE - $(call if_changed,link_o_target) +$(builtin-target): $(real-obj-y) FORCE + $(call if_changed,ar_builtin) targets += $(builtin-target) endif # builtin-target @@ -499,11 +479,8 @@ $(modorder-target): $(subdir-ym) FORCE ifdef lib-target quiet_cmd_link_l_target = AR $@ -ifdef CONFIG_THIN_ARCHIVES - cmd_link_l_target = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(lib-y) -else - cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y) -endif +# lib target archives do get a symbol table and index +cmd_link_l_target = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(lib-y) $(lib-target): $(lib-y) FORCE $(call if_changed,link_l_target) @@ -549,22 +526,8 @@ $($(subst $(obj)/,,$(@:.o=-objs))) \ $($(subst $(obj)/,,$(@:.o=-y))) \ $($(subst $(obj)/,,$(@:.o=-m)))), $^) -cmd_link_multi-link = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis) - -ifdef CONFIG_THIN_ARCHIVES - quiet_cmd_link_multi-y = AR $@ - cmd_link_multi-y = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(link_multi_deps) -else - quiet_cmd_link_multi-y = LD $@ - cmd_link_multi-y = $(cmd_link_multi-link) -endif - quiet_cmd_link_multi-m = LD [M] $@ -cmd_link_multi-m = $(cmd_link_multi-link) - -$(multi-used-y): FORCE - $(call if_changed,link_multi-y) -$(call multi_depend, $(multi-used-y), .o, -objs -y) +cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis) $(multi-used-m): FORCE $(call if_changed,link_multi-m) @@ -572,7 +535,7 @@ $(multi-used-m): FORCE $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) $(call multi_depend, $(multi-used-m), .o, -objs -y -m) -targets += $(multi-used-y) $(multi-used-m) +targets += $(multi-used-m) targets := $(filter-out $(PHONY), $(targets)) # Descending diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index a6f538b..45b9aa3 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -27,7 +27,7 @@ modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko # Handle objects in subdirs # --------------------------------------------------------------------------- -# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o +# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a # and add the directory to the list of dirs to descend into: $(subdir-y) # o if we encounter foo/ in $(obj-m), remove it from $(obj-m) # and add the directory to the list of dirs to descend into: $(subdir-m) @@ -35,7 +35,7 @@ __subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) subdir-y += $(__subdir-y) __subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) subdir-m += $(__subdir-m) -obj-y := $(patsubst %/, %/built-in.o, $(obj-y)) +obj-y := $(patsubst %/, %/built-in.a, $(obj-y)) obj-m := $(filter-out %/, $(obj-m)) # Subdirectories we need to descend into @@ -47,18 +47,14 @@ multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m multi-used := $(multi-used-y) $(multi-used-m) single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) -# Build list of the parts of our composite objects, our composite -# objects depend on those (obviously) -multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y))) -multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y))) - # $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to # tell kbuild to descend -subdir-obj-y := $(filter %/built-in.o, $(obj-y)) +subdir-obj-y := $(filter %/built-in.a, $(obj-y)) -# Replace multi-part objects by their individual parts, look at local dir only -real-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))) -real-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))) +# Replace multi-part objects by their individual parts, +# including built-in.a from subdirectories +real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) +real-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))) # DTB # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built @@ -71,29 +67,29 @@ extra-y := $(addprefix $(obj)/,$(extra-y)) always := $(addprefix $(obj)/,$(always)) targets := $(addprefix $(obj)/,$(targets)) modorder := $(addprefix $(obj)/,$(modorder)) -obj-y := $(addprefix $(obj)/,$(obj-y)) obj-m := $(addprefix $(obj)/,$(obj-m)) lib-y := $(addprefix $(obj)/,$(lib-y)) subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) -real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) -real-objs-m := $(addprefix $(obj)/,$(real-objs-m)) +real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) +real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) single-used-m := $(addprefix $(obj)/,$(single-used-m)) -multi-used-y := $(addprefix $(obj)/,$(multi-used-y)) multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) -multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y)) -multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +# Finds the multi-part object the current object will be linked into. +# If the object belongs to two or more multi-part objects, all of them are +# concatenated with a colon separator. +modname-multi = $(subst $(space),:,$(sort $(foreach m,$(multi-used),\ + $(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=))))) + +modname = $(if $(modname-multi),$(modname-multi),$(basetarget)) + # These flags are needed for modversions and compiling, so we define them here # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) -# Note: Files that end up in two or more modules are compiled without the -# KBUILD_MODNAME definition. The reason is that any made-up name would -# differ in different configs. name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = $(if $(filter 1,$(words $(modname))),\ - -DKBUILD_MODNAME=$(call name-fix,$(modname))) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) @@ -156,6 +152,7 @@ __cpp_flags = $(call flags,_cpp_flags) endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ + -include $(srctree)/include/linux/compiler_types.h \ $(__c_flags) $(modkern_cflags) \ $(basename_flags) $(modname_flags) @@ -173,10 +170,6 @@ dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ -# Finds the multi-part object the current object will be linked into -modname-multi = $(sort $(foreach m,$(multi-used),\ - $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=)))) - # Useful for describing the dependency of composite objects # Usage: # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) @@ -217,7 +210,7 @@ $(filter %.tab.c,$(targets)): $(obj)/%.tab.c: $(src)/%.y FORCE $(call if_changed,bison) quiet_cmd_bison_h = YACC $@ - cmd_bison_h = bison -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $< + cmd_bison_h = bison -o/dev/null --defines=$@ -t -l $< ifdef REGENERATE_PARSERS .PRECIOUS: $(src)/%.tab.h_shipped @@ -276,10 +269,9 @@ DTC ?= $(objtree)/scripts/dtc/dtc # Disable noisy checks by default ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) DTC_FLAGS += -Wno-unit_address_vs_reg \ - -Wno-simple_bus_reg \ -Wno-unit_address_format \ - -Wno-pci_bridge \ - -Wno-pci_device_bus_num \ + -Wno-avoid_unnecessary_addr_size \ + -Wno-alias_paths \ -Wno-pci_device_reg endif @@ -316,7 +308,7 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -$(obj)/%.dtb: $(src)/%.dts FORCE +$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE $(call if_changed_dep,dtc) dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) @@ -329,7 +321,7 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) size_append = printf $(shell \ dec_size=0; \ for F in $1; do \ - fsize=$$(stat -c "%s" $$F); \ + fsize=$$($(CONFIG_SHELL) $(srctree)/scripts/file-size.sh $$F); \ dec_size=$$(expr $$dec_size + $$fsize); \ done; \ printf "%08x\n" $$dec_size | \ diff --git a/scripts/adjust_autoksyms.sh b/scripts/adjust_autoksyms.sh index 513da1a..016b3c4 100755 --- a/scripts/adjust_autoksyms.sh +++ b/scripts/adjust_autoksyms.sh @@ -48,9 +48,6 @@ case "${KCONFIG_CONFIG}" in . "./${KCONFIG_CONFIG}" esac -# In case it doesn't exist yet... -if [ -e "$cur_ksyms_file" ]; then touch "$cur_ksyms_file"; fi - # Generate a new ksym list file with symbols needed by the current # set of modules. cat > "$new_ksyms_file" << EOT @@ -60,7 +57,9 @@ cat > "$new_ksyms_file" << EOT EOT [ "$(ls -A "$MODVERDIR")" ] && -sed -ns -e '3{s/ /\n/g;/^$/!p;}' "$MODVERDIR"/*.mod | sort -u | +for mod in "$MODVERDIR"/*.mod; do + sed -n -e '3{s/ /\n/g;/^$/!p;}' "$mod" +done | sort -u | while read sym; do if [ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]; then sym="${sym#_}" @@ -81,9 +80,16 @@ sort "$cur_ksyms_file" "$new_ksyms_file" | uniq -u | sed -n 's/^#define __KSYM_\(.*\) 1/\1/p' | tr "A-Z_" "a-z/" | while read sympath; do if [ -z "$sympath" ]; then continue; fi - depfile="include/config/ksym/${sympath}.h" + depfile="include/ksym/${sympath}.h" mkdir -p "$(dirname "$depfile")" touch "$depfile" + # Filesystems with coarse time precision may create timestamps + # equal to the one from a file that was very recently built and that + # needs to be rebuild. Let's guard against that by making sure our + # dep files are always newer than the first file we created here. + while [ ! "$depfile" -nt "$new_ksyms_file" ]; do + touch "$depfile" + done echo $((count += 1)) done | tail -1 ) changed=${changed:-0} diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 449b68c..f387538 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -113,11 +113,11 @@ static void usage(void) /* * Print out a dependency path from a symbol name */ -static void print_config(const char *m, int slen) +static void print_dep(const char *m, int slen, const char *dir) { int c, i; - printf(" $(wildcard include/config/"); + printf(" $(wildcard %s/", dir); for (i = 0; i < slen; i++) { c = m[i]; if (c == '_') @@ -140,7 +140,7 @@ static void do_extra_deps(void) fprintf(stderr, "fixdep: bad data on stdin\n"); exit(1); } - print_config(buf, len - 1); + print_dep(buf, len - 1, "include/ksym"); } } @@ -208,7 +208,7 @@ static void use_config(const char *m, int slen) return; define_config(m, slen, hash); - print_config(m, slen); + print_dep(m, slen, "include/config"); } /* test if s ends in sub */ diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3d40403..e16d671 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -791,7 +791,8 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; our $declaration_macros = qr{(?x: (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| - (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( + (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(| + (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( )}; sub deparenthesize { @@ -1075,7 +1076,7 @@ sub parse_email { } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { $address = $1; $comment = $2 if defined $2; - $formatted_email =~ s/$address.*$//; + $formatted_email =~ s/\Q$address\E.*$//; $name = $formatted_email; $name = trim($name); $name =~ s/^\"|\"$//g; @@ -1217,7 +1218,7 @@ sub sanitise_line { for ($off = 1; $off < length($line); $off++) { $c = substr($line, $off, 1); - # Comments we are wacking completly including the begin + # Comments we are whacking completely including the begin # and end, all to $;. if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { $sanitise_quote = '*/'; @@ -1297,6 +1298,7 @@ sub sanitise_line { sub get_quoted_string { my ($line, $rawline) = @_; + return "" if (!defined($line) || !defined($rawline)); return "" if ($line !~ m/($String)/g); return substr($rawline, $-[0], $+[0] - $-[0]); } @@ -1644,6 +1646,28 @@ sub raw_line { return $line; } +sub get_stat_real { + my ($linenr, $lc) = @_; + + my $stat_real = raw_line($linenr, 0); + for (my $count = $linenr + 1; $count <= $lc; $count++) { + $stat_real = $stat_real . "\n" . raw_line($count, 0); + } + + return $stat_real; +} + +sub get_stat_here { + my ($linenr, $cnt, $here) = @_; + + my $herectx = $here . "\n"; + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + return $herectx; +} + sub cat_vet { my ($vet) = @_; my ($res, $coded); @@ -2257,6 +2281,8 @@ sub process { my $camelcase_file_seeded = 0; + my $checklicenseline = 1; + sanitise_line_reset(); my $line; foreach my $rawline (@rawlines) { @@ -2448,6 +2474,7 @@ sub process { } else { $check = $check_orig; } + $checklicenseline = 1; next; } @@ -2797,7 +2824,10 @@ sub process { # Only applies when adding the entry originally, after that we do not have # sufficient context to determine whether it is indeed long enough. if ($realfile =~ /Kconfig/ && - $line =~ /^\+\s*config\s+/) { + # 'choice' is usually the last thing on the line (though + # Kconfig supports named choices), so use a word boundary + # (\b) rather than a whitespace character (\s) + $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { my $length = 0; my $cnt = $realcnt; my $ln = $linenr + 1; @@ -2812,9 +2842,13 @@ sub process { next if ($f =~ /^-/); last if (!$file && $f =~ /^\@\@/); - if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { + if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { $is_start = 1; - } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { + } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) { + if ($lines[$ln - 1] =~ "---help---") { + WARN("CONFIG_DESCRIPTION", + "prefer 'help' over '---help---' for new help texts\n" . $herecurr); + } $length = -1; } @@ -2822,7 +2856,13 @@ sub process { $f =~ s/#.*//; $f =~ s/^\s+//; next if ($f =~ /^$/); - if ($f =~ /^\s*config\s/) { + + # This only checks context lines in the patch + # and so hopefully shouldn't trigger false + # positives, even though some of these are + # common words in help texts + if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| + if|endif|menu|endmenu|source)\b/x) { $is_end = 1; last; } @@ -2898,6 +2938,30 @@ sub process { } } +# check for using SPDX license tag at beginning of files + if ($realline == $checklicenseline) { + if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { + $checklicenseline = 2; + } elsif ($rawline =~ /^\+/) { + my $comment = ""; + if ($realfile =~ /\.(h|s|S)$/) { + $comment = '/*'; + } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { + $comment = '//'; + } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) { + $comment = '#'; + } elsif ($realfile =~ /\.rst$/) { + $comment = '..'; + } + + if ($comment !~ /^$/ && + $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) { + WARN("SPDX_LICENSE_TAG", + "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); + } + } + } + # check we are in a valid source file if not then ignore this hunk next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); @@ -2969,20 +3033,6 @@ sub process { "adding a line without newline at end of file\n" . $herecurr); } -# Blackfin: use hi/lo macros - if ($realfile =~ m@arch/blackfin/.*\.S$@) { - if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("LO_MACRO", - "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); - } - if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("HI_MACRO", - "use the HI() macro, not (... >> 16)\n" . $herevet); - } - } - # check we are in a valid source file C or perl if not then ignore this hunk next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); @@ -3012,6 +3062,12 @@ sub process { } } +# check for assignments on the start of a line + if ($sline =~ /^\+\s+($Assignment)[^=]/) { + CHK("ASSIGNMENT_CONTINUATIONS", + "Assignment operator '$1' should be on the previous line\n" . $hereprev); + } + # check for && or || at the start of a line if ($rawline =~ /^\+\s*(&&|\|\|)/) { CHK("LOGICAL_CONTINUATIONS", @@ -3269,18 +3325,6 @@ sub process { "CVS style keyword markers, these will _not_ be updated\n". $herecurr); } -# Blackfin: don't use __builtin_bfin_[cs]sync - if ($line =~ /__builtin_bfin_csync/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("CSYNC", - "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); - } - if ($line =~ /__builtin_bfin_ssync/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("SSYNC", - "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); - } - # check for old HOTPLUG __dev<foo> section markings if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { WARN("HOTPLUG_SECTION", @@ -4045,7 +4089,7 @@ sub process { my ($where, $prefix) = ($-[1], $1); if ($prefix !~ /$Type\s+$/ && ($where != 0 || $prefix !~ /^.\s+$/) && - $prefix !~ /[{,]\s+$/) { + $prefix !~ /[{,:]\s+$/) { if (ERROR("BRACKET_SPACE", "space prohibited before open square bracket '['\n" . $herecurr) && $fix) { @@ -4941,12 +4985,8 @@ sub process { #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; $ctx =~ s/\n*$//; - my $herectx = $here . "\n"; my $stmt_cnt = statement_rawlines($ctx); - - for (my $n = 0; $n < $stmt_cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $stmt_cnt, $here); if ($dstat ne '' && $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), @@ -5018,12 +5058,9 @@ sub process { # check for macros with flow control, but without ## concatenation # ## concatenation is commonly a macro that defines a function so ignore those if ($has_flow_statement && !$has_arg_concat) { - my $herectx = $here . "\n"; my $cnt = statement_rawlines($ctx); + my $herectx = get_stat_here($linenr, $cnt, $here); - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } WARN("MACRO_WITH_FLOW_CONTROL", "Macros with flow control statements should be avoided\n" . "$herectx"); } @@ -5063,11 +5100,7 @@ sub process { $ctx =~ s/\n*$//; my $cnt = statement_rawlines($ctx); - my $herectx = $here . "\n"; - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); if (($stmts =~ tr/;/;/) == 1 && $stmts !~ /^\s*(if|while|for|switch)\b/) { @@ -5081,11 +5114,7 @@ sub process { } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { $ctx =~ s/\n*$//; my $cnt = statement_rawlines($ctx); - my $herectx = $here . "\n"; - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); WARN("TRAILING_SEMICOLON", "macros should not use a trailing semicolon\n" . "$herectx"); @@ -5208,12 +5237,8 @@ sub process { } } if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { - my $herectx = $here . "\n"; my $cnt = statement_rawlines($block); - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); WARN("BRACES", "braces {} are not necessary for single statement blocks\n" . $herectx); @@ -5789,36 +5814,50 @@ sub process { } } - # check for vsprintf extension %p<foo> misuses +# check for vsprintf extension %p<foo> misuses if ($^V && $^V ge 5.10.0 && defined $stat && $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && $1 !~ /^_*volatile_*$/) { - my $bad_extension = ""; + my $specifier; + my $extension; + my $bad_specifier = ""; + my $stat_real; + my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; for (my $count = $linenr; $count <= $lc; $count++) { my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); $fmt =~ s/%%//g; - if ($fmt =~ /(\%[\*\d\.]*p(?![\WSsBKRraEhMmIiUDdgVCbGNOx]).)/) { - $bad_extension = $1; - last; - } - } - if ($bad_extension ne "") { - my $stat_real = raw_line($linenr, 0); - my $ext_type = "Invalid"; - my $use = ""; - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); + + while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { + $specifier = $1; + $extension = $2; + if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) { + $bad_specifier = $specifier; + last; + } + if ($extension eq "x" && !defined($stat_real)) { + if (!defined($stat_real)) { + $stat_real = get_stat_real($linenr, $lc); + } + WARN("VSPRINTF_SPECIFIER_PX", + "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"); + } } - if ($bad_extension =~ /p[Ff]/) { - $ext_type = "Deprecated"; - $use = " - use %pS instead"; - $use =~ s/pS/ps/ if ($bad_extension =~ /pf/); + if ($bad_specifier ne "") { + my $stat_real = get_stat_real($linenr, $lc); + my $ext_type = "Invalid"; + my $use = ""; + if ($bad_specifier =~ /p[Ff]/) { + $ext_type = "Deprecated"; + $use = " - use %pS instead"; + $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); + } + + WARN("VSPRINTF_POINTER_EXTENSION", + "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); } - WARN("VSPRINTF_POINTER_EXTENSION", - "$ext_type vsprintf pointer extension '$bad_extension'$use\n" . "$here\n$stat_real\n"); } } @@ -5931,10 +5970,7 @@ sub process { $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } + my $stat_real = get_stat_real($linenr, $lc); WARN("NAKED_SSCANF", "unchecked sscanf return value\n" . "$here\n$stat_real\n"); } @@ -5945,10 +5981,7 @@ sub process { $line =~ /\bsscanf\b/) { my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } + my $stat_real = get_stat_real($linenr, $lc); if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { my $format = $6; my $count = $format =~ tr@%@%@; @@ -6078,12 +6111,9 @@ sub process { } if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { - my $ctx = ''; - my $herectx = $here . "\n"; my $cnt = statement_rawlines($stat); - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); + if (WARN("ALLOC_WITH_MULTIPLY", "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && $cnt == 1 && @@ -6166,12 +6196,9 @@ sub process { if ($^V && $^V ge 5.10.0 && defined $stat && $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { - my $ctx = ''; - my $herectx = $here . "\n"; my $cnt = statement_rawlines($stat); - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); + WARN("DEFAULT_NO_BREAK", "switch default: should use break\n" . $herectx); } @@ -6224,6 +6251,12 @@ sub process { } } +# check for bool bitfields + if ($sline =~ /^.\s+bool\s*$Ident\s*:\s*\d+\s*;/) { + WARN("BOOL_BITFIELD", + "Avoid using bool as bitfield. Prefer bool bitfields as unsigned int or u<8|16|32>\n" . $herecurr); + } + # check for semaphores initialized locked if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { WARN("CONSIDER_COMPLETION", @@ -6382,10 +6415,7 @@ sub process { my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } + my $stat_real = get_stat_real($linenr, $lc); my $skip_args = ""; if ($arg_pos > 1) { @@ -6411,7 +6441,7 @@ sub process { } # check for uses of S_<PERMS> that could be octal for readability - if ($line =~ /\b($multi_mode_perms_string_search)\b/) { + while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { my $oval = $1; my $octal = perms_to_octal($oval); if (WARN("SYMBOLIC_PERMS", diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index cb99380..cbdf0df 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl @@ -64,10 +64,6 @@ my (@stack, $re, $dre, $x, $xs, $funcre); # 2b6c: 4e56 fb70 linkw %fp,#-1168 # 1df770: defc ffe4 addaw #-28,%sp $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o; - } elsif ($arch eq 'metag') { - #400026fc: 40 00 00 82 ADD A0StP,A0StP,#0x8 - $re = qr/.*ADD.*A0StP,A0StP,\#(0x$x{1,8})/o; - $funcre = qr/^$x* <[^\$](.*)>:$/; } elsif ($arch eq 'mips64') { #8800402c: 67bdfff0 daddiu sp,sp,-16 $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o; @@ -102,9 +98,6 @@ my (@stack, $re, $dre, $x, $xs, $funcre); # pair for larger users. -- PFM. #a00048e0: d4fc40f0 addi.l r15,-240,r15 $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o; - } elsif ($arch =~ /^blackfin$/) { - # 0: 00 e8 38 01 LINK 0x4e0; - $re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o; } elsif ($arch eq 'sparc' || $arch eq 'sparc64') { # f0019d10: 9d e3 bf 90 save %sp, -112, %sp $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 0000000..9780efa --- /dev/null +++ b/scripts/clang-version.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# clang-version [-p] clang-command +# +# Prints the compiler version of `clang-command' in a canonical 4-digit form +# such as `0500' for clang-5.0 etc. +# +# With the -p option, prints the patchlevel as well, for example `050001' for +# clang-5.0.1 etc. +# + +if [ "$1" = "-p" ] ; then + with_patchlevel=1; + shift; +fi + +compiler="$*" + +if [ ${#compiler} -eq 0 ]; then + echo "Error: No compiler specified." + printf "Usage:\n\t$0 <clang-command>\n" + exit 1 +fi + +MAJOR=$(echo __clang_major__ | $compiler -E -x c - | tail -n 1) +MINOR=$(echo __clang_minor__ | $compiler -E -x c - | tail -n 1) +if [ "x$with_patchlevel" != "x" ] ; then + PATCHLEVEL=$(echo __clang_patchlevel__ | $compiler -E -x c - | tail -n 1) + printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL +else + printf "%02d%02d\\n" $MAJOR $MINOR +fi diff --git a/scripts/coccinelle/api/drm-get-put.cocci b/scripts/coccinelle/api/drm-get-put.cocci index 91fceb8..ceb71ea 100644 --- a/scripts/coccinelle/api/drm-get-put.cocci +++ b/scripts/coccinelle/api/drm-get-put.cocci @@ -16,12 +16,6 @@ expression object; @@ ( -- drm_mode_object_reference(object) -+ drm_mode_object_get(object) -| -- drm_mode_object_unreference(object) -+ drm_mode_object_put(object) -| - drm_connector_reference(object) + drm_connector_get(object) | @@ -62,10 +56,6 @@ position p; @@ ( -drm_mode_object_unreference@p(object) -| -drm_mode_object_reference@p(object) -| drm_connector_unreference@p(object) | drm_connector_reference@p(object) diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 0dc922b..a88b8c9 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -28,5 +28,7 @@ HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) # dependencies on generated files need to be listed explicitly $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h -# generated files need to be cleaned explicitly -clean-files := dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h +# generated files need to include *.cmd and be cleaned explicitly +generated-files := dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h +targets := $(generated-files) +clean-files := $(generated-files) diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index e661384..c07ba4d 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -53,26 +53,28 @@ struct check { struct check **prereq; }; -#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...) \ - static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \ - static struct check _nm = { \ - .name = #_nm, \ - .fn = (_fn), \ - .data = (_d), \ - .warn = (_w), \ - .error = (_e), \ +#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \ + static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \ + static struct check nm_ = { \ + .name = #nm_, \ + .fn = (fn_), \ + .data = (d_), \ + .warn = (w_), \ + .error = (e_), \ .status = UNCHECKED, \ - .num_prereqs = ARRAY_SIZE(_nm##_prereqs), \ - .prereq = _nm##_prereqs, \ + .num_prereqs = ARRAY_SIZE(nm_##_prereqs), \ + .prereq = nm_##_prereqs, \ }; -#define WARNING(_nm, _fn, _d, ...) \ - CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__) -#define ERROR(_nm, _fn, _d, ...) \ - CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__) -#define CHECK(_nm, _fn, _d, ...) \ - CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__) - -static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, +#define WARNING(nm_, fn_, d_, ...) \ + CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__) +#define ERROR(nm_, fn_, d_, ...) \ + CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__) +#define CHECK(nm_, fn_, d_, ...) \ + CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__) + +static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, + struct node *node, + struct property *prop, const char *fmt, ...) { va_list ap; @@ -83,19 +85,33 @@ static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, fprintf(stderr, "%s: %s (%s): ", strcmp(dti->outname, "-") ? dti->outname : "<stdout>", (c->error) ? "ERROR" : "Warning", c->name); + if (node) { + fprintf(stderr, "%s", node->fullpath); + if (prop) + fprintf(stderr, ":%s", prop->name); + fputs(": ", stderr); + } vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); } va_end(ap); } -#define FAIL(c, dti, ...) \ +#define FAIL(c, dti, node, ...) \ + do { \ + TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ + (c)->status = FAILED; \ + check_msg((c), dti, node, NULL, __VA_ARGS__); \ + } while (0) + +#define FAIL_PROP(c, dti, node, prop, ...) \ do { \ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ (c)->status = FAILED; \ - check_msg((c), dti, __VA_ARGS__); \ + check_msg((c), dti, node, prop, __VA_ARGS__); \ } while (0) + static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) { struct node *child; @@ -126,7 +142,7 @@ static bool run_check(struct check *c, struct dt_info *dti) error = error || run_check(prq, dti); if (prq->status != PASSED) { c->status = PREREQ; - check_msg(c, dti, "Failed prerequisite '%s'", + check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'", c->prereq[i]->name); } } @@ -156,7 +172,7 @@ out: static inline void check_always_fail(struct check *c, struct dt_info *dti, struct node *node) { - FAIL(c, dti, "always_fail check"); + FAIL(c, dti, node, "always_fail check"); } CHECK(always_fail, check_always_fail, NULL); @@ -171,14 +187,42 @@ static void check_is_string(struct check *c, struct dt_info *dti, return; /* Not present, assumed ok */ if (!data_is_one_string(prop->val)) - FAIL(c, dti, "\"%s\" property in %s is not a string", - propname, node->fullpath); + FAIL_PROP(c, dti, node, prop, "property is not a string"); } #define WARNING_IF_NOT_STRING(nm, propname) \ WARNING(nm, check_is_string, (propname)) #define ERROR_IF_NOT_STRING(nm, propname) \ ERROR(nm, check_is_string, (propname)) +static void check_is_string_list(struct check *c, struct dt_info *dti, + struct node *node) +{ + int rem, l; + struct property *prop; + char *propname = c->data; + char *str; + + prop = get_property(node, propname); + if (!prop) + return; /* Not present, assumed ok */ + + str = prop->val.val; + rem = prop->val.len; + while (rem > 0) { + l = strnlen(str, rem); + if (l == rem) { + FAIL_PROP(c, dti, node, prop, "property is not a string list"); + break; + } + rem -= l + 1; + str += l + 1; + } +} +#define WARNING_IF_NOT_STRING_LIST(nm, propname) \ + WARNING(nm, check_is_string_list, (propname)) +#define ERROR_IF_NOT_STRING_LIST(nm, propname) \ + ERROR(nm, check_is_string_list, (propname)) + static void check_is_cell(struct check *c, struct dt_info *dti, struct node *node) { @@ -190,8 +234,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti, return; /* Not present, assumed ok */ if (prop->val.len != sizeof(cell_t)) - FAIL(c, dti, "\"%s\" property in %s is not a single cell", - propname, node->fullpath); + FAIL_PROP(c, dti, node, prop, "property is not a single cell"); } #define WARNING_IF_NOT_CELL(nm, propname) \ WARNING(nm, check_is_cell, (propname)) @@ -212,8 +255,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti, child2; child2 = child2->next_sibling) if (streq(child->name, child2->name)) - FAIL(c, dti, "Duplicate node name %s", - child->fullpath); + FAIL(c, dti, node, "Duplicate node name"); } ERROR(duplicate_node_names, check_duplicate_node_names, NULL); @@ -227,8 +269,7 @@ static void check_duplicate_property_names(struct check *c, struct dt_info *dti, if (prop2->deleted) continue; if (streq(prop->name, prop2->name)) - FAIL(c, dti, "Duplicate property name %s in %s", - prop->name, node->fullpath); + FAIL_PROP(c, dti, node, prop, "Duplicate property name"); } } } @@ -246,8 +287,8 @@ static void check_node_name_chars(struct check *c, struct dt_info *dti, int n = strspn(node->name, c->data); if (n < strlen(node->name)) - FAIL(c, dti, "Bad character '%c' in node %s", - node->name[n], node->fullpath); + FAIL(c, dti, node, "Bad character '%c' in node name", + node->name[n]); } ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); @@ -257,8 +298,8 @@ static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, int n = strspn(node->name, c->data); if (n < node->basenamelen) - FAIL(c, dti, "Character '%c' not recommended in node %s", - node->name[n], node->fullpath); + FAIL(c, dti, node, "Character '%c' not recommended in node name", + node->name[n]); } CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); @@ -266,8 +307,7 @@ static void check_node_name_format(struct check *c, struct dt_info *dti, struct node *node) { if (strchr(get_unitname(node), '@')) - FAIL(c, dti, "Node %s has multiple '@' characters in name", - node->fullpath); + FAIL(c, dti, node, "multiple '@' characters in node name"); } ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); @@ -285,12 +325,10 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, if (prop) { if (!unitname[0]) - FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name", - node->fullpath); + FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); } else { if (unitname[0]) - FAIL(c, dti, "Node %s has a unit name, but no reg property", - node->fullpath); + FAIL(c, dti, node, "node has a unit name, but no reg property"); } } WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); @@ -304,8 +342,8 @@ static void check_property_name_chars(struct check *c, struct dt_info *dti, int n = strspn(prop->name, c->data); if (n < strlen(prop->name)) - FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s", - prop->name[n], prop->name, node->fullpath); + FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", + prop->name[n]); } } ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); @@ -336,8 +374,8 @@ static void check_property_name_chars_strict(struct check *c, n = strspn(name, c->data); } if (n < strlen(name)) - FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s", - name[n], prop->name, node->fullpath); + FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", + name[n]); } } CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); @@ -370,7 +408,7 @@ static void check_duplicate_label(struct check *c, struct dt_info *dti, return; if ((othernode != node) || (otherprop != prop) || (othermark != mark)) - FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT + FAIL(c, dti, node, "Duplicate label '%s' on " DESCLABEL_FMT " and " DESCLABEL_FMT, label, DESCLABEL_ARGS(node, prop, mark), DESCLABEL_ARGS(othernode, otherprop, othermark)); @@ -410,8 +448,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, return 0; if (prop->val.len != sizeof(cell_t)) { - FAIL(c, dti, "%s has bad length (%d) %s property", - node->fullpath, prop->val.len, prop->name); + FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", + prop->val.len, prop->name); return 0; } @@ -422,8 +460,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, /* "Set this node's phandle equal to some * other node's phandle". That's nonsensical * by construction. */ { - FAIL(c, dti, "%s in %s is a reference to another node", - prop->name, node->fullpath); + FAIL(c, dti, node, "%s is a reference to another node", + prop->name); } /* But setting this node's phandle equal to its own * phandle is allowed - that means allocate a unique @@ -436,8 +474,8 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, phandle = propval_cell(prop); if ((phandle == 0) || (phandle == -1)) { - FAIL(c, dti, "%s has bad value (0x%x) in %s property", - node->fullpath, phandle, prop->name); + FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", + phandle, prop->name); return 0; } @@ -463,16 +501,16 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti, return; if (linux_phandle && phandle && (phandle != linux_phandle)) - FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'" - " properties", node->fullpath); + FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" + " properties"); if (linux_phandle && !phandle) phandle = linux_phandle; other = get_node_by_phandle(root, phandle); if (other && (other != node)) { - FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)", - node->fullpath, phandle, other->fullpath); + FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", + phandle, other->fullpath); return; } @@ -496,8 +534,8 @@ static void check_name_properties(struct check *c, struct dt_info *dti, if ((prop->val.len != node->basenamelen+1) || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { - FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead" - " of base node name)", node->fullpath, prop->val.val); + FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" + " of base node name)", prop->val.val); } else { /* The name property is correct, and therefore redundant. * Delete it */ @@ -531,7 +569,7 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti, refnode = get_node_by_ref(dt, m->ref); if (! refnode) { if (!(dti->dtsflags & DTSF_PLUGIN)) - FAIL(c, dti, "Reference to non-existent node or " + FAIL(c, dti, node, "Reference to non-existent node or " "label \"%s\"\n", m->ref); else /* mark the entry as unresolved */ *((fdt32_t *)(prop->val.val + m->offset)) = @@ -563,7 +601,7 @@ static void fixup_path_references(struct check *c, struct dt_info *dti, refnode = get_node_by_ref(dt, m->ref); if (!refnode) { - FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n", + FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", m->ref); continue; } @@ -586,6 +624,45 @@ WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); WARNING_IF_NOT_STRING(model_is_string, "model"); WARNING_IF_NOT_STRING(status_is_string, "status"); +WARNING_IF_NOT_STRING(label_is_string, "label"); + +WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible"); + +static void check_names_is_string_list(struct check *c, struct dt_info *dti, + struct node *node) +{ + struct property *prop; + + for_each_property(node, prop) { + const char *s = strrchr(prop->name, '-'); + if (!s || !streq(s, "-names")) + continue; + + c->data = prop->name; + check_is_string_list(c, dti, node); + } +} +WARNING(names_is_string_list, check_names_is_string_list, NULL); + +static void check_alias_paths(struct check *c, struct dt_info *dti, + struct node *node) +{ + struct property *prop; + + if (!streq(node->name, "aliases")) + return; + + for_each_property(node, prop) { + if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { + FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", + prop->val.val); + continue; + } + if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) + FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); + } +} +WARNING(alias_paths, check_alias_paths, NULL); static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, struct node *node) @@ -622,21 +699,21 @@ static void check_reg_format(struct check *c, struct dt_info *dti, return; /* No "reg", that's fine */ if (!node->parent) { - FAIL(c, dti, "Root node has a \"reg\" property"); + FAIL(c, dti, node, "Root node has a \"reg\" property"); return; } if (prop->val.len == 0) - FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath); + FAIL_PROP(c, dti, node, prop, "property is empty"); addr_cells = node_addr_cells(node->parent); size_cells = node_size_cells(node->parent); entrylen = (addr_cells + size_cells) * sizeof(cell_t); if (!entrylen || (prop->val.len % entrylen) != 0) - FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) " - "(#address-cells == %d, #size-cells == %d)", - node->fullpath, prop->val.len, addr_cells, size_cells); + FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " + "(#address-cells == %d, #size-cells == %d)", + prop->val.len, addr_cells, size_cells); } WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); @@ -651,7 +728,7 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, return; if (!node->parent) { - FAIL(c, dti, "Root node has a \"ranges\" property"); + FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property"); return; } @@ -663,20 +740,20 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, if (prop->val.len == 0) { if (p_addr_cells != c_addr_cells) - FAIL(c, dti, "%s has empty \"ranges\" property but its " - "#address-cells (%d) differs from %s (%d)", - node->fullpath, c_addr_cells, node->parent->fullpath, - p_addr_cells); + FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " + "#address-cells (%d) differs from %s (%d)", + c_addr_cells, node->parent->fullpath, + p_addr_cells); if (p_size_cells != c_size_cells) - FAIL(c, dti, "%s has empty \"ranges\" property but its " - "#size-cells (%d) differs from %s (%d)", - node->fullpath, c_size_cells, node->parent->fullpath, - p_size_cells); + FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " + "#size-cells (%d) differs from %s (%d)", + c_size_cells, node->parent->fullpath, + p_size_cells); } else if ((prop->val.len % entrylen) != 0) { - FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) " - "(parent #address-cells == %d, child #address-cells == %d, " - "#size-cells == %d)", node->fullpath, prop->val.len, - p_addr_cells, c_addr_cells, c_size_cells); + FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) " + "(parent #address-cells == %d, child #address-cells == %d, " + "#size-cells == %d)", prop->val.len, + p_addr_cells, c_addr_cells, c_size_cells); } } WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); @@ -696,41 +773,33 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node * node->bus = &pci_bus; - if (!strneq(node->name, "pci", node->basenamelen) && - !strneq(node->name, "pcie", node->basenamelen)) - FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"", - node->fullpath); + if (!strprefixeq(node->name, node->basenamelen, "pci") && + !strprefixeq(node->name, node->basenamelen, "pcie")) + FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); prop = get_property(node, "ranges"); if (!prop) - FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)", - node->fullpath); + FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); if (node_addr_cells(node) != 3) - FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge", - node->fullpath); + FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); if (node_size_cells(node) != 2) - FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge", - node->fullpath); + FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); prop = get_property(node, "bus-range"); if (!prop) { - FAIL(c, dti, "Node %s missing bus-range for PCI bridge", - node->fullpath); + FAIL(c, dti, node, "missing bus-range for PCI bridge"); return; } if (prop->val.len != (sizeof(cell_t) * 2)) { - FAIL(c, dti, "Node %s bus-range must be 2 cells", - node->fullpath); + FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); return; } cells = (cell_t *)prop->val.val; if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) - FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell", - node->fullpath); + FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); if (fdt32_to_cpu(cells[1]) > 0xff) - FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256", - node->fullpath); + FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); } WARNING(pci_bridge, check_pci_bridge, NULL, &device_type_is_string, &addr_size_cells); @@ -760,8 +829,8 @@ static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struc max_bus = fdt32_to_cpu(cells[0]); } if ((bus_num < min_bus) || (bus_num > max_bus)) - FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)", - node->fullpath, bus_num, min_bus, max_bus); + FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", + bus_num, min_bus, max_bus); } WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); @@ -778,25 +847,22 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no prop = get_property(node, "reg"); if (!prop) { - FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath); + FAIL(c, dti, node, "missing PCI reg property"); return; } cells = (cell_t *)prop->val.val; if (cells[1] || cells[2]) - FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0", - node->fullpath); + FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); reg = fdt32_to_cpu(cells[0]); dev = (reg & 0xf800) >> 11; func = (reg & 0x700) >> 8; if (reg & 0xff000000) - FAIL(c, dti, "Node %s PCI reg address is not configuration space", - node->fullpath); + FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); if (reg & 0x000000ff) - FAIL(c, dti, "Node %s PCI reg config space address register number must be 0", - node->fullpath); + FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); if (func == 0) { snprintf(unit_addr, sizeof(unit_addr), "%x", dev); @@ -808,8 +874,8 @@ static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct no if (streq(unitname, unit_addr)) return; - FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"", - node->fullpath, unit_addr); + FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", + unit_addr); } WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); @@ -828,7 +894,7 @@ static bool node_is_compatible(struct node *node, const char *compat) for (str = prop->val.val, end = str + prop->val.len; str < end; str += strnlen(str, end - str) + 1) { - if (strneq(str, compat, end - str)) + if (strprefixeq(str, end - str, compat)) return true; } return false; @@ -865,7 +931,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no if (!cells) { if (node->parent->parent && !(node->bus == &simple_bus)) - FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath); + FAIL(c, dti, node, "missing or empty reg/ranges property"); return; } @@ -875,8 +941,8 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); if (!streq(unitname, unit_addr)) - FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", - node->fullpath, unit_addr); + FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", + unit_addr); } WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); @@ -892,14 +958,12 @@ static void check_unit_address_format(struct check *c, struct dt_info *dti, return; if (!strncmp(unitname, "0x", 2)) { - FAIL(c, dti, "Node %s unit name should not have leading \"0x\"", - node->fullpath); + FAIL(c, dti, node, "unit name should not have leading \"0x\""); /* skip over 0x for next test */ unitname += 2; } if (unitname[0] == '0' && isxdigit(unitname[1])) - FAIL(c, dti, "Node %s unit name should not have leading 0s", - node->fullpath); + FAIL(c, dti, node, "unit name should not have leading 0s"); } WARNING(unit_address_format, check_unit_address_format, NULL, &node_name_format, &pci_bridge, &simple_bus_bridge); @@ -922,16 +986,38 @@ static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, return; if (node->parent->addr_cells == -1) - FAIL(c, dti, "Relying on default #address-cells value for %s", - node->fullpath); + FAIL(c, dti, node, "Relying on default #address-cells value"); if (node->parent->size_cells == -1) - FAIL(c, dti, "Relying on default #size-cells value for %s", - node->fullpath); + FAIL(c, dti, node, "Relying on default #size-cells value"); } WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, &addr_size_cells); +static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, + struct node *node) +{ + struct property *prop; + struct node *child; + bool has_reg = false; + + if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) + return; + + if (get_property(node, "ranges") || !node->children) + return; + + for_each_child(node, child) { + prop = get_property(child, "reg"); + if (prop) + has_reg = true; + } + + if (!has_reg) + FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); +} +WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); + static void check_obsolete_chosen_interrupt_controller(struct check *c, struct dt_info *dti, struct node *node) @@ -950,12 +1036,61 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, prop = get_property(chosen, "interrupt-controller"); if (prop) - FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" " - "property"); + FAIL_PROP(c, dti, node, prop, + "/chosen has obsolete \"interrupt-controller\" property"); } WARNING(obsolete_chosen_interrupt_controller, check_obsolete_chosen_interrupt_controller, NULL); +static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, + struct node *node) +{ + if (!streq(node->name, "chosen")) + return; + + if (node->parent != dti->dt) + FAIL(c, dti, node, "chosen node must be at root node"); +} +WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL); + +static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, + struct node *node) +{ + struct property *prop; + + if (!streq(node->name, "chosen")) + return; + + prop = get_property(node, "bootargs"); + if (!prop) + return; + + c->data = prop->name; + check_is_string(c, dti, node); +} +WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL); + +static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, + struct node *node) +{ + struct property *prop; + + if (!streq(node->name, "chosen")) + return; + + prop = get_property(node, "stdout-path"); + if (!prop) { + prop = get_property(node, "linux,stdout-path"); + if (!prop) + return; + FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); + } + + c->data = prop->name; + check_is_string(c, dti, node); +} +WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL); + struct provider { const char *prop_name; const char *cell_name; @@ -972,8 +1107,9 @@ static void check_property_phandle_args(struct check *c, int cell, cellsize = 0; if (prop->val.len % sizeof(cell_t)) { - FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s", - prop->name, prop->val.len, sizeof(cell_t), node->fullpath); + FAIL_PROP(c, dti, node, prop, + "property size (%d) is invalid, expected multiple of %zu", + prop->val.len, sizeof(cell_t)); return; } @@ -1004,14 +1140,16 @@ static void check_property_phandle_args(struct check *c, break; } if (!m) - FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s", - prop->name, cell, node->fullpath); + FAIL_PROP(c, dti, node, prop, + "cell %d is not a phandle reference", + cell); } provider_node = get_node_by_phandle(root, phandle); if (!provider_node) { - FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)", - node->fullpath, prop->name, cell); + FAIL_PROP(c, dti, node, prop, + "Could not get phandle node for (cell %d)", + cell); break; } @@ -1021,16 +1159,17 @@ static void check_property_phandle_args(struct check *c, } else if (provider->optional) { cellsize = 0; } else { - FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])", + FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", provider->cell_name, provider_node->fullpath, - node->fullpath, prop->name, cell); + prop->name, cell); break; } if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { - FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s", - prop->name, prop->val.len, cellsize, node->fullpath); + FAIL_PROP(c, dti, node, prop, + "property size (%d) too small for cell size %d", + prop->val.len, cellsize); } } } @@ -1066,7 +1205,7 @@ WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); -WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells"); +WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells"); WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); static bool prop_is_gpio(struct property *prop) @@ -1132,8 +1271,8 @@ static void check_deprecated_gpio_property(struct check *c, if (!streq(str, "gpio")) continue; - FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s", - node->fullpath, prop->name); + FAIL_PROP(c, dti, node, prop, + "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); } } @@ -1167,9 +1306,8 @@ static void check_interrupts_property(struct check *c, return; if (irq_prop->val.len % sizeof(cell_t)) - FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s", - irq_prop->name, irq_prop->val.len, sizeof(cell_t), - node->fullpath); + FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", + irq_prop->val.len, sizeof(cell_t)); while (parent && !prop) { if (parent != node && node_is_interrupt_provider(parent)) { @@ -1187,14 +1325,12 @@ static void check_interrupts_property(struct check *c, irq_node = get_node_by_phandle(root, phandle); if (!irq_node) { - FAIL(c, dti, "Bad interrupt-parent phandle for %s", - node->fullpath); + FAIL_PROP(c, dti, parent, prop, "Bad phandle"); return; } if (!node_is_interrupt_provider(irq_node)) - FAIL(c, dti, - "Missing interrupt-controller or interrupt-map property in %s", - irq_node->fullpath); + FAIL(c, dti, irq_node, + "Missing interrupt-controller or interrupt-map property"); break; } @@ -1203,23 +1339,21 @@ static void check_interrupts_property(struct check *c, } if (!irq_node) { - FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath); + FAIL(c, dti, node, "Missing interrupt-parent"); return; } prop = get_property(irq_node, "#interrupt-cells"); if (!prop) { - FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s", - irq_node->fullpath); + FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); return; } irq_cells = propval_cell(prop); if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { - FAIL(c, dti, - "interrupts size is (%d), expected multiple of %d in %s", - irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)), - node->fullpath); + FAIL_PROP(c, dti, node, prop, + "size is (%d), expected multiple of %d", + irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); } } WARNING(interrupts_property, check_interrupts_property, &phandle_references); @@ -1236,6 +1370,9 @@ static struct check *check_table[] = { &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, &device_type_is_string, &model_is_string, &status_is_string, + &label_is_string, + + &compatible_is_string_list, &names_is_string_list, &property_name_chars_strict, &node_name_chars_strict, @@ -1253,7 +1390,9 @@ static struct check *check_table[] = { &simple_bus_reg, &avoid_default_addr_size, + &avoid_unnecessary_addr_size, &obsolete_chosen_interrupt_controller, + &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, &clocks_property, &cooling_device_property, @@ -1269,13 +1408,15 @@ static struct check *check_table[] = { &power_domains_property, &pwms_property, &resets_property, - &sound_dais_property, + &sound_dai_property, &thermal_sensors_property, &deprecated_gpio_property, &gpios_property, &interrupts_property, + &alias_paths, + &always_fail, }; diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped deleted file mode 100644 index 011bb96..0000000 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ /dev/null @@ -1,2259 +0,0 @@ -#line 2 "dtc-lexer.lex.c" - -#line 4 "dtc-lexer.lex.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 1 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -/* TODO: this is always defined, so inline it */ -#define yyconst const - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define yynoreturn __attribute__((__noreturn__)) -#else -#define yynoreturn -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - #define YY_LINENO_REWIND_TO(ptr) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = NULL; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -static void yyensure_buffer_stack (void ); -static void yy_load_buffer_state (void ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define yywrap() (/*CONSTCOND*/1) -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -FILE *yyin = NULL, *yyout = NULL; - -typedef int yy_state_type; - -extern int yylineno; - -int yylineno = 1; - -extern char *yytext; -#ifdef yytext_ptr -#undef yytext_ptr -#endif -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yynoreturn yy_fatal_error (yyconst char* msg ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 31 -#define YY_END_OF_BUFFER 32 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[166] = - { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, - 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, - 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, - 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, - 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, - 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, - 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, - 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, - 0, 0, 0, 8, 0 - } ; - -static yyconst YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 6, 7, 1, 1, 8, 9, 1, - 1, 10, 11, 11, 12, 11, 13, 14, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 17, 1, 18, - 19, 20, 11, 11, 21, 21, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 23, 22, 22, 22, 22, - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - - 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, - 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, - 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst YY_CHAR yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 3, 1, 4 - } ; - -static yyconst flex_uint16_t yy_base[180] = - { 0, - 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, - 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, - 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, - 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, - 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, - 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, - 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, - 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, - 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, - 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, - - 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, - 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, - 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, - 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, - 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, - 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, - 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, - 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - -static yyconst flex_int16_t yy_def[180] = - { 0, - 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, - 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, - 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, - 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, - 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, - 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, - 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, - 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, - - 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, - 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, - 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, - 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - -static yyconst flex_uint16_t yy_nxt[449] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, - 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, - 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, - 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, - 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, - 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, - - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, - 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, - 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, - 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, - 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, - 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, - 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, - 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, - 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, - - 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, - 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, - 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, - 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, - 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, - 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, - 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, - 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, - 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, - 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, - - 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, - 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, - 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, - 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, - 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, - 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, - 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, - 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, - 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, - 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, - - 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165 - } ; - -static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, - 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, - 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, - 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, - 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, - 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, - 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, - 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, - 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, - 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, - 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, - - 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, - 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, - 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, - 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, - 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, - 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, - 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, - 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, - 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, - 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, - - 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, - 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, - 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, - 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, - 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, - 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, - 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, - 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, - 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, - - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "dtc-lexer.l" -/* - * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#define YY_NO_INPUT 1 - - - -#line 37 "dtc-lexer.l" -#include "dtc.h" -#include "srcpos.h" -#include "dtc-parser.tab.h" - -YYLTYPE yylloc; -extern bool treesource_error; - -/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ -#define YY_USER_ACTION \ - { \ - srcpos_update(&yylloc, yytext, yyleng); \ - } - -/*#define LEXDEBUG 1*/ - -#ifdef LEXDEBUG -#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) -#else -#define DPRINT(fmt, ...) do { } while (0) -#endif - -static int dts_version = 1; - -#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ - BEGIN(V1); \ - -static void push_input_file(const char *filename); -static bool pop_input_file(void); -static void PRINTF(1, 2) lexical_error(const char *fmt, ...); - -#line 661 "dtc-lexer.lex.c" - -#define INITIAL 0 -#define BYTESTRING 1 -#define PROPNODENAME 2 -#define V1 3 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * _in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * _out_str ); - - int yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int _line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - -#ifndef YY_NO_UNPUT - -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK /*LINTED*/break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - yy_state_type yy_current_state; - char *yy_cp, *yy_bp; - int yy_act; - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - { -#line 69 "dtc-lexer.l" - -#line 885 "dtc-lexer.lex.c" - - while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); -yy_match: - do - { - YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -/* rule 1 can match eol */ -YY_RULE_SETUP -#line 70 "dtc-lexer.l" -{ - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; - push_input_file(name); - } - YY_BREAK -case 2: -/* rule 2 can match eol */ -YY_RULE_SETUP -#line 76 "dtc-lexer.l" -{ - char *line, *fnstart, *fnend; - struct data fn; - /* skip text before line # */ - line = yytext; - while (!isdigit((unsigned char)*line)) - line++; - - /* regexp ensures that first and list " - * in the whole yytext are those at - * beginning and end of the filename string */ - fnstart = memchr(yytext, '"', yyleng); - for (fnend = yytext + yyleng - 1; - *fnend != '"'; fnend--) - ; - assert(fnstart && fnend && (fnend > fnstart)); - - fn = data_copy_escape_string(fnstart + 1, - fnend - fnstart - 1); - - /* Don't allow nuls in filenames */ - if (memchr(fn.val, '\0', fn.len - 1)) - lexical_error("nul in line number directive"); - - /* -1 since #line is the number of the next line */ - srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); - data_free(fn); - } - YY_BREAK -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(BYTESTRING): -case YY_STATE_EOF(PROPNODENAME): -case YY_STATE_EOF(V1): -#line 105 "dtc-lexer.l" -{ - if (!pop_input_file()) { - yyterminate(); - } - } - YY_BREAK -case 3: -/* rule 3 can match eol */ -YY_RULE_SETUP -#line 111 "dtc-lexer.l" -{ - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, - yyleng-2); - return DT_STRING; - } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 118 "dtc-lexer.l" -{ - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; - BEGIN_DEFAULT(); - return DT_V1; - } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 125 "dtc-lexer.l" -{ - DPRINT("Keyword: /plugin/\n"); - return DT_PLUGIN; - } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 130 "dtc-lexer.l" -{ - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 136 "dtc-lexer.l" -{ - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 142 "dtc-lexer.l" -{ - DPRINT("Keyword: /delete-property/\n"); - DPRINT("<PROPNODENAME>\n"); - BEGIN(PROPNODENAME); - return DT_DEL_PROP; - } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 149 "dtc-lexer.l" -{ - DPRINT("Keyword: /delete-node/\n"); - DPRINT("<PROPNODENAME>\n"); - BEGIN(PROPNODENAME); - return DT_DEL_NODE; - } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 156 "dtc-lexer.l" -{ - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); - yylval.labelref[yyleng-1] = '\0'; - return DT_LABEL; - } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 163 "dtc-lexer.l" -{ - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); - - errno = 0; - yylval.integer = strtoull(yytext, &e, 0); - - if (*e && e[strspn(e, "UL")]) { - lexical_error("Bad integer literal '%s'", - yytext); - } - - if (errno == ERANGE) - lexical_error("Integer literal '%s' out of range", - yytext); - else - /* ERANGE is the only strtoull error triggerable - * by strings matching the pattern */ - assert(errno == 0); - return DT_LITERAL; - } - YY_BREAK -case 12: -/* rule 12 can match eol */ -YY_RULE_SETUP -#line 185 "dtc-lexer.l" -{ - struct data d; - DPRINT("Character literal: %s\n", yytext); - - d = data_copy_escape_string(yytext+1, yyleng-2); - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; - } else { - yylval.integer = (unsigned char)d.val[0]; - - if (d.len > 2) - lexical_error("Character literal has %d" - " characters instead of 1", - d.len - 1); - } - - data_free(d); - return DT_CHAR_LITERAL; - } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 206 "dtc-lexer.l" -{ /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 212 "dtc-lexer.l" -{ /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); - return DT_REF; - } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 219 "dtc-lexer.l" -{ - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 225 "dtc-lexer.l" -{ - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 231 "dtc-lexer.l" -{ - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? - yytext + 1 : yytext); - BEGIN_DEFAULT(); - return DT_PROPNODENAME; - } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 239 "dtc-lexer.l" -{ - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK -case 19: -/* rule 19 can match eol */ -YY_RULE_SETUP -#line 244 "dtc-lexer.l" -/* eat whitespace */ - YY_BREAK -case 20: -/* rule 20 can match eol */ -YY_RULE_SETUP -#line 245 "dtc-lexer.l" -/* eat C-style comments */ - YY_BREAK -case 21: -/* rule 21 can match eol */ -YY_RULE_SETUP -#line 246 "dtc-lexer.l" -/* eat C++-style comments */ - YY_BREAK -case 22: -YY_RULE_SETUP -#line 248 "dtc-lexer.l" -{ return DT_LSHIFT; }; - YY_BREAK -case 23: -YY_RULE_SETUP -#line 249 "dtc-lexer.l" -{ return DT_RSHIFT; }; - YY_BREAK -case 24: -YY_RULE_SETUP -#line 250 "dtc-lexer.l" -{ return DT_LE; }; - YY_BREAK -case 25: -YY_RULE_SETUP -#line 251 "dtc-lexer.l" -{ return DT_GE; }; - YY_BREAK -case 26: -YY_RULE_SETUP -#line 252 "dtc-lexer.l" -{ return DT_EQ; }; - YY_BREAK -case 27: -YY_RULE_SETUP -#line 253 "dtc-lexer.l" -{ return DT_NE; }; - YY_BREAK -case 28: -YY_RULE_SETUP -#line 254 "dtc-lexer.l" -{ return DT_AND; }; - YY_BREAK -case 29: -YY_RULE_SETUP -#line 255 "dtc-lexer.l" -{ return DT_OR; }; - YY_BREAK -case 30: -YY_RULE_SETUP -#line 257 "dtc-lexer.l" -{ - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); - if (yytext[0] == '[') { - DPRINT("<BYTESTRING>\n"); - BEGIN(BYTESTRING); - } - if ((yytext[0] == '{') - || (yytext[0] == ';')) { - DPRINT("<PROPNODENAME>\n"); - BEGIN(PROPNODENAME); - } - return yytext[0]; - } - YY_BREAK -case 31: -YY_RULE_SETUP -#line 272 "dtc-lexer.l" -ECHO; - YY_BREAK -#line 1257 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of user's declarations */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - char *source = (yytext_ptr); - int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = NULL; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - yy_state_type yy_current_state; - char *yy_cp; - - yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - int yy_is_jam; - char *yy_cp = (yy_c_buf_p); - - YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - yy_is_jam = (yy_current_state == 165); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_UNPUT - -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = (yy_size_t)size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ); - - yyfree((void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - int num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return NULL; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = NULL; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -{ - - return yy_scan_bytes(yystr,(int) strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = (yy_size_t) (_yybytes_len + 2); - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yynoreturn yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -int yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param _line_number line number - * - */ -void yyset_lineno (int _line_number ) -{ - - yylineno = _line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param _in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * _in_str ) -{ - yyin = _in_str ; -} - -void yyset_out (FILE * _out_str ) -{ - yyout = _out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int _bdebug ) -{ - yy_flex_debug = _bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = NULL; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = NULL; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = NULL; - yyout = NULL; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - - int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return malloc(size); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return realloc(ptr, size); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 272 "dtc-lexer.l" - - - -static void push_input_file(const char *filename) -{ - assert(filename); - - srcfile_push(filename); - - yyin = current_srcfile->f; - - yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE)); -} - - -static bool pop_input_file(void) -{ - if (srcfile_pop() == 0) - return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - - return true; -} - -static void lexical_error(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - srcpos_verror(&yylloc, "Lexical error", fmt, ap); - va_end(ap); - - treesource_error = true; -} - diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped deleted file mode 100644 index aea514f..0000000 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ /dev/null @@ -1,2321 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.0.4" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* Copy the first part of user declarations. */ -#line 20 "dtc-parser.y" /* yacc.c:339 */ - -#include <stdio.h> -#include <inttypes.h> - -#include "dtc.h" -#include "srcpos.h" - -extern int yylex(void); -extern void yyerror(char const *s); -#define ERROR(loc, ...) \ - do { \ - srcpos_error((loc), "Error", __VA_ARGS__); \ - treesource_error = true; \ - } while (0) - -extern struct dt_info *parser_output; -extern bool treesource_error; - -#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ - -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "dtc-parser.tab.h". */ -#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED -# define YY_YY_DTC_PARSER_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - DT_V1 = 258, - DT_PLUGIN = 259, - DT_MEMRESERVE = 260, - DT_LSHIFT = 261, - DT_RSHIFT = 262, - DT_LE = 263, - DT_GE = 264, - DT_EQ = 265, - DT_NE = 266, - DT_AND = 267, - DT_OR = 268, - DT_BITS = 269, - DT_DEL_PROP = 270, - DT_DEL_NODE = 271, - DT_PROPNODENAME = 272, - DT_LITERAL = 273, - DT_CHAR_LITERAL = 274, - DT_BYTE = 275, - DT_STRING = 276, - DT_LABEL = 277, - DT_REF = 278, - DT_INCBIN = 279 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE -{ -#line 39 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; - char *labelref; - uint8_t byte; - struct data data; - - struct { - struct data data; - int bits; - } array; - - struct property *prop; - struct property *proplist; - struct node *node; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; - unsigned int flags; - -#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -extern YYSTYPE yylval; -extern YYLTYPE yylloc; -int yyparse (void); - -#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -#line 201 "dtc-parser.tab.c" /* yacc.c:358 */ - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 6 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 138 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 48 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 30 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 85 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 149 - -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 279 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, - 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, - 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 -}; - -#if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 109, 109, 117, 121, 128, 129, 139, 142, 149, - 153, 161, 165, 170, 181, 200, 213, 220, 228, 231, - 238, 242, 246, 250, 258, 262, 266, 270, 274, 290, - 300, 308, 311, 315, 322, 338, 343, 362, 376, 383, - 384, 385, 392, 396, 397, 401, 402, 406, 407, 411, - 412, 416, 417, 421, 422, 426, 427, 428, 432, 433, - 434, 435, 436, 440, 441, 442, 446, 447, 448, 452, - 453, 462, 471, 475, 476, 477, 478, 483, 486, 490, - 498, 501, 505, 513, 517, 521 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", - "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", - "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", - "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", - "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", - "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", - "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", - "header", "headers", "memreserves", "memreserve", "devicetree", - "nodedef", "proplist", "propdef", "propdata", "propdataprefix", - "arrayprefix", "integer_prim", "integer_expr", "integer_trinary", - "integer_or", "integer_and", "integer_bitor", "integer_bitxor", - "integer_bitand", "integer_eq", "integer_rela", "integer_shift", - "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes", - "subnode", YY_NULLPTR -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, - 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, - 94, 38, 43, 45, 42, 37, 126, 33 -}; -# endif - -#define YYPACT_NINF -44 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-44))) - -#define YYTABLE_NINF -1 - -#define yytable_value_is_error(Yytable_value) \ - 0 - - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int8 yypact[] = -{ - 14, 27, 61, 14, 8, 18, -44, -44, 37, 8, - 40, 8, 64, -44, -44, -12, 37, -44, 50, 52, - -44, -44, -12, -12, -12, -44, 51, -44, -4, 78, - 53, 54, 55, 17, 2, 30, 38, -3, -44, 66, - -44, -44, 70, 72, 50, 50, -44, -44, -44, -44, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -44, - 3, 73, 50, -44, -44, 78, 59, 53, 54, 55, - 17, 2, 2, 30, 30, 30, 30, 38, 38, -3, - -3, -44, -44, -44, 82, 83, 44, 3, -44, 74, - 3, -44, -44, -12, 76, 79, -44, -44, -44, -44, - -44, 80, -44, -44, -44, -44, -44, -10, 36, -44, - -44, -44, -44, 85, -44, -44, -44, 75, -44, -44, - 21, 71, 88, -6, -44, -44, -44, -44, -44, 11, - -44, -44, -44, 37, -44, 77, 37, 81, -44 -}; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 0, 5, 7, 3, 1, 6, 0, 0, - 16, 7, 0, 39, 40, 0, 0, 10, 0, 2, - 8, 4, 0, 0, 0, 73, 0, 42, 43, 45, - 47, 49, 51, 53, 55, 58, 65, 68, 72, 0, - 18, 11, 0, 0, 0, 0, 74, 75, 76, 41, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 80, 0, 0, 14, 12, 46, 0, 48, 50, 52, - 54, 56, 57, 61, 62, 60, 59, 63, 64, 66, - 67, 70, 69, 71, 0, 0, 0, 0, 19, 0, - 80, 15, 13, 0, 0, 0, 21, 31, 83, 23, - 85, 0, 82, 81, 44, 22, 84, 0, 0, 17, - 30, 20, 32, 0, 24, 33, 27, 0, 77, 35, - 0, 0, 0, 0, 38, 37, 25, 36, 34, 0, - 78, 79, 26, 0, 29, 0, 0, 0, 28 -}; - - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -44, -44, -44, 103, 99, 104, -44, -43, -44, -21, - -44, -44, -44, -8, 63, 9, -44, 65, 67, 68, - 69, 62, 26, 4, 22, 23, -19, -44, 20, 28 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 2, 3, 4, 10, 11, 19, 41, 70, 98, - 117, 118, 130, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 133, 99, 100 -}; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_uint8 yytable[] = -{ - 16, 73, 74, 46, 47, 48, 13, 14, 39, 50, - 58, 59, 120, 8, 140, 121, 141, 1, 94, 95, - 96, 15, 12, 66, 122, 97, 142, 56, 57, 102, - 9, 22, 60, 51, 23, 24, 62, 63, 61, 13, - 14, 67, 68, 134, 135, 143, 144, 91, 92, 93, - 123, 136, 5, 108, 15, 13, 14, 124, 125, 126, - 127, 6, 83, 84, 85, 86, 18, 128, 42, 106, - 15, 40, 129, 107, 43, 44, 109, 40, 45, 112, - 64, 65, 81, 82, 87, 88, 49, 89, 90, 21, - 52, 69, 53, 71, 54, 72, 55, 103, 101, 104, - 105, 115, 111, 131, 116, 119, 7, 138, 132, 139, - 20, 146, 114, 17, 76, 75, 148, 80, 0, 77, - 113, 78, 137, 79, 0, 110, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 145, 0, 0, 147 -}; - -static const yytype_int16 yycheck[] = -{ - 8, 44, 45, 22, 23, 24, 18, 19, 16, 13, - 8, 9, 22, 5, 20, 25, 22, 3, 15, 16, - 17, 33, 4, 26, 34, 22, 32, 10, 11, 72, - 22, 43, 30, 37, 46, 47, 6, 7, 36, 18, - 19, 44, 45, 22, 23, 34, 35, 66, 67, 68, - 14, 30, 25, 96, 33, 18, 19, 21, 22, 23, - 24, 0, 58, 59, 60, 61, 26, 31, 16, 25, - 33, 27, 36, 29, 22, 23, 97, 27, 26, 100, - 42, 43, 56, 57, 62, 63, 35, 64, 65, 25, - 12, 25, 39, 23, 40, 23, 41, 38, 25, 17, - 17, 25, 28, 18, 25, 25, 3, 36, 33, 21, - 11, 34, 103, 9, 51, 50, 35, 55, -1, 52, - 100, 53, 130, 54, -1, 97, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 143, -1, -1, 146 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 49, 50, 51, 25, 0, 51, 5, 22, - 52, 53, 4, 18, 19, 33, 61, 53, 26, 54, - 52, 25, 43, 46, 47, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 61, - 27, 55, 16, 22, 23, 26, 74, 74, 74, 35, - 13, 37, 12, 39, 40, 41, 10, 11, 8, 9, - 30, 36, 6, 7, 42, 43, 26, 44, 45, 25, - 56, 23, 23, 55, 55, 65, 62, 66, 67, 68, - 69, 70, 70, 71, 71, 71, 71, 72, 72, 73, - 73, 74, 74, 74, 15, 16, 17, 22, 57, 76, - 77, 25, 55, 38, 17, 17, 25, 29, 55, 57, - 77, 28, 57, 76, 63, 25, 25, 58, 59, 25, - 22, 25, 34, 14, 21, 22, 23, 24, 31, 36, - 60, 18, 33, 75, 22, 23, 30, 61, 36, 21, - 20, 22, 32, 34, 35, 61, 34, 61, 35 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, - 53, 54, 54, 54, 54, 54, 54, 55, 56, 56, - 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, - 58, 59, 59, 59, 60, 60, 60, 60, 60, 61, - 61, 61, 62, 63, 63, 64, 64, 65, 65, 66, - 66, 67, 67, 68, 68, 69, 69, 69, 70, 70, - 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, - 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, - 76, 76, 76, 77, 77, 77 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 3, 2, 4, 1, 2, 0, 2, 4, - 2, 2, 3, 4, 3, 4, 0, 5, 0, 2, - 4, 2, 3, 2, 2, 3, 4, 2, 9, 5, - 2, 0, 2, 2, 3, 1, 2, 2, 2, 1, - 1, 3, 1, 1, 5, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 1, 3, 3, 1, 3, - 3, 3, 1, 1, 2, 2, 2, 0, 2, 2, - 0, 2, 2, 2, 3, 2 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -YY_ATTRIBUTE_UNUSED -static unsigned -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -{ - unsigned res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += YYFPRINTF (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += YYFPRINTF (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += YYFPRINTF (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += YYFPRINTF (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += YYFPRINTF (yyo, "-%d", end_col); - } - return res; - } - -# define YY_LOCATION_PRINT(File, Loc) \ - yy_location_print_ (File, &(Loc)) - -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - YYUSE (yylocationp); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -{ - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -{ - unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; -/* Number of syntax errors so far. */ -int yynerrs; - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - 'yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - yylsp[0] = yylloc; - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 110 "dtc-parser.y" /* yacc.c:1646 */ - { - parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node), - guess_boot_cpuid((yyvsp[0].node))); - } -#line 1478 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: -#line 118 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.flags) = DTSF_V1; - } -#line 1486 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: -#line 122 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.flags) = DTSF_V1 | DTSF_PLUGIN; - } -#line 1494 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: -#line 130 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].flags) != (yyvsp[-1].flags)) - ERROR(&(yylsp[0]), "Header flags don't match earlier ones"); - (yyval.flags) = (yyvsp[-1].flags); - } -#line 1504 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 7: -#line 139 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = NULL; - } -#line 1512 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 8: -#line 143 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } -#line 1520 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 9: -#line 150 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } -#line 1528 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 10: -#line 154 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); - (yyval.re) = (yyvsp[0].re); - } -#line 1537 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 11: -#line 162 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), ""); - } -#line 1545 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 12: -#line 166 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } -#line 1553 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 13: -#line 171 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - - if (target) { - add_label(&target->labels, (yyvsp[-2].labelref)); - merge_nodes(target, (yyvsp[0].node)); - } else - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[-3].node); - } -#line 1568 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 14: -#line 182 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); - - if (target) { - merge_nodes(target, (yyvsp[0].node)); - } else { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN) - add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref)); - else - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - } - (yyval.node) = (yyvsp[-2].node); - } -#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 15: -#line 201 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - - if (target) - delete_node(target); - else - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - - - (yyval.node) = (yyvsp[-3].node); - } -#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 16: -#line 213 "dtc-parser.y" /* yacc.c:1646 */ - { - /* build empty node */ - (yyval.node) = name_node(build_node(NULL, NULL), ""); - } -#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 17: -#line 221 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } -#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 18: -#line 228 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = NULL; - } -#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 19: -#line 232 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } -#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 20: -#line 239 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } -#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 21: -#line 243 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } -#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 22: -#line 247 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } -#line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 23: -#line 251 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); - (yyval.prop) = (yyvsp[0].prop); - } -#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 24: -#line 259 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } -#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 25: -#line 263 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } -#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 26: -#line 267 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); - } -#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 27: -#line 271 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); - } -#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 28: -#line 275 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; - - if ((yyvsp[-3].integer) != 0) - if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, - strerror(errno)); - - d = data_copy_file(f, (yyvsp[-1].integer)); - - (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } -#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 29: -#line 291 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - - (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } -#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 30: -#line 301 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 31: -#line 308 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } -#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 32: -#line 312 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = (yyvsp[-1].data); - } -#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 33: -#line 316 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 34: -#line 323 "dtc-parser.y" /* yacc.c:1646 */ - { - unsigned long long bits; - - bits = (yyvsp[-1].integer); - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { - ERROR(&(yylsp[-1]), "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } - - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } -#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 35: -#line 339 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } -#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 36: -#line 344 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[-1].array).bits < 64) { - uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one - * (negative and sign-extended). The second - * condition is true if when we set all bits - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ - if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) - ERROR(&(yylsp[0]), "Value out of range for" - " %d-bit array element", (yyvsp[-1].array).bits); - } - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } -#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 37: -#line 363 "dtc-parser.y" /* yacc.c:1646 */ - { - uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - - if ((yyvsp[-1].array).bits == 32) - (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, - REF_PHANDLE, - (yyvsp[0].labelref)); - else - ERROR(&(yylsp[0]), "References are only allowed in " - "arrays with 32-bit elements."); - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } -#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 38: -#line 377 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } -#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 41: -#line 386 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.integer) = (yyvsp[-1].integer); - } -#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 44: -#line 397 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } -#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 46: -#line 402 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } -#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 48: -#line 407 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } -#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 50: -#line 412 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } -#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 52: -#line 417 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } -#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 54: -#line 422 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } -#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 56: -#line 427 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } -#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 57: -#line 428 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } -#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 59: -#line 433 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } -#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 60: -#line 434 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } -#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 61: -#line 435 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } -#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 62: -#line 436 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } -#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 63: -#line 440 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } -#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 64: -#line 441 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } -#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 66: -#line 446 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } -#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 67: -#line 447 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } -#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 69: -#line 452 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } -#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 70: -#line 454 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].integer) != 0) { - (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); - } else { - ERROR(&(yyloc), "Division by zero"); - (yyval.integer) = 0; - } - } -#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 71: -#line 463 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].integer) != 0) { - (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); - } else { - ERROR(&(yyloc), "Division by zero"); - (yyval.integer) = 0; - } - } -#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 74: -#line 476 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = -(yyvsp[0].integer); } -#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 75: -#line 477 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = ~(yyvsp[0].integer); } -#line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 76: -#line 478 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = !(yyvsp[0].integer); } -#line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 77: -#line 483 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } -#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 78: -#line 487 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); - } -#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 79: -#line 491 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } -#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 80: -#line 498 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = NULL; - } -#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 81: -#line 502 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } -#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 82: -#line 506 "dtc-parser.y" /* yacc.c:1646 */ - { - ERROR(&(yylsp[0]), "Properties must precede subnodes"); - YYERROR; - } -#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 83: -#line 514 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } -#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 84: -#line 518 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); - } -#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 85: -#line 522 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[0].node); - } -#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - -#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - return yyresult; -} -#line 528 "dtc-parser.y" /* yacc.c:1906 */ - - -void yyerror(char const *s) -{ - ERROR(&yylloc, "%s", s); -} diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped deleted file mode 100644 index 6aa512c..0000000 --- a/scripts/dtc/dtc-parser.tab.h_shipped +++ /dev/null @@ -1,125 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED -# define YY_YY_DTC_PARSER_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - DT_V1 = 258, - DT_PLUGIN = 259, - DT_MEMRESERVE = 260, - DT_LSHIFT = 261, - DT_RSHIFT = 262, - DT_LE = 263, - DT_GE = 264, - DT_EQ = 265, - DT_NE = 266, - DT_AND = 267, - DT_OR = 268, - DT_BITS = 269, - DT_DEL_PROP = 270, - DT_DEL_NODE = 271, - DT_PROPNODENAME = 272, - DT_LITERAL = 273, - DT_CHAR_LITERAL = 274, - DT_BYTE = 275, - DT_STRING = 276, - DT_LABEL = 277, - DT_REF = 278, - DT_INCBIN = 279 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE -{ -#line 39 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; - char *labelref; - uint8_t byte; - struct data data; - - struct { - struct data data; - int bits; - } array; - - struct property *prop; - struct property *proplist; - struct node *node; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; - unsigned int flags; - -#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -extern YYSTYPE yylval; -extern YYLTYPE yylloc; -int yyparse (void); - -#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index affc81a..44af170 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -166,7 +166,17 @@ devicetree: { $$ = merge_nodes($1, $3); } - + | DT_REF nodedef + { + /* + * We rely on the rule being always: + * versioninfo plugindecl memreserves devicetree + * so $-1 is what we want (plugindecl) + */ + if (!($<flags>-1 & DTSF_PLUGIN)) + ERROR(&@2, "Label or path %s not found", $1); + $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); + } | devicetree DT_LABEL DT_REF nodedef { struct node *target = get_node_by_ref($1, $3); @@ -209,11 +219,6 @@ devicetree: $$ = $1; } - | /* empty */ - { - /* build empty node */ - $$ = name_node(build_node(NULL, NULL), ""); - } ; nodedef: diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index 5ed873c..c36994e 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) } /* Usage related data. */ -#define FDT_VERSION(version) _FDT_VERSION(version) -#define _FDT_VERSION(version) #version static const char usage_synopsis[] = "dtc [options] <input file>"; static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; static struct option const usage_long_opts[] = { @@ -98,7 +96,7 @@ static const char * const usage_opts_help[] = { "\t\tdts - device tree source text\n" "\t\tdtb - device tree blob\n" "\t\tasm - assembler source", - "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", + "\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)", "\n\tOutput dependency file", "\n\tMake space for <number> reserve map entries (for dtb and asm output)", "\n\tMake the blob at least <bytes> long (extra space)", @@ -319,13 +317,14 @@ int main(int argc, char *argv[]) dti->boot_cpuid_phys = cmdline_boot_cpuid; fill_fullpaths(dti->dt, ""); - process_checks(force, dti); /* on a plugin, generate by default */ if (dti->dtsflags & DTSF_PLUGIN) { generate_fixups = 1; } + process_checks(force, dti); + if (auto_label_aliases) generate_label_tree(dti, "aliases", false); diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 35cf926..3b18a42 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -1,5 +1,5 @@ -#ifndef _DTC_H -#define _DTC_H +#ifndef DTC_H +#define DTC_H /* * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. @@ -67,7 +67,8 @@ typedef uint32_t cell_t; #define streq(a, b) (strcmp((a), (b)) == 0) -#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0) +#define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0)) #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) @@ -203,7 +204,7 @@ struct node *build_node_delete(void); struct node *name_node(struct node *node, char *name); struct node *chain_node(struct node *first, struct node *list); struct node *merge_nodes(struct node *old_node, struct node *new_node); -void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); +struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref); void add_property(struct node *node, struct property *prop); void delete_property_by_name(struct node *node, char *name); @@ -289,4 +290,4 @@ struct dt_info *dt_from_source(const char *f); struct dt_info *dt_from_fs(const char *dirname); -#endif /* _DTC_H */ +#endif /* DTC_H */ diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index fcf7154..8d268fb 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -731,7 +731,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath) plen = strlen(ppath); - if (!strneq(ppath, cpath, plen)) + if (!strstarts(cpath, ppath)) die("Path \"%s\" is not valid as a child of \"%s\"\n", cpath, ppath); diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 22286a1..7855a17 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c @@ -88,7 +88,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) || ((offset + len) > fdt_size_dt_struct(fdt))) return NULL; - return _fdt_offset_ptr(fdt, offset); + return fdt_offset_ptr_(fdt, offset); } uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) @@ -123,6 +123,9 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) /* skip-name offset, length and value */ offset += sizeof(struct fdt_property) - FDT_TAGSIZE + fdt32_to_cpu(*lenp); + if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && + ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) + offset += 4; break; case FDT_END: @@ -141,7 +144,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) return tag; } -int _fdt_check_node_offset(const void *fdt, int offset) +int fdt_check_node_offset_(const void *fdt, int offset) { if ((offset < 0) || (offset % FDT_TAGSIZE) || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) @@ -150,7 +153,7 @@ int _fdt_check_node_offset(const void *fdt, int offset) return offset; } -int _fdt_check_prop_offset(const void *fdt, int offset) +int fdt_check_prop_offset_(const void *fdt, int offset) { if ((offset < 0) || (offset % FDT_TAGSIZE) || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) @@ -165,7 +168,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth) uint32_t tag; if (offset >= 0) - if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) + if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0) return nextoffset; do { @@ -227,7 +230,7 @@ int fdt_next_subnode(const void *fdt, int offset) return offset; } -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) +const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; const char *last = strtab + tabsize - len; diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h index 526aedb..74961f9 100644 --- a/scripts/dtc/libfdt/fdt.h +++ b/scripts/dtc/libfdt/fdt.h @@ -1,5 +1,5 @@ -#ifndef _FDT_H -#define _FDT_H +#ifndef FDT_H +#define FDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. @@ -108,4 +108,4 @@ struct fdt_property { #define FDT_V16_SIZE FDT_V3_SIZE #define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) -#endif /* _FDT_H */ +#endif /* FDT_H */ diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c index bd81241..bf75388 100644 --- a/scripts/dtc/libfdt/fdt_overlay.c +++ b/scripts/dtc/libfdt/fdt_overlay.c @@ -1,3 +1,54 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2016 Free Electrons + * Copyright (C) 2016 NextThing Co. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "libfdt_env.h" #include <fdt.h> diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index 08de2cc..dfb3236 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c @@ -55,12 +55,13 @@ #include "libfdt_internal.h" -static int _fdt_nodename_eq(const void *fdt, int offset, +static int fdt_nodename_eq_(const void *fdt, int offset, const char *s, int len) { - const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); + int olen; + const char *p = fdt_get_name(fdt, offset, &olen); - if (!p) + if (!p || olen < len) /* short match */ return 0; @@ -80,7 +81,7 @@ const char *fdt_string(const void *fdt, int stroffset) return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; } -static int _fdt_string_eq(const void *fdt, int stroffset, +static int fdt_string_eq_(const void *fdt, int stroffset, const char *s, int len) { const char *p = fdt_string(fdt, stroffset); @@ -117,8 +118,8 @@ uint32_t fdt_get_max_phandle(const void *fdt) int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { FDT_CHECK_HEADER(fdt); - *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); - *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); + *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); + *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); return 0; } @@ -126,12 +127,12 @@ int fdt_num_mem_rsv(const void *fdt) { int i = 0; - while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) + while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) i++; return i; } -static int _nextprop(const void *fdt, int offset) +static int nextprop_(const void *fdt, int offset) { uint32_t tag; int nextoffset; @@ -166,7 +167,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, (offset >= 0) && (depth >= 0); offset = fdt_next_node(fdt, offset, &depth)) if ((depth == 1) - && _fdt_nodename_eq(fdt, offset, name, namelen)) + && fdt_nodename_eq_(fdt, offset, name, namelen)) return offset; if (depth < 0) @@ -232,17 +233,35 @@ int fdt_path_offset(const void *fdt, const char *path) const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) { - const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); + const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); + const char *nameptr; int err; if (((err = fdt_check_header(fdt)) != 0) - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) + || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) goto fail; + nameptr = nh->name; + + if (fdt_version(fdt) < 0x10) { + /* + * For old FDT versions, match the naming conventions of V16: + * give only the leaf name (after all /). The actual tree + * contents are loosely checked. + */ + const char *leaf; + leaf = strrchr(nameptr, '/'); + if (leaf == NULL) { + err = -FDT_ERR_BADSTRUCTURE; + goto fail; + } + nameptr = leaf+1; + } + if (len) - *len = strlen(nh->name); + *len = strlen(nameptr); - return nh->name; + return nameptr; fail: if (len) @@ -254,34 +273,34 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset) { int offset; - if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) + if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) return offset; - return _nextprop(fdt, offset); + return nextprop_(fdt, offset); } int fdt_next_property_offset(const void *fdt, int offset) { - if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) + if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) return offset; - return _nextprop(fdt, offset); + return nextprop_(fdt, offset); } -const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - int offset, - int *lenp) +static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, + int offset, + int *lenp) { int err; const struct fdt_property *prop; - if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { + if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; } - prop = _fdt_offset_ptr(fdt, offset); + prop = fdt_offset_ptr_(fdt, offset); if (lenp) *lenp = fdt32_to_cpu(prop->len); @@ -289,23 +308,44 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, return prop; } -const struct fdt_property *fdt_get_property_namelen(const void *fdt, - int offset, - const char *name, - int namelen, int *lenp) +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + int offset, + int *lenp) +{ + /* Prior to version 16, properties may need realignment + * and this API does not work. fdt_getprop_*() will, however. */ + + if (fdt_version(fdt) < 0x10) { + if (lenp) + *lenp = -FDT_ERR_BADVERSION; + return NULL; + } + + return fdt_get_property_by_offset_(fdt, offset, lenp); +} + +static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, + int offset, + const char *name, + int namelen, + int *lenp, + int *poffset) { for (offset = fdt_first_property_offset(fdt, offset); (offset >= 0); (offset = fdt_next_property_offset(fdt, offset))) { const struct fdt_property *prop; - if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { + if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) { offset = -FDT_ERR_INTERNAL; break; } - if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), - name, namelen)) + if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + name, namelen)) { + if (poffset) + *poffset = offset; return prop; + } } if (lenp) @@ -313,6 +353,25 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, return NULL; } + +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int offset, + const char *name, + int namelen, int *lenp) +{ + /* Prior to version 16, properties may need realignment + * and this API does not work. fdt_getprop_*() will, however. */ + if (fdt_version(fdt) < 0x10) { + if (lenp) + *lenp = -FDT_ERR_BADVERSION; + return NULL; + } + + return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp, + NULL); +} + + const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, const char *name, int *lenp) @@ -324,12 +383,18 @@ const struct fdt_property *fdt_get_property(const void *fdt, const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp) { + int poffset; const struct fdt_property *prop; - prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); + prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp, + &poffset); if (!prop) return NULL; + /* Handle realignment */ + if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 && + fdt32_to_cpu(prop->len) >= 8) + return prop->data + 4; return prop->data; } @@ -338,11 +403,16 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, { const struct fdt_property *prop; - prop = fdt_get_property_by_offset(fdt, offset, lenp); + prop = fdt_get_property_by_offset_(fdt, offset, lenp); if (!prop) return NULL; if (namep) *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + + /* Handle realignment */ + if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 && + fdt32_to_cpu(prop->len) >= 8) + return prop->data + 4; return prop->data; } diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 5c3a2bb..9b82905 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c @@ -55,8 +55,8 @@ #include "libfdt_internal.h" -static int _fdt_blocks_misordered(const void *fdt, - int mem_rsv_size, int struct_size) +static int fdt_blocks_misordered_(const void *fdt, + int mem_rsv_size, int struct_size) { return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) || (fdt_off_dt_struct(fdt) < @@ -67,13 +67,13 @@ static int _fdt_blocks_misordered(const void *fdt, (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); } -static int _fdt_rw_check_header(void *fdt) +static int fdt_rw_check_header_(void *fdt) { FDT_CHECK_HEADER(fdt); if (fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; - if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), + if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; if (fdt_version(fdt) > 17) @@ -84,20 +84,20 @@ static int _fdt_rw_check_header(void *fdt) #define FDT_RW_CHECK_HEADER(fdt) \ { \ - int __err; \ - if ((__err = _fdt_rw_check_header(fdt)) != 0) \ - return __err; \ + int err_; \ + if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ + return err_; \ } -static inline int _fdt_data_size(void *fdt) +static inline int fdt_data_size_(void *fdt) { return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); } -static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) +static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) { char *p = splicepoint; - char *end = (char *)fdt + _fdt_data_size(fdt); + char *end = (char *)fdt + fdt_data_size_(fdt); if (((p + oldlen) < p) || ((p + oldlen) > end)) return -FDT_ERR_BADOFFSET; @@ -109,12 +109,12 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) return 0; } -static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, +static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p, int oldn, int newn) { int delta = (newn - oldn) * sizeof(*p); int err; - err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); + err = fdt_splice_(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); if (err) return err; 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, return 0; } -static int _fdt_splice_struct(void *fdt, void *p, +static int fdt_splice_struct_(void *fdt, void *p, int oldlen, int newlen) { int delta = newlen - oldlen; int err; - if ((err = _fdt_splice(fdt, p, oldlen, newlen))) + if ((err = fdt_splice_(fdt, p, oldlen, newlen))) return err; 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, return 0; } -static int _fdt_splice_string(void *fdt, int newlen) +static int fdt_splice_string_(void *fdt, int newlen) { void *p = (char *)fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); int err; - if ((err = _fdt_splice(fdt, p, 0, newlen))) + if ((err = fdt_splice_(fdt, p, 0, newlen))) return err; fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); return 0; } -static int _fdt_find_add_string(void *fdt, const char *s) +static int fdt_find_add_string_(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); const char *p; @@ -157,13 +157,13 @@ static int _fdt_find_add_string(void *fdt, const char *s) int len = strlen(s) + 1; int err; - p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); + p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s); if (p) /* found it */ return (p - strtab); new = strtab + fdt_size_dt_strings(fdt); - err = _fdt_splice_string(fdt, len); + err = fdt_splice_string_(fdt, len); if (err) return err; @@ -178,8 +178,8 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) FDT_RW_CHECK_HEADER(fdt); - re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); - err = _fdt_splice_mem_rsv(fdt, re, 0, 1); + re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); + err = fdt_splice_mem_rsv_(fdt, re, 0, 1); if (err) return err; @@ -190,17 +190,17 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) int fdt_del_mem_rsv(void *fdt, int n) { - struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); + struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); FDT_RW_CHECK_HEADER(fdt); if (n >= fdt_num_mem_rsv(fdt)) return -FDT_ERR_NOTFOUND; - return _fdt_splice_mem_rsv(fdt, re, 1, 0); + return fdt_splice_mem_rsv_(fdt, re, 1, 0); } -static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, +static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, int len, struct fdt_property **prop) { int oldlen; @@ -210,7 +210,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, if (!*prop) return oldlen; - if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), + if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), FDT_TAGALIGN(len)))) return err; @@ -218,7 +218,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, return 0; } -static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, +static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, int len, struct fdt_property **prop) { int proplen; @@ -226,17 +226,17 @@ static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, int namestroff; int err; - if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) + if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) return nextoffset; - namestroff = _fdt_find_add_string(fdt, name); + namestroff = fdt_find_add_string_(fdt, name); if (namestroff < 0) return namestroff; - *prop = _fdt_offset_ptr_w(fdt, nextoffset); + *prop = fdt_offset_ptr_w_(fdt, nextoffset); proplen = sizeof(**prop) + FDT_TAGALIGN(len); - err = _fdt_splice_struct(fdt, *prop, 0, proplen); + err = fdt_splice_struct_(fdt, *prop, 0, proplen); if (err) return err; @@ -260,7 +260,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) newlen = strlen(name); - err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), + err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), FDT_TAGALIGN(newlen+1)); if (err) return err; @@ -277,9 +277,9 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, FDT_RW_CHECK_HEADER(fdt); - err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); + err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); if (err == -FDT_ERR_NOTFOUND) - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); + err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); if (err) return err; @@ -313,7 +313,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); if (prop) { newlen = len + oldlen; - err = _fdt_splice_struct(fdt, prop->data, + err = fdt_splice_struct_(fdt, prop->data, FDT_TAGALIGN(oldlen), FDT_TAGALIGN(newlen)); if (err) @@ -321,7 +321,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, prop->len = cpu_to_fdt32(newlen); memcpy(prop->data + oldlen, val, len); } else { - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); + err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); if (err) return err; memcpy(prop->data, val, len); @@ -341,7 +341,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) return len; proplen = sizeof(*prop) + FDT_TAGALIGN(len); - return _fdt_splice_struct(fdt, prop, proplen, 0); + return fdt_splice_struct_(fdt, prop, proplen, 0); } int fdt_add_subnode_namelen(void *fdt, int parentoffset, @@ -369,10 +369,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, tag = fdt_next_tag(fdt, offset, &nextoffset); } while ((tag == FDT_PROP) || (tag == FDT_NOP)); - nh = _fdt_offset_ptr_w(fdt, offset); + nh = fdt_offset_ptr_w_(fdt, offset); nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; - err = _fdt_splice_struct(fdt, nh, 0, nodelen); + err = fdt_splice_struct_(fdt, nh, 0, nodelen); if (err) return err; @@ -396,15 +396,15 @@ int fdt_del_node(void *fdt, int nodeoffset) FDT_RW_CHECK_HEADER(fdt); - endoffset = _fdt_node_end_offset(fdt, nodeoffset); + endoffset = fdt_node_end_offset_(fdt, nodeoffset); if (endoffset < 0) return endoffset; - return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), + return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), endoffset - nodeoffset, 0); } -static void _fdt_packblocks(const char *old, char *new, +static void fdt_packblocks_(const char *old, char *new, int mem_rsv_size, int struct_size) { int mem_rsv_off, struct_off, strings_off; @@ -450,7 +450,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) return struct_size; } - if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { + if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { /* no further work necessary */ err = fdt_move(fdt, buf, bufsize); if (err) @@ -478,7 +478,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) return -FDT_ERR_NOSPACE; } - _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); + fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size); memmove(buf, tmp, newsize); fdt_set_magic(buf, FDT_MAGIC); @@ -498,8 +498,8 @@ int fdt_pack(void *fdt) mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); - _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); - fdt_set_totalsize(fdt, _fdt_data_size(fdt)); + fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); + fdt_set_totalsize(fdt, fdt_data_size_(fdt)); return 0; } diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c index 2bd15e7..6d33cc2 100644 --- a/scripts/dtc/libfdt/fdt_sw.c +++ b/scripts/dtc/libfdt/fdt_sw.c @@ -55,7 +55,7 @@ #include "libfdt_internal.h" -static int _fdt_sw_check_header(void *fdt) +static int fdt_sw_check_header_(void *fdt) { if (fdt_magic(fdt) != FDT_SW_MAGIC) return -FDT_ERR_BADMAGIC; @@ -66,11 +66,11 @@ static int _fdt_sw_check_header(void *fdt) #define FDT_SW_CHECK_HEADER(fdt) \ { \ int err; \ - if ((err = _fdt_sw_check_header(fdt)) != 0) \ + if ((err = fdt_sw_check_header_(fdt)) != 0) \ return err; \ } -static void *_fdt_grab_space(void *fdt, size_t len) +static void *fdt_grab_space_(void *fdt, size_t len) { int offset = fdt_size_dt_struct(fdt); int spaceleft; @@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, size_t len) return NULL; fdt_set_size_dt_struct(fdt, offset + len); - return _fdt_offset_ptr_w(fdt, offset); + return fdt_offset_ptr_w_(fdt, offset); } int fdt_create(void *buf, int bufsize) @@ -174,7 +174,7 @@ int fdt_begin_node(void *fdt, const char *name) FDT_SW_CHECK_HEADER(fdt); - nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); + nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); if (! nh) return -FDT_ERR_NOSPACE; @@ -189,7 +189,7 @@ int fdt_end_node(void *fdt) FDT_SW_CHECK_HEADER(fdt); - en = _fdt_grab_space(fdt, FDT_TAGSIZE); + en = fdt_grab_space_(fdt, FDT_TAGSIZE); if (! en) return -FDT_ERR_NOSPACE; @@ -197,7 +197,7 @@ int fdt_end_node(void *fdt) return 0; } -static int _fdt_find_add_string(void *fdt, const char *s) +static int fdt_find_add_string_(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_totalsize(fdt); const char *p; @@ -205,7 +205,7 @@ static int _fdt_find_add_string(void *fdt, const char *s) int len = strlen(s) + 1; int struct_top, offset; - p = _fdt_find_string(strtab - strtabsize, strtabsize, s); + p = fdt_find_string_(strtab - strtabsize, strtabsize, s); if (p) return p - strtab; @@ -227,11 +227,11 @@ int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) FDT_SW_CHECK_HEADER(fdt); - nameoff = _fdt_find_add_string(fdt, name); + nameoff = fdt_find_add_string_(fdt, name); if (nameoff == 0) return -FDT_ERR_NOSPACE; - prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); + prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); if (! prop) return -FDT_ERR_NOSPACE; @@ -265,7 +265,7 @@ int fdt_finish(void *fdt) FDT_SW_CHECK_HEADER(fdt); /* Add terminator */ - end = _fdt_grab_space(fdt, sizeof(*end)); + end = fdt_grab_space_(fdt, sizeof(*end)); if (! end) return -FDT_ERR_NOSPACE; *end = cpu_to_fdt32(FDT_END); @@ -281,7 +281,7 @@ int fdt_finish(void *fdt) while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { if (tag == FDT_PROP) { struct fdt_property *prop = - _fdt_offset_ptr_w(fdt, offset); + fdt_offset_ptr_w_(fdt, offset); int nameoff; nameoff = fdt32_to_cpu(prop->nameoff); diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c index 5e85919..534c1cb 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, val, len); } -static void _fdt_nop_region(void *start, int len) +static void fdt_nop_region_(void *start, int len) { fdt32_t *p; @@ -110,12 +110,12 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) if (!prop) return len; - _fdt_nop_region(prop, len + sizeof(*prop)); + fdt_nop_region_(prop, len + sizeof(*prop)); return 0; } -int _fdt_node_end_offset(void *fdt, int offset) +int fdt_node_end_offset_(void *fdt, int offset) { int depth = 0; @@ -129,11 +129,11 @@ int fdt_nop_node(void *fdt, int nodeoffset) { int endoffset; - endoffset = _fdt_node_end_offset(fdt, nodeoffset); + endoffset = fdt_node_end_offset_(fdt, nodeoffset); if (endoffset < 0) return endoffset; - _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), + fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset); return 0; } diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index 7f83023..1e27780 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -1,5 +1,5 @@ -#ifndef _LIBFDT_H -#define _LIBFDT_H +#ifndef LIBFDT_H +#define LIBFDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. @@ -54,7 +54,7 @@ #include "libfdt_env.h" #include "fdt.h" -#define FDT_FIRST_SUPPORTED_VERSION 0x10 +#define FDT_FIRST_SUPPORTED_VERSION 0x02 #define FDT_LAST_SUPPORTED_VERSION 0x11 /* Error codes: informative error codes */ @@ -225,23 +225,23 @@ int fdt_next_subnode(const void *fdt, int offset); #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) -#define __fdt_set_hdr(name) \ +#define fdt_set_hdr_(name) \ static inline void fdt_set_##name(void *fdt, uint32_t val) \ { \ struct fdt_header *fdth = (struct fdt_header *)fdt; \ fdth->name = cpu_to_fdt32(val); \ } -__fdt_set_hdr(magic); -__fdt_set_hdr(totalsize); -__fdt_set_hdr(off_dt_struct); -__fdt_set_hdr(off_dt_strings); -__fdt_set_hdr(off_mem_rsvmap); -__fdt_set_hdr(version); -__fdt_set_hdr(last_comp_version); -__fdt_set_hdr(boot_cpuid_phys); -__fdt_set_hdr(size_dt_strings); -__fdt_set_hdr(size_dt_struct); -#undef __fdt_set_hdr +fdt_set_hdr_(magic); +fdt_set_hdr_(totalsize); +fdt_set_hdr_(off_dt_struct); +fdt_set_hdr_(off_dt_strings); +fdt_set_hdr_(off_mem_rsvmap); +fdt_set_hdr_(version); +fdt_set_hdr_(last_comp_version); +fdt_set_hdr_(boot_cpuid_phys); +fdt_set_hdr_(size_dt_strings); +fdt_set_hdr_(size_dt_struct); +#undef fdt_set_hdr_ /** * fdt_check_header - sanity check a device tree or possible device tree @@ -527,6 +527,9 @@ int fdt_next_property_offset(const void *fdt, int offset); * offset. If lenp is non-NULL, the length of the property value is * also returned, in the integer pointed to by lenp. * + * Note that this code only works on device tree versions >= 16. fdt_getprop() + * works on all versions. + * * returns: * pointer to the structure representing the property * if lenp is non-NULL, *lenp contains the length of the property @@ -1449,7 +1452,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len); /** - * fdt_setprop _placeholder - allocate space for a property + * fdt_setprop_placeholder - allocate space for a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change @@ -1896,4 +1899,4 @@ int fdt_overlay_apply(void *fdt, void *fdto); const char *fdt_strerror(int errval); -#endif /* _LIBFDT_H */ +#endif /* LIBFDT_H */ diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h index 952056c..bd24746 100644 --- a/scripts/dtc/libfdt/libfdt_env.h +++ b/scripts/dtc/libfdt/libfdt_env.h @@ -1,5 +1,5 @@ -#ifndef _LIBFDT_ENV_H -#define _LIBFDT_ENV_H +#ifndef LIBFDT_ENV_H +#define LIBFDT_ENV_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. @@ -109,4 +109,31 @@ static inline fdt64_t cpu_to_fdt64(uint64_t x) #undef CPU_TO_FDT16 #undef EXTRACT_BYTE -#endif /* _LIBFDT_ENV_H */ +#ifdef __APPLE__ +#include <AvailabilityMacros.h> + +/* strnlen() is not available on Mac OS < 10.7 */ +# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \ + MAC_OS_X_VERSION_10_7) + +#define strnlen fdt_strnlen + +/* + * fdt_strnlen: returns the length of a string or max_count - which ever is + * smallest. + * Input 1 string: the string whose size is to be determined + * Input 2 max_count: the maximum value returned by this function + * Output: length of the string or max_count (the smallest of the two) + */ +static inline size_t fdt_strnlen(const char *string, size_t max_count) +{ + const char *p = memchr(string, 0, max_count); + return p ? p - string : max_count; +} + +#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < + MAC_OS_X_VERSION_10_7) */ + +#endif /* __APPLE__ */ + +#endif /* LIBFDT_ENV_H */ diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h index 02cfa6f..7681e19 100644 --- a/scripts/dtc/libfdt/libfdt_internal.h +++ b/scripts/dtc/libfdt/libfdt_internal.h @@ -1,5 +1,5 @@ -#ifndef _LIBFDT_INTERNAL_H -#define _LIBFDT_INTERNAL_H +#ifndef LIBFDT_INTERNAL_H +#define LIBFDT_INTERNAL_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. @@ -57,27 +57,27 @@ #define FDT_CHECK_HEADER(fdt) \ { \ - int __err; \ - if ((__err = fdt_check_header(fdt)) != 0) \ - return __err; \ + int err_; \ + if ((err_ = fdt_check_header(fdt)) != 0) \ + return err_; \ } -int _fdt_check_node_offset(const void *fdt, int offset); -int _fdt_check_prop_offset(const void *fdt, int offset); -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); -int _fdt_node_end_offset(void *fdt, int nodeoffset); +int fdt_check_node_offset_(const void *fdt, int offset); +int fdt_check_prop_offset_(const void *fdt, int offset); +const char *fdt_find_string_(const char *strtab, int tabsize, const char *s); +int fdt_node_end_offset_(void *fdt, int nodeoffset); -static inline const void *_fdt_offset_ptr(const void *fdt, int offset) +static inline const void *fdt_offset_ptr_(const void *fdt, int offset) { return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; } -static inline void *_fdt_offset_ptr_w(void *fdt, int offset) +static inline void *fdt_offset_ptr_w_(void *fdt, int offset) { - return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); + return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset); } -static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) +static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n) { const struct fdt_reserve_entry *rsv_table = (const struct fdt_reserve_entry *) @@ -85,11 +85,11 @@ static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int return rsv_table + n; } -static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) +static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) { - return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); + return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n); } #define FDT_SW_MAGIC (~FDT_MAGIC) -#endif /* _LIBFDT_INTERNAL_H */ +#endif /* LIBFDT_INTERNAL_H */ diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index 6846ad2f..57b7db2 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -216,7 +216,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) return old_node; } -void add_orphan_node(struct node *dt, struct node *new_node, char *ref) +struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) { static unsigned int next_orphan_fragment = 0; struct node *node; @@ -236,6 +236,7 @@ void add_orphan_node(struct node *dt, struct node *new_node, char *ref) name_node(node, name); add_child(dt, node); + return dt; } struct node *chain_node(struct node *first, struct node *list) @@ -507,7 +508,7 @@ struct node *get_node_by_path(struct node *tree, const char *path) for_each_child(tree, child) { if (p && (strlen(child->name) == p-path) && - strneq(path, child->name, p-path)) + strprefixeq(path, p - path, child->name)) return get_node_by_path(child, p+1); else if (!p && streq(path, child->name)) return child; @@ -540,7 +541,10 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) { struct node *child, *node; - assert((phandle != 0) && (phandle != -1)); + if ((phandle == 0) || (phandle == -1)) { + assert(generate_fixups); + return NULL; + } if (tree->phandle == phandle) { if (tree->deleted) diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 9d38459..cb6ed0e 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -209,8 +209,6 @@ struct srcpos srcpos_empty = { .file = NULL, }; -#define TAB_SIZE 8 - void srcpos_update(struct srcpos *pos, const char *text, int len) { int i; @@ -224,9 +222,6 @@ void srcpos_update(struct srcpos *pos, const char *text, int len) if (text[i] == '\n') { current_srcfile->lineno++; current_srcfile->colno = 1; - } else if (text[i] == '\t') { - current_srcfile->colno = - ALIGN(current_srcfile->colno, TAB_SIZE); } else { current_srcfile->colno++; } diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h index 7caca82..9ded12a 100644 --- a/scripts/dtc/srcpos.h +++ b/scripts/dtc/srcpos.h @@ -17,8 +17,8 @@ * USA */ -#ifndef _SRCPOS_H_ -#define _SRCPOS_H_ +#ifndef SRCPOS_H +#define SRCPOS_H #include <stdio.h> #include <stdbool.h> @@ -114,4 +114,4 @@ extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix, extern void srcpos_set_line(char *f, int l); -#endif /* _SRCPOS_H_ */ +#endif /* SRCPOS_H */ diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh index fe8926b..1a009fd 100755 --- a/scripts/dtc/update-dtc-source.sh +++ b/scripts/dtc/update-dtc-source.sh @@ -4,7 +4,7 @@ # # This script assumes that the dtc and the linux git trees are in the # same directory. After building dtc in the dtc directory, it copies the -# source files and generated source files into the scripts/dtc directory +# source files and generated source file(s) into the scripts/dtc directory # in the kernel and creates a git commit updating them to the new # version. # @@ -34,7 +34,6 @@ DTC_LINUX_PATH=`pwd`/scripts/dtc DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \ srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \ dtc-lexer.l dtc-parser.y" -DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h" LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h" @@ -59,10 +58,6 @@ for f in $DTC_SOURCE; do cp ${DTC_UPSTREAM_PATH}/${f} ${f} git add ${f} done -for f in $DTC_GENERATED; do - cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped - git add ${f}_shipped -done for f in $LIBFDT_SOURCE; do cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f} git add libfdt/${f} diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h index ad5f411..66fba8e 100644 --- a/scripts/dtc/util.h +++ b/scripts/dtc/util.h @@ -1,5 +1,5 @@ -#ifndef _UTIL_H -#define _UTIL_H +#ifndef UTIL_H +#define UTIL_H #include <stdarg.h> #include <stdbool.h> @@ -35,6 +35,9 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define stringify(s) stringify_(s) +#define stringify_(s) #s + static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) { va_list ap; @@ -260,4 +263,4 @@ void NORETURN util_usage(const char *errmsg, const char *synopsis, case 'V': util_version(); \ case '?': usage("unknown option"); -#endif /* _UTIL_H */ +#endif /* UTIL_H */ diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 6a4e847..ad87849 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.6-gaadd0b65" diff --git a/scripts/faddr2line b/scripts/faddr2line index 7721d5b..9e5735a 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -163,7 +163,17 @@ __faddr2line() { # pass real address to addr2line echo "$func+$offset/$sym_size:" - ${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;" + local file_lines=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;") + [[ -z $file_lines ]] && return + + # show each line with context + echo "$file_lines" | while read -r line + do + echo $line + eval $(echo $line | awk -F "[ :]" '{printf("n1=%d;n2=%d;f=%s",$NF-5, $NF+5, $(NF-1))}') + awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") {printf("%d\t%s\n", NR, $0)}' $f + done + DONE=1 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; }') diff --git a/scripts/file-size.sh b/scripts/file-size.sh new file mode 100755 index 0000000..7eb7423 --- /dev/null +++ b/scripts/file-size.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +set -- $(ls -dn "$1") +printf '%s\n' "$5" diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index c4a345c..6d5bbd3 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[] = { { "net/unix/af_unix.c", "unix_skb_parms", "char" }, /* big_key payload.data struct splashing */ { "security/keys/big_key.c", "path", "void *" }, - /* walk struct security_hook_heads as an array of struct list_head */ - { "security/security.c", "list_head", "security_hook_heads" }, + /* walk struct security_hook_heads as an array of struct hlist_head */ + { "security/security.c", "hlist_head", "security_hook_heads" }, { } }; diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 86a3c0e..10e528b 100755 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -194,7 +194,7 @@ input_file() { source="$1" if [ -f "$1" ]; then ${dep_list}header "$1" - is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\?/cpio/')" + is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')" if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then cpio_file=$1 echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed" diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index a18bca7..593f8879 100755 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh @@ -31,13 +31,13 @@ trap 'rm -f "$OUTDIR/$FILE" "$OUTDIR/$FILE.sed"' EXIT for i in "$@" do FILE="$(basename "$i")" - sed -r \ - -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \ - -e 's/__attribute_const__([ \t]|$)/\1/g' \ + sed -E \ + -e 's/([[:space:](])(__user|__force|__iomem)[[:space:]]/\1/g' \ + -e 's/__attribute_const__([[:space:]]|$)/\1/g' \ -e 's@^#include <linux/compiler(|_types).h>@@' \ -e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \ - -e 's/(^|[ \t(])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \ - -e 's@#(ifndef|define|endif[ \t]*/[*])[ \t]*_UAPI@#\1 @' \ + -e 's/(^|[[:space:](])(inline|asm|volatile)([[:space:](]|$)/\1__\2__\3/g' \ + -e 's@#(ifndef|define|endif[[:space:]]*/[*])[[:space:]]*_UAPI@#\1 @' \ "$SRCDIR/$i" > "$OUTDIR/$FILE.sed" || exit 1 scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$FILE.sed" \ > "$OUTDIR/$FILE" diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 6579265..5abfbf1 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -221,6 +221,7 @@ static int symbol_valid(struct sym_entry *s) static char *special_prefixes[] = { "__crc_", /* modversions */ + "__efistub_", /* arm64 EFI stub namespace */ NULL }; static char *special_suffixes[] = { diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index cb3ec53..f9bdd02 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -3,7 +3,7 @@ # Kernel configuration targets # These targets are used from top-level makefile -PHONY += xconfig gconfig menuconfig config silentoldconfig update-po-config \ +PHONY += xconfig gconfig menuconfig config syncconfig update-po-config \ localmodconfig localyesconfig ifdef KBUILD_KCONFIG @@ -36,24 +36,22 @@ nconfig: $(obj)/nconf # This has become an internal implementation detail and is now deprecated # for external use. -silentoldconfig: $(obj)/conf +syncconfig: $(obj)/conf $(Q)mkdir -p include/config include/generated - $(Q)test -e include/generated/autoksyms.h || \ - touch include/generated/autoksyms.h $< $(silent) --$@ $(Kconfig) -localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf +localyesconfig localmodconfig: $(obj)/conf $(Q)mkdir -p include/config include/generated - $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config + $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ mv -f .tmp.config .config; \ - $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \ + $< $(silent) --oldconfig $(Kconfig); \ mv -f .config.old.1 .config.old) \ else \ mv -f .tmp.config .config; \ - $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \ + $< $(silent) --oldconfig $(Kconfig); \ fi $(Q)rm -f .tmp.config @@ -88,7 +86,7 @@ PHONY += $(simple-targets) $(simple-targets): $(obj)/conf $< $(silent) --$@ $(Kconfig) -PHONY += oldnoconfig savedefconfig defconfig +PHONY += oldnoconfig silentoldconfig savedefconfig defconfig # oldnoconfig is an alias of olddefconfig, because people already are dependent # on its behavior (sets new symbols to their default value but not 'n') with the @@ -97,6 +95,13 @@ oldnoconfig: olddefconfig @echo " WARNING: \"oldnoconfig\" target will be removed after Linux 4.19" @echo " Please use \"olddefconfig\" instead, which is an alias." +# We do not expect manual invokcation of "silentoldcofig" (or "syncconfig"). +silentoldconfig: syncconfig + @echo " WARNING: \"silentoldconfig\" has been renamed to \"syncconfig\"" + @echo " and is now an internal implementation detail." + @echo " What you want is probably \"oldconfig\"." + @echo " \"silentoldconfig\" will be removed after Linux 4.19" + savedefconfig: $(obj)/conf $< $(silent) --$@=defconfig $(Kconfig) @@ -135,6 +140,14 @@ PHONY += tinyconfig tinyconfig: $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config +# CHECK: -o cache_dir=<path> working? +PHONY += testconfig +testconfig: $(obj)/conf + $(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ + -o cache_dir=$(abspath $(obj)/tests/.cache) \ + $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) +clean-dirs += tests/.cache + # Help text used by make help help: @echo ' config - Update current config utilising a line-oriented program' diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 822dc51..4e08121 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -23,7 +23,7 @@ static void check_conf(struct menu *menu); enum input_mode { oldaskconfig, - silentoldconfig, + syncconfig, oldconfig, allnoconfig, allyesconfig, @@ -100,7 +100,7 @@ static int conf_askvalue(struct symbol *sym, const char *def) switch (input_mode) { case oldconfig: - case silentoldconfig: + case syncconfig: if (sym_has_value(sym)) { printf("%s\n", def); return 0; @@ -293,7 +293,7 @@ static int conf_choice(struct menu *menu) printf("[1-%d?]: ", cnt); switch (input_mode) { case oldconfig: - case silentoldconfig: + case syncconfig: if (!is_new) { cnt = def; printf("%d\n", cnt); @@ -358,10 +358,11 @@ static void conf(struct menu *menu) switch (prop->type) { case P_MENU: - if ((input_mode == silentoldconfig || - input_mode == listnewconfig || - input_mode == olddefconfig) && - rootEntry != menu) { + /* + * Except in oldaskconfig mode, we show only menus that + * contain new symbols. + */ + if (input_mode != oldaskconfig && rootEntry != menu) { check_conf(menu); return; } @@ -424,7 +425,7 @@ static void check_conf(struct menu *menu) if (sym->name && !sym_is_choice_value(sym)) { printf("%s%s\n", CONFIG_, sym->name); } - } else if (input_mode != olddefconfig) { + } else { if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); @@ -440,7 +441,7 @@ static void check_conf(struct menu *menu) static struct option long_opts[] = { {"oldaskconfig", no_argument, NULL, oldaskconfig}, {"oldconfig", no_argument, NULL, oldconfig}, - {"silentoldconfig", no_argument, NULL, silentoldconfig}, + {"syncconfig", no_argument, NULL, syncconfig}, {"defconfig", optional_argument, NULL, defconfig}, {"savedefconfig", required_argument, NULL, savedefconfig}, {"allnoconfig", no_argument, NULL, allnoconfig}, @@ -467,8 +468,8 @@ static void conf_usage(const char *progname) printf(" --listnewconfig List new options\n"); printf(" --oldaskconfig Start a new configuration using a line-oriented program\n"); printf(" --oldconfig Update a configuration using a provided .config as base\n"); - printf(" --silentoldconfig Similar to oldconfig but generates configuration in\n" - " include/{generated/,config/} (oldconfig used to be more verbose)\n"); + printf(" --syncconfig Similar to oldconfig but generates configuration in\n" + " include/{generated/,config/}\n"); printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n"); printf(" --oldnoconfig An alias of olddefconfig\n"); printf(" --defconfig <file> New config with default defined in <file>\n"); @@ -500,7 +501,7 @@ int main(int ac, char **av) } input_mode = (enum input_mode)opt; switch (opt) { - case silentoldconfig: + case syncconfig: sync_kconfig = 1; break; case defconfig: @@ -582,7 +583,7 @@ int main(int ac, char **av) } break; case savedefconfig: - case silentoldconfig: + case syncconfig: case oldaskconfig: case oldconfig: case listnewconfig: @@ -662,24 +663,24 @@ int main(int ac, char **av) case oldaskconfig: rootEntry = &rootmenu; conf(&rootmenu); - input_mode = silentoldconfig; + input_mode = oldconfig; /* fall through */ case oldconfig: case listnewconfig: - case olddefconfig: - case silentoldconfig: + case syncconfig: /* Update until a loop caused no more changes */ do { conf_cnt = 0; check_conf(&rootmenu); - } while (conf_cnt && - (input_mode != listnewconfig && - input_mode != olddefconfig)); + } while (conf_cnt); + break; + case olddefconfig: + default: break; } if (sync_kconfig) { - /* silentoldconfig is used during the build so we shall update autoconf. + /* syncconfig is used during the build so we shall update autoconf. * All other commands are only used to generate a config. */ if (conf_get_changed() && conf_write(NULL)) { diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index d453819..e1a39e9 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) return 0; } -static inline struct expr * -expr_get_leftmost_symbol(const struct expr *e) -{ - - if (e == NULL) - return NULL; - - while (e->type != E_SYMBOL) - e = e->left.expr; - - return expr_copy(e); -} - -/* - * Given expression `e1' and `e2', returns the leaf of the longest - * sub-expression of `e1' not containing 'e2. - */ -struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2) -{ - struct expr *ret; - - switch (e1->type) { - case E_OR: - return expr_alloc_and( - expr_simplify_unmet_dep(e1->left.expr, e2), - expr_simplify_unmet_dep(e1->right.expr, e2)); - case E_AND: { - struct expr *e; - e = expr_alloc_and(expr_copy(e1), expr_copy(e2)); - e = expr_eliminate_dups(e); - ret = (!expr_eq(e, e1)) ? e1 : NULL; - expr_free(e); - break; - } - default: - ret = e1; - break; - } - - return expr_get_leftmost_symbol(ret); -} - -static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken, bool revdep) +void expr_print(struct expr *e, + void (*fn)(void *, struct symbol *, const char *), + void *data, int prevtoken) { if (!e) { fn(data, NULL, "y"); @@ -1234,14 +1194,9 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con fn(data, e->right.sym, e->right.sym->name); break; case E_OR: - if (revdep && e->left.expr->type != E_OR) - fn(data, NULL, "\n - "); - __expr_print(e->left.expr, fn, data, E_OR, revdep); - if (revdep) - fn(data, NULL, "\n - "); - else - fn(data, NULL, " || "); - __expr_print(e->right.expr, fn, data, E_OR, revdep); + expr_print(e->left.expr, fn, data, E_OR); + fn(data, NULL, " || "); + expr_print(e->right.expr, fn, data, E_OR); break; case E_AND: 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 fn(data, NULL, ")"); } -void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) -{ - __expr_print(e, fn, data, prevtoken, false); -} - static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) { xfwrite(str, strlen(str), 1, data); @@ -1329,7 +1279,27 @@ void expr_gstr_print(struct expr *e, struct gstr *gs) * line with a minus. This makes expressions much easier to read. * Suitable for reverse dependency expressions. */ -void expr_gstr_print_revdep(struct expr *e, struct gstr *gs) +static void expr_print_revdep(struct expr *e, + void (*fn)(void *, struct symbol *, const char *), + void *data, tristate pr_type, const char **title) +{ + if (e->type == E_OR) { + expr_print_revdep(e->left.expr, fn, data, pr_type, title); + expr_print_revdep(e->right.expr, fn, data, pr_type, title); + } else if (expr_calc_value(e) == pr_type) { + if (*title) { + fn(data, NULL, *title); + *title = NULL; + } + + fn(data, NULL, " - "); + expr_print(e, fn, data, E_NONE); + fn(data, NULL, "\n"); + } +} + +void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, + tristate pr_type, const char *title) { - __expr_print(e, expr_print_gstr_helper, gs, E_NONE, true); + expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title); } diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index c16e82e..94a383b 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -305,12 +305,12 @@ struct expr *expr_transform(struct expr *e); int expr_contains_symbol(struct expr *dep, struct symbol *sym); bool expr_depends_symbol(struct expr *dep, struct symbol *sym); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); -struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2); void expr_fprint(struct expr *e, FILE *out); struct gstr; /* forward */ void expr_gstr_print(struct expr *e, struct gstr *gs); -void expr_gstr_print_revdep(struct expr *e, struct gstr *gs); +void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, + tristate pr_type, const char *title); static inline int expr_is_yes(struct expr *e) { diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 2d5ec2d..f4394af 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -68,6 +68,7 @@ struct kconf_id { enum symbol_type stype; }; +extern int yylineno; void zconfdump(FILE *out); void zconf_starthelp(void); FILE *zconf_fopen(const char *name); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 36cd3e1..5c5c137 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -828,16 +828,16 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym, get_symbol_props_str(r, sym, P_SELECT, _(" Selects: ")); if (sym->rev_dep.expr) { - str_append(r, _(" Selected by: ")); - expr_gstr_print_revdep(sym->rev_dep.expr, r); - str_append(r, "\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n"); } get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: ")); if (sym->implied.expr) { - str_append(r, _(" Implied by: ")); - expr_gstr_print_revdep(sym->implied.expr, r); - str_append(r, "\n"); + expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n"); + expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n"); } str_append(r, "\n\n"); diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h index 0d52617..9f6f21d 100644 --- a/scripts/kconfig/nconf.h +++ b/scripts/kconfig/nconf.h @@ -15,7 +15,7 @@ #include <string.h> #include <unistd.h> #include <locale.h> -#include <curses.h> +#include <ncurses.h> #include <menu.h> #include <panel.h> #include <form.h> @@ -24,8 +24,6 @@ #include <time.h> #include <sys/time.h> -#include "ncurses.h" - #define max(a, b) ({\ typeof(a) _a = a;\ typeof(b) _b = b;\ diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 2220bc4..f0b2e3b 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -243,7 +243,7 @@ static void sym_calc_visibility(struct symbol *sym) tri = yes; if (sym->dir_dep.expr) tri = expr_calc_value(sym->dir_dep.expr); - if (tri == mod) + if (tri == mod && sym_get_type(sym) == S_BOOLEAN) tri = yes; if (sym->dir_dep.tri != tri) { sym->dir_dep.tri = tri; @@ -333,6 +333,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym) return def_sym; } +static void sym_warn_unmet_dep(struct symbol *sym) +{ + struct gstr gs = str_new(); + + str_printf(&gs, + "\nWARNING: unmet direct dependencies detected for %s\n", + sym->name); + str_printf(&gs, + " Depends on [%c]: ", + sym->dir_dep.tri == mod ? 'm' : 'n'); + expr_gstr_print(sym->dir_dep.expr, &gs); + str_printf(&gs, "\n"); + + expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes, + " Selected by [y]:\n"); + expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod, + " Selected by [m]:\n"); + + fputs(str_get(&gs), stderr); +} + void sym_calc_value(struct symbol *sym) { struct symbol_value newval, oldval; @@ -403,9 +424,10 @@ void sym_calc_value(struct symbol *sym) if (!sym_is_choice(sym)) { prop = sym_get_default_prop(sym); if (prop) { - sym->flags |= SYMBOL_WRITE; newval.tri = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); + if (newval.tri != no) + sym->flags |= SYMBOL_WRITE; } if (sym->implied.tri != no) { sym->flags |= SYMBOL_WRITE; @@ -413,18 +435,8 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: - if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { - struct expr *e; - e = expr_simplify_unmet_dep(sym->rev_dep.expr, - sym->dir_dep.expr); - fprintf(stderr, "warning: ("); - expr_fprint(e, stderr); - fprintf(stderr, ") selects %s which has unmet direct dependencies (", - sym->name); - expr_fprint(sym->dir_dep.expr, stderr); - fprintf(stderr, ")\n"); - expr_free(e); - } + if (sym->dir_dep.tri < sym->rev_dep.tri) + sym_warn_unmet_dep(sym); newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && diff --git a/scripts/kconfig/tests/auto_submenu/Kconfig b/scripts/kconfig/tests/auto_submenu/Kconfig new file mode 100644 index 0000000..c17bf2ca --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/Kconfig @@ -0,0 +1,50 @@ +config A + bool "A" + default y + +config A0 + bool "A0" + depends on A + default y + help + This depends on A, so should be a submenu of A. + +config A0_0 + bool "A1_0" + depends on A0 + help + Submenus are created recursively. + This should be a submenu of A0. + +config A1 + bool "A1" + depends on A + default y + help + This should line up with A0. + +choice + prompt "choice" + depends on A1 + help + Choice should become a submenu as well. + +config A1_0 + bool "A1_0" + +config A1_1 + bool "A1_1" + +endchoice + +config B + bool "B" + help + This is independent of A. + +config C + bool "C" + depends on A + help + This depends on A, but not a consecutive item, so can/should not + 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 0000000..32e79b8 --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/__init__.py @@ -0,0 +1,12 @@ +""" +Create submenu for symbols that depend on the preceding one. + +If a symbols has dependency on the preceding symbol, the menu entry +should become the submenu of the preceding one, and displayed with +deeper indentation. +""" + + +def test(conf): + assert conf.oldaskconfig() == 0 + 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 0000000..bf5236f --- /dev/null +++ b/scripts/kconfig/tests/auto_submenu/expected_stdout @@ -0,0 +1,10 @@ +A (A) [Y/n/?] (NEW) + A0 (A0) [Y/n/?] (NEW) + A1_0 (A0_0) [N/y/?] (NEW) + A1 (A1) [Y/n/?] (NEW) + choice + > 1. A1_0 (A1_0) (NEW) + 2. A1_1 (A1_1) (NEW) + choice[1-2?]: +B (B) [N/y/?] (NEW) +C (C) [N/y/?] (NEW) diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig new file mode 100644 index 0000000..cc60e9c --- /dev/null +++ b/scripts/kconfig/tests/choice/Kconfig @@ -0,0 +1,54 @@ +config MODULES + bool "Enable loadable module support" + option modules + default y + +choice + prompt "boolean choice" + default BOOL_CHOICE1 + +config BOOL_CHOICE0 + bool "choice 0" + +config BOOL_CHOICE1 + bool "choice 1" + +endchoice + +choice + prompt "optional boolean choice" + optional + default OPT_BOOL_CHOICE1 + +config OPT_BOOL_CHOICE0 + bool "choice 0" + +config OPT_BOOL_CHOICE1 + bool "choice 1" + +endchoice + +choice + prompt "tristate choice" + default TRI_CHOICE1 + +config TRI_CHOICE0 + tristate "choice 0" + +config TRI_CHOICE1 + tristate "choice 1" + +endchoice + +choice + prompt "optional tristate choice" + optional + default OPT_TRI_CHOICE1 + +config OPT_TRI_CHOICE0 + tristate "choice 0" + +config OPT_TRI_CHOICE1 + tristate "choice 1" + +endchoice diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py new file mode 100644 index 0000000..9edcc52 --- /dev/null +++ b/scripts/kconfig/tests/choice/__init__.py @@ -0,0 +1,40 @@ +""" +Basic choice tests. + +The handling of 'choice' is a bit complicated part in Kconfig. + +The behavior of 'y' choice is intuitive. If choice values are tristate, +the choice can be 'm' where each value can be enabled independently. +Also, if a choice is marked as 'optional', the whole choice can be +invisible. +""" + + +def test_oldask0(conf): + assert conf.oldaskconfig() == 0 + assert conf.stdout_contains('oldask0_expected_stdout') + + +def test_oldask1(conf): + assert conf.oldaskconfig('oldask1_config') == 0 + assert conf.stdout_contains('oldask1_expected_stdout') + + +def test_allyes(conf): + assert conf.allyesconfig() == 0 + assert conf.config_contains('allyes_expected_config') + + +def test_allmod(conf): + assert conf.allmodconfig() == 0 + assert conf.config_contains('allmod_expected_config') + + +def test_allno(conf): + assert conf.allnoconfig() == 0 + assert conf.config_contains('allno_expected_config') + + +def test_alldef(conf): + assert conf.alldefconfig() == 0 + 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 0000000..7a754bf --- /dev/null +++ b/scripts/kconfig/tests/choice/alldef_expected_config @@ -0,0 +1,5 @@ +CONFIG_MODULES=y +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_TRI_CHOICE0 is not set +# 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 0000000..f1f5dcd --- /dev/null +++ b/scripts/kconfig/tests/choice/allmod_expected_config @@ -0,0 +1,9 @@ +CONFIG_MODULES=y +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_OPT_BOOL_CHOICE0 is not set +CONFIG_OPT_BOOL_CHOICE1=y +CONFIG_TRI_CHOICE0=m +CONFIG_TRI_CHOICE1=m +CONFIG_OPT_TRI_CHOICE0=m +CONFIG_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 0000000..b88ee7a --- /dev/null +++ b/scripts/kconfig/tests/choice/allno_expected_config @@ -0,0 +1,5 @@ +# CONFIG_MODULES is not set +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_TRI_CHOICE0 is not set +CONFIG_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 0000000..e5a062a --- /dev/null +++ b/scripts/kconfig/tests/choice/allyes_expected_config @@ -0,0 +1,9 @@ +CONFIG_MODULES=y +# CONFIG_BOOL_CHOICE0 is not set +CONFIG_BOOL_CHOICE1=y +# CONFIG_OPT_BOOL_CHOICE0 is not set +CONFIG_OPT_BOOL_CHOICE1=y +# CONFIG_TRI_CHOICE0 is not set +CONFIG_TRI_CHOICE1=y +# CONFIG_OPT_TRI_CHOICE0 is not set +CONFIG_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 0000000..b251bba --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask0_expected_stdout @@ -0,0 +1,10 @@ +Enable loadable module support (MODULES) [Y/n/?] (NEW) +boolean choice + 1. choice 0 (BOOL_CHOICE0) (NEW) +> 2. choice 1 (BOOL_CHOICE1) (NEW) +choice[1-2?]: +optional boolean choice [N/y/?] (NEW) +tristate choice [M/y/?] (NEW) + choice 0 (TRI_CHOICE0) [N/m/?] (NEW) + choice 1 (TRI_CHOICE1) [N/m/?] (NEW) +optional 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 0000000..b67bfe3 --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask1_config @@ -0,0 +1,2 @@ +# CONFIG_MODULES is not set +CONFIG_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 0000000..c2125e9b --- /dev/null +++ b/scripts/kconfig/tests/choice/oldask1_expected_stdout @@ -0,0 +1,15 @@ +Enable loadable module support (MODULES) [N/y/?] +boolean choice + 1. choice 0 (BOOL_CHOICE0) (NEW) +> 2. choice 1 (BOOL_CHOICE1) (NEW) +choice[1-2?]: +optional boolean choice [Y/n/?] (NEW) +optional boolean choice +> 1. choice 0 (OPT_BOOL_CHOICE0) + 2. choice 1 (OPT_BOOL_CHOICE1) (NEW) +choice[1-2?]: +tristate choice + 1. choice 0 (TRI_CHOICE0) (NEW) +> 2. choice 1 (TRI_CHOICE1) (NEW) +choice[1-2?]: +optional 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 0000000..11ac25c --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/Kconfig @@ -0,0 +1,19 @@ +config MODULES + def_bool y + option modules + +config DEP + tristate + default m + +choice + prompt "Tristate Choice" + +config CHOICE0 + tristate "Choice 0" + +config CHOICE1 + tristate "Choice 1" + depends on DEP + +endchoice 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 0000000..f8d728c --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/__init__.py @@ -0,0 +1,15 @@ +""" +Hide tristate choice values with mod dependency in y choice. + +If tristate choice values depend on symbols set to 'm', they should be +hidden when the choice containing them is changed from 'm' to 'y' +(i.e. exclusive choice). + +Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074 +""" + + +def test(conf): + assert conf.oldaskconfig('config', 'y') == 0 + assert conf.config_contains('expected_config') + 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 0000000..3a126b7 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/config @@ -0,0 +1,2 @@ +CONFIG_CHOICE0=m +CONFIG_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 0000000..4d07b44 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_config @@ -0,0 +1,3 @@ +CONFIG_MODULES=y +CONFIG_DEP=m +CONFIG_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 0000000..2b50ab6 --- /dev/null +++ b/scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout @@ -0,0 +1,4 @@ +Tristate Choice [M/y/?] y +Tristate Choice +> 1. Choice 0 (CHOICE0) +choice[1]: 1 diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py new file mode 100644 index 0000000..0345ef6 --- /dev/null +++ b/scripts/kconfig/tests/conftest.py @@ -0,0 +1,291 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com> +# + +""" +Kconfig unit testing framework. + +This provides fixture functions commonly used from test files. +""" + +import os +import pytest +import shutil +import subprocess +import tempfile + +CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf')) + + +class Conf: + """Kconfig runner and result checker. + + This class provides methods to run text-based interface of Kconfig + (scripts/kconfig/conf) and retrieve the resulted configuration, + stdout, and stderr. It also provides methods to compare those + results with expectations. + """ + + def __init__(self, request): + """Create a new Conf instance. + + request: object to introspect the requesting test module + """ + # the directory of the test being run + self._test_dir = os.path.dirname(str(request.fspath)) + + # runners + def _run_conf(self, mode, dot_config=None, out_file='.config', + interactive=False, in_keys=None, extra_env={}): + """Run text-based Kconfig executable and save the result. + + mode: input mode option (--oldaskconfig, --defconfig=<file> etc.) + dot_config: .config file to use for configuration base + out_file: file name to contain the output config data + interactive: flag to specify the interactive mode + in_keys: key inputs for interactive modes + extra_env: additional environments + returncode: exit status of the Kconfig executable + """ + command = [CONF_PATH, mode, 'Kconfig'] + + # Override 'srctree' environment to make the test as the top directory + extra_env['srctree'] = self._test_dir + + # Run Kconfig in a temporary directory. + # This directory is automatically removed when done. + with tempfile.TemporaryDirectory() as temp_dir: + + # if .config is given, copy it to the working directory + if dot_config: + shutil.copyfile(os.path.join(self._test_dir, dot_config), + os.path.join(temp_dir, '.config')) + + ps = subprocess.Popen(command, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=temp_dir, + env=dict(os.environ, **extra_env)) + + # If input key sequence is given, feed it to stdin. + if in_keys: + ps.stdin.write(in_keys.encode('utf-8')) + + while ps.poll() is None: + # For interactive modes such as oldaskconfig, oldconfig, + # send 'Enter' key until the program finishes. + if interactive: + ps.stdin.write(b'\n') + + self.retcode = ps.returncode + self.stdout = ps.stdout.read().decode() + self.stderr = ps.stderr.read().decode() + + # Retrieve the resulted config data only when .config is supposed + # to exist. If the command fails, the .config does not exist. + # 'listnewconfig' does not produce .config in the first place. + if self.retcode == 0 and out_file: + with open(os.path.join(temp_dir, out_file)) as f: + self.config = f.read() + else: + self.config = None + + # Logging: + # Pytest captures the following information by default. In failure + # of tests, the captured log will be displayed. This will be useful to + # figure out what has happened. + + print("[command]\n{}\n".format(' '.join(command))) + + print("[retcode]\n{}\n".format(self.retcode)) + + print("[stdout]") + print(self.stdout) + + print("[stderr]") + print(self.stderr) + + if self.config is not None: + print("[output for '{}']".format(out_file)) + print(self.config) + + return self.retcode + + def oldaskconfig(self, dot_config=None, in_keys=None): + """Run oldaskconfig. + + dot_config: .config file to use for configuration base (optional) + in_key: key inputs (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--oldaskconfig', dot_config=dot_config, + interactive=True, in_keys=in_keys) + + def oldconfig(self, dot_config=None, in_keys=None): + """Run oldconfig. + + dot_config: .config file to use for configuration base (optional) + in_key: key inputs (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--oldconfig', dot_config=dot_config, + interactive=True, in_keys=in_keys) + + def olddefconfig(self, dot_config=None): + """Run olddefconfig. + + dot_config: .config file to use for configuration base (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--olddefconfig', dot_config=dot_config) + + def defconfig(self, defconfig): + """Run defconfig. + + defconfig: defconfig file for input + returncode: exit status of the Kconfig executable + """ + defconfig_path = os.path.join(self._test_dir, defconfig) + return self._run_conf('--defconfig={}'.format(defconfig_path)) + + def _allconfig(self, mode, all_config): + if all_config: + all_config_path = os.path.join(self._test_dir, all_config) + extra_env = {'KCONFIG_ALLCONFIG': all_config_path} + else: + extra_env = {} + + return self._run_conf('--{}config'.format(mode), extra_env=extra_env) + + def allyesconfig(self, all_config=None): + """Run allyesconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('allyes', all_config) + + def allmodconfig(self, all_config=None): + """Run allmodconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('allmod', all_config) + + def allnoconfig(self, all_config=None): + """Run allnoconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('allno', all_config) + + def alldefconfig(self, all_config=None): + """Run alldefconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('alldef', all_config) + + def randconfig(self, all_config=None): + """Run randconfig. + + all_config: fragment config file for KCONFIG_ALLCONFIG (optional) + returncode: exit status of the Kconfig executable + """ + return self._allconfig('rand', all_config) + + def savedefconfig(self, dot_config): + """Run savedefconfig. + + dot_config: .config file for input + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--savedefconfig', out_file='defconfig') + + def listnewconfig(self, dot_config=None): + """Run listnewconfig. + + dot_config: .config file to use for configuration base (optional) + returncode: exit status of the Kconfig executable + """ + return self._run_conf('--listnewconfig', dot_config=dot_config, + out_file=None) + + # checkers + def _read_and_compare(self, compare, expected): + """Compare the result with expectation. + + compare: function to compare the result with expectation + expected: file that contains the expected data + """ + with open(os.path.join(self._test_dir, expected)) as f: + expected_data = f.read() + return compare(self, expected_data) + + def _contains(self, attr, expected): + return self._read_and_compare( + lambda s, e: getattr(s, attr).find(e) >= 0, + expected) + + def _matches(self, attr, expected): + return self._read_and_compare(lambda s, e: getattr(s, attr) == e, + expected) + + def config_contains(self, expected): + """Check if resulted configuration contains expected data. + + expected: file that contains the expected data + returncode: True if result contains the expected data, False otherwise + """ + return self._contains('config', expected) + + def config_matches(self, expected): + """Check if resulted configuration exactly matches expected data. + + expected: file that contains the expected data + returncode: True if result matches the expected data, False otherwise + """ + return self._matches('config', expected) + + def stdout_contains(self, expected): + """Check if resulted stdout contains expected data. + + expected: file that contains the expected data + returncode: True if result contains the expected data, False otherwise + """ + return self._contains('stdout', expected) + + def stdout_matches(self, expected): + """Check if resulted stdout exactly matches expected data. + + expected: file that contains the expected data + returncode: True if result matches the expected data, False otherwise + """ + return self._matches('stdout', expected) + + def stderr_contains(self, expected): + """Check if resulted stderr contains expected data. + + expected: file that contains the expected data + returncode: True if result contains the expected data, False otherwise + """ + return self._contains('stderr', expected) + + def stderr_matches(self, expected): + """Check if resulted stderr exactly matches expected data. + + expected: file that contains the expected data + returncode: True if result matches the expected data, False otherwise + """ + return self._matches('stderr', expected) + + +@pytest.fixture(scope="module") +def conf(request): + """Create a Conf instance and provide it to test functions.""" + return Conf(request) diff --git a/scripts/kconfig/tests/err_recursive_inc/Kconfig b/scripts/kconfig/tests/err_recursive_inc/Kconfig new file mode 100644 index 0000000..0e4c875 --- /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 0000000..00e408d --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc1 @@ -0,0 +1,4 @@ + + + +source "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 0000000..349ea2d --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/Kconfig.inc2 @@ -0,0 +1,3 @@ + + +source "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 0000000..0e4c875 --- /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 0000000..0e4c839 --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/__init__.py @@ -0,0 +1,10 @@ +""" +Detect recursive inclusion error. + +If recursive inclusion is detected, it should fail with error messages. +""" + + +def test(conf): + assert conf.oldaskconfig() != 0 + 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 0000000..6b582ee --- /dev/null +++ b/scripts/kconfig/tests/err_recursive_inc/expected_stderr @@ -0,0 +1,6 @@ +Recursive inclusion detected. +Inclusion path: + current file : Kconfig.inc1 + included from: Kconfig.inc3:1 + included from: Kconfig.inc2:3 + 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 0000000..e44449f --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/Kconfig @@ -0,0 +1,23 @@ +config MODULES + def_bool y + option modules + +choice + prompt "Choice" + +config CHOICE_VAL0 + tristate "Choice 0" + +config CHOIVE_VAL1 + tristate "Choice 1" + +endchoice + +choice + prompt "Another choice" + depends on CHOICE_VAL0 + +config DUMMY + bool "dummy" + +endchoice diff --git a/scripts/kconfig/tests/inter_choice/__init__.py b/scripts/kconfig/tests/inter_choice/__init__.py new file mode 100644 index 0000000..5c7fc36 --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/__init__.py @@ -0,0 +1,14 @@ +""" +Do not affect user-assigned choice value by another choice. + +Handling of state flags for choices is complecated. In old days, +the defconfig result of a choice could be affected by another choice +if those choices interact by 'depends on', 'select', etc. + +Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a +""" + + +def test(conf): + assert conf.defconfig('defconfig') == 0 + 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 0000000..162c414 --- /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 0000000..5dceefb --- /dev/null +++ b/scripts/kconfig/tests/inter_choice/expected_config @@ -0,0 +1,4 @@ +CONFIG_MODULES=y +CONFIG_CHOICE_VAL0=y +# CONFIG_CHOIVE_VAL1 is not set +CONFIG_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 0000000..53ef1b8 --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/Kconfig @@ -0,0 +1,37 @@ +config A + bool "A" + help + This is a new symbol. + +choice + prompt "Choice ?" + depends on A + help + "depends on A" has been newly added. + +config CHOICE_B + bool "Choice B" + +config CHOICE_C + bool "Choice C" + help + This is a new symbol, so should be asked. + +endchoice + +choice + prompt "Choice2 ?" + +config CHOICE_D + bool "Choice D" + +config CHOICE_E + bool "Choice E" + +config CHOICE_F + bool "Choice F" + depends on A + help + This is a new symbol, so should be asked. + +endchoice 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 0000000..f0e0ead --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/__init__.py @@ -0,0 +1,14 @@ +""" +Ask new choice values when they become visible. + +If new choice values are added with new dependency, and they become +visible during user configuration, oldconfig should recognize them +as (NEW), and ask the user for choice. + +Related Linux commit: 5d09598d488f081e3be23f885ed65cbbe2d073b5 +""" + + +def test(conf): + assert conf.oldconfig('config', 'y') == 0 + 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 0000000..47ef95d --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/config @@ -0,0 +1,3 @@ +CONFIG_CHOICE_B=y +# CONFIG_CHOICE_D is not set +CONFIG_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 0000000..74dc0bc --- /dev/null +++ b/scripts/kconfig/tests/new_choice_with_dep/expected_stdout @@ -0,0 +1,10 @@ +A (A) [N/y/?] (NEW) y + Choice ? + > 1. Choice B (CHOICE_B) + 2. Choice C (CHOICE_C) (NEW) + choice[1-2?]: +Choice2 ? + 1. Choice D (CHOICE_D) +> 2. Choice E (CHOICE_E) + 3. Choice F (CHOICE_F) (NEW) +choice[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 0000000..c00b8fe --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/Kconfig @@ -0,0 +1,14 @@ +config A + bool "A" + +choice + prompt "Choice ?" + depends on A + +config CHOICE_B + bool "Choice B" + +config CHOICE_C + bool "Choice C" + +endchoice 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 0000000..207261b --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/__init__.py @@ -0,0 +1,19 @@ +""" +Do not write choice values to .config if the dependency is unmet. + +"# CONFIG_... is not set" should not be written into the .config file +for symbols with unmet dependency. + +This was not working correctly for choice values because choice needs +a bit different symbol computation. + +This checks that no unneeded "# COFIG_... is not set" is contained in +the .config file. + +Related Linux commit: cb67ab2cd2b8abd9650292c986c79901e3073a59 +""" + + +def test(conf): + assert conf.oldaskconfig('config', 'n') == 0 + 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 0000000..abd280e --- /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 0000000..0d15e41 --- /dev/null +++ b/scripts/kconfig/tests/no_write_if_dep_unmet/expected_config @@ -0,0 +1,5 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux Kernel Configuration +# +# CONFIG_A is not set diff --git a/scripts/kconfig/tests/pytest.ini b/scripts/kconfig/tests/pytest.ini new file mode 100644 index 0000000..85d7ce8 --- /dev/null +++ b/scripts/kconfig/tests/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +addopts = --verbose + +# Pytest requires that test files have unique names, because pytest imports +# them as top-level modules. It is silly to prefix or suffix a test file with +# the directory name that contains it. Use __init__.py for all test files. +python_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 0000000..c591d51 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/Kconfig @@ -0,0 +1,33 @@ +choice + prompt "choice" + +config A + bool "A" + +config B + bool "B" + +if B +choice + prompt "sub choice" + +config C + bool "C" + +config D + bool "D" + +if D +choice + prompt "subsub choice" + +config E + bool "E" + +endchoice +endif # D + +endchoice +endif # B + +endchoice 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 0000000..e729a4e --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/__init__.py @@ -0,0 +1,16 @@ +""" +Set random values recursively in nested choices. + +Kconfig can create a choice-in-choice structure by using 'if' statement. +randconfig should correctly set random choice values. + +Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29 +""" + + +def test(conf): + for i in range(20): + assert conf.randconfig() == 0 + assert (conf.config_contains('expected_stdout0') or + conf.config_contains('expected_stdout1') or + 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 0000000..05450f3 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 @@ -0,0 +1,2 @@ +CONFIG_A=y +# 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 0000000..37ab295 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 @@ -0,0 +1,4 @@ +# CONFIG_A is not set +CONFIG_B=y +CONFIG_C=y +# 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 0000000..849ff47 --- /dev/null +++ b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 @@ -0,0 +1,5 @@ +# CONFIG_A is not set +CONFIG_B=y +# CONFIG_C is not set +CONFIG_D=y +CONFIG_E=y diff --git a/scripts/kconfig/tests/warn_recursive_dep/Kconfig b/scripts/kconfig/tests/warn_recursive_dep/Kconfig new file mode 100644 index 0000000..a65bfcb --- /dev/null +++ b/scripts/kconfig/tests/warn_recursive_dep/Kconfig @@ -0,0 +1,62 @@ +# depends on itself + +config A + bool "A" + depends on A + +# select itself + +config B + bool + select B + +# depends on each other + +config C1 + bool "C1" + depends on C2 + +config C2 + bool "C2" + depends on C1 + +# depends on and select + +config D1 + bool "D1" + depends on D2 + select D2 + +config D2 + bool + +# depends on and imply +# This is not recursive dependency + +config E1 + bool "E1" + depends on E2 + imply E2 + +config E2 + bool "E2" + +# property + +config F1 + bool "F1" + default F2 + +config F2 + bool "F2" + depends on F1 + +# menu + +menu "menu depending on its content" + depends on G + +config G + bool "G" + +endmenu diff --git a/scripts/kconfig/tests/warn_recursive_dep/__init__.py b/scripts/kconfig/tests/warn_recursive_dep/__init__.py new file mode 100644 index 0000000..adb2195 --- /dev/null +++ b/scripts/kconfig/tests/warn_recursive_dep/__init__.py @@ -0,0 +1,9 @@ +""" +Warn recursive inclusion. + +Recursive dependency should be warned. +""" + +def test(conf): + assert conf.oldaskconfig() == 0 + assert conf.stderr_contains('expected_stderr') diff --git a/scripts/kconfig/tests/warn_recursive_dep/expected_stderr b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr new file mode 100644 index 0000000..3de807d --- /dev/null +++ b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr @@ -0,0 +1,30 @@ +Kconfig:9:error: recursive dependency detected! +Kconfig:9: symbol B is selected by B +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:3:error: recursive dependency detected! +Kconfig:3: symbol A depends on A +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:15:error: recursive dependency detected! +Kconfig:15: symbol C1 depends on C2 +Kconfig:19: symbol C2 depends on C1 +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:30:error: recursive dependency detected! +Kconfig:30: symbol D2 is selected by D1 +Kconfig:25: symbol D1 depends on D2 +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:59:error: recursive dependency detected! +Kconfig:59: symbol G depends on G +For a resolution refer to Documentation/kbuild/kconfig-language.txt +subsection "Kconfig recursive dependency limitations" + +Kconfig:50:error: recursive dependency detected! +Kconfig:50: symbol F2 depends on F1 +Kconfig:48: symbol F1 default value contains F2 diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 88b650e..045093d 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -1,5 +1,5 @@ %option nostdinit noyywrap never-interactive full ecs -%option 8bit nodefault perf-report perf-report +%option 8bit nodefault yylineno %option noinput %x COMMAND HELP STRING PARAM %{ @@ -83,7 +83,6 @@ n [A-Za-z0-9_-] [ \t]*#.*\n | [ \t]*\n { - current_file->lineno++; return T_EOL; } [ \t]*#.* @@ -104,7 +103,7 @@ n [A-Za-z0-9_-] const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); BEGIN(PARAM); current_pos.file = current_file; - current_pos.lineno = current_file->lineno; + current_pos.lineno = yylineno; if (id && id->flags & TF_COMMAND) { yylval.id = id; return id->token; @@ -116,7 +115,6 @@ n [A-Za-z0-9_-] . warn_ignored_character(*yytext); \n { BEGIN(INITIAL); - current_file->lineno++; return T_EOL; } } @@ -138,7 +136,7 @@ n [A-Za-z0-9_-] new_string(); BEGIN(STRING); } - \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; + \n BEGIN(INITIAL); return T_EOL; ({n}|[/.])+ { const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); if (id && id->flags & TF_PARAM) { @@ -150,7 +148,7 @@ n [A-Za-z0-9_-] return T_WORD; } #.* /* comment */ - \\\n current_file->lineno++; + \\\n ; [[:blank:]]+ . warn_ignored_character(*yytext); <<EOF>> { @@ -187,7 +185,6 @@ n [A-Za-z0-9_-] fprintf(stderr, "%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); - current_file->lineno++; BEGIN(INITIAL); return T_EOL; } @@ -220,12 +217,10 @@ n [A-Za-z0-9_-] } } [ \t]*\n/[^ \t\n] { - current_file->lineno++; zconf_endhelp(); return T_HELPTEXT; } [ \t]*\n { - current_file->lineno++; append_string("\n", 1); } [^ \t\n].* { @@ -304,7 +299,7 @@ void zconf_initscan(const char *name) memset(current_buf, 0, sizeof(*current_buf)); current_file = file_lookup(name); - current_file->lineno = 1; + yylineno = 1; } void zconf_nextfile(const char *name) @@ -325,24 +320,26 @@ void zconf_nextfile(const char *name) buf->parent = current_buf; current_buf = buf; - for (iter = current_file->parent; iter; iter = iter->parent ) { - if (!strcmp(current_file->name,iter->name) ) { + current_file->lineno = yylineno; + file->parent = current_file; + + for (iter = current_file; iter; iter = iter->parent) { + if (!strcmp(iter->name, file->name)) { fprintf(stderr, - "%s:%d: recursive inclusion detected. " - "Inclusion path:\n current file : '%s'\n", - zconf_curname(), zconf_lineno(), - zconf_curname()); - iter = current_file; + "Recursive inclusion detected.\n" + "Inclusion path:\n" + " current file : %s\n", file->name); + iter = file; do { iter = iter->parent; - fprintf(stderr, " included from: '%s:%d'\n", + fprintf(stderr, " included from: %s:%d\n", iter->name, iter->lineno - 1); - } while (strcmp(iter->name, current_file->name)); + } while (strcmp(iter->name, file->name)); exit(1); } } - file->lineno = 1; - file->parent = current_file; + + yylineno = 1; current_file = file; } @@ -351,6 +348,8 @@ static void zconf_endfile(void) struct buffer *parent; current_file = current_file->parent; + if (current_file) + yylineno = current_file->lineno; parent = current_buf->parent; if (parent) { diff --git a/scripts/kernel-doc b/scripts/kernel-doc index fee8952..0057d8e 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 use warnings; use strict; @@ -328,13 +329,15 @@ my $lineprefix=""; use constant { STATE_NORMAL => 0, # normal code STATE_NAME => 1, # looking for function name - STATE_FIELD => 2, # scanning field start - STATE_PROTO => 3, # scanning prototype - STATE_DOCBLOCK => 4, # documentation block - STATE_INLINE => 5, # gathering documentation outside main block + STATE_BODY_MAYBE => 2, # body - or maybe more description + STATE_BODY => 3, # the body of the comment + STATE_PROTO => 4, # scanning prototype + STATE_DOCBLOCK => 5, # documentation block + STATE_INLINE => 6, # gathering documentation outside main block }; my $state; my $in_doc_sect; +my $leading_space; # Inline documentation state use constant { @@ -363,7 +366,7 @@ my $doc_sect = $doc_com . my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; -my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; +my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; my $doc_inline_end = '^\s*\*/\s*$'; my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; @@ -553,10 +556,9 @@ sub output_highlight { } if ($line eq ""){ if (! $output_preformatted) { - print $lineprefix, local_unescape($blankline); + print $lineprefix, $blankline; } } else { - $line =~ s/\\\\\\/\&/g; if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { print "\\&$line"; } else { @@ -747,17 +749,73 @@ sub output_blockhead_rst(%) { } } -sub output_highlight_rst { - my $contents = join "\n",@_; - my $line; - - # undo the evil effects of xml_escape() earlier - $contents = xml_unescape($contents); - +# +# Apply the RST highlights to a sub-block of text. +# +sub highlight_block($) { + # The dohighlight kludge requires the text be called $contents + my $contents = shift; eval $dohighlight; die $@ if $@; + return $contents; +} - foreach $line (split "\n", $contents) { +# +# Regexes used only here. +# +my $sphinx_literal = '^[^.].*::$'; +my $sphinx_cblock = '^\.\.\ +code-block::'; + +sub output_highlight_rst { + my $input = join "\n",@_; + my $output = ""; + my $line; + my $in_literal = 0; + my $litprefix; + my $block = ""; + + foreach $line (split "\n",$input) { + # + # If we're in a literal block, see if we should drop out + # of it. Otherwise pass the line straight through unmunged. + # + if ($in_literal) { + if (! ($line =~ /^\s*$/)) { + # + # If this is the first non-blank line in a literal + # block we need to figure out what the proper indent is. + # + if ($litprefix eq "") { + $line =~ /^(\s*)/; + $litprefix = '^' . $1; + $output .= $line . "\n"; + } elsif (! ($line =~ /$litprefix/)) { + $in_literal = 0; + } else { + $output .= $line . "\n"; + } + } else { + $output .= $line . "\n"; + } + } + # + # Not in a literal block (or just dropped out) + # + if (! $in_literal) { + $block .= $line . "\n"; + if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { + $in_literal = 1; + $litprefix = ""; + $output .= highlight_block($block); + $block = "" + } + } + } + + if ($block) { + $output .= highlight_block($block); + } + foreach $line (split "\n", $output) { print $lineprefix . $line . "\n"; } } @@ -1062,7 +1120,7 @@ sub dump_struct($$) { # Handle bitmaps $arg =~ s/:\s*\d+\s*//g; # Handle arrays - $arg =~ s/\[\S+\]//g; + $arg =~ s/\[.*\]//g; # The type may have multiple words, # and multiple IDs can be defined, like: # const struct foo, *bar, foobar @@ -1422,8 +1480,6 @@ sub push_parameter($$$$) { } } - $param = xml_escape($param); - # strip spaces from $param so that it is one continuous string # on @parameterlist; # this fixes a problem where check_sections() cannot find @@ -1522,6 +1578,7 @@ sub dump_function($$) { $prototype =~ s/__meminit +//; $prototype =~ s/__must_check +//; $prototype =~ s/__weak +//; + $prototype =~ s/__sched +//; my $define = $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\( (?: @@ -1748,47 +1805,6 @@ sub process_proto_type($$) { } } -# xml_escape: replace <, >, and & in the text stream; -# -# however, formatting controls that are generated internally/locally in the -# kernel-doc script are not escaped here; instead, they begin life like -# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings -# are converted to their mnemonic-expected output, without the 4 * '\' & ':', -# just before actual output; (this is done by local_unescape()) -sub xml_escape($) { - my $text = shift; - if ($output_mode eq "man") { - return $text; - } - $text =~ s/\&/\\\\\\amp;/g; - $text =~ s/\</\\\\\\lt;/g; - $text =~ s/\>/\\\\\\gt;/g; - return $text; -} - -# xml_unescape: reverse the effects of xml_escape -sub xml_unescape($) { - my $text = shift; - if ($output_mode eq "man") { - return $text; - } - $text =~ s/\\\\\\amp;/\&/g; - $text =~ s/\\\\\\lt;/</g; - $text =~ s/\\\\\\gt;/>/g; - return $text; -} - -# convert local escape strings to html -# local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) -sub local_unescape($) { - my $text = shift; - if ($output_mode eq "man") { - return $text; - } - $text =~ s/\\\\\\\\lt:/</g; - $text =~ s/\\\\\\\\gt:/>/g; - return $text; -} sub map_filename($) { my $file; @@ -1826,15 +1842,291 @@ sub process_export_file($) { close(IN); } -sub process_file($) { - my $file; +# +# Parsers for the various processing states. +# +# STATE_NORMAL: looking for the /** to begin everything. +# +sub process_normal() { + if (/$doc_start/o) { + $state = STATE_NAME; # next line is always the function name + $in_doc_sect = 0; + $declaration_start_line = $. + 1; + } +} + +# +# STATE_NAME: Looking for the "name - description" line +# +sub process_name($$) { + my $file = shift; my $identifier; - my $func; my $descr; - my $in_purpose = 0; + + if (/$doc_block/o) { + $state = STATE_DOCBLOCK; + $contents = ""; + $new_start_line = $. + 1; + + if ( $1 eq "" ) { + $section = $section_intro; + } else { + $section = $1; + } + } + elsif (/$doc_decl/o) { + $identifier = $1; + if (/\s*([\w\s]+?)(\(\))?\s*-/) { + $identifier = $1; + } + + $state = STATE_BODY; + # if there's no @param blocks need to set up default section + # here + $contents = ""; + $section = $section_default; + $new_start_line = $. + 1; + if (/-(.*)/) { + # strip leading/trailing/multiple spaces + $descr= $1; + $descr =~ s/^\s*//; + $descr =~ s/\s*$//; + $descr =~ s/\s+/ /g; + $declaration_purpose = $descr; + $state = STATE_BODY_MAYBE; + } else { + $declaration_purpose = ""; + } + + if (($declaration_purpose eq "") && $verbose) { + print STDERR "${file}:$.: warning: missing initial short description on line:\n"; + print STDERR $_; + ++$warnings; + } + + if ($identifier =~ m/^struct/) { + $decl_type = 'struct'; + } elsif ($identifier =~ m/^union/) { + $decl_type = 'union'; + } elsif ($identifier =~ m/^enum/) { + $decl_type = 'enum'; + } elsif ($identifier =~ m/^typedef/) { + $decl_type = 'typedef'; + } else { + $decl_type = 'function'; + } + + if ($verbose) { + print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; + } + } else { + print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", + " - I thought it was a doc line\n"; + ++$warnings; + $state = STATE_NORMAL; + } +} + + +# +# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. +# +sub process_body($$) { + my $file = shift; + + if (/$doc_sect/i) { # case insensitive for supported section names + $newsection = $1; + $newcontents = $2; + + # map the supported section names to the canonical names + if ($newsection =~ m/^description$/i) { + $newsection = $section_default; + } elsif ($newsection =~ m/^context$/i) { + $newsection = $section_context; + } elsif ($newsection =~ m/^returns?$/i) { + $newsection = $section_return; + } elsif ($newsection =~ m/^\@return$/) { + # special: @return is a section, not a param description + $newsection = $section_return; + } + + if (($contents ne "") && ($contents ne "\n")) { + if (!$in_doc_sect && $verbose) { + print STDERR "${file}:$.: warning: contents before sections\n"; + ++$warnings; + } + dump_section($file, $section, $contents); + $section = $section_default; + } + + $in_doc_sect = 1; + $state = STATE_BODY; + $contents = $newcontents; + $new_start_line = $.; + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + $leading_space = undef; + } elsif (/$doc_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + # look for doc_com + <text> + doc_end: + if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { + print STDERR "${file}:$.: warning: suspicious ending line: $_"; + ++$warnings; + } + + $prototype = ""; + $state = STATE_PROTO; + $brcount = 0; + } elsif (/$doc_content/) { + # miguel-style comment kludge, look for blank lines after + # @parameter line to signify start of description + if ($1 eq "") { + if ($section =~ m/^@/ || $section eq $section_context) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $new_start_line = $.; + } else { + $contents .= "\n"; + } + $state = STATE_BODY; + } elsif ($state == STATE_BODY_MAYBE) { + # Continued declaration purpose + chomp($declaration_purpose); + $declaration_purpose .= " " . $1; + $declaration_purpose =~ s/\s+/ /g; + } else { + my $cont = $1; + if ($section =~ m/^@/ || $section eq $section_context) { + if (!defined $leading_space) { + if ($cont =~ m/^(\s+)/) { + $leading_space = $1; + } else { + $leading_space = ""; + } + } + $cont =~ s/^$leading_space//; + } + $contents .= $cont . "\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "${file}:$.: warning: bad line: $_"; + ++$warnings; + } +} + + +# +# STATE_PROTO: reading a function/whatever prototype. +# +sub process_proto($$) { + my $file = shift; + + if (/$doc_inline_oneline/) { + $section = $1; + $contents = $2; + if ($contents ne "") { + $contents .= "\n"; + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + } elsif (/$doc_inline_start/) { + $state = STATE_INLINE; + $inline_doc_state = STATE_INLINE_NAME; + } elsif ($decl_type eq 'function') { + process_proto_function($_, $file); + } else { + process_proto_type($_, $file); + } +} + +# +# STATE_DOCBLOCK: within a DOC: block. +# +sub process_docblock($$) { + my $file = shift; + + if (/$doc_end/) { + dump_doc_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $function = ""; + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + $state = STATE_NORMAL; + } elsif (/$doc_content/) { + if ( $1 eq "" ) { + $contents .= $blankline; + } else { + $contents .= $1 . "\n"; + } + } +} + +# +# STATE_INLINE: docbook comments within a prototype. +# +sub process_inline($$) { + my $file = shift; + + # First line (state 1) needs to be a @parameter + if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { + $section = $1; + $contents = $2; + $new_start_line = $.; + if ($contents ne "") { + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + $contents .= "\n"; + } + $inline_doc_state = STATE_INLINE_TEXT; + # Documentation block end */ + } elsif (/$doc_inline_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + $state = STATE_PROTO; + $inline_doc_state = STATE_INLINE_NA; + # Regular text + } elsif (/$doc_content/) { + if ($inline_doc_state == STATE_INLINE_TEXT) { + $contents .= $1 . "\n"; + # nuke leading blank lines + if ($contents =~ /^\s*$/) { + $contents = ""; + } + } elsif ($inline_doc_state == STATE_INLINE_NAME) { + $inline_doc_state = STATE_INLINE_ERROR; + print STDERR "${file}:$.: warning: "; + print STDERR "Incorrect use of kernel-doc format: $_"; + ++$warnings; + } + } +} + + +sub process_file($) { + my $file; my $initial_section_counter = $section_counter; my ($orig_file) = @_; - my $leading_space; $file = map_filename($orig_file); @@ -1853,250 +2145,23 @@ sub process_file($) { } # Replace tabs by spaces while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; + # Hand this line to the appropriate state handler if ($state == STATE_NORMAL) { - if (/$doc_start/o) { - $state = STATE_NAME; # next line is always the function name - $in_doc_sect = 0; - $declaration_start_line = $. + 1; - } - } elsif ($state == STATE_NAME) {# this line is the function name (always) - if (/$doc_block/o) { - $state = STATE_DOCBLOCK; - $contents = ""; - $new_start_line = $. + 1; - - if ( $1 eq "" ) { - $section = $section_intro; - } else { - $section = $1; - } - } - elsif (/$doc_decl/o) { - $identifier = $1; - if (/\s*([\w\s]+?)\s*-/) { - $identifier = $1; - } - - $state = STATE_FIELD; - # if there's no @param blocks need to set up default section - # here - $contents = ""; - $section = $section_default; - $new_start_line = $. + 1; - if (/-(.*)/) { - # strip leading/trailing/multiple spaces - $descr= $1; - $descr =~ s/^\s*//; - $descr =~ s/\s*$//; - $descr =~ s/\s+/ /g; - $declaration_purpose = xml_escape($descr); - $in_purpose = 1; - } else { - $declaration_purpose = ""; - } - - if (($declaration_purpose eq "") && $verbose) { - print STDERR "${file}:$.: warning: missing initial short description on line:\n"; - print STDERR $_; - ++$warnings; - } - - if ($identifier =~ m/^struct/) { - $decl_type = 'struct'; - } elsif ($identifier =~ m/^union/) { - $decl_type = 'union'; - } elsif ($identifier =~ m/^enum/) { - $decl_type = 'enum'; - } elsif ($identifier =~ m/^typedef/) { - $decl_type = 'typedef'; - } else { - $decl_type = 'function'; - } - - if ($verbose) { - print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; - } - } else { - print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", - " - I thought it was a doc line\n"; - ++$warnings; - $state = STATE_NORMAL; - } - } elsif ($state == STATE_FIELD) { # look for head: lines, and include content - if (/$doc_sect/i) { # case insensitive for supported section names - $newsection = $1; - $newcontents = $2; - - # map the supported section names to the canonical names - if ($newsection =~ m/^description$/i) { - $newsection = $section_default; - } elsif ($newsection =~ m/^context$/i) { - $newsection = $section_context; - } elsif ($newsection =~ m/^returns?$/i) { - $newsection = $section_return; - } elsif ($newsection =~ m/^\@return$/) { - # special: @return is a section, not a param description - $newsection = $section_return; - } - - if (($contents ne "") && ($contents ne "\n")) { - if (!$in_doc_sect && $verbose) { - print STDERR "${file}:$.: warning: contents before sections\n"; - ++$warnings; - } - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - } - - $in_doc_sect = 1; - $in_purpose = 0; - $contents = $newcontents; - $new_start_line = $.; - while (substr($contents, 0, 1) eq " ") { - $contents = substr($contents, 1); - } - if ($contents ne "") { - $contents .= "\n"; - } - $section = $newsection; - $leading_space = undef; - } elsif (/$doc_end/) { - if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - } - # look for doc_com + <text> + doc_end: - if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { - print STDERR "${file}:$.: warning: suspicious ending line: $_"; - ++$warnings; - } - - $prototype = ""; - $state = STATE_PROTO; - $brcount = 0; -# print STDERR "end of doc comment, looking for prototype\n"; - } elsif (/$doc_content/) { - # miguel-style comment kludge, look for blank lines after - # @parameter line to signify start of description - if ($1 eq "") { - if ($section =~ m/^@/ || $section eq $section_context) { - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - $new_start_line = $.; - } else { - $contents .= "\n"; - } - $in_purpose = 0; - } elsif ($in_purpose == 1) { - # Continued declaration purpose - chomp($declaration_purpose); - $declaration_purpose .= " " . xml_escape($1); - $declaration_purpose =~ s/\s+/ /g; - } else { - my $cont = $1; - if ($section =~ m/^@/ || $section eq $section_context) { - if (!defined $leading_space) { - if ($cont =~ m/^(\s+)/) { - $leading_space = $1; - } else { - $leading_space = ""; - } - } - - $cont =~ s/^$leading_space//; - } - $contents .= $cont . "\n"; - } - } else { - # i dont know - bad line? ignore. - print STDERR "${file}:$.: warning: bad line: $_"; - ++$warnings; - } + process_normal(); + } elsif ($state == STATE_NAME) { + process_name($file, $_); + } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { + process_body($file, $_); } elsif ($state == STATE_INLINE) { # scanning for inline parameters - # First line (state 1) needs to be a @parameter - if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { - $section = $1; - $contents = $2; - $new_start_line = $.; - if ($contents ne "") { - while (substr($contents, 0, 1) eq " ") { - $contents = substr($contents, 1); - } - $contents .= "\n"; - } - $inline_doc_state = STATE_INLINE_TEXT; - # Documentation block end */ - } elsif (/$doc_inline_end/) { - if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - } - $state = STATE_PROTO; - $inline_doc_state = STATE_INLINE_NA; - # Regular text - } elsif (/$doc_content/) { - if ($inline_doc_state == STATE_INLINE_TEXT) { - $contents .= $1 . "\n"; - # nuke leading blank lines - if ($contents =~ /^\s*$/) { - $contents = ""; - } - } elsif ($inline_doc_state == STATE_INLINE_NAME) { - $inline_doc_state = STATE_INLINE_ERROR; - print STDERR "${file}:$.: warning: "; - print STDERR "Incorrect use of kernel-doc format: $_"; - ++$warnings; - } - } - } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) - if (/$doc_inline_oneline/) { - $section = $1; - $contents = $2; - if ($contents ne "") { - $contents .= "\n"; - dump_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - } - } elsif (/$doc_inline_start/) { - $state = STATE_INLINE; - $inline_doc_state = STATE_INLINE_NAME; - } elsif ($decl_type eq 'function') { - process_proto_function($_, $file); - } else { - process_proto_type($_, $file); - } + process_inline($file, $_); + } elsif ($state == STATE_PROTO) { + process_proto($file, $_); } elsif ($state == STATE_DOCBLOCK) { - if (/$doc_end/) - { - dump_doc_section($file, $section, xml_escape($contents)); - $section = $section_default; - $contents = ""; - $function = ""; - %parameterdescs = (); - %parametertypes = (); - @parameterlist = (); - %sections = (); - @sectionlist = (); - $prototype = ""; - $state = STATE_NORMAL; - } - elsif (/$doc_content/) - { - if ( $1 eq "" ) - { - $contents .= $blankline; - } - else - { - $contents .= $1 . "\n"; - } - } + process_docblock($file, $_); } } + + # Make sure we got something interesting. if ($initial_section_counter == $section_counter) { if ($output_mode ne "none") { print STDERR "${file}:1: warning: no structured comments found\n"; diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl index bc57880..6a89778 100755 --- a/scripts/leaking_addresses.pl +++ b/scripts/leaking_addresses.pl @@ -3,15 +3,20 @@ # (c) 2017 Tobin C. Harding <me@tobin.cc> # Licensed under the terms of the GNU GPL License version 2 # -# leaking_addresses.pl: Scan 64 bit kernel for potential leaking addresses. +# leaking_addresses.pl: Scan the kernel for potential leaking addresses. # - Scans dmesg output. # - Walks directory tree and parses each file (for each directory in @DIRS). # # Use --debug to output path before parsing, this is useful to find files that # cause the script to choke. + # -# You may like to set kptr_restrict=2 before running script -# (see Documentation/sysctl/kernel.txt). +# When the system is idle it is likely that most files under /proc/PID will be +# identical for various processes. Scanning _all_ the PIDs under /proc is +# unnecessary and implies that we are thoroughly scanning /proc. This is _not_ +# the case because there may be ways userspace can trigger creation of /proc +# files that leak addresses but were not present during a scan. For these two +# reasons we exclude all PID directories under /proc except '1/' use warnings; use strict; @@ -22,9 +27,10 @@ use Cwd 'abs_path'; use Term::ANSIColor qw(:constants); use Getopt::Long qw(:config no_auto_abbrev); use Config; +use bigint qw/hex/; +use feature 'state'; my $P = $0; -my $V = '0.01'; # Directories to scan. my @DIRS = ('/proc', '/sys'); @@ -32,10 +38,9 @@ my @DIRS = ('/proc', '/sys'); # Timer for parsing each file, in seconds. my $TIMEOUT = 10; -# Script can only grep for kernel addresses on the following architectures. If -# your architecture is not listed here and has a grep'able kernel address please -# consider submitting a patch. -my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64'); +# Kernel addresses vary by architecture. We can only auto-detect the following +# architectures (using `uname -m`). (flag --32-bit overrides auto-detection.) +my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64', 'x86'); # Command line options. my $help = 0; @@ -43,46 +48,34 @@ my $debug = 0; my $raw = 0; my $output_raw = ""; # Write raw results to file. my $input_raw = ""; # Read raw results from file instead of scanning. - my $suppress_dmesg = 0; # Don't show dmesg in output. my $squash_by_path = 0; # Summary report grouped by absolute path. my $squash_by_filename = 0; # Summary report grouped by filename. - -# Do not parse these files (absolute path). -my @skip_parse_files_abs = ('/proc/kmsg', - '/proc/kcore', - '/proc/fs/ext4/sdb1/mb_groups', - '/proc/1/fd/3', - '/sys/firmware/devicetree', - '/proc/device-tree', - '/sys/kernel/debug/tracing/trace_pipe', - '/sys/kernel/security/apparmor/revision'); - -# Do not parse these files under any subdirectory. -my @skip_parse_files_any = ('0', - '1', - '2', - 'pagemap', - 'events', - 'access', - 'registers', - 'snapshot_raw', - 'trace_pipe_raw', - 'ptmx', - 'trace_pipe'); - -# Do not walk these directories (absolute path). -my @skip_walk_dirs_abs = (); - -# Do not walk these directories under any subdirectory. -my @skip_walk_dirs_any = ('self', - 'thread-self', - 'cwd', - 'fd', - 'usbmon', - 'stderr', - 'stdin', - 'stdout'); +my $kernel_config_file = ""; # Kernel configuration file. +my $opt_32bit = 0; # Scan 32-bit kernel. +my $page_offset_32bit = 0; # Page offset for 32-bit kernel. + +# Skip these absolute paths. +my @skip_abs = ( + '/proc/kmsg', + '/proc/device-tree', + '/proc/1/syscall', + '/sys/firmware/devicetree', + '/sys/kernel/debug/tracing/trace_pipe', + '/sys/kernel/security/apparmor/revision'); + +# Skip these under any subdirectory. +my @skip_any = ( + 'pagemap', + 'events', + 'access', + 'registers', + 'snapshot_raw', + 'trace_pipe_raw', + 'ptmx', + 'trace_pipe', + 'fd', + 'usbmon'); sub help { @@ -91,31 +84,22 @@ sub help print << "EOM"; Usage: $P [OPTIONS] -Version: $V Options: - -o, --output-raw=<file> Save results for future processing. - -i, --input-raw=<file> Read results from file instead of scanning. - --raw Show raw results (default). - --suppress-dmesg Do not show dmesg results. - --squash-by-path Show one result per unique path. - --squash-by-filename Show one result per unique filename. - -d, --debug Display debugging output. - -h, --help, --version Display this help and exit. - -Examples: - - # Scan kernel and dump raw results. - $0 - - # Scan kernel and save results to file. - $0 --output-raw scan.out + -o, --output-raw=<file> Save results for future processing. + -i, --input-raw=<file> Read results from file instead of scanning. + --raw Show raw results (default). + --suppress-dmesg Do not show dmesg results. + --squash-by-path Show one result per unique path. + --squash-by-filename Show one result per unique filename. + --kernel-config-file=<file> Kernel configuration file (e.g /boot/config) + --32-bit Scan 32-bit kernel. + --page-offset-32-bit=o Page offset (for 32-bit kernel 0xABCD1234). + -d, --debug Display debugging output. + -h, --help, --version Display this help and exit. - # View summary report. - $0 --input-raw scan.out --squash-by-filename - -Scans the running (64 bit) kernel for potential leaking addresses. +Scans the running kernel for potential leaking addresses. EOM exit($exitcode); @@ -131,6 +115,9 @@ GetOptions( 'squash-by-path' => \$squash_by_path, 'squash-by-filename' => \$squash_by_filename, 'raw' => \$raw, + 'kernel-config-file=s' => \$kernel_config_file, + '32-bit' => \$opt_32bit, + 'page-offset-32-bit=o' => \$page_offset_32bit, ) or help(1); help(0) if ($help); @@ -146,16 +133,19 @@ if (!$input_raw and ($squash_by_path or $squash_by_filename)) { exit(128); } -if (!is_supported_architecture()) { +if (!(is_supported_architecture() or $opt_32bit or $page_offset_32bit)) { printf "\nScript does not support your architecture, sorry.\n"; printf "\nCurrently we support: \n\n"; foreach(@SUPPORTED_ARCHITECTURES) { printf "\t%s\n", $_; } + printf("\n"); + + printf("If you are running a 32-bit architecture you may use:\n"); + printf("\n\t--32-bit or --page-offset-32-bit=<page offset>\n\n"); - my $archname = $Config{archname}; - printf "\n\$ perl -MConfig -e \'print \"\$Config{archname}\\n\"\'\n"; - printf "%s\n", $archname; + my $archname = `uname -m`; + printf("Machine hardware name (`uname -m`): %s\n", $archname); exit(129); } @@ -177,49 +167,183 @@ sub dprint sub is_supported_architecture { - return (is_x86_64() or is_ppc64()); + return (is_x86_64() or is_ppc64() or is_ix86_32()); } -sub is_x86_64 +sub is_32bit { - my $archname = $Config{archname}; - - if ($archname =~ m/x86_64/) { + # Allow --32-bit or --page-offset-32-bit to override + if ($opt_32bit or $page_offset_32bit) { return 1; } - return 0; + + return is_ix86_32(); +} + +sub is_ix86_32 +{ + state $arch = `uname -m`; + + chomp $arch; + if ($arch =~ m/i[3456]86/) { + return 1; + } + return 0; +} + +sub is_arch +{ + my ($desc) = @_; + my $arch = `uname -m`; + + chomp $arch; + if ($arch eq $desc) { + return 1; + } + return 0; +} + +sub is_x86_64 +{ + state $is = is_arch('x86_64'); + return $is; } sub is_ppc64 { - my $archname = $Config{archname}; + state $is = is_arch('ppc64'); + return $is; +} - if ($archname =~ m/powerpc/ and $archname =~ m/64/) { - return 1; +# Gets config option value from kernel config file. +# Returns "" on error or if config option not found. +sub get_kernel_config_option +{ + my ($option) = @_; + my $value = ""; + my $tmp_file = ""; + my @config_files; + + # Allow --kernel-config-file to override. + if ($kernel_config_file ne "") { + @config_files = ($kernel_config_file); + } elsif (-R "/proc/config.gz") { + my $tmp_file = "/tmp/tmpkconf"; + + if (system("gunzip < /proc/config.gz > $tmp_file")) { + dprint "$0: system(gunzip < /proc/config.gz) failed\n"; + return ""; + } else { + @config_files = ($tmp_file); + } + } else { + my $file = '/boot/config-' . `uname -r`; + chomp $file; + @config_files = ($file, '/boot/config'); } - return 0; + + foreach my $file (@config_files) { + dprint("parsing config file: %s\n", $file); + $value = option_from_file($option, $file); + if ($value ne "") { + last; + } + } + + if ($tmp_file ne "") { + system("rm -f $tmp_file"); + } + + return $value; +} + +# Parses $file and returns kernel configuration option value. +sub option_from_file +{ + my ($option, $file) = @_; + my $str = ""; + my $val = ""; + + open(my $fh, "<", $file) or return ""; + while (my $line = <$fh> ) { + if ($line =~ /^$option/) { + ($str, $val) = split /=/, $line; + chomp $val; + last; + } + } + + close $fh; + return $val; } sub is_false_positive { my ($match) = @_; + if (is_32bit()) { + return is_false_positive_32bit($match); + } + + # 64 bit false positives. + if ($match =~ '\b(0x)?(f|F){16}\b' or $match =~ '\b(0x)?0{16}\b') { return 1; } - if (is_x86_64) { - # vsyscall memory region, we should probably check against a range here. - if ($match =~ '\bf{10}600000\b' or - $match =~ '\bf{10}601000\b') { - return 1; - } + if (is_x86_64() and is_in_vsyscall_memory_region($match)) { + return 1; } return 0; } +sub is_false_positive_32bit +{ + my ($match) = @_; + state $page_offset = get_page_offset(); + + if ($match =~ '\b(0x)?(f|F){8}\b') { + return 1; + } + + if (hex($match) < $page_offset) { + return 1; + } + + return 0; +} + +# returns integer value +sub get_page_offset +{ + my $page_offset; + my $default_offset = 0xc0000000; + + # Allow --page-offset-32bit to override. + if ($page_offset_32bit != 0) { + return $page_offset_32bit; + } + + $page_offset = get_kernel_config_option('CONFIG_PAGE_OFFSET'); + if (!$page_offset) { + return $default_offset; + } + return $page_offset; +} + +sub is_in_vsyscall_memory_region +{ + my ($match) = @_; + + my $hex = hex($match); + my $region_min = hex("0xffffffffff600000"); + my $region_max = hex("0xffffffffff601000"); + + return ($hex >= $region_min and $hex <= $region_max); +} + # True if argument potentially contains a kernel address. sub may_leak_address { @@ -238,14 +362,8 @@ sub may_leak_address return 0; } - # One of these is guaranteed to be true. - if (is_x86_64()) { - $address_re = '\b(0x)?ffff[[:xdigit:]]{12}\b'; - } elsif (is_ppc64()) { - $address_re = '\b(0x)?[89abcdef]00[[:xdigit:]]{13}\b'; - } - - while (/($address_re)/g) { + $address_re = get_address_re(); + while ($line =~ /($address_re)/g) { if (!is_false_positive($1)) { return 1; } @@ -254,6 +372,31 @@ sub may_leak_address return 0; } +sub get_address_re +{ + if (is_ppc64()) { + return '\b(0x)?[89abcdef]00[[:xdigit:]]{13}\b'; + } elsif (is_32bit()) { + return '\b(0x)?[[:xdigit:]]{8}\b'; + } + + return get_x86_64_re(); +} + +sub get_x86_64_re +{ + # We handle page table levels but only if explicitly configured using + # CONFIG_PGTABLE_LEVELS. If config file parsing fails or config option + # is not found we default to using address regular expression suitable + # for 4 page table levels. + state $ptl = get_kernel_config_option('CONFIG_PGTABLE_LEVELS'); + + if ($ptl == 5) { + return '\b(0x)?ff[[:xdigit:]]{14}\b'; + } + return '\b(0x)?ffff[[:xdigit:]]{12}\b'; +} + sub parse_dmesg { open my $cmd, '-|', 'dmesg'; @@ -268,26 +411,20 @@ sub parse_dmesg # True if we should skip this path. sub skip { - my ($path, $paths_abs, $paths_any) = @_; + my ($path) = @_; - foreach (@$paths_abs) { + foreach (@skip_abs) { return 1 if (/^$path$/); } my($filename, $dirs, $suffix) = fileparse($path); - foreach (@$paths_any) { + foreach (@skip_any) { return 1 if (/^$filename$/); } return 0; } -sub skip_parse -{ - my ($path) = @_; - return skip($path, \@skip_parse_files_abs, \@skip_parse_files_any); -} - sub timed_parse_file { my ($file) = @_; @@ -313,11 +450,9 @@ sub parse_file return; } - if (skip_parse($file)) { - dprint "skipping file: $file\n"; + if (! -T $file) { return; } - dprint "parsing: $file\n"; open my $fh, "<", $file or return; while ( <$fh> ) { @@ -328,12 +463,14 @@ sub parse_file close $fh; } - -# True if we should skip walking this directory. -sub skip_walk +# Checks if the actual path name is leaking a kernel address. +sub check_path_for_leaks { my ($path) = @_; - return skip($path, \@skip_walk_dirs_abs, \@skip_walk_dirs_any) + + if (may_leak_address($path)) { + printf("Path name may contain address: $path\n"); + } } # Recursively walk directory tree. @@ -342,7 +479,6 @@ sub walk my @dirs = @_; while (my $pwd = shift @dirs) { - next if (skip_walk($pwd)); next if (!opendir(DIR, $pwd)); my @files = readdir(DIR); closedir(DIR); @@ -353,11 +489,21 @@ sub walk my $path = "$pwd/$file"; next if (-l $path); + # skip /proc/PID except /proc/1 + next if (($path =~ /^\/proc\/[0-9]+$/) && + ($path !~ /^\/proc\/1$/)); + + next if (skip($path)); + + check_path_for_leaks($path); + if (-d $path) { push @dirs, $path; - } else { - timed_parse_file($path); + next; } + + dprint "parsing: $path\n"; + timed_parse_file($path); } } } diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index be56a11..9045823 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -4,7 +4,7 @@ # link vmlinux # # vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and -# $(KBUILD_VMLINUX_MAIN) and $(KBUILD_VMLINUX_LIBS). Most are built-in.o files +# $(KBUILD_VMLINUX_MAIN) and $(KBUILD_VMLINUX_LIBS). Most are built-in.a files # from top-level directories in the kernel tree, others are specified in # arch/$(ARCH)/Makefile. Ordering when linking is important, and # $(KBUILD_VMLINUX_INIT) must be first. $(KBUILD_VMLINUX_LIBS) are archives @@ -18,7 +18,7 @@ # | +--< init/version.o + more # | # +--< $(KBUILD_VMLINUX_MAIN) -# | +--< drivers/built-in.o mm/built-in.o + more +# | +--< drivers/built-in.a mm/built-in.a + more # | # +--< $(KBUILD_VMLINUX_LIBS) # | +--< lib/lib.a + more @@ -51,17 +51,15 @@ info() # # Traditional incremental style of link does not require this step # -# built-in.o output file +# built-in.a output file # archive_builtin() { - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - info AR built-in.o - rm -f built-in.o; - ${AR} rcsTP${KBUILD_ARFLAGS} built-in.o \ - ${KBUILD_VMLINUX_INIT} \ - ${KBUILD_VMLINUX_MAIN} - fi + info AR built-in.a + rm -f built-in.a; + ${AR} rcsTP${KBUILD_ARFLAGS} built-in.a \ + ${KBUILD_VMLINUX_INIT} \ + ${KBUILD_VMLINUX_MAIN} } # Link of vmlinux.o used for section mismatch analysis @@ -70,20 +68,13 @@ modpost_link() { local objects - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="--whole-archive \ - built-in.o \ - --no-whole-archive \ - --start-group \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group" - else - objects="${KBUILD_VMLINUX_INIT} \ - --start-group \ - ${KBUILD_VMLINUX_MAIN} \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group" - fi + objects="--whole-archive \ + built-in.a \ + --no-whole-archive \ + --start-group \ + ${KBUILD_VMLINUX_LIBS} \ + --end-group" + ${LD} ${LDFLAGS} -r -o ${1} ${objects} } @@ -96,46 +87,28 @@ vmlinux_link() local objects if [ "${SRCARCH}" != "um" ]; then - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="--whole-archive \ - built-in.o \ - --no-whole-archive \ - --start-group \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group \ - ${1}" - else - objects="${KBUILD_VMLINUX_INIT} \ - --start-group \ - ${KBUILD_VMLINUX_MAIN} \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group \ - ${1}" - fi - - ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ + objects="--whole-archive \ + built-in.a \ + --no-whole-archive \ + --start-group \ + ${KBUILD_VMLINUX_LIBS} \ + --end-group \ + ${1}" + + ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ -T ${lds} ${objects} else - if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then - objects="-Wl,--whole-archive \ - built-in.o \ - -Wl,--no-whole-archive \ - -Wl,--start-group \ - ${KBUILD_VMLINUX_LIBS} \ - -Wl,--end-group \ - ${1}" - else - objects="${KBUILD_VMLINUX_INIT} \ - -Wl,--start-group \ - ${KBUILD_VMLINUX_MAIN} \ - ${KBUILD_VMLINUX_LIBS} \ - -Wl,--end-group \ - ${1}" - fi - - ${CC} ${CFLAGS_vmlinux} -o ${2} \ - -Wl,-T,${lds} \ - ${objects} \ + objects="-Wl,--whole-archive \ + built-in.a \ + -Wl,--no-whole-archive \ + -Wl,--start-group \ + ${KBUILD_VMLINUX_LIBS} \ + -Wl,--end-group \ + ${1}" + + ${CC} ${CFLAGS_vmlinux} -o ${2} \ + -Wl,-T,${lds} \ + ${objects} \ -lutil -lrt -lpthread rm -f linux fi @@ -191,7 +164,7 @@ cleanup() rm -f .tmp_System.map rm -f .tmp_kallsyms* rm -f .tmp_vmlinux* - rm -f built-in.o + rm -f built-in.a rm -f System.map rm -f vmlinux rm -f vmlinux.o @@ -296,8 +269,8 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o # step 3 - size1=$(stat -c "%s" .tmp_kallsyms1.o) - size2=$(stat -c "%s" .tmp_kallsyms2.o) + size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" .tmp_kallsyms1.o) + size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" .tmp_kallsyms2.o) if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then kallsymso=.tmp_kallsyms3.o diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 9917f92..4ff08a0 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -840,8 +840,7 @@ static const char *const section_white_list[] = ".debug*", ".cranges", /* sh64 */ ".zdebug*", /* Compressed debug sections. */ - ".GCC-command-line", /* mn10300 */ - ".GCC.command.line", /* record-gcc-switches, non mn10300 */ + ".GCC.command.line", /* record-gcc-switches */ ".mdebug*", /* alpha, score, mips etc. */ ".pdr", /* alpha, score, mips etc. */ ".stab*", @@ -1104,8 +1103,8 @@ static const struct sectioncheck *section_mismatch( /* * The target section could be the SHT_NUL section when we're * handling relocations to un-resolved symbols, trying to match it - * doesn't make much sense and causes build failures on parisc and - * mn10300 architectures. + * doesn't make much sense and causes build failures on parisc + * architectures. */ if (*tosec == '\0') return NULL; diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 729c547..6135574 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -164,7 +164,7 @@ sub linux_objects s:^\./::; if (/.*\.o$/ && ! ( - m:/built-in.o$: + m:/built-in.a$: || m:arch/x86/vdso/: || m:arch/x86/boot/: || m:arch/ia64/ia32/ia32.o$: diff --git a/scripts/package/builddeb b/scripts/package/builddeb index b4f0f2b..13fabb1 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -313,7 +313,7 @@ fi # Build kernel header package (cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles" -(cd $srctree; find arch/*/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles" +(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles" (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles" if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 280027f..61427c6 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -98,7 +98,7 @@ $M make %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} KBUILD_SRC= modules_instal $S$M rm -f %{buildroot}/lib/modules/$KERNELRELEASE/build $S$M rm -f %{buildroot}/lib/modules/$KERNELRELEASE/source $S$M mkdir -p %{buildroot}/usr/src/kernels/$KERNELRELEASE -$S$M tar cf - . $EXCLUDES | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE +$S$M tar cf - $EXCLUDES . | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE $S$M cd %{buildroot}/lib/modules/$KERNELRELEASE $S$M ln -sf /usr/src/kernels/$KERNELRELEASE build $S$M ln -sf /usr/src/kernels/$KERNELRELEASE source diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 16e086d..8c9691c 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -33,20 +33,6 @@ #include <string.h> #include <unistd.h> -/* - * glibc synced up and added the metag number but didn't add the relocations. - * Work around this in a crude manner for now. - */ -#ifndef EM_METAG -#define EM_METAG 174 -#endif -#ifndef R_METAG_ADDR32 -#define R_METAG_ADDR32 2 -#endif -#ifndef R_METAG_NONE -#define R_METAG_NONE 3 -#endif - #ifndef EM_AARCH64 #define EM_AARCH64 183 #define R_AARCH64_NONE 0 @@ -538,12 +524,6 @@ do_file(char const *const fname) gpfx = '_'; break; case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; - case EM_METAG: reltype = R_METAG_ADDR32; - altmcount = "_mcount_wrapper"; - rel_type_nop = R_METAG_NONE; - /* We happen to have the same requirement as MIPS */ - is_fake_mcount32 = MIPS32_is_fake_mcount; - break; case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 2033af7..191eb94 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -368,14 +368,11 @@ if ($arch eq "x86_64") { } elsif ($arch eq "microblaze") { # Microblaze calls '_mcount' instead of plain 'mcount'. $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; -} elsif ($arch eq "blackfin") { - $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; - $mcount_adjust = -4; -} elsif ($arch eq "tilegx" || $arch eq "tile") { - # Default to the newer TILE-Gx architecture if only "tile" is given. - $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$"; +} elsif ($arch eq "riscv") { + $function_regex = "^([0-9a-fA-F]+)\\s+<([^.0-9][0-9a-zA-Z_\\.]+)>:"; + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL\\s_mcount\$"; $type = ".quad"; - $alignment = 8; + $alignment = 2; } else { die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; } diff --git a/scripts/split-man.pl b/scripts/split-man.pl new file mode 100755 index 0000000..bfe16cb --- /dev/null +++ b/scripts/split-man.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0 +# +# Author: Mauro Carvalho Chehab <mchehab@s-opensource.com> +# +# Produce manpages from kernel-doc. +# See Documentation/doc-guide/kernel-doc.rst for instructions + +if ($#ARGV < 0) { + die "where do I put the results?\n"; +} + +mkdir $ARGV[0],0777; +$state = 0; +while (<STDIN>) { + if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) { + if ($state == 1) { close OUT } + $state = 1; + $fn = "$ARGV[0]/$1.9"; + print STDERR "Creating $fn\n"; + open OUT, ">$fn" or die "can't open $fn: $!\n"; + print OUT $_; + } elsif ($state != 0) { + print OUT $_; + } +} + +close OUT; |