diff options
Diffstat (limited to 'scripts')
37 files changed, 1445 insertions, 289 deletions
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 3ee8ecfb8c04..3500a3d62f0d 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -33,7 +33,8 @@ ld-option = $(success,$(LD) -v $(1)) # $(as-instr,<instr>) # Return y if the assembler supports <instr>, n otherwise -as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -Wa$(comma)--fatal-warnings -c -x assembler-with-cpp -o /dev/null -) +as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) $(2) -Wa$(comma)--fatal-warnings -c -x assembler-with-cpp -o /dev/null -) +as-instr64 = $(as-instr,$(1),$(m64-flag)) # check if $(CC) and $(LD) exist $(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found) diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic deleted file mode 100644 index 1486abf34c7c..000000000000 --- a/scripts/Makefile.asm-generic +++ /dev/null @@ -1,58 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# include/asm-generic contains a lot of files that are used -# verbatim by several architectures. -# -# This Makefile reads the file arch/$(SRCARCH)/include/(uapi/)/asm/Kbuild -# and for each file listed in this file with generic-y creates -# a small wrapper file in arch/$(SRCARCH)/include/generated/(uapi/)/asm. - -PHONY := all -all: - -src := $(srctree)/$(subst /generated,,$(obj)) - -include $(srctree)/scripts/Kbuild.include --include $(kbuild-file) - -# $(generic)/Kbuild lists mandatory-y. Exclude um since it is a special case. -ifneq ($(SRCARCH),um) -include $(srctree)/$(generic)/Kbuild -endif - -redundant := $(filter $(mandatory-y) $(generated-y), $(generic-y)) -redundant += $(foreach f, $(generic-y), $(if $(wildcard $(src)/$(f)),$(f))) -redundant := $(sort $(redundant)) -$(if $(redundant),\ - $(warning redundant generic-y found in $(src)/Kbuild: $(redundant))) - -# If arch does not implement mandatory headers, fallback to asm-generic ones. -mandatory-y := $(filter-out $(generated-y), $(mandatory-y)) -generic-y += $(foreach f, $(mandatory-y), $(if $(wildcard $(src)/$(f)),,$(f))) - -generic-y := $(addprefix $(obj)/, $(generic-y)) -generated-y := $(addprefix $(obj)/, $(generated-y)) - -# Remove stale wrappers when the corresponding files are removed from generic-y -old-headers := $(wildcard $(obj)/*.h) -unwanted := $(filter-out $(generic-y) $(generated-y),$(old-headers)) - -quiet_cmd_wrap = WRAP $@ - cmd_wrap = echo "\#include <asm-generic/$*.h>" > $@ - -quiet_cmd_remove = REMOVE $(unwanted) - cmd_remove = rm -f $(unwanted) - -all: $(generic-y) - $(if $(unwanted),$(call cmd,remove)) - @: - -$(obj)/%.h: - $(call cmd,wrap) - -# Create output directory. Skip it if at least one old header exists -# since we know the output directory already exists. -ifeq ($(old-headers),) -$(shell mkdir -p $(obj)) -endif - -.PHONY: $(PHONY) diff --git a/scripts/Makefile.asm-headers b/scripts/Makefile.asm-headers new file mode 100644 index 000000000000..8a4856e74180 --- /dev/null +++ b/scripts/Makefile.asm-headers @@ -0,0 +1,106 @@ +# SPDX-License-Identifier: GPL-2.0 +# include/asm-generic contains a lot of files that are used +# verbatim by several architectures. +# +# This Makefile generates arch/$(SRCARCH)/include/generated/(uapi/)/asm +# headers from multiple sources: +# - a small wrapper to include the corresponding asm-generic/*.h +# is generated for each file listed as generic-y +# - uapi/asm/unistd_*.h files listed as syscalls-y are generated from +# syscall.tbl with the __NR_* macros +# - Corresponding asm/syscall_table_*.h are generated from the same input + +PHONY := all +all: + +src := $(srctree)/$(subst /generated,,$(obj)) + +syscall_abis_32 += common,32 +syscall_abis_64 += common,64 +syscalltbl := $(srctree)/scripts/syscall.tbl +syshdr-args := --emit-nr + +# let architectures override $(syscall_abis_%) and $(syscalltbl) +-include $(srctree)/arch/$(SRCARCH)/kernel/Makefile.syscalls +include $(srctree)/scripts/Kbuild.include +-include $(kbuild-file) + +syshdr := $(srctree)/scripts/syscallhdr.sh +systbl := $(srctree)/scripts/syscalltbl.sh + +# $(generic)/Kbuild lists mandatory-y. Exclude um since it is a special case. +ifneq ($(SRCARCH),um) +include $(srctree)/$(generic)/Kbuild +endif + +redundant := $(filter $(mandatory-y) $(generated-y), $(generic-y)) +redundant += $(foreach f, $(generic-y), $(if $(wildcard $(src)/$(f)),$(f))) +redundant := $(sort $(redundant)) +$(if $(redundant),\ + $(warning redundant generic-y found in $(src)/Kbuild: $(redundant))) + +# If arch does not implement mandatory headers, fallback to asm-generic ones. +mandatory-y := $(filter-out $(generated-y), $(mandatory-y)) +generic-y += $(foreach f, $(mandatory-y), $(if $(wildcard $(src)/$(f)),,$(f))) + +generic-y := $(addprefix $(obj)/, $(generic-y)) +syscall-y := $(addprefix $(obj)/, $(syscall-y)) +generated-y := $(addprefix $(obj)/, $(generated-y)) + +# Remove stale wrappers when the corresponding files are removed from generic-y +old-headers := $(wildcard $(obj)/*.h) +unwanted := $(filter-out $(generic-y) $(generated-y) $(syscall-y),$(old-headers)) + +quiet_cmd_wrap = WRAP $@ + cmd_wrap = echo "\#include <asm-generic/$*.h>" > $@ + +quiet_cmd_remove = REMOVE $(unwanted) + cmd_remove = rm -f $(unwanted) + +quiet_cmd_syshdr = SYSHDR $@ + cmd_syshdr = $(CONFIG_SHELL) $(syshdr) \ + $(if $(syshdr-args-$*),$(syshdr-args-$*),$(syshdr-args)) \ + $(if $(syscall_compat),--prefix "compat$*_") \ + --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \ + $< $@ + +quiet_cmd_systbl = SYSTBL $@ + cmd_systbl = $(CONFIG_SHELL) $(systbl) \ + $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \ + --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \ + $< $@ + +all: $(generic-y) $(syscall-y) + $(if $(unwanted),$(call cmd,remove)) + @: + +$(obj)/%.h: $(srctree)/$(generic)/%.h + $(call cmd,wrap) + +$(obj)/unistd_%.h: $(syscalltbl) $(syshdr) FORCE + $(call if_changed,syshdr) + +$(obj)/unistd_compat_%.h: syscall_compat:=1 +$(obj)/unistd_compat_%.h: $(syscalltbl) $(syshdr) FORCE + $(call if_changed,syshdr) + +$(obj)/syscall_table_%.h: $(syscalltbl) $(systbl) FORCE + $(call if_changed,systbl) + +targets := $(syscall-y) + +# Create output directory. Skip it if at least one old header exists +# since we know the output directory already exists. +ifeq ($(old-headers),) +$(shell mkdir -p $(obj)) +endif + +PHONY += FORCE + +FORCE: + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index 2d6e5ed9081e..b75f09f3f424 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -14,17 +14,20 @@ pahole-flags-$(call test-ge, $(pahole-ver), 121) += --btf_gen_floats pahole-flags-$(call test-ge, $(pahole-ver), 122) += -j -ifeq ($(pahole-ver), 125) -pahole-flags-y += --skip_encoding_btf_inconsistent_proto --btf_gen_optimized -endif +pahole-flags-$(call test-ge, $(pahole-ver), 125) += --skip_encoding_btf_inconsistent_proto --btf_gen_optimized else # Switch to using --btf_features for v1.26 and later. -pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func +pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func,decl_tag_kfuncs + +ifneq ($(KBUILD_EXTMOD),) +module-pahole-flags-$(call test-ge, $(pahole-ver), 126) += --btf_features=distilled_base +endif endif pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust export PAHOLE_FLAGS := $(pahole-flags-y) +export MODULE_PAHOLE_FLAGS := $(module-pahole-flags-y) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 636119dc4403..fe3668dc4954 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -407,12 +407,19 @@ cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) +DT_CHECK_CMD = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) + # NOTE: # Do not replace $(filter %.dtb %.dtbo, $^) with $(real-prereqs). When a single # DTB is turned into a multi-blob DTB, $^ will contain header file dependencies # recorded in the .*.cmd file. +ifneq ($(CHECK_DTBS),) +quiet_cmd_fdtoverlay = DTOVLCH $@ + cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) ; $(DT_CHECK_CMD) $@ || true +else quiet_cmd_fdtoverlay = DTOVL $@ cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) +endif $(multi-dtb-y): FORCE $(call if_changed,fdtoverlay) @@ -425,7 +432,7 @@ DT_BINDING_DIR := Documentation/devicetree/bindings DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json quiet_cmd_dtb = DTC_CHK $@ - cmd_dtb = $(cmd_dtc) ; $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true + cmd_dtb = $(cmd_dtc) ; $(DT_CHECK_CMD) $@ || true else quiet_cmd_dtb = $(quiet_cmd_dtc) cmd_dtb = $(cmd_dtc) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 3bec9043e4f3..1fa98b5e952b 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -41,7 +41,7 @@ quiet_cmd_btf_ko = BTF [M] $@ if [ ! -f vmlinux ]; then \ printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ else \ - LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ + LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base vmlinux $@; \ $(RESOLVE_BTFIDS) -b vmlinux $@; \ fi; diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2b812210b412..39032224d504 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -28,6 +28,7 @@ my %verbose_messages = (); my %verbose_emitted = (); my $tree = 1; my $chk_signoff = 1; +my $chk_fixes_tag = 1; my $chk_patch = 1; my $tst_only; my $emacs = 0; @@ -88,6 +89,7 @@ Options: -v, --verbose verbose mode --no-tree run without a kernel tree --no-signoff do not check for 'Signed-off-by' line + --no-fixes-tag do not check for 'Fixes:' tag --patch treat FILE as patchfile (default) --emacs emacs compile window format --terse one line per report @@ -295,6 +297,7 @@ GetOptions( 'v|verbose!' => \$verbose, 'tree!' => \$tree, 'signoff!' => \$chk_signoff, + 'fixes-tag!' => \$chk_fixes_tag, 'patch!' => \$chk_patch, 'emacs!' => \$emacs, 'terse!' => \$terse, @@ -1257,6 +1260,7 @@ sub git_commit_info { } $chk_signoff = 0 if ($file); +$chk_fixes_tag = 0 if ($file); my @rawlines = (); my @lines = (); @@ -2636,6 +2640,9 @@ sub process { our $clean = 1; my $signoff = 0; + my $fixes_tag = 0; + my $is_revert = 0; + my $needs_fixes_tag = ""; my $author = ''; my $authorsignoff = 0; my $author_sob = ''; @@ -3189,6 +3196,16 @@ sub process { } } +# These indicate a bug fix + if (!$in_header_lines && !$is_patch && + $line =~ /^This reverts commit/) { + $is_revert = 1; + } + + if (!$in_header_lines && !$is_patch && + $line =~ /((?:(?:BUG: K.|UB)SAN: |Call Trace:|stable\@|syzkaller))/) { + $needs_fixes_tag = $1; + } # Check Fixes: styles is correct if (!$in_header_lines && @@ -3201,6 +3218,7 @@ sub process { my $id_length = 1; my $id_case = 1; my $title_has_quotes = 0; + $fixes_tag = 1; if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { my $tag = $1; @@ -3858,7 +3876,7 @@ sub process { } if ($msg_type ne "" && - (show_type("LONG_LINE") || show_type($msg_type))) { + show_type("LONG_LINE") && show_type($msg_type)) { my $msg_level = \&WARN; $msg_level = \&CHK if ($file); &{$msg_level}($msg_type, @@ -7697,6 +7715,12 @@ sub process { ERROR("NOT_UNIFIED_DIFF", "Does not appear to be a unified-diff format patch\n"); } + if ($is_patch && $has_commit_log && $chk_fixes_tag) { + if ($needs_fixes_tag ne "" && !$is_revert && !$fixes_tag) { + WARN("MISSING_FIXES_TAG", + "The commit message has '$needs_fixes_tag', perhaps it also needs a 'Fixes:' tag?\n"); + } + } if ($is_patch && $has_commit_log && $chk_signoff) { if ($signoff == 0) { ERROR("MISSING_SIGN_OFF", diff --git a/scripts/checktransupdate.py b/scripts/checktransupdate.py new file mode 100755 index 000000000000..5a0fc99e3f93 --- /dev/null +++ b/scripts/checktransupdate.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +""" +This script helps track the translation status of the documentation +in different locales, e.g., zh_CN. More specially, it uses `git log` +commit to find the latest english commit from the translation commit +(order by author date) and the latest english commits from HEAD. If +differences occur, report the file and commits that need to be updated. + +The usage is as follows: +- ./scripts/checktransupdate.py -l zh_CN +This will print all the files that need to be updated in the zh_CN locale. +- ./scripts/checktransupdate.py Documentation/translations/zh_CN/dev-tools/testing-overview.rst +This will only print the status of the specified file. + +The output is something like: +Documentation/translations/zh_CN/dev-tools/testing-overview.rst (1 commits) +commit 42fb9cfd5b18 ("Documentation: dev-tools: Add link to RV docs") +""" + +import os +from argparse import ArgumentParser, BooleanOptionalAction +from datetime import datetime + +flag_p_c = False +flag_p_uf = False +flag_debug = False + + +def dprint(*args, **kwargs): + if flag_debug: + print("[DEBUG] ", end="") + print(*args, **kwargs) + + +def get_origin_path(file_path): + paths = file_path.split("/") + tidx = paths.index("translations") + opaths = paths[:tidx] + opaths += paths[tidx + 2 :] + return "/".join(opaths) + + +def get_latest_commit_from(file_path, commit): + command = "git log --pretty=format:%H%n%aD%n%cD%n%n%B {} -1 -- {}".format( + commit, file_path + ) + dprint(command) + pipe = os.popen(command) + result = pipe.read() + result = result.split("\n") + if len(result) <= 1: + return None + + dprint("Result: {}".format(result[0])) + + return { + "hash": result[0], + "author_date": datetime.strptime(result[1], "%a, %d %b %Y %H:%M:%S %z"), + "commit_date": datetime.strptime(result[2], "%a, %d %b %Y %H:%M:%S %z"), + "message": result[4:], + } + + +def get_origin_from_trans(origin_path, t_from_head): + o_from_t = get_latest_commit_from(origin_path, t_from_head["hash"]) + while o_from_t is not None and o_from_t["author_date"] > t_from_head["author_date"]: + o_from_t = get_latest_commit_from(origin_path, o_from_t["hash"] + "^") + if o_from_t is not None: + dprint("tracked origin commit id: {}".format(o_from_t["hash"])) + return o_from_t + + +def get_commits_count_between(opath, commit1, commit2): + command = "git log --pretty=format:%H {}...{} -- {}".format(commit1, commit2, opath) + dprint(command) + pipe = os.popen(command) + result = pipe.read().split("\n") + # filter out empty lines + result = list(filter(lambda x: x != "", result)) + return result + + +def pretty_output(commit): + command = "git log --pretty='format:%h (\"%s\")' -1 {}".format(commit) + dprint(command) + pipe = os.popen(command) + return pipe.read() + + +def check_per_file(file_path): + opath = get_origin_path(file_path) + + if not os.path.isfile(opath): + dprint("Error: Cannot find the origin path for {}".format(file_path)) + return + + o_from_head = get_latest_commit_from(opath, "HEAD") + t_from_head = get_latest_commit_from(file_path, "HEAD") + + if o_from_head is None or t_from_head is None: + print("Error: Cannot find the latest commit for {}".format(file_path)) + return + + o_from_t = get_origin_from_trans(opath, t_from_head) + + if o_from_t is None: + print("Error: Cannot find the latest origin commit for {}".format(file_path)) + return + + if o_from_head["hash"] == o_from_t["hash"]: + if flag_p_uf: + print("No update needed for {}".format(file_path)) + return + else: + print("{}".format(file_path), end="\t") + commits = get_commits_count_between( + opath, o_from_t["hash"], o_from_head["hash"] + ) + print("({} commits)".format(len(commits))) + if flag_p_c: + for commit in commits: + msg = pretty_output(commit) + if "Merge tag" not in msg: + print("commit", msg) + + +def main(): + script_path = os.path.dirname(os.path.abspath(__file__)) + linux_path = os.path.join(script_path, "..") + + parser = ArgumentParser(description="Check the translation update") + parser.add_argument( + "-l", + "--locale", + help="Locale to check when files are not specified", + ) + parser.add_argument( + "--print-commits", + action=BooleanOptionalAction, + default=True, + help="Print commits between the origin and the translation", + ) + + parser.add_argument( + "--print-updated-files", + action=BooleanOptionalAction, + default=False, + help="Print files that do no need to be updated", + ) + + parser.add_argument( + "--debug", + action=BooleanOptionalAction, + help="Print debug information", + default=False, + ) + + parser.add_argument( + "files", nargs="*", help="Files to check, if not specified, check all files" + ) + args = parser.parse_args() + + global flag_p_c, flag_p_uf, flag_debug + flag_p_c = args.print_commits + flag_p_uf = args.print_updated_files + flag_debug = args.debug + + # get files related to linux path + files = args.files + if len(files) == 0: + if args.locale is not None: + files = ( + os.popen( + "find {}/Documentation/translations/{} -type f".format( + linux_path, args.locale + ) + ) + .read() + .split("\n") + ) + else: + files = ( + os.popen( + "find {}/Documentation/translations -type f".format(linux_path) + ) + .read() + .split("\n") + ) + + files = list(filter(lambda x: x != "", files)) + files = list(map(lambda x: os.path.relpath(os.path.abspath(x), linux_path), files)) + + # cd to linux root directory + os.chdir(linux_path) + + for file in files: + check_per_file(file) + + +if __name__ == "__main__": + main() diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch index 52e5bfb61fd0..014b3bfe3237 100644 --- a/scripts/const_structs.checkpatch +++ b/scripts/const_structs.checkpatch @@ -64,7 +64,17 @@ platform_suspend_ops proc_ops proto_ops pwm_ops +reg_default +reg_field +reg_sequence regmap_access_table +regmap_bus +regmap_config +regmap_irq +regmap_irq_chip +regmap_irq_sub_irq_map +regmap_range +regmap_range_cfg regulator_ops reset_control_ops rpc_pipe_ops @@ -79,6 +89,7 @@ snd_rawmidi_ops snd_soc_component_driver snd_soc_dai_ops snd_soc_ops +snd_soc_tplg_ops soc_pcmcia_socket_ops stacktrace_ops sysfs_ops diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index fa5be6f57b00..a0f50a5b4f7c 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -30,6 +30,7 @@ fi READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX} ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX} +NM=${UTIL_PREFIX}nm${UTIL_SUFFIX} if [[ $1 == "-r" ]] ; then vmlinux="" @@ -158,7 +159,7 @@ parse_symbol() { if [[ $aarray_support == true && "${cache[$module,$name]+isset}" == "isset" ]]; then local base_addr=${cache[$module,$name]} else - local base_addr=$(nm "$objfile" 2>/dev/null | awk '$3 == "'$name'" && ($2 == "t" || $2 == "T") {print $1; exit}') + local base_addr=$(${NM} "$objfile" 2>/dev/null | awk '$3 == "'$name'" && ($2 == "t" || $2 == "T") {print $1; exit}') if [[ $base_addr == "" ]] ; then # address not found return @@ -282,6 +283,9 @@ handle_line() { if [[ ${words[$last]} =~ \[([^]]+)\] ]]; then module=${words[$last]} + # some traces format is "(%pS)", which like "(foo+0x0/0x1 [bar])" + # so $module may like "[bar])". Strip the right parenthesis firstly + module=${module%\)} module=${module#\[} module=${module%\]} modbuildid=${module#* } diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 9f31d2607182..10fb63894369 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -31,7 +31,7 @@ typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node struct check { const char *name; check_fn fn; - void *data; + const void *data; bool warn, error; enum checkstatus status; bool inprogress; @@ -114,6 +114,7 @@ static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, } fputs(str, stderr); + free(str); } #define FAIL(c, dti, node, ...) \ @@ -207,7 +208,7 @@ static void check_is_string(struct check *c, struct dt_info *dti, struct node *node) { struct property *prop; - char *propname = c->data; + const char *propname = c->data; prop = get_property(node, propname); if (!prop) @@ -226,7 +227,7 @@ static void check_is_string_list(struct check *c, struct dt_info *dti, { int rem, l; struct property *prop; - char *propname = c->data; + const char *propname = c->data; char *str; prop = get_property(node, propname); @@ -254,7 +255,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti, struct node *node) { struct property *prop; - char *propname = c->data; + const char *propname = c->data; prop = get_property(node, propname); if (!prop) @@ -1078,10 +1079,11 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node /* Ignore I2C_OWN_SLAVE_ADDRESS */ reg &= ~I2C_OWN_SLAVE_ADDRESS; - if ((reg & I2C_TEN_BIT_ADDRESS) && ((reg & ~I2C_TEN_BIT_ADDRESS) > 0x3ff)) - FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"", + if (reg & I2C_TEN_BIT_ADDRESS) { + if ((reg & ~I2C_TEN_BIT_ADDRESS) > 0x3ff) + FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"", reg); - else if (reg > 0x7f) + } else if (reg > 0x7f) FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\". Set I2C_TEN_BIT_ADDRESS for 10 bit addresses or fix the property", reg); } @@ -1108,7 +1110,7 @@ static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct no for_each_child(node, child) { struct property *prop; for_each_property(child, prop) { - if (strprefixeq(prop->name, 4, "spi-")) { + if (strstarts(prop->name, "spi-")) { node->bus = &spi_bus; break; } @@ -1180,7 +1182,7 @@ static void check_unit_address_format(struct check *c, struct dt_info *dti, /* skip over 0x for next test */ unitname += 2; } - if (unitname[0] == '0' && isxdigit(unitname[1])) + if (unitname[0] == '0' && isxdigit((unsigned char)unitname[1])) FAIL(c, dti, node, "unit name should not have leading 0s"); } WARNING(unit_address_format, check_unit_address_format, NULL, @@ -1222,7 +1224,7 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) return; - if (get_property(node, "ranges") || !node->children) + if (get_property(node, "ranges") || get_property(node, "dma-ranges") || !node->children) return; for_each_child(node, child) { @@ -1232,7 +1234,7 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d } if (!has_reg) - FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); + FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" property"); } WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); @@ -1465,7 +1467,7 @@ static void check_provider_cells_property(struct check *c, struct dt_info *dti, struct node *node) { - struct provider *provider = c->data; + const struct provider *provider = c->data; struct property *prop; prop = get_property(node, provider->prop_name); @@ -1673,6 +1675,10 @@ static void check_interrupt_map(struct check *c, parent_cellsize += propval_cell(cellprop); cell += 1 + parent_cellsize; + if (cell > map_cells) + FAIL_PROP(c, dti, node, irq_map_prop, + "property size (%d) mismatch, expected %zu", + irq_map_prop->val.len, cell * sizeof(cell_t)); } } WARNING(interrupt_map, check_interrupt_map, NULL, &phandle_references, &addr_size_cells, &interrupt_provider); @@ -1765,6 +1771,11 @@ static void check_graph_nodes(struct check *c, struct dt_info *dti, get_property(child, "remote-endpoint"))) continue; + /* The root node cannot be a port */ + if (!node->parent) { + FAIL(c, dti, node, "root node contains endpoint node '%s', potentially misplaced remote-endpoint property", child->name); + continue; + } node->bus = &graph_port_bus; /* The parent of 'port' nodes can be either 'ports' or a device */ @@ -1778,31 +1789,6 @@ static void check_graph_nodes(struct check *c, struct dt_info *dti, } WARNING(graph_nodes, check_graph_nodes, NULL); -static void check_graph_child_address(struct check *c, struct dt_info *dti, - struct node *node) -{ - int cnt = 0; - struct node *child; - - if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus) - return; - - for_each_child(node, child) { - struct property *prop = get_property(child, "reg"); - - /* No error if we have any non-zero unit address */ - if (prop && propval_cell(prop) != 0) - return; - - cnt++; - } - - if (cnt == 1 && node->addr_cells != -1) - FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary", - node->children->name); -} -WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes); - static void check_graph_reg(struct check *c, struct dt_info *dti, struct node *node) { @@ -1893,6 +1879,31 @@ static void check_graph_endpoint(struct check *c, struct dt_info *dti, } WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes); +static void check_graph_child_address(struct check *c, struct dt_info *dti, + struct node *node) +{ + int cnt = 0; + struct node *child; + + if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus) + return; + + for_each_child(node, child) { + struct property *prop = get_property(child, "reg"); + + /* No error if we have any non-zero unit address */ + if (prop && propval_cell(prop) != 0 ) + return; + + cnt++; + } + + if (cnt == 1 && node->addr_cells != -1) + FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary", + node->children->name); +} +WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes, &graph_port, &graph_endpoint); + static struct check *check_table[] = { &duplicate_node_names, &duplicate_property_names, &node_name_chars, &node_name_format, &property_name_chars, diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index bff1337ec266..4d5eece52624 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -284,14 +284,17 @@ propdef: DT_PROPNODENAME '=' propdata ';' { $$ = build_property($1, $3, &@$); + free($1); } | DT_PROPNODENAME ';' { $$ = build_property($1, empty_data, &@$); + free($1); } | DT_DEL_PROP DT_PROPNODENAME ';' { $$ = build_property_delete($2); + free($2); } | DT_LABEL propdef { @@ -570,10 +573,12 @@ subnode: DT_PROPNODENAME nodedef { $$ = name_node($2, $1); + free($1); } | DT_DEL_NODE DT_PROPNODENAME ';' { $$ = name_node(build_node_delete(&@$), $2); + free($2); } | DT_OMIT_NO_REF subnode { diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index bc786c543b7e..0655c2e2c362 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c @@ -47,7 +47,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) /* Usage related data. */ 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:@AThv"; +static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@LAThv"; static struct option const usage_long_opts[] = { {"quiet", no_argument, NULL, 'q'}, {"in-format", a_argument, NULL, 'I'}, @@ -67,6 +67,7 @@ static struct option const usage_long_opts[] = { {"warning", a_argument, NULL, 'W'}, {"error", a_argument, NULL, 'E'}, {"symbols", no_argument, NULL, '@'}, + {"local-fixups", no_argument, NULL, 'L'}, {"auto-alias", no_argument, NULL, 'A'}, {"annotate", no_argument, NULL, 'T'}, {"help", no_argument, NULL, 'h'}, @@ -104,6 +105,7 @@ static const char * const usage_opts_help[] = { "\n\tEnable/disable warnings (prefix with \"no-\")", "\n\tEnable/disable errors (prefix with \"no-\")", "\n\tEnable generation of symbols", + "\n\tPossibly generates a __local_fixups__ and a __fixups__ node at the root node", "\n\tEnable auto-alias of labels", "\n\tAnnotate output .dts with input source file and line (-T -T for more details)", "\n\tPrint this help and exit", @@ -252,6 +254,11 @@ int main(int argc, char *argv[]) case '@': generate_symbols = 1; break; + + case 'L': + generate_fixups = 1; + break; + case 'A': auto_label_aliases = 1; break; diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 0a1f54991026..4c4aaca1fc41 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -260,16 +260,16 @@ struct node { void add_label(struct label **labels, char *label); void delete_labels(struct label **labels); -struct property *build_property(char *name, struct data val, +struct property *build_property(const char *name, struct data val, struct srcpos *srcpos); -struct property *build_property_delete(char *name); +struct property *build_property_delete(const char *name); struct property *chain_property(struct property *first, struct property *list); struct property *reverse_properties(struct property *first); struct node *build_node(struct property *proplist, struct node *children, struct srcpos *srcpos); struct node *build_node_delete(struct srcpos *srcpos); -struct node *name_node(struct node *node, char *name); +struct node *name_node(struct node *node, const char *name); struct node *omit_node_if_unused(struct node *node); struct node *reference_node(struct node *node); struct node *chain_node(struct node *first, struct node *list); @@ -336,9 +336,9 @@ struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys); void sort_tree(struct dt_info *dti); -void generate_label_tree(struct dt_info *dti, char *name, bool allocph); -void generate_fixups_tree(struct dt_info *dti, char *name); -void generate_local_fixups_tree(struct dt_info *dti, char *name); +void generate_label_tree(struct dt_info *dti, const char *name, bool allocph); +void generate_fixups_tree(struct dt_info *dti, const char *name); +void generate_local_fixups_tree(struct dt_info *dti, const char *name); /* Checks */ diff --git a/scripts/dtc/fdtoverlay.c b/scripts/dtc/fdtoverlay.c index 5350af65679f..4eba0460f240 100644 --- a/scripts/dtc/fdtoverlay.c +++ b/scripts/dtc/fdtoverlay.c @@ -23,9 +23,7 @@ /* Usage related data. */ static const char usage_synopsis[] = "apply a number of overlays to a base blob\n" - " fdtoverlay <options> [<overlay.dtbo> [<overlay.dtbo>]]\n" - "\n" - USAGE_TYPE_MSG; + " fdtoverlay <options> [<overlay.dtbo> [<overlay.dtbo>]]"; static const char usage_short_opts[] = "i:o:v" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] = { {"input", required_argument, NULL, 'i'}, @@ -50,7 +48,7 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len, int ret; /* - * We take a copies first, because a a failed apply can trash + * We take a copies first, because a failed apply can trash * both the base blob and the overlay */ tmpo = xmalloc(fdt_totalsize(overlay)); diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index 95e43d32c3e6..1bcd8089c5b9 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -604,11 +604,11 @@ static void flat_realign(struct inbuf *inb, int align) die("Premature end of data parsing flat device tree\n"); } -static char *flat_read_string(struct inbuf *inb) +static const char *flat_read_string(struct inbuf *inb) { int len = 0; const char *p = inb->ptr; - char *str; + const char *str; do { if (p >= inb->limit) @@ -616,7 +616,7 @@ static char *flat_read_string(struct inbuf *inb) len++; } while ((*p++) != '\0'); - str = xstrdup(inb->ptr); + str = inb->ptr; inb->ptr += len; @@ -711,7 +711,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) } -static char *nodename_from_path(const char *ppath, const char *cpath) +static const char *nodename_from_path(const char *ppath, const char *cpath) { int plen; @@ -725,7 +725,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath) if (!streq(ppath, "/")) plen++; - return xstrdup(cpath + plen); + return cpath + plen; } static struct node *unflatten_tree(struct inbuf *dtbuf, @@ -733,7 +733,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, const char *parent_flatname, int flags) { struct node *node; - char *flatname; + const char *flatname; uint32_t val; node = build_node(NULL, NULL, NULL); @@ -741,9 +741,10 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, flatname = flat_read_string(dtbuf); if (flags & FTF_FULLPATH) - node->name = nodename_from_path(parent_flatname, flatname); + node->name = xstrdup(nodename_from_path(parent_flatname, + flatname)); else - node->name = flatname; + node->name = xstrdup(flatname); do { struct property *prop; @@ -785,10 +786,6 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, } } while (val != FDT_END_NODE); - if (node->name != flatname) { - free(flatname); - } - return node; } diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c index 5e59594ab301..0f9a534bacdb 100644 --- a/scripts/dtc/fstree.c +++ b/scripts/dtc/fstree.c @@ -43,7 +43,7 @@ static struct node *read_fstree(const char *dirname) "WARNING: Cannot open %s: %s\n", tmpname, strerror(errno)); } else { - prop = build_property(xstrdup(de->d_name), + prop = build_property(de->d_name, data_copy_file(pfile, st.st_size), NULL); diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c index 5c0c3981b89d..28b667ffc490 100644 --- a/scripts/dtc/libfdt/fdt_overlay.c +++ b/scripts/dtc/libfdt/fdt_overlay.c @@ -101,26 +101,22 @@ int fdt_overlay_target_offset(const void *fdt, const void *fdto, static int overlay_phandle_add_offset(void *fdt, int node, const char *name, uint32_t delta) { - const fdt32_t *val; - uint32_t adj_val; + fdt32_t *valp, val; int len; - val = fdt_getprop(fdt, node, name, &len); - if (!val) + valp = fdt_getprop_w(fdt, node, name, &len); + if (!valp) return len; - if (len != sizeof(*val)) + if (len != sizeof(val)) return -FDT_ERR_BADPHANDLE; - adj_val = fdt32_to_cpu(*val); - if ((adj_val + delta) < adj_val) - return -FDT_ERR_NOPHANDLES; - - adj_val += delta; - if (adj_val == (uint32_t)-1) + val = fdt32_ld(valp); + if (val + delta < val || val + delta == (uint32_t)-1) return -FDT_ERR_NOPHANDLES; - return fdt_setprop_inplace_u32(fdt, node, name, adj_val); + fdt32_st(valp, val + delta); + return 0; } /** @@ -213,8 +209,8 @@ static int overlay_update_local_node_references(void *fdto, fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { const fdt32_t *fixup_val; - const char *tree_val; const char *name; + char *tree_val; int fixup_len; int tree_len; int i; @@ -228,7 +224,7 @@ static int overlay_update_local_node_references(void *fdto, return -FDT_ERR_BADOVERLAY; fixup_len /= sizeof(uint32_t); - tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); + tree_val = fdt_getprop_w(fdto, tree_node, name, &tree_len); if (!tree_val) { if (tree_len == -FDT_ERR_NOTFOUND) return -FDT_ERR_BADOVERLAY; @@ -237,33 +233,15 @@ static int overlay_update_local_node_references(void *fdto, } for (i = 0; i < fixup_len; i++) { - fdt32_t adj_val; - uint32_t poffset; + fdt32_t *refp; - poffset = fdt32_to_cpu(fixup_val[i]); + refp = (fdt32_t *)(tree_val + fdt32_ld_(fixup_val + i)); /* - * phandles to fixup can be unaligned. - * - * Use a memcpy for the architectures that do - * not support unaligned accesses. + * phandles to fixup can be unaligned, so use + * fdt32_{ld,st}() to read/write them. */ - memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); - - adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); - - ret = fdt_setprop_inplace_namelen_partial(fdto, - tree_node, - name, - strlen(name), - poffset, - &adj_val, - sizeof(adj_val)); - if (ret == -FDT_ERR_NOSPACE) - return -FDT_ERR_BADOVERLAY; - - if (ret) - return ret; + fdt32_st(refp, fdt32_ld(refp) + delta); } } @@ -337,7 +315,7 @@ static int overlay_update_local_references(void *fdto, uint32_t delta) * @name: Name of the property holding the phandle reference in the overlay * @name_len: number of name characters to consider * @poffset: Offset within the overlay property where the phandle is stored - * @label: Label of the node referenced by the phandle + * @phandle: Phandle referencing the node * * overlay_fixup_one_phandle() resolves an overlay phandle pointing to * a node in the base device tree. @@ -354,30 +332,14 @@ static int overlay_fixup_one_phandle(void *fdt, void *fdto, int symbols_off, const char *path, uint32_t path_len, const char *name, uint32_t name_len, - int poffset, const char *label) + int poffset, uint32_t phandle) { - const char *symbol_path; - uint32_t phandle; fdt32_t phandle_prop; - int symbol_off, fixup_off; - int prop_len; + int fixup_off; if (symbols_off < 0) return symbols_off; - symbol_path = fdt_getprop(fdt, symbols_off, label, - &prop_len); - if (!symbol_path) - return prop_len; - - symbol_off = fdt_path_offset(fdt, symbol_path); - if (symbol_off < 0) - return symbol_off; - - phandle = fdt_get_phandle(fdt, symbol_off); - if (!phandle) - return -FDT_ERR_NOTFOUND; - fixup_off = fdt_path_offset_namelen(fdto, path, path_len); if (fixup_off == -FDT_ERR_NOTFOUND) return -FDT_ERR_BADOVERLAY; @@ -416,6 +378,10 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, const char *value; const char *label; int len; + const char *symbol_path; + int prop_len; + int symbol_off; + uint32_t phandle; value = fdt_getprop_by_offset(fdto, property, &label, &len); @@ -426,6 +392,18 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, return len; } + symbol_path = fdt_getprop(fdt, symbols_off, label, &prop_len); + if (!symbol_path) + return prop_len; + + symbol_off = fdt_path_offset(fdt, symbol_path); + if (symbol_off < 0) + return symbol_off; + + phandle = fdt_get_phandle(fdt, symbol_off); + if (!phandle) + return -FDT_ERR_NOTFOUND; + do { const char *path, *name, *fixup_end; const char *fixup_str = value; @@ -467,7 +445,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, path, path_len, name, name_len, - poffset, label); + poffset, phandle); if (ret) return ret; } while (len > 0); @@ -521,6 +499,255 @@ static int overlay_fixup_phandles(void *fdt, void *fdto) } /** + * overlay_adjust_local_conflicting_phandle: Changes a phandle value + * @fdto: Device tree overlay + * @node: The node the phandle is set for + * @fdt_phandle: The new value for the phandle + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_adjust_local_conflicting_phandle(void *fdto, int node, + uint32_t fdt_phandle) +{ + const fdt32_t *php; + int len, ret; + + php = fdt_getprop(fdto, node, "phandle", &len); + if (php && len == sizeof(*php)) { + ret = fdt_setprop_inplace_u32(fdto, node, "phandle", fdt_phandle); + if (ret) + return ret; + } + + php = fdt_getprop(fdto, node, "linux,phandle", &len); + if (php && len == sizeof(*php)) { + ret = fdt_setprop_inplace_u32(fdto, node, "linux,phandle", fdt_phandle); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_update_node_conflicting_references - Recursively replace phandle values + * @fdto: Device tree overlay blob + * @tree_node: Node to recurse into + * @fixup_node: Node offset of the matching local fixups node + * @fdt_phandle: Value to replace phandles with + * @fdto_phandle: Value to be replaced + * + * Replaces all phandles with value @fdto_phandle by @fdt_phandle. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_update_node_conflicting_references(void *fdto, int tree_node, + int fixup_node, + uint32_t fdt_phandle, + uint32_t fdto_phandle) +{ + int fixup_prop; + int fixup_child; + int ret; + + fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { + const fdt32_t *fixup_val; + const char *name; + char *tree_val; + int fixup_len; + int tree_len; + int i; + + fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, + &name, &fixup_len); + if (!fixup_val) + return fixup_len; + + if (fixup_len % sizeof(uint32_t)) + return -FDT_ERR_BADOVERLAY; + fixup_len /= sizeof(uint32_t); + + tree_val = fdt_getprop_w(fdto, tree_node, name, &tree_len); + if (!tree_val) { + if (tree_len == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + + return tree_len; + } + + for (i = 0; i < fixup_len; i++) { + fdt32_t *refp; + uint32_t valp; + + refp = (fdt32_t *)(tree_val + fdt32_ld_(fixup_val + i)); + valp = fdt32_ld(refp); + + if (valp == fdto_phandle) + fdt32_st(refp, fdt_phandle); + } + } + + fdt_for_each_subnode(fixup_child, fdto, fixup_node) { + const char *fixup_child_name = fdt_get_name(fdto, fixup_child, NULL); + int tree_child; + + tree_child = fdt_subnode_offset(fdto, tree_node, fixup_child_name); + + if (tree_child == -FDT_ERR_NOTFOUND) + return -FDT_ERR_BADOVERLAY; + if (tree_child < 0) + return tree_child; + + ret = overlay_update_node_conflicting_references(fdto, tree_child, + fixup_child, + fdt_phandle, + fdto_phandle); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_update_local_conflicting_references - Recursively replace phandle values + * @fdto: Device tree overlay blob + * @fdt_phandle: Value to replace phandles with + * @fdto_phandle: Value to be replaced + * + * Replaces all phandles with value @fdto_phandle by @fdt_phandle. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_update_local_conflicting_references(void *fdto, + uint32_t fdt_phandle, + uint32_t fdto_phandle) +{ + int fixups; + + fixups = fdt_path_offset(fdto, "/__local_fixups__"); + if (fixups == -FDT_ERR_NOTFOUND) + return 0; + if (fixups < 0) + return fixups; + + return overlay_update_node_conflicting_references(fdto, 0, fixups, + fdt_phandle, + fdto_phandle); +} + +/** + * overlay_prevent_phandle_overwrite_node - Helper function for overlay_prevent_phandle_overwrite + * @fdt: Base Device tree blob + * @fdtnode: Node in fdt that is checked for an overwrite + * @fdto: Device tree overlay blob + * @fdtonode: Node in fdto matching @fdtnode + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_prevent_phandle_overwrite_node(void *fdt, int fdtnode, + void *fdto, int fdtonode) +{ + uint32_t fdt_phandle, fdto_phandle; + int fdtochild; + + fdt_phandle = fdt_get_phandle(fdt, fdtnode); + fdto_phandle = fdt_get_phandle(fdto, fdtonode); + + if (fdt_phandle && fdto_phandle) { + int ret; + + ret = overlay_adjust_local_conflicting_phandle(fdto, fdtonode, + fdt_phandle); + if (ret) + return ret; + + ret = overlay_update_local_conflicting_references(fdto, + fdt_phandle, + fdto_phandle); + if (ret) + return ret; + } + + fdt_for_each_subnode(fdtochild, fdto, fdtonode) { + const char *name = fdt_get_name(fdto, fdtochild, NULL); + int fdtchild; + int ret; + + fdtchild = fdt_subnode_offset(fdt, fdtnode, name); + if (fdtchild == -FDT_ERR_NOTFOUND) + /* + * no further overwrites possible here as this node is + * new + */ + continue; + + ret = overlay_prevent_phandle_overwrite_node(fdt, fdtchild, + fdto, fdtochild); + if (ret) + return ret; + } + + return 0; +} + +/** + * overlay_prevent_phandle_overwrite - Fixes overlay phandles to not overwrite base phandles + * @fdt: Base Device Tree blob + * @fdto: Device tree overlay blob + * + * Checks recursively if applying fdto overwrites phandle values in the base + * dtb. When such a phandle is found, the fdto is changed to use the fdt's + * phandle value to not break references in the base. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int overlay_prevent_phandle_overwrite(void *fdt, void *fdto) +{ + int fragment; + + fdt_for_each_subnode(fragment, fdto, 0) { + int overlay; + int target; + int ret; + + overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); + if (overlay == -FDT_ERR_NOTFOUND) + continue; + + if (overlay < 0) + return overlay; + + target = fdt_overlay_target_offset(fdt, fdto, fragment, NULL); + if (target == -FDT_ERR_NOTFOUND) + /* + * The subtree doesn't exist in the base, so nothing + * will be overwritten. + */ + continue; + else if (target < 0) + return target; + + ret = overlay_prevent_phandle_overwrite_node(fdt, target, + fdto, overlay); + if (ret) + return ret; + } + + return 0; +} + +/** * overlay_apply_node - Merges a node into the base device tree * @fdt: Base Device Tree blob * @target: Node offset in the base device tree to apply the fragment to @@ -824,18 +1051,26 @@ int fdt_overlay_apply(void *fdt, void *fdto) if (ret) goto err; + /* Increase all phandles in the fdto by delta */ ret = overlay_adjust_local_phandles(fdto, delta); if (ret) goto err; + /* Adapt the phandle values in fdto to the above increase */ ret = overlay_update_local_references(fdto, delta); if (ret) goto err; + /* Update fdto's phandles using symbols from fdt */ ret = overlay_fixup_phandles(fdt, fdto); if (ret) goto err; + /* Don't overwrite phandles in fdt */ + ret = overlay_prevent_phandle_overwrite(fdt, fdto); + if (ret) + goto err; + ret = overlay_merge(fdt, fdto); if (ret) goto err; diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index 9f6c551a22c2..b78c4e48f1cb 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c @@ -255,6 +255,9 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) FDT_RO_PROBE(fdt); + if (!can_assume(VALID_INPUT) && namelen <= 0) + return -FDT_ERR_BADPATH; + /* see if we have an alias */ if (*path != '/') { const char *q = memchr(path, '/', end - p); @@ -522,16 +525,31 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) return fdt32_ld_(php); } +static const void *fdt_path_getprop_namelen(const void *fdt, const char *path, + const char *propname, int propnamelen, + int *lenp) +{ + int offset = fdt_path_offset(fdt, path); + + if (offset < 0) + return NULL; + + return fdt_getprop_namelen(fdt, offset, propname, propnamelen, lenp); +} + const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen) { - int aliasoffset; + int len; + const char *alias; - aliasoffset = fdt_path_offset(fdt, "/aliases"); - if (aliasoffset < 0) + alias = fdt_path_getprop_namelen(fdt, "/aliases", name, namelen, &len); + + if (!can_assume(VALID_DTB) && + !(alias && len > 0 && alias[len - 1] == '\0' && *alias == '/')) return NULL; - return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); + return alias; } const char *fdt_get_alias(const void *fdt, const char *name) @@ -539,6 +557,17 @@ const char *fdt_get_alias(const void *fdt, const char *name) return fdt_get_alias_namelen(fdt, name, strlen(name)); } +const char *fdt_get_symbol_namelen(const void *fdt, + const char *name, int namelen) +{ + return fdt_path_getprop_namelen(fdt, "/__symbols__", name, namelen, NULL); +} + +const char *fdt_get_symbol(const void *fdt, const char *name) +{ + return fdt_get_symbol_namelen(fdt, name, strlen(name)); +} + int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) { int pdepth = 0, p = 0; diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index 77ccff19911e..2d409d8e829b 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -524,10 +524,35 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); * level matching the given component, differentiated only by unit * address). * + * If the path is not absolute (i.e. does not begin with '/'), the + * first component is treated as an alias. That is, the property by + * that name is looked up in the /aliases node, and the value of that + * property used in place of that first component. + * + * For example, for this small fragment + * + * / { + * aliases { + * i2c2 = &foo; // RHS compiles to "/soc@0/i2c@30a40000/eeprom@52" + * }; + * soc@0 { + * foo: i2c@30a40000 { + * bar: eeprom@52 { + * }; + * }; + * }; + * }; + * + * these would be equivalent: + * + * /soc@0/i2c@30a40000/eeprom@52 + * i2c2/eeprom@52 + * * returns: * structure block offset of the node with the requested path (>=0), on * success - * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid + * -FDT_ERR_BADPATH, given path does not begin with '/' and the first + * component is not a valid alias * -FDT_ERR_NOTFOUND, if the requested node does not exist * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, @@ -870,6 +895,42 @@ const char *fdt_get_alias_namelen(const void *fdt, const char *fdt_get_alias(const void *fdt, const char *name); /** + * fdt_get_symbol_namelen - get symbol based on substring + * @fdt: pointer to the device tree blob + * @name: name of the symbol to look up + * @namelen: number of characters of name to consider + * + * Identical to fdt_get_symbol(), but only examine the first @namelen + * characters of @name for matching the symbol name. + * + * Return: a pointer to the expansion of the symbol named @name, if it exists, + * NULL otherwise + */ +#ifndef SWIG /* Not available in Python */ +const char *fdt_get_symbol_namelen(const void *fdt, + const char *name, int namelen); +#endif + +/** + * fdt_get_symbol - retrieve the path referenced by a given symbol + * @fdt: pointer to the device tree blob + * @name: name of the symbol to look up + * + * fdt_get_symbol() retrieves the value of a given symbol. That is, + * the value of the property named @name in the node + * /__symbols__. Such a node exists only for a device tree blob that + * has been compiled with the -@ dtc option. Each property corresponds + * to a label appearing in the device tree source, with the name of + * the property being the label and the value being the full path of + * the node it is attached to. + * + * returns: + * a pointer to the expansion of the symbol named 'name', if it exists + * NULL, if the given symbol or the /__symbols__ node does not exist + */ +const char *fdt_get_symbol(const void *fdt, const char *name); + +/** * fdt_get_path - determine the full path of a node * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose path to find @@ -1450,7 +1511,7 @@ int fdt_nop_node(void *fdt, int nodeoffset); * fdt_create_with_flags() begins the process of creating a new fdt with * the sequential write interface. * - * fdt creation process must end with fdt_finished() to produce a valid fdt. + * fdt creation process must end with fdt_finish() to produce a valid fdt. * * returns: * 0, on success @@ -1968,7 +2029,7 @@ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, * address and size) to the value of the named property in the given * node, or creates a new property with that value if it does not * already exist. - * If "name" is not specified, a default "reg" is used. + * * Cell sizes are determined by parent's #address-cells and #size-cells. * * This function may insert data into the blob, and will therefore diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index f46a098d5ada..49f723002f85 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -36,27 +36,27 @@ void delete_labels(struct label **labels) label->deleted = 1; } -struct property *build_property(char *name, struct data val, +struct property *build_property(const char *name, struct data val, struct srcpos *srcpos) { struct property *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); - new->name = name; + new->name = xstrdup(name); new->val = val; new->srcpos = srcpos_copy(srcpos); return new; } -struct property *build_property_delete(char *name) +struct property *build_property_delete(const char *name) { struct property *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); - new->name = name; + new->name = xstrdup(name); new->deleted = 1; return new; @@ -116,11 +116,11 @@ struct node *build_node_delete(struct srcpos *srcpos) return new; } -struct node *name_node(struct node *node, char *name) +struct node *name_node(struct node *node, const char *name) { assert(node->name == NULL); - node->name = name; + node->name = xstrdup(name); return node; } @@ -250,6 +250,7 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) name_node(new_node, "__overlay__"); node = build_node(p, new_node, NULL); name_node(node, name); + free(name); add_child(dt, node); return dt; @@ -440,7 +441,7 @@ cell_t propval_cell(struct property *prop) cell_t propval_cell_n(struct property *prop, unsigned int n) { - assert(prop->val.len / sizeof(cell_t) >= n); + assert(prop->val.len / sizeof(cell_t) > n); return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); } @@ -616,10 +617,25 @@ struct node *get_node_by_ref(struct node *tree, const char *ref) return target; } +static void add_phandle_property(struct node *node, + const char *name, int format) +{ + struct data d; + + if (!(phandle_format & format)) + return; + if (get_property(node, name)) + return; + + d = data_add_marker(empty_data, TYPE_UINT32, NULL); + d = data_append_cell(d, node->phandle); + + add_property(node, build_property(name, d, NULL)); +} + cell_t get_node_phandle(struct node *root, struct node *node) { static cell_t phandle = 1; /* FIXME: ick, static local */ - struct data d = empty_data; if (phandle_is_valid(node->phandle)) return node->phandle; @@ -629,16 +645,8 @@ cell_t get_node_phandle(struct node *root, struct node *node) node->phandle = phandle; - d = data_add_marker(d, TYPE_UINT32, NULL); - d = data_append_cell(d, phandle); - - if (!get_property(node, "linux,phandle") - && (phandle_format & PHANDLE_LEGACY)) - add_property(node, build_property("linux,phandle", d, NULL)); - - if (!get_property(node, "phandle") - && (phandle_format & PHANDLE_EPAPR)) - add_property(node, build_property("phandle", d, NULL)); + add_phandle_property(node, "linux,phandle", PHANDLE_LEGACY); + add_phandle_property(node, "phandle", PHANDLE_EPAPR); /* If the node *does* have a phandle property, we must * be dealing with a self-referencing phandle, which will be @@ -808,18 +816,18 @@ void sort_tree(struct dt_info *dti) } /* utility helper to avoid code duplication */ -static struct node *build_and_name_child_node(struct node *parent, char *name) +static struct node *build_and_name_child_node(struct node *parent, const char *name) { struct node *node; node = build_node(NULL, NULL, NULL); - name_node(node, xstrdup(name)); + name_node(node, name); add_child(parent, node); return node; } -static struct node *build_root_node(struct node *dt, char *name) +static struct node *build_root_node(struct node *dt, const char *name) { struct node *an; @@ -1040,7 +1048,7 @@ static void generate_local_fixups_tree_internal(struct dt_info *dti, generate_local_fixups_tree_internal(dti, lfn, c); } -void generate_label_tree(struct dt_info *dti, char *name, bool allocph) +void generate_label_tree(struct dt_info *dti, const char *name, bool allocph) { if (!any_label_tree(dti, dti->dt)) return; @@ -1048,7 +1056,7 @@ void generate_label_tree(struct dt_info *dti, char *name, bool allocph) dti->dt, allocph); } -void generate_fixups_tree(struct dt_info *dti, char *name) +void generate_fixups_tree(struct dt_info *dti, const char *name) { if (!any_fixup_tree(dti, dti->dt)) return; @@ -1056,7 +1064,7 @@ void generate_fixups_tree(struct dt_info *dti, char *name) dti->dt); } -void generate_local_fixups_tree(struct dt_info *dti, char *name) +void generate_local_fixups_tree(struct dt_info *dti, const char *name) { if (!any_local_fixup_tree(dti, dti->dt)) return; diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 4fdb22a019bd..8e4d18a90b47 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -3,7 +3,9 @@ * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include <stdio.h> @@ -311,8 +313,8 @@ srcpos_string(struct srcpos *pos) static char * srcpos_string_comment(struct srcpos *pos, bool first_line, int level) { - char *pos_str, *fname, *first, *rest; - bool fresh_fname = false; + char *pos_str, *fresh_fname = NULL, *first, *rest; + const char *fname; if (!pos) { if (level > 1) { @@ -330,9 +332,9 @@ srcpos_string_comment(struct srcpos *pos, bool first_line, int level) else if (level > 1) fname = pos->file->name; else { - fname = shorten_to_initial_path(pos->file->name); - if (fname) - fresh_fname = true; + fresh_fname = shorten_to_initial_path(pos->file->name); + if (fresh_fname) + fname = fresh_fname; else fname = pos->file->name; } @@ -346,7 +348,7 @@ srcpos_string_comment(struct srcpos *pos, bool first_line, int level) first_line ? pos->first_line : pos->last_line); if (fresh_fname) - free(fname); + free(fresh_fname); if (pos->next != NULL) { rest = srcpos_string_comment(pos->next, first_line, level); diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c index 33fedee82d58..ae15839ba6a5 100644 --- a/scripts/dtc/treesource.c +++ b/scripts/dtc/treesource.c @@ -139,6 +139,28 @@ static const char *delim_end[] = { [TYPE_STRING] = "", }; +static void add_string_markers(struct property *prop) +{ + int l, len = prop->val.len; + const char *p = prop->val.val; + + for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) { + struct marker *m, **nextp; + + m = xmalloc(sizeof(*m)); + m->offset = l; + m->type = TYPE_STRING; + m->ref = NULL; + m->next = NULL; + + /* Find the end of the markerlist */ + nextp = &prop->val.markers; + while (*nextp) + nextp = &((*nextp)->next); + *nextp = m; + } +} + static enum markertype guess_value_type(struct property *prop) { int len = prop->val.len; @@ -164,6 +186,8 @@ static enum markertype guess_value_type(struct property *prop) if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul)) && (nnotstringlbl == 0)) { + if (nnul > 1) + add_string_markers(prop); return TYPE_STRING; } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { return TYPE_UINT32; @@ -241,6 +265,8 @@ static void write_propval(FILE *f, struct property *prop) } else { write_propval_int(f, p, chunk_len, 4); } + if (data_len > chunk_len) + fputc(' ', f); break; case TYPE_UINT64: write_propval_int(f, p, chunk_len, 8); diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h index 9d38edee9736..b448cd79efd3 100644 --- a/scripts/dtc/util.h +++ b/scripts/dtc/util.h @@ -13,7 +13,9 @@ */ #ifdef __GNUC__ -#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +#ifdef __MINGW_PRINTF_FORMAT +#define PRINTF(i, j) __attribute__((format (__MINGW_PRINTF_FORMAT, i, j))) +#elif __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) #define PRINTF(i, j) __attribute__((format (gnu_printf, i, j))) #else #define PRINTF(i, j) __attribute__((format (printf, i, j))) @@ -65,7 +67,7 @@ extern char *xstrndup(const char *s, size_t len); extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); extern int PRINTF(2, 3) xasprintf_append(char **strp, const char *fmt, ...); -extern int xavsprintf_append(char **strp, const char *fmt, va_list ap); +extern int PRINTF(2, 0) xavsprintf_append(char **strp, const char *fmt, va_list ap); extern char *join_path(const char *path, const char *name); /** diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 99614ec1a289..4c5e17639d2b 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.6.1-gabbd523b" +#define DTC_VERSION "DTC 1.7.0-g1df7b047" diff --git a/scripts/faddr2line b/scripts/faddr2line index 587415a52b6f..fe0cc45f03be 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -85,15 +85,17 @@ command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed" # init/main.c! This only works for vmlinux. Otherwise it falls back to # printing the absolute path. find_dir_prefix() { - local objfile=$1 - - local start_kernel_addr=$(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | + local start_kernel_addr=$(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') [[ -z $start_kernel_addr ]] && return - local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr) - [[ -z $file_line ]] && return + run_addr2line ${start_kernel_addr} "" + [[ -z $ADDR2LINE_OUT ]] && return + local file_line=${ADDR2LINE_OUT#* at } + if [[ -z $file_line ]] || [[ $file_line = $ADDR2LINE_OUT ]]; then + return + fi local prefix=${file_line%init/main.c:*} if [[ -z $prefix ]] || [[ $prefix = $file_line ]]; then return @@ -103,6 +105,71 @@ find_dir_prefix() { return 0 } +run_readelf() { + local objfile=$1 + local out=$(${READELF} --file-header --section-headers --symbols --wide $objfile) + + # This assumes that readelf first prints the file header, then the section headers, then the symbols. + # Note: It seems that GNU readelf does not prefix section headers with the "There are X section headers" + # line when multiple options are given, so let's also match with the "Section Headers:" line. + ELF_FILEHEADER=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/q;p') + ELF_SECHEADERS=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset\|Section Headers:/,$p' | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') + ELF_SYMS=$(echo "${out}" | sed -n '/Symbol table .* contains [0-9]* entries:/,$p') +} + +check_vmlinux() { + # vmlinux uses absolute addresses in the section table rather than + # section offsets. + IS_VMLINUX=0 + local file_type=$(echo "${ELF_FILEHEADER}" | + ${AWK} '$1 == "Type:" { print $2; exit }') + if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then + IS_VMLINUX=1 + fi +} + +init_addr2line() { + local objfile=$1 + + check_vmlinux + + ADDR2LINE_ARGS="--functions --pretty-print --inlines --addresses --exe=$objfile" + if [[ $IS_VMLINUX = 1 ]]; then + # If the executable file is vmlinux, we don't pass section names to + # addr2line, so we can launch it now as a single long-running process. + coproc ADDR2LINE_PROC (${ADDR2LINE} ${ADDR2LINE_ARGS}) + fi +} + +run_addr2line() { + local addr=$1 + local sec_name=$2 + + if [[ $IS_VMLINUX = 1 ]]; then + # We send to the addr2line process: (1) the address, then (2) a sentinel + # value, i.e., something that can't be interpreted as a valid address + # (i.e., ","). This causes addr2line to write out: (1) the answer for + # our address, then (2) either "?? ??:0" or "0x0...0: ..." (if + # using binutils' addr2line), or "," (if using LLVM's addr2line). + echo ${addr} >& "${ADDR2LINE_PROC[1]}" + echo "," >& "${ADDR2LINE_PROC[1]}" + local first_line + read -r first_line <& "${ADDR2LINE_PROC[0]}" + ADDR2LINE_OUT=$(echo "${first_line}" | sed 's/^0x[0-9a-fA-F]*: //') + while read -r line <& "${ADDR2LINE_PROC[0]}"; do + if [[ "$line" == "?? ??:0" ]] || [[ "$line" == "," ]] || [[ $(echo "$line" | ${GREP} "^0x00*: ") ]]; then + break + fi + ADDR2LINE_OUT+=$'\n'$(echo "$line" | sed 's/^0x[0-9a-fA-F]*: //') + done + else + # Run addr2line as a single invocation. + local sec_arg + [[ -z $sec_name ]] && sec_arg="" || sec_arg="--section=${sec_name}" + ADDR2LINE_OUT=$(${ADDR2LINE} ${ADDR2LINE_ARGS} ${sec_arg} ${addr} | sed 's/^0x[0-9a-fA-F]*: //') + fi +} + __faddr2line() { local objfile=$1 local func_addr=$2 @@ -113,8 +180,6 @@ __faddr2line() { local func_offset=${func_addr#*+} func_offset=${func_offset%/*} local user_size= - local file_type - local is_vmlinux=0 [[ $func_addr =~ "/" ]] && user_size=${func_addr#*/} if [[ -z $sym_name ]] || [[ -z $func_offset ]] || [[ $sym_name = $func_addr ]]; then @@ -123,14 +188,6 @@ __faddr2line() { return fi - # vmlinux uses absolute addresses in the section table rather than - # section offsets. - local file_type=$(${READELF} --file-header $objfile | - ${AWK} '$1 == "Type:" { print $2; exit }') - if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then - is_vmlinux=1 - fi - # Go through each of the object's symbols which match the func name. # In rare cases there might be duplicates, in which case we print all # matches. @@ -143,8 +200,7 @@ __faddr2line() { local sec_name # Get the section size: - sec_size=$(${READELF} --section-headers --wide $objfile | - sed 's/\[ /\[/' | + sec_size=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') if [[ -z $sec_size ]]; then @@ -154,8 +210,7 @@ __faddr2line() { fi # Get the section name: - sec_name=$(${READELF} --section-headers --wide $objfile | - sed 's/\[ /\[/' | + sec_name=$(echo "${ELF_SECHEADERS}" | sed 's/\[ /\[/' | ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print $2; exit }') if [[ -z $sec_name ]]; then @@ -197,7 +252,7 @@ __faddr2line() { found=2 break fi - done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) + done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2 | ${GREP} -A1 --no-group-separator " ${sym_name}$") if [[ $found = 0 ]]; then warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size" @@ -249,9 +304,8 @@ __faddr2line() { # Pass section address to addr2line and strip absolute paths # from the output: - local args="--functions --pretty-print --inlines --exe=$objfile" - [[ $is_vmlinux = 0 ]] && args="$args --section=$sec_name" - local output=$(${ADDR2LINE} $args $addr | sed "s; $dir_prefix\(\./\)*; ;") + run_addr2line $addr $sec_name + local output=$(echo "${ADDR2LINE_OUT}" | sed "s; $dir_prefix\(\./\)*; ;") [[ -z $output ]] && continue # Default output (non --list): @@ -278,7 +332,7 @@ __faddr2line() { DONE=1 - done < <(${READELF} --symbols --wide $objfile | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$8 == fn') + done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v fn=$sym_name '$8 == fn') } [[ $# -lt 2 ]] && usage @@ -291,10 +345,14 @@ LIST=0 [[ ! -f $objfile ]] && die "can't find objfile $objfile" shift -${READELF} --section-headers --wide $objfile | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" +run_readelf $objfile + +echo "${ELF_SECHEADERS}" | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled" + +init_addr2line $objfile DIR_PREFIX=supercalifragilisticexpialidocious -find_dir_prefix $objfile +find_dir_prefix FIRST=1 while [[ $# -gt 0 ]]; do diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 1ae39b9f4a95..3222c1070444 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -62,11 +62,7 @@ #include "pass_manager.h" #include "predict.h" #include "ipa-utils.h" - -#if BUILDING_GCC_VERSION >= 8000 #include "stringpool.h" -#endif - #include "attribs.h" #include "varasm.h" #include "stor-layout.h" @@ -78,7 +74,6 @@ #include "context.h" #include "tree-ssa-alias.h" #include "tree-ssa.h" -#include "stringpool.h" #if BUILDING_GCC_VERSION >= 7000 #include "tree-vrp.h" #endif diff --git a/scripts/gdb/linux/mm.py b/scripts/gdb/linux/mm.py index 515730fd4c9d..7571aebbe650 100644 --- a/scripts/gdb/linux/mm.py +++ b/scripts/gdb/linux/mm.py @@ -33,7 +33,7 @@ class aarch64_page_ops(): def __init__(self): self.SUBSECTION_SHIFT = 21 self.SEBSECTION_SIZE = 1 << self.SUBSECTION_SHIFT - self.MODULES_VSIZE = 128 * 1024 * 1024 + self.MODULES_VSIZE = 2 * 1024 * 1024 * 1024 if constants.LX_CONFIG_ARM64_64K_PAGES: self.SECTION_SIZE_BITS = 29 @@ -47,8 +47,13 @@ class aarch64_page_ops(): self.VA_BITS = constants.LX_CONFIG_ARM64_VA_BITS if self.VA_BITS > 48: - self.VA_BITS_MIN = 48 - self.vabits_actual = gdb.parse_and_eval('vabits_actual') + if constants.LX_CONFIG_ARM64_16K_PAGES: + self.VA_BITS_MIN = 47 + else: + self.VA_BITS_MIN = 48 + tcr_el1 = gdb.execute("info registers $TCR_EL1", to_string=True) + tcr_el1 = int(tcr_el1.split()[1], 16) + self.vabits_actual = 64 - ((tcr_el1 >> 16) & 63) else: self.VA_BITS_MIN = self.VA_BITS self.vabits_actual = self.VA_BITS @@ -59,9 +64,9 @@ class aarch64_page_ops(): if str(constants.LX_CONFIG_ARCH_FORCE_MAX_ORDER).isdigit(): self.MAX_ORDER = constants.LX_CONFIG_ARCH_FORCE_MAX_ORDER else: - self.MAX_ORDER = 11 + self.MAX_ORDER = 10 - self.MAX_ORDER_NR_PAGES = 1 << (self.MAX_ORDER - 1) + self.MAX_ORDER_NR_PAGES = 1 << (self.MAX_ORDER) self.PFN_SECTION_SHIFT = self.SECTION_SIZE_BITS - self.PAGE_SHIFT self.NR_MEM_SECTIONS = 1 << self.SECTIONS_SHIFT self.PAGES_PER_SECTION = 1 << self.PFN_SECTION_SHIFT @@ -89,10 +94,10 @@ class aarch64_page_ops(): self.MODULES_VADDR = self._PAGE_END(self.VA_BITS_MIN) self.MODULES_END = self.MODULES_VADDR + self.MODULES_VSIZE - self.VMEMMAP_SHIFT = (self.PAGE_SHIFT - self.STRUCT_PAGE_MAX_SHIFT) - self.VMEMMAP_SIZE = ((self._PAGE_END(self.VA_BITS_MIN) - self.PAGE_OFFSET) >> self.VMEMMAP_SHIFT) - self.VMEMMAP_START = (-(1 << (self.VA_BITS - self.VMEMMAP_SHIFT))) & 0xffffffffffffffff - self.VMEMMAP_END = self.VMEMMAP_START + self.VMEMMAP_SIZE + self.VMEMMAP_RANGE = self._PAGE_END(self.VA_BITS_MIN) - self.PAGE_OFFSET + self.VMEMMAP_SIZE = (self.VMEMMAP_RANGE >> self.PAGE_SHIFT) * self.struct_page_size + self.VMEMMAP_END = (-(1 * 1024 * 1024 * 1024)) & 0xffffffffffffffff + self.VMEMMAP_START = self.VMEMMAP_END - self.VMEMMAP_SIZE self.VMALLOC_START = self.MODULES_END self.VMALLOC_END = self.VMEMMAP_START - 256 * 1024 * 1024 diff --git a/scripts/gdb/linux/stackdepot.py b/scripts/gdb/linux/stackdepot.py index 0281d9de4b7c..bb3a0f843931 100644 --- a/scripts/gdb/linux/stackdepot.py +++ b/scripts/gdb/linux/stackdepot.py @@ -27,14 +27,18 @@ def stack_depot_fetch(handle): offset = parts['offset'] << DEPOT_STACK_ALIGN pools_num = gdb.parse_and_eval('pools_num') - if parts['pool_index'] > pools_num: + if handle == 0: + raise gdb.GdbError("handle is 0\n") + + pool_index = parts['pool_index_plus_1'] - 1 + if pool_index >= pools_num: gdb.write("pool index %d out of bounds (%d) for stack id 0x%08x\n" % (parts['pool_index'], pools_num, handle)) return gdb.Value(0), 0 stack_pools = gdb.parse_and_eval('stack_pools') try: - pool = stack_pools[parts['pool_index']] + pool = stack_pools[pool_index] stack = (pool + gdb.Value(offset).cast(utils.get_size_t_type())).cast(stack_record_type.get_type().pointer()) size = int(stack['size'].cast(utils.get_ulong_type())) return stack['entries'], size diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt index 890f69005bab..fd5d00bac447 100644 --- a/scripts/head-object-list.txt +++ b/scripts/head-object-list.txt @@ -27,7 +27,6 @@ arch/mips/kernel/head.o arch/nios2/kernel/head.o arch/openrisc/kernel/head.o arch/parisc/kernel/head.o -arch/powerpc/kernel/head_40x.o arch/powerpc/kernel/head_44x.o arch/powerpc/kernel/head_64.o arch/powerpc/kernel/head_8xx.o diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 95a59ac78f82..2791f8195203 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1729,6 +1729,7 @@ sub dump_function($$) { $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; $prototype =~ s/__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//; $prototype =~ s/__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +//; + $prototype =~ s/DECL_BUCKET_PARAMS\s*\(\s*(\S+)\s*,\s*(\S+)\s*\)/$1, $2/; my $define = $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute_const__ +//; $prototype =~ s/__attribute__\s*\(\( diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh index a78b804b680c..b9513d224476 100755 --- a/scripts/ld-version.sh +++ b/scripts/ld-version.sh @@ -57,9 +57,11 @@ else fi fi -# Some distributions append a package release number, as in 2.34-4.fc32 -# Trim the hyphen and any characters that follow. -version=${version%-*} +# There may be something after the version, such as a distribution's package +# release number (like Fedora's "2.34-4.fc32") or punctuation (like LLD briefly +# added before the "compatible with GNU linkers" string), so remove everything +# after just numbers and periods. +version=${version%%[!0-9.]*} cversion=$(get_canonical_version $version) min_cversion=$(get_canonical_version $min_version) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b78d93919712..d16d0ace2775 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -770,17 +770,14 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_INIT_DATA_SECTIONS \ - ".init.setup", ".init.rodata", ".meminit.rodata", \ - ".init.data", ".meminit.data" + ".init.setup", ".init.rodata", ".init.data" #define ALL_PCI_INIT_SECTIONS \ ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ ".pci_fixup_enable", ".pci_fixup_resume", \ ".pci_fixup_resume_early", ".pci_fixup_suspend" -#define ALL_XXXINIT_SECTIONS ".meminit.*" - -#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS +#define ALL_INIT_SECTIONS ".init.*" #define ALL_EXIT_SECTIONS ".exit.*" #define DATA_SECTIONS ".data", ".data.rel" @@ -791,9 +788,7 @@ static void check_section(const char *modname, struct elf_info *elf, ".fixup", ".entry.text", ".exception.text", \ ".coldtext", ".softirqentry.text" -#define INIT_SECTIONS ".init.*" - -#define ALL_TEXT_SECTIONS ".init.text", ".meminit.text", ".exit.text", \ +#define ALL_TEXT_SECTIONS ".init.text", ".exit.text", \ TEXT_SECTIONS, OTHER_TEXT_SECTIONS enum mismatch { @@ -833,12 +828,6 @@ static const struct sectioncheck sectioncheck[] = { .bad_tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }, .mismatch = TEXTDATA_TO_ANY_INIT_EXIT, }, -/* Do not reference init code/data from meminit code/data */ -{ - .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, - .bad_tosec = { INIT_SECTIONS, NULL }, - .mismatch = XXXINIT_TO_SOME_INIT, -}, /* Do not use exit code/data from init code */ { .fromsec = { ALL_INIT_SECTIONS, NULL }, @@ -853,7 +842,7 @@ static const struct sectioncheck sectioncheck[] = { }, { .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, - .bad_tosec = { INIT_SECTIONS, NULL }, + .bad_tosec = { ALL_INIT_SECTIONS, NULL }, .mismatch = ANY_INIT_TO_ANY_EXIT, }, { diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec index 4b7df76076c4..74355ff0e106 100644 --- a/scripts/package/kernel.spec +++ b/scripts/package/kernel.spec @@ -83,7 +83,6 @@ ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEA done if [ -d "%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb" ];then - echo "/lib/modules/%{KERNELRELEASE}/dtb" find "%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb" -printf "%%%ghost /boot/dtb-%{KERNELRELEASE}/%%P\n" fi diff --git a/scripts/spelling.txt b/scripts/spelling.txt index edec60d39bbf..554329a074ce 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -176,8 +176,10 @@ assigment||assignment assigments||assignments assistent||assistant assocaited||associated +assocated||associated assocating||associating assocation||association +assocative||associative associcated||associated assotiated||associated asssert||assert @@ -543,6 +545,7 @@ direcly||directly direectly||directly diregard||disregard disassocation||disassociation +disassocative||disassociative disapear||disappear disapeared||disappeared disappared||disappeared diff --git a/scripts/syscall.tbl b/scripts/syscall.tbl new file mode 100644 index 000000000000..591d85e8ca7e --- /dev/null +++ b/scripts/syscall.tbl @@ -0,0 +1,405 @@ +# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note +# +# This file contains the system call numbers for all of the +# more recently added architectures. +# +# As a basic principle, no duplication of functionality +# should be added, e.g. we don't use lseek when llseek +# is present. New architectures should use this file +# and implement the less feature-full calls in user space. +# +0 common io_setup sys_io_setup compat_sys_io_setup +1 common io_destroy sys_io_destroy +2 common io_submit sys_io_submit compat_sys_io_submit +3 common io_cancel sys_io_cancel +4 time32 io_getevents sys_io_getevents_time32 +4 64 io_getevents sys_io_getevents +5 common setxattr sys_setxattr +6 common lsetxattr sys_lsetxattr +7 common fsetxattr sys_fsetxattr +8 common getxattr sys_getxattr +9 common lgetxattr sys_lgetxattr +10 common fgetxattr sys_fgetxattr +11 common listxattr sys_listxattr +12 common llistxattr sys_llistxattr +13 common flistxattr sys_flistxattr +14 common removexattr sys_removexattr +15 common lremovexattr sys_lremovexattr +16 common fremovexattr sys_fremovexattr +17 common getcwd sys_getcwd +18 common lookup_dcookie sys_ni_syscall +19 common eventfd2 sys_eventfd2 +20 common epoll_create1 sys_epoll_create1 +21 common epoll_ctl sys_epoll_ctl +22 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait +23 common dup sys_dup +24 common dup3 sys_dup3 +25 32 fcntl64 sys_fcntl64 compat_sys_fcntl64 +25 64 fcntl sys_fcntl +26 common inotify_init1 sys_inotify_init1 +27 common inotify_add_watch sys_inotify_add_watch +28 common inotify_rm_watch sys_inotify_rm_watch +29 common ioctl sys_ioctl compat_sys_ioctl +30 common ioprio_set sys_ioprio_set +31 common ioprio_get sys_ioprio_get +32 common flock sys_flock +33 common mknodat sys_mknodat +34 common mkdirat sys_mkdirat +35 common unlinkat sys_unlinkat +36 common symlinkat sys_symlinkat +37 common linkat sys_linkat +# renameat is superseded with flags by renameat2 +38 renameat renameat sys_renameat +39 common umount2 sys_umount +40 common mount sys_mount +41 common pivot_root sys_pivot_root +43 32 statfs64 sys_statfs64 compat_sys_statfs64 +43 64 statfs sys_statfs +44 32 fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 +44 64 fstatfs sys_fstatfs +45 32 truncate64 sys_truncate64 compat_sys_truncate64 +45 64 truncate sys_truncate +46 32 ftruncate64 sys_ftruncate64 compat_sys_ftruncate64 +46 64 ftruncate sys_ftruncate +47 common fallocate sys_fallocate compat_sys_fallocate +48 common faccessat sys_faccessat +49 common chdir sys_chdir +50 common fchdir sys_fchdir +51 common chroot sys_chroot +52 common fchmod sys_fchmod +53 common fchmodat sys_fchmodat +54 common fchownat sys_fchownat +55 common fchown sys_fchown +56 common openat sys_openat +57 common close sys_close +58 common vhangup sys_vhangup +59 common pipe2 sys_pipe2 +60 common quotactl sys_quotactl +61 common getdents64 sys_getdents64 +62 32 llseek sys_llseek +62 64 lseek sys_lseek +63 common read sys_read +64 common write sys_write +65 common readv sys_readv sys_readv +66 common writev sys_writev sys_writev +67 common pread64 sys_pread64 compat_sys_pread64 +68 common pwrite64 sys_pwrite64 compat_sys_pwrite64 +69 common preadv sys_preadv compat_sys_preadv +70 common pwritev sys_pwritev compat_sys_pwritev +71 32 sendfile64 sys_sendfile64 +71 64 sendfile sys_sendfile64 +72 time32 pselect6 sys_pselect6_time32 compat_sys_pselect6_time32 +72 64 pselect6 sys_pselect6 +73 time32 ppoll sys_ppoll_time32 compat_sys_ppoll_time32 +73 64 ppoll sys_ppoll +74 common signalfd4 sys_signalfd4 compat_sys_signalfd4 +75 common vmsplice sys_vmsplice +76 common splice sys_splice +77 common tee sys_tee +78 common readlinkat sys_readlinkat +79 stat64 fstatat64 sys_fstatat64 +79 newstat fstatat sys_newfstatat +80 stat64 fstat64 sys_fstat64 +80 newstat fstat sys_newfstat +81 common sync sys_sync +82 common fsync sys_fsync +83 common fdatasync sys_fdatasync +84 common sync_file_range sys_sync_file_range compat_sys_sync_file_range +85 common timerfd_create sys_timerfd_create +86 time32 timerfd_settime sys_timerfd_settime32 +86 64 timerfd_settime sys_timerfd_settime +87 time32 timerfd_gettime sys_timerfd_gettime32 +87 64 timerfd_gettime sys_timerfd_gettime +88 time32 utimensat sys_utimensat_time32 +88 64 utimensat sys_utimensat +89 common acct sys_acct +90 common capget sys_capget +91 common capset sys_capset +92 common personality sys_personality +93 common exit sys_exit +94 common exit_group sys_exit_group +95 common waitid sys_waitid compat_sys_waitid +96 common set_tid_address sys_set_tid_address +97 common unshare sys_unshare +98 time32 futex sys_futex_time32 +98 64 futex sys_futex +99 common set_robust_list sys_set_robust_list compat_sys_set_robust_list +100 common get_robust_list sys_get_robust_list compat_sys_get_robust_list +101 time32 nanosleep sys_nanosleep_time32 +101 64 nanosleep sys_nanosleep +102 common getitimer sys_getitimer compat_sys_getitimer +103 common setitimer sys_setitimer compat_sys_setitimer +104 common kexec_load sys_kexec_load compat_sys_kexec_load +105 common init_module sys_init_module +106 common delete_module sys_delete_module +107 common timer_create sys_timer_create compat_sys_timer_create +108 time32 timer_gettime sys_timer_gettime32 +108 64 timer_gettime sys_timer_gettime +109 common timer_getoverrun sys_timer_getoverrun +110 time32 timer_settime sys_timer_settime32 +110 64 timer_settime sys_timer_settime +111 common timer_delete sys_timer_delete +112 time32 clock_settime sys_clock_settime32 +112 64 clock_settime sys_clock_settime +113 time32 clock_gettime sys_clock_gettime32 +113 64 clock_gettime sys_clock_gettime +114 time32 clock_getres sys_clock_getres_time32 +114 64 clock_getres sys_clock_getres +115 time32 clock_nanosleep sys_clock_nanosleep_time32 +115 64 clock_nanosleep sys_clock_nanosleep +116 common syslog sys_syslog +117 common ptrace sys_ptrace compat_sys_ptrace +118 common sched_setparam sys_sched_setparam +119 common sched_setscheduler sys_sched_setscheduler +120 common sched_getscheduler sys_sched_getscheduler +121 common sched_getparam sys_sched_getparam +122 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity +123 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity +124 common sched_yield sys_sched_yield +125 common sched_get_priority_max sys_sched_get_priority_max +126 common sched_get_priority_min sys_sched_get_priority_min +127 time32 sched_rr_get_interval sys_sched_rr_get_interval_time32 +127 64 sched_rr_get_interval sys_sched_rr_get_interval +128 common restart_syscall sys_restart_syscall +129 common kill sys_kill +130 common tkill sys_tkill +131 common tgkill sys_tgkill +132 common sigaltstack sys_sigaltstack compat_sys_sigaltstack +133 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend +134 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction +135 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask +136 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending +137 time32 rt_sigtimedwait sys_rt_sigtimedwait_time32 compat_sys_rt_sigtimedwait_time32 +137 64 rt_sigtimedwait sys_rt_sigtimedwait +138 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo +139 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn +140 common setpriority sys_setpriority +141 common getpriority sys_getpriority +142 common reboot sys_reboot +143 common setregid sys_setregid +144 common setgid sys_setgid +145 common setreuid sys_setreuid +146 common setuid sys_setuid +147 common setresuid sys_setresuid +148 common getresuid sys_getresuid +149 common setresgid sys_setresgid +150 common getresgid sys_getresgid +151 common setfsuid sys_setfsuid +152 common setfsgid sys_setfsgid +153 common times sys_times compat_sys_times +154 common setpgid sys_setpgid +155 common getpgid sys_getpgid +156 common getsid sys_getsid +157 common setsid sys_setsid +158 common getgroups sys_getgroups +159 common setgroups sys_setgroups +160 common uname sys_newuname +161 common sethostname sys_sethostname +162 common setdomainname sys_setdomainname +# getrlimit and setrlimit are superseded with prlimit64 +163 rlimit getrlimit sys_getrlimit compat_sys_getrlimit +164 rlimit setrlimit sys_setrlimit compat_sys_setrlimit +165 common getrusage sys_getrusage compat_sys_getrusage +166 common umask sys_umask +167 common prctl sys_prctl +168 common getcpu sys_getcpu +169 time32 gettimeofday sys_gettimeofday compat_sys_gettimeofday +169 64 gettimeofday sys_gettimeofday +170 time32 settimeofday sys_settimeofday compat_sys_settimeofday +170 64 settimeofday sys_settimeofday +171 time32 adjtimex sys_adjtimex_time32 +171 64 adjtimex sys_adjtimex +172 common getpid sys_getpid +173 common getppid sys_getppid +174 common getuid sys_getuid +175 common geteuid sys_geteuid +176 common getgid sys_getgid +177 common getegid sys_getegid +178 common gettid sys_gettid +179 common sysinfo sys_sysinfo compat_sys_sysinfo +180 common mq_open sys_mq_open compat_sys_mq_open +181 common mq_unlink sys_mq_unlink +182 time32 mq_timedsend sys_mq_timedsend_time32 +182 64 mq_timedsend sys_mq_timedsend +183 time32 mq_timedreceive sys_mq_timedreceive_time32 +183 64 mq_timedreceive sys_mq_timedreceive +184 common mq_notify sys_mq_notify compat_sys_mq_notify +185 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr +186 common msgget sys_msgget +187 common msgctl sys_msgctl compat_sys_msgctl +188 common msgrcv sys_msgrcv compat_sys_msgrcv +189 common msgsnd sys_msgsnd compat_sys_msgsnd +190 common semget sys_semget +191 common semctl sys_semctl compat_sys_semctl +192 time32 semtimedop sys_semtimedop_time32 +192 64 semtimedop sys_semtimedop +193 common semop sys_semop +194 common shmget sys_shmget +195 common shmctl sys_shmctl compat_sys_shmctl +196 common shmat sys_shmat compat_sys_shmat +197 common shmdt sys_shmdt +198 common socket sys_socket +199 common socketpair sys_socketpair +200 common bind sys_bind +201 common listen sys_listen +202 common accept sys_accept +203 common connect sys_connect +204 common getsockname sys_getsockname +205 common getpeername sys_getpeername +206 common sendto sys_sendto +207 common recvfrom sys_recvfrom compat_sys_recvfrom +208 common setsockopt sys_setsockopt sys_setsockopt +209 common getsockopt sys_getsockopt sys_getsockopt +210 common shutdown sys_shutdown +211 common sendmsg sys_sendmsg compat_sys_sendmsg +212 common recvmsg sys_recvmsg compat_sys_recvmsg +213 common readahead sys_readahead compat_sys_readahead +214 common brk sys_brk +215 common munmap sys_munmap +216 common mremap sys_mremap +217 common add_key sys_add_key +218 common request_key sys_request_key +219 common keyctl sys_keyctl compat_sys_keyctl +220 common clone sys_clone +221 common execve sys_execve compat_sys_execve +222 32 mmap2 sys_mmap2 +222 64 mmap sys_mmap +223 32 fadvise64_64 sys_fadvise64_64 compat_sys_fadvise64_64 +223 64 fadvise64 sys_fadvise64_64 +224 common swapon sys_swapon +225 common swapoff sys_swapoff +226 common mprotect sys_mprotect +227 common msync sys_msync +228 common mlock sys_mlock +229 common munlock sys_munlock +230 common mlockall sys_mlockall +231 common munlockall sys_munlockall +232 common mincore sys_mincore +233 common madvise sys_madvise +234 common remap_file_pages sys_remap_file_pages +235 common mbind sys_mbind +236 common get_mempolicy sys_get_mempolicy +237 common set_mempolicy sys_set_mempolicy +238 common migrate_pages sys_migrate_pages +239 common move_pages sys_move_pages +240 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo +241 common perf_event_open sys_perf_event_open +242 common accept4 sys_accept4 +243 time32 recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32 +243 64 recvmmsg sys_recvmmsg +# Architectures may provide up to 16 syscalls of their own between 244 and 259 +244 arc cacheflush sys_cacheflush +245 arc arc_settls sys_arc_settls +246 arc arc_gettls sys_arc_gettls +247 arc sysfs sys_sysfs +248 arc arc_usr_cmpxchg sys_arc_usr_cmpxchg + +244 csky set_thread_area sys_set_thread_area +245 csky cacheflush sys_cacheflush + +244 nios2 cacheflush sys_cacheflush + +244 or1k or1k_atomic sys_or1k_atomic + +258 riscv riscv_hwprobe sys_riscv_hwprobe +259 riscv riscv_flush_icache sys_riscv_flush_icache + +260 time32 wait4 sys_wait4 compat_sys_wait4 +260 64 wait4 sys_wait4 +261 common prlimit64 sys_prlimit64 +262 common fanotify_init sys_fanotify_init +263 common fanotify_mark sys_fanotify_mark +264 common name_to_handle_at sys_name_to_handle_at +265 common open_by_handle_at sys_open_by_handle_at +266 time32 clock_adjtime sys_clock_adjtime32 +266 64 clock_adjtime sys_clock_adjtime +267 common syncfs sys_syncfs +268 common setns sys_setns +269 common sendmmsg sys_sendmmsg compat_sys_sendmmsg +270 common process_vm_readv sys_process_vm_readv +271 common process_vm_writev sys_process_vm_writev +272 common kcmp sys_kcmp +273 common finit_module sys_finit_module +274 common sched_setattr sys_sched_setattr +275 common sched_getattr sys_sched_getattr +276 common renameat2 sys_renameat2 +277 common seccomp sys_seccomp +278 common getrandom sys_getrandom +279 common memfd_create sys_memfd_create +280 common bpf sys_bpf +281 common execveat sys_execveat compat_sys_execveat +282 common userfaultfd sys_userfaultfd +283 common membarrier sys_membarrier +284 common mlock2 sys_mlock2 +285 common copy_file_range sys_copy_file_range +286 common preadv2 sys_preadv2 compat_sys_preadv2 +287 common pwritev2 sys_pwritev2 compat_sys_pwritev2 +288 common pkey_mprotect sys_pkey_mprotect +289 common pkey_alloc sys_pkey_alloc +290 common pkey_free sys_pkey_free +291 common statx sys_statx +292 time32 io_pgetevents sys_io_pgetevents_time32 compat_sys_io_pgetevents +292 64 io_pgetevents sys_io_pgetevents +293 common rseq sys_rseq +294 common kexec_file_load sys_kexec_file_load +# 295 through 402 are unassigned to sync up with generic numbers don't use +403 32 clock_gettime64 sys_clock_gettime +404 32 clock_settime64 sys_clock_settime +405 32 clock_adjtime64 sys_clock_adjtime +406 32 clock_getres_time64 sys_clock_getres +407 32 clock_nanosleep_time64 sys_clock_nanosleep +408 32 timer_gettime64 sys_timer_gettime +409 32 timer_settime64 sys_timer_settime +410 32 timerfd_gettime64 sys_timerfd_gettime +411 32 timerfd_settime64 sys_timerfd_settime +412 32 utimensat_time64 sys_utimensat +413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 +414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 +417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 +418 32 mq_timedsend_time64 sys_mq_timedsend +419 32 mq_timedreceive_time64 sys_mq_timedreceive +420 32 semtimedop_time64 sys_semtimedop +421 32 rt_sigtimedwait_time64 sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time64 +422 32 futex_time64 sys_futex +423 32 sched_rr_get_interval_time64 sys_sched_rr_get_interval +424 common pidfd_send_signal sys_pidfd_send_signal +425 common io_uring_setup sys_io_uring_setup +426 common io_uring_enter sys_io_uring_enter +427 common io_uring_register sys_io_uring_register +428 common open_tree sys_open_tree +429 common move_mount sys_move_mount +430 common fsopen sys_fsopen +431 common fsconfig sys_fsconfig +432 common fsmount sys_fsmount +433 common fspick sys_fspick +434 common pidfd_open sys_pidfd_open +435 common clone3 sys_clone3 +436 common close_range sys_close_range +437 common openat2 sys_openat2 +438 common pidfd_getfd sys_pidfd_getfd +439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 +442 common mount_setattr sys_mount_setattr +443 common quotactl_fd sys_quotactl_fd +444 common landlock_create_ruleset sys_landlock_create_ruleset +445 common landlock_add_rule sys_landlock_add_rule +446 common landlock_restrict_self sys_landlock_restrict_self +447 memfd_secret memfd_secret sys_memfd_secret +448 common process_mrelease sys_process_mrelease +449 common futex_waitv sys_futex_waitv +450 common set_mempolicy_home_node sys_set_mempolicy_home_node +451 common cachestat sys_cachestat +452 common fchmodat2 sys_fchmodat2 +453 common map_shadow_stack sys_map_shadow_stack +454 common futex_wake sys_futex_wake +455 common futex_wait sys_futex_wait +456 common futex_requeue sys_futex_requeue +457 common statmount sys_statmount +458 common listmount sys_listmount +459 common lsm_get_self_attr sys_lsm_get_self_attr +460 common lsm_set_self_attr sys_lsm_set_self_attr +461 common lsm_list_modules sys_lsm_list_modules +462 common mseal sys_mseal +467 common uretprobe sys_uretprobe diff --git a/scripts/syscalltbl.sh b/scripts/syscalltbl.sh index 6abe143889ef..6a903b87a7c2 100755 --- a/scripts/syscalltbl.sh +++ b/scripts/syscalltbl.sh @@ -54,7 +54,7 @@ nxt=0 grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | { - while read nr abi name native compat ; do + while read nr abi name native compat noreturn; do if [ $nxt -gt $nr ]; then echo "error: $infile: syscall table is not sorted or duplicates the same syscall number" >&2 @@ -66,7 +66,21 @@ grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | { nxt=$((nxt + 1)) done - if [ -n "$compat" ]; then + if [ "$compat" = "-" ]; then + unset compat + fi + + if [ -n "$noreturn" ]; then + if [ "$noreturn" != "noreturn" ]; then + echo "error: $infile: invalid string \"$noreturn\" in 'noreturn' column" + exit 1 + fi + if [ -n "$compat" ]; then + echo "__SYSCALL_COMPAT_NORETURN($nr, $native, $compat)" + else + echo "__SYSCALL_NORETURN($nr, $native)" + fi + elif [ -n "$compat" ]; then echo "__SYSCALL_WITH_COMPAT($nr, $native, $compat)" elif [ -n "$native" ]; then echo "__SYSCALL($nr, $native)" |