summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.dtbs1
-rw-r--r--scripts/Makefile.extrawarn18
-rw-r--r--scripts/Makefile.kasan12
-rw-r--r--scripts/Makefile.vmlinux79
-rw-r--r--scripts/Makefile.vmlinux_o26
-rwxr-xr-xscripts/atomic/gen-atomics.sh1
-rwxr-xr-xscripts/atomic/gen-rust-atomic-helpers.sh67
-rwxr-xr-xscripts/crypto/gen-hash-testvecs.py27
-rw-r--r--scripts/dtc/checks.c23
-rw-r--r--scripts/dtc/data.c47
-rwxr-xr-xscripts/dtc/dt_to_config8
-rw-r--r--scripts/dtc/dtc-lexer.l15
-rw-r--r--scripts/dtc/dtc.c6
-rw-r--r--scripts/dtc/dtc.h5
-rw-r--r--scripts/dtc/fdtoverlay.c8
-rw-r--r--scripts/dtc/flattree.c2
-rw-r--r--scripts/dtc/libfdt/fdt.c8
-rw-r--r--scripts/dtc/libfdt/fdt.h4
-rw-r--r--scripts/dtc/libfdt/fdt_overlay.c8
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c41
-rw-r--r--scripts/dtc/libfdt/libfdt.h179
-rw-r--r--scripts/dtc/libfdt/libfdt_internal.h14
-rw-r--r--scripts/dtc/livetree.c25
-rw-r--r--scripts/dtc/srcpos.c17
-rw-r--r--scripts/dtc/srcpos.h1
-rw-r--r--scripts/dtc/treesource.c52
-rw-r--r--scripts/dtc/util.c16
-rw-r--r--scripts/dtc/util.h5
-rw-r--r--scripts/dtc/version_gen.h2
-rwxr-xr-xscripts/extract-vmlinux8
-rw-r--r--scripts/gcc-plugins/gcc-common.h7
-rw-r--r--scripts/gdb/linux/timerlist.py2
-rwxr-xr-xscripts/generate_rust_analyzer.py4
-rw-r--r--scripts/generate_rust_target.rs12
-rw-r--r--scripts/kconfig/expr.h1
-rw-r--r--scripts/kconfig/lexer.l1
-rw-r--r--scripts/kconfig/nconf.gui.c8
-rw-r--r--scripts/kconfig/parser.y47
-rw-r--r--scripts/kconfig/qconf.cc13
-rw-r--r--scripts/kconfig/symbol.c7
-rw-r--r--scripts/kconfig/tests/conftest.py17
-rw-r--r--scripts/kconfig/tests/err_transitional/Kconfig52
-rw-r--r--scripts/kconfig/tests/err_transitional/__init__.py14
-rw-r--r--scripts/kconfig/tests/err_transitional/expected_stderr7
-rw-r--r--scripts/kconfig/tests/transitional/Kconfig100
-rw-r--r--scripts/kconfig/tests/transitional/__init__.py18
-rw-r--r--scripts/kconfig/tests/transitional/expected_config12
-rw-r--r--scripts/kconfig/tests/transitional/initial_config16
-rwxr-xr-xscripts/link-vmlinux.sh5
-rwxr-xr-xscripts/min-tool-version.sh6
-rwxr-xr-xscripts/misc-check4
-rwxr-xr-xscripts/mksysmap6
-rw-r--r--scripts/mod/file2alias.c35
-rw-r--r--scripts/mod/modpost.c15
-rw-r--r--scripts/mod/modpost.h2
-rw-r--r--scripts/rustdoc_test_gen.rs2
56 files changed, 932 insertions, 206 deletions
diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs
index 8d56c0815f33..2d321b813600 100644
--- a/scripts/Makefile.dtbs
+++ b/scripts/Makefile.dtbs
@@ -97,6 +97,7 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
-Wno-avoid_unnecessary_addr_size \
-Wno-alias_paths \
-Wno-graph_child_address \
+ -Wno-interrupt_map \
-Wno-simple_bus_reg
else
DTC_FLAGS += -Wunique_unit_address_if_enabled
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index dca175fffcab..1434cb6208cb 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -25,8 +25,6 @@ ifneq ($(CONFIG_FRAME_WARN),0)
KBUILD_CFLAGS += -Wframe-larger-than=$(CONFIG_FRAME_WARN)
endif
-KBUILD_CPPFLAGS-$(CONFIG_WERROR) += -Werror
-KBUILD_CPPFLAGS += $(KBUILD_CPPFLAGS-y)
KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds
ifdef CONFIG_CC_IS_CLANG
@@ -214,10 +212,20 @@ KBUILD_CFLAGS += -Wno-unused-parameter
endif
#
-# W=e - error out on warnings
+# W=e and CONFIG_WERROR - error out on warnings
#
-ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),)
+ifneq ($(findstring e, $(KBUILD_EXTRA_WARN))$(CONFIG_WERROR),)
-KBUILD_CFLAGS += -Werror
+KBUILD_CPPFLAGS += -Werror
+KBUILD_AFLAGS += -Wa,--fatal-warnings
+KBUILD_LDFLAGS += --fatal-warnings
+KBUILD_USERCFLAGS += -Werror
+KBUILD_USERLDFLAGS += -Wl,--fatal-warnings
+KBUILD_RUSTFLAGS += -Dwarnings
endif
+
+# Hostprog flags are used during build bootstrapping and can not rely on CONFIG_ symbols.
+KBUILD_HOSTCFLAGS += -Werror
+KBUILD_HOSTLDFLAGS += -Wl,--fatal-warnings
+KBUILD_HOSTRUSTFLAGS += -Dwarnings
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 693dbbebebba..0ba2aac3b8dc 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -86,10 +86,14 @@ kasan_params += hwasan-instrument-stack=$(stack_enable) \
hwasan-use-short-granules=0 \
hwasan-inline-all-checks=0
-# Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*().
-ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y)
- kasan_params += hwasan-kernel-mem-intrinsic-prefix=1
-endif
+# Instrument memcpy/memset/memmove calls by using instrumented __(hw)asan_mem*().
+ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
+ ifdef CONFIG_CC_IS_GCC
+ kasan_params += asan-kernel-mem-intrinsic-prefix=1
+ else
+ kasan_params += hwasan-kernel-mem-intrinsic-prefix=1
+ endif
+endif # CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
endif # CONFIG_KASAN_SW_TAGS
diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
index b64862dc6f08..7c6ae9886f8f 100644
--- a/scripts/Makefile.vmlinux
+++ b/scripts/Makefile.vmlinux
@@ -9,20 +9,6 @@ include $(srctree)/scripts/Makefile.lib
targets :=
-ifdef CONFIG_ARCH_VMLINUX_NEEDS_RELOCS
-vmlinux-final := vmlinux.unstripped
-
-quiet_cmd_strip_relocs = RSTRIP $@
- cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' --remove-section=!'.rel*.dyn' $< $@
-
-vmlinux: $(vmlinux-final) FORCE
- $(call if_changed,strip_relocs)
-
-targets += vmlinux
-else
-vmlinux-final := vmlinux
-endif
-
%.o: %.c FORCE
$(call if_changed_rule,cc_o_c)
@@ -61,19 +47,14 @@ targets += .builtin-dtbs-list
ifdef CONFIG_GENERIC_BUILTIN_DTB
targets += .builtin-dtbs.S .builtin-dtbs.o
-$(vmlinux-final): .builtin-dtbs.o
+vmlinux.unstripped: .builtin-dtbs.o
endif
-# vmlinux
+# vmlinux.unstripped
# ---------------------------------------------------------------------------
-ifdef CONFIG_MODULES
-targets += .vmlinux.export.o
-$(vmlinux-final): .vmlinux.export.o
-endif
-
ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
-$(vmlinux-final): arch/$(SRCARCH)/tools/vmlinux.arch.o
+vmlinux.unstripped: arch/$(SRCARCH)/tools/vmlinux.arch.o
arch/$(SRCARCH)/tools/vmlinux.arch.o: vmlinux.o FORCE
$(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools $@
@@ -86,17 +67,61 @@ cmd_link_vmlinux = \
$< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
-targets += $(vmlinux-final)
-$(vmlinux-final): scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
+targets += vmlinux.unstripped .vmlinux.export.o
+vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE
+$(call if_changed_dep,link_vmlinux)
ifdef CONFIG_DEBUG_INFO_BTF
-$(vmlinux-final): $(RESOLVE_BTFIDS)
+vmlinux.unstripped: $(RESOLVE_BTFIDS)
endif
ifdef CONFIG_BUILDTIME_TABLE_SORT
-$(vmlinux-final): scripts/sorttable
+vmlinux.unstripped: scripts/sorttable
endif
+# vmlinux
+# ---------------------------------------------------------------------------
+
+remove-section-y := .modinfo
+remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*'
+
+remove-symbols := -w --strip-symbol='__mod_device_table__*'
+
+# To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy,
+# it is necessary to remove the PT_LOAD flag from the segment.
+quiet_cmd_strip_relocs = OBJCOPY $@
+ cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \
+ $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@
+
+targets += vmlinux
+vmlinux: vmlinux.unstripped FORCE
+ $(call if_changed,strip_relocs)
+
+# modules.builtin.modinfo
+# ---------------------------------------------------------------------------
+
+OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary
+
+targets += modules.builtin.modinfo
+modules.builtin.modinfo: vmlinux.unstripped FORCE
+ $(call if_changed,objcopy)
+
+# modules.builtin
+# ---------------------------------------------------------------------------
+
+__default: modules.builtin
+
+# The second line aids cases where multiple modules share the same object.
+
+quiet_cmd_modules_builtin = GEN $@
+ cmd_modules_builtin = \
+ tr '\0' '\n' < $< | \
+ sed -n 's/^[[:alnum:]:_]*\.file=//p' | \
+ tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@
+
+targets += modules.builtin
+modules.builtin: modules.builtin.modinfo FORCE
+ $(call if_changed,modules_builtin)
+
# modules.builtin.ranges
# ---------------------------------------------------------------------------
ifdef CONFIG_BUILTIN_MODULE_RANGES
@@ -110,7 +135,7 @@ modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \
modules.builtin vmlinux.map vmlinux.o.map FORCE
$(call if_changed,modules_builtin_ranges)
-vmlinux.map: $(vmlinux-final)
+vmlinux.map: vmlinux.unstripped
@:
endif
diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index b024ffb3e201..23c8751285d7 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
PHONY := __default
-__default: vmlinux.o modules.builtin.modinfo modules.builtin
+__default: vmlinux.o
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
@@ -73,30 +73,6 @@ vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
targets += vmlinux.o
-# modules.builtin.modinfo
-# ---------------------------------------------------------------------------
-
-OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary
-
-targets += modules.builtin.modinfo
-modules.builtin.modinfo: vmlinux.o FORCE
- $(call if_changed,objcopy)
-
-# modules.builtin
-# ---------------------------------------------------------------------------
-
-# The second line aids cases where multiple modules share the same object.
-
-quiet_cmd_modules_builtin = GEN $@
- cmd_modules_builtin = \
- tr '\0' '\n' < $< | \
- sed -n 's/^[[:alnum:]:_]*\.file=//p' | \
- tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@
-
-targets += modules.builtin
-modules.builtin: modules.builtin.modinfo FORCE
- $(call if_changed,modules_builtin)
-
# Add FORCE to the prerequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh
index 5b98a8307693..02508d0d6fe4 100755
--- a/scripts/atomic/gen-atomics.sh
+++ b/scripts/atomic/gen-atomics.sh
@@ -11,6 +11,7 @@ cat <<EOF |
gen-atomic-instrumented.sh linux/atomic/atomic-instrumented.h
gen-atomic-long.sh linux/atomic/atomic-long.h
gen-atomic-fallback.sh linux/atomic/atomic-arch-fallback.h
+gen-rust-atomic-helpers.sh ../rust/helpers/atomic.c
EOF
while read script header args; do
/bin/sh ${ATOMICDIR}/${script} ${ATOMICTBL} ${args} > ${LINUXDIR}/include/${header}
diff --git a/scripts/atomic/gen-rust-atomic-helpers.sh b/scripts/atomic/gen-rust-atomic-helpers.sh
new file mode 100755
index 000000000000..45b1e100ed7c
--- /dev/null
+++ b/scripts/atomic/gen-rust-atomic-helpers.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+ATOMICDIR=$(dirname $0)
+
+. ${ATOMICDIR}/atomic-tbl.sh
+
+#gen_proto_order_variant(meta, pfx, name, sfx, order, atomic, int, arg...)
+gen_proto_order_variant()
+{
+ local meta="$1"; shift
+ local pfx="$1"; shift
+ local name="$1"; shift
+ local sfx="$1"; shift
+ local order="$1"; shift
+ local atomic="$1"; shift
+ local int="$1"; shift
+
+ local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
+
+ local ret="$(gen_ret_type "${meta}" "${int}")"
+ local params="$(gen_params "${int}" "${atomic}" "$@")"
+ local args="$(gen_args "$@")"
+ local retstmt="$(gen_ret_stmt "${meta}")"
+
+cat <<EOF
+__rust_helper ${ret}
+rust_helper_${atomicname}(${params})
+{
+ ${retstmt}${atomicname}(${args});
+}
+
+EOF
+}
+
+cat << EOF
+// SPDX-License-Identifier: GPL-2.0
+
+// Generated by $0
+// DO NOT MODIFY THIS FILE DIRECTLY
+
+/*
+ * This file provides helpers for the various atomic functions for Rust.
+ */
+#ifndef _RUST_ATOMIC_API_H
+#define _RUST_ATOMIC_API_H
+
+#include <linux/atomic.h>
+
+// TODO: Remove this after INLINE_HELPERS support is added.
+#ifndef __rust_helper
+#define __rust_helper
+#endif
+
+EOF
+
+grep '^[a-z]' "$1" | while read name meta args; do
+ gen_proto "${meta}" "${name}" "atomic" "int" ${args}
+done
+
+grep '^[a-z]' "$1" | while read name meta args; do
+ gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
+done
+
+cat <<EOF
+#endif /* _RUST_ATOMIC_API_H */
+EOF
diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py
index 4ac927d40cf5..fc063f2ee95f 100755
--- a/scripts/crypto/gen-hash-testvecs.py
+++ b/scripts/crypto/gen-hash-testvecs.py
@@ -84,11 +84,16 @@ def print_c_struct_u8_array_field(name, value):
print_bytes('\t\t\t', value, 8)
print('\t\t},')
+def alg_digest_size_const(alg):
+ if alg == 'blake2s':
+ return 'BLAKE2S_HASH_SIZE'
+ return f'{alg.upper()}_DIGEST_SIZE'
+
def gen_unkeyed_testvecs(alg):
print('')
print('static const struct {')
print('\tsize_t data_len;')
- print(f'\tu8 digest[{alg.upper()}_DIGEST_SIZE];')
+ print(f'\tu8 digest[{alg_digest_size_const(alg)}];')
print('} hash_testvecs[] = {')
for data_len in DATA_LENS:
data = rand_bytes(data_len)
@@ -103,7 +108,7 @@ def gen_unkeyed_testvecs(alg):
for data_len in range(len(data) + 1):
hash_update(ctx, compute_hash(alg, data[:data_len]))
print_static_u8_array_definition(
- f'hash_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
+ f'hash_testvec_consolidated[{alg_digest_size_const(alg)}]',
hash_final(ctx))
def gen_hmac_testvecs(alg):
@@ -119,6 +124,20 @@ def gen_hmac_testvecs(alg):
f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
ctx.digest())
+BLAKE2S_KEY_SIZE = 32
+BLAKE2S_HASH_SIZE = 32
+
+def gen_additional_blake2s_testvecs():
+ hashes = b''
+ for key_len in range(BLAKE2S_KEY_SIZE + 1):
+ for out_len in range(1, BLAKE2S_HASH_SIZE + 1):
+ h = hashlib.blake2s(digest_size=out_len, key=rand_bytes(key_len))
+ h.update(rand_bytes(100))
+ hashes += h.digest()
+ print_static_u8_array_definition(
+ 'blake2s_keyed_testvec_consolidated[BLAKE2S_HASH_SIZE]',
+ compute_hash('blake2s', hashes))
+
def gen_additional_poly1305_testvecs():
key = b'\xff' * POLY1305_KEY_SIZE
data = b''
@@ -141,7 +160,9 @@ alg = sys.argv[1]
print('/* SPDX-License-Identifier: GPL-2.0-or-later */')
print(f'/* This file was generated by: {sys.argv[0]} {" ".join(sys.argv[1:])} */')
gen_unkeyed_testvecs(alg)
-if alg == 'poly1305':
+if alg == 'blake2s':
+ gen_additional_blake2s_testvecs()
+elif alg == 'poly1305':
gen_additional_poly1305_testvecs()
else:
gen_hmac_testvecs(alg)
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 6e06aeab5503..7e3fed5005b3 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -1024,7 +1024,7 @@ static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct no
} else if (strprefixeq(node->name, node->basenamelen, "i2c")) {
struct node *child;
for_each_child(node, child) {
- if (strprefixeq(child->name, node->basenamelen, "i2c-bus"))
+ if (strprefixeq(child->name, child->basenamelen, "i2c-bus"))
return;
}
node->bus = &i2c_bus;
@@ -1217,9 +1217,7 @@ WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti,
struct node *node)
{
- struct property *prop;
struct node *child;
- bool has_reg = false;
if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)
return;
@@ -1228,13 +1226,18 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
return;
for_each_child(node, child) {
- prop = get_property(child, "reg");
- if (prop)
- has_reg = true;
+ /*
+ * Even if the child devices' address space is not mapped into
+ * the parent bus (no 'ranges' property on node), children can
+ * still have registers on a local bus, or map local addresses
+ * to another subordinate address space. The properties on the
+ * child nodes then make #address-cells/#size-cells necessary:
+ */
+ if (get_property(child, "reg") || get_property(child, "ranges"))
+ return;
}
- if (!has_reg)
- FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" property");
+ FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" or \"ranges\" property");
}
WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
@@ -1673,6 +1676,10 @@ static void check_interrupt_map(struct check *c,
cellprop = get_property(provider_node, "#address-cells");
if (cellprop)
parent_cellsize += propval_cell(cellprop);
+ else
+ FAIL_PROP(c, dti, node, irq_map_prop,
+ "Missing property '#address-cells' in node %s, using 0 as fallback",
+ provider_node->fullpath);
cell += 1 + parent_cellsize;
if (cell > map_cells)
diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
index 14734233ad8b..5b25aa060416 100644
--- a/scripts/dtc/data.c
+++ b/scripts/dtc/data.c
@@ -228,11 +228,7 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref)
{
struct marker *m;
- m = xmalloc(sizeof(*m));
- m->offset = d.len;
- m->type = type;
- m->ref = ref;
- m->next = NULL;
+ m = alloc_marker(d.len, type, ref);
return data_append_markers(d, m);
}
@@ -254,3 +250,44 @@ bool data_is_one_string(struct data d)
return true;
}
+
+struct data data_insert_data(struct data d, struct marker *m, struct data old)
+{
+ unsigned int offset = m->offset;
+ struct marker *next = m->next;
+ struct marker *marker;
+ struct data new_data;
+ char *ref;
+
+ new_data = data_insert_at_marker(d, m, old.val, old.len);
+
+ /* Copy all markers from old value */
+ marker = old.markers;
+ for_each_marker(marker) {
+ ref = NULL;
+
+ if (marker->ref)
+ ref = xstrdup(marker->ref);
+
+ m->next = alloc_marker(marker->offset + offset, marker->type,
+ ref);
+ m = m->next;
+ }
+ m->next = next;
+
+ return new_data;
+}
+
+struct marker *alloc_marker(unsigned int offset, enum markertype type,
+ char *ref)
+{
+ struct marker *m;
+
+ m = xmalloc(sizeof(*m));
+ m->offset = offset;
+ m->type = type;
+ m->ref = ref;
+ m->next = NULL;
+
+ return m;
+}
diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config
index 299d1c2b20d7..70d6d5f06bdc 100755
--- a/scripts/dtc/dt_to_config
+++ b/scripts/dtc/dt_to_config
@@ -51,10 +51,10 @@ $num_pr_flags = $pr_flag_pos_config_test_fail + 1;
"compatible is white listed",
"matching driver and/or kernel config is hard coded",
"kernel config hard coded in Makefile",
- "one or more kernel config file options is not set",
- "one or more kernel config file options is set to 'm'",
- "one or more kernel config file options is set to 'y'",
- "one of more kernel config file options fails to have correct value"
+ "one or more kernel config file options are not set",
+ "one or more kernel config file options are set to 'm'",
+ "one or more kernel config file options are set to 'y'",
+ "one or more kernel config file options fail to have correct value"
);
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index de60a70b6bdb..15d585c80798 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -151,6 +151,21 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
return DT_LABEL;
}
+<V1>{LABEL} {
+ /* Missed includes or macro definitions while
+ * preprocessing can lead to unexpected identifiers in
+ * the input. Report a slightly more informative error
+ * in this case */
+
+ lexical_error("Unexpected '%s'", yytext);
+
+ /* Treat it as a literal which often generates further
+ * useful error messages */
+
+ yylval.integer = 0;
+ return DT_LITERAL;
+ }
+
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
char *e;
DPRINT("Integer Literal: '%s'\n", yytext);
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 0655c2e2c362..b3445b7d6473 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -15,7 +15,7 @@ int quiet; /* Level of quietness */
unsigned int reservenum;/* Number of memory reservation slots */
int minsize; /* Minimum blob size */
int padsize; /* Additional padding to blob */
-int alignsize; /* Additional padding to blob accroding to the alignsize */
+int alignsize; /* Additional padding to blob according to the alignsize */
int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */
@@ -289,7 +289,9 @@ int main(int argc, char *argv[])
if (!depfile)
die("Couldn't open dependency file %s: %s\n", depname,
strerror(errno));
- fprintf(depfile, "%s:", outname);
+
+ fprint_path_escaped(depfile, outname);
+ fputc(':', depfile);
}
if (inform == NULL)
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 4c4aaca1fc41..3a220b9afc99 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -38,7 +38,7 @@ extern int quiet; /* Level of quietness */
extern unsigned int reservenum; /* Number of memory reservation slots */
extern int minsize; /* Minimum blob size */
extern int padsize; /* Additional padding to blob */
-extern int alignsize; /* Additional padding to blob accroding to the alignsize */
+extern int alignsize; /* Additional padding to blob according to the alignsize */
extern int phandle_format; /* Use linux,phandle or phandle properties */
extern int generate_symbols; /* generate symbols for nodes with labels */
extern int generate_fixups; /* generate fixups */
@@ -182,7 +182,10 @@ struct data data_append_addr(struct data d, uint64_t addr);
struct data data_append_byte(struct data d, uint8_t byte);
struct data data_append_zeroes(struct data d, int len);
struct data data_append_align(struct data d, int align);
+struct data data_insert_data(struct data d, struct marker *m, struct data old);
+struct marker *alloc_marker(unsigned int offset, enum markertype type,
+ char *ref);
struct data data_add_marker(struct data d, enum markertype type, char *ref);
bool data_is_one_string(struct data d);
diff --git a/scripts/dtc/fdtoverlay.c b/scripts/dtc/fdtoverlay.c
index 699b4f616502..ee1eb8f3ad28 100644
--- a/scripts/dtc/fdtoverlay.c
+++ b/scripts/dtc/fdtoverlay.c
@@ -46,6 +46,7 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len,
char *tmp = NULL;
char *tmpo;
int ret;
+ bool has_symbols;
/*
* We take copies first, because a failed apply can trash
@@ -62,6 +63,8 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len,
fdt_strerror(ret));
goto fail;
}
+ ret = fdt_path_offset(tmp, "/__symbols__");
+ has_symbols = ret >= 0;
memcpy(tmpo, overlay, fdt_totalsize(overlay));
@@ -74,6 +77,11 @@ static void *apply_one(char *base, const char *overlay, size_t *buf_len,
if (ret) {
fprintf(stderr, "\nFailed to apply '%s': %s\n",
name, fdt_strerror(ret));
+ if (!has_symbols) {
+ fprintf(stderr,
+ "base blob does not have a '/__symbols__' node, "
+ "make sure you have compiled the base blob with '-@' option\n");
+ }
goto fail;
}
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 1bcd8089c5b9..30e6de2044b2 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -503,7 +503,7 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)
* Reserve map entries.
* Align the reserve map to a doubleword boundary.
* Each entry is an (address, size) pair of u64 values.
- * Always supply a zero-sized temination entry.
+ * Always supply a zero-sized termination entry.
*/
asm_emit_align(f, 8);
emit_label(f, symprefix, "reserve_map");
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 20c6415b9ced..95f644c31f94 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -312,14 +312,14 @@ int fdt_next_subnode(const void *fdt, int offset)
return offset;
}
-const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
+const char *fdt_find_string_len_(const char *strtab, int tabsize, const char *s,
+ int slen)
{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
+ const char *last = strtab + tabsize - (slen + 1);
const char *p;
for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
+ if (memcmp(p, s, slen) == 0 && p[slen] == '\0')
return p;
return NULL;
}
diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h
index 0c91aa7f67b5..a07abfcc7108 100644
--- a/scripts/dtc/libfdt/fdt.h
+++ b/scripts/dtc/libfdt/fdt.h
@@ -7,7 +7,7 @@
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*/
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
struct fdt_header {
fdt32_t magic; /* magic word FDT_MAGIC */
@@ -45,7 +45,7 @@ struct fdt_property {
char data[];
};
-#endif /* !__ASSEMBLY */
+#endif /* !__ASSEMBLER__ */
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(fdt32_t)
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
index 28b667ffc490..e6b9eb643958 100644
--- a/scripts/dtc/libfdt/fdt_overlay.c
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -307,7 +307,6 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)
/**
* overlay_fixup_one_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
* @symbols_off: Node offset of the symbols node in the base device tree
* @path: Path to a node holding a phandle in the overlay
@@ -328,8 +327,7 @@ static int overlay_update_local_references(void *fdto, uint32_t delta)
* 0 on success
* Negative error code on failure
*/
-static int overlay_fixup_one_phandle(void *fdt, void *fdto,
- int symbols_off,
+static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
const char *path, uint32_t path_len,
const char *name, uint32_t name_len,
int poffset, uint32_t phandle)
@@ -351,7 +349,7 @@ static int overlay_fixup_one_phandle(void *fdt, void *fdto,
name, name_len, poffset,
&phandle_prop,
sizeof(phandle_prop));
-};
+}
/**
* overlay_fixup_phandle - Set an overlay phandle to the base one
@@ -443,7 +441,7 @@ static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
if ((*endptr != '\0') || (endptr <= (sep + 1)))
return -FDT_ERR_BADOVERLAY;
- ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
+ ret = overlay_fixup_one_phandle(fdto, symbols_off,
path, path_len, name, name_len,
poffset, phandle);
if (ret)
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 3621d3651d3f..7475cafce071 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -124,31 +124,33 @@ static int fdt_splice_string_(void *fdt, int newlen)
* allocated. Ignored if can_assume(NO_ROLLBACK)
* @return offset of string in the string table (whether found or added)
*/
-static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
+static int fdt_find_add_string_(void *fdt, const char *s, int slen,
+ int *allocated)
{
char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
const char *p;
char *new;
- int len = strlen(s) + 1;
int err;
if (!can_assume(NO_ROLLBACK))
*allocated = 0;
- p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
+ p = fdt_find_string_len_(strtab, fdt_size_dt_strings(fdt), s, slen);
if (p)
/* found it */
return (p - strtab);
new = strtab + fdt_size_dt_strings(fdt);
- err = fdt_splice_string_(fdt, len);
+ err = fdt_splice_string_(fdt, slen + 1);
if (err)
return err;
if (!can_assume(NO_ROLLBACK))
*allocated = 1;
- memcpy(new, s, len);
+ memcpy(new, s, slen);
+ new[slen] = '\0';
+
return (new - strtab);
}
@@ -181,13 +183,15 @@ int fdt_del_mem_rsv(void *fdt, int n)
return fdt_splice_mem_rsv_(fdt, re, 1, 0);
}
-static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
+static int fdt_resize_property_(void *fdt, int nodeoffset,
+ const char *name, int namelen,
int len, struct fdt_property **prop)
{
int oldlen;
int err;
- *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ *prop = fdt_get_property_namelen_w(fdt, nodeoffset, name, namelen,
+ &oldlen);
if (!*prop)
return oldlen;
@@ -200,7 +204,7 @@ static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
}
static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
+ int namelen, int len, struct fdt_property **prop)
{
int proplen;
int nextoffset;
@@ -211,7 +215,7 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
return nextoffset;
- namestroff = fdt_find_add_string_(fdt, name, &allocated);
+ namestroff = fdt_find_add_string_(fdt, name, namelen, &allocated);
if (namestroff < 0)
return namestroff;
@@ -255,17 +259,18 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
return 0;
}
-int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
- int len, void **prop_data)
+int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, int len, void **prop_data)
{
struct fdt_property *prop;
int err;
FDT_RW_PROBE(fdt);
- err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
+ err = fdt_resize_property_(fdt, nodeoffset, name, namelen, len, &prop);
if (err == -FDT_ERR_NOTFOUND)
- err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
+ err = fdt_add_property_(fdt, nodeoffset, name, namelen, len,
+ &prop);
if (err)
return err;
@@ -273,13 +278,14 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
return 0;
}
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, const void *val, int len)
{
void *prop_data;
int err;
- err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
+ err = fdt_setprop_placeholder_namelen(fdt, nodeoffset, name, namelen,
+ len, &prop_data);
if (err)
return err;
@@ -307,7 +313,8 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
prop->len = cpu_to_fdt32(newlen);
memcpy(prop->data + oldlen, val, len);
} else {
- err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
+ err = fdt_add_property_(fdt, nodeoffset, name, strlen(name),
+ len, &prop);
if (err)
return err;
memcpy(prop->data, val, len);
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 2d409d8e829b..914bf90785ab 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -14,7 +14,7 @@ extern "C" {
#endif
#define FDT_FIRST_SUPPORTED_VERSION 0x02
-#define FDT_LAST_COMPATIBLE_VERSION 0x10
+#define FDT_LAST_COMPATIBLE_VERSION 0x10
#define FDT_LAST_SUPPORTED_VERSION 0x11
/* Error codes: informative error codes */
@@ -263,16 +263,16 @@ int fdt_next_subnode(const void *fdt, int offset);
struct fdt_header *fdth = (struct fdt_header *)fdt; \
fdth->name = cpu_to_fdt32(val); \
}
-fdt_set_hdr_(magic);
-fdt_set_hdr_(totalsize);
-fdt_set_hdr_(off_dt_struct);
-fdt_set_hdr_(off_dt_strings);
-fdt_set_hdr_(off_mem_rsvmap);
-fdt_set_hdr_(version);
-fdt_set_hdr_(last_comp_version);
-fdt_set_hdr_(boot_cpuid_phys);
-fdt_set_hdr_(size_dt_strings);
-fdt_set_hdr_(size_dt_struct);
+fdt_set_hdr_(magic)
+fdt_set_hdr_(totalsize)
+fdt_set_hdr_(off_dt_struct)
+fdt_set_hdr_(off_dt_strings)
+fdt_set_hdr_(off_mem_rsvmap)
+fdt_set_hdr_(version)
+fdt_set_hdr_(last_comp_version)
+fdt_set_hdr_(boot_cpuid_phys)
+fdt_set_hdr_(size_dt_strings)
+fdt_set_hdr_(size_dt_struct)
#undef fdt_set_hdr_
/**
@@ -285,7 +285,7 @@ size_t fdt_header_size(const void *fdt);
/**
* fdt_header_size_ - internal function to get header size from a version number
- * @version: devicetree version number
+ * @version: device tree version number
*
* Return: size of DTB header in bytes
*/
@@ -554,7 +554,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
* -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_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
@@ -599,7 +599,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
* structure block offset of the property (>=0), on success
* -FDT_ERR_NOTFOUND, if the requested node has no properties
* -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
@@ -620,7 +620,7 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset);
* structure block offset of the next property (>=0), on success
* -FDT_ERR_NOTFOUND, if the given property is the last in its node
* -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
@@ -712,6 +712,13 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
int nodeoffset,
const char *name,
int namelen, int *lenp);
+static inline struct fdt_property *
+fdt_get_property_namelen_w(void *fdt, int nodeoffset, const char *name,
+ int namelen, int *lenp)
+{
+ return (struct fdt_property *)(uintptr_t)fdt_get_property_namelen(
+ fdt, nodeoffset, name, namelen, lenp);
+}
#endif
/**
@@ -764,7 +771,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
* to within the device blob itself, not a copy of the value). If
* lenp is non-NULL, the length of the property value is also
* returned, in the integer pointed to by lenp. If namep is non-NULL,
- * the property's namne will also be returned in the char * pointed to
+ * the property's name will also be returned in the char * pointed to
* by namep (this will be a pointer to within the device tree's string
* block, not a new copy of the name).
*
@@ -772,7 +779,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
* pointer to the property's value
* if lenp is non-NULL, *lenp contains the length of the property
* value (>=0)
- * if namep is non-NULL *namep contiains a pointer to the property
+ * if namep is non-NULL *namep contains a pointer to the property
* name.
* NULL, on error
* if lenp is non-NULL, *lenp contains an error code (<0):
@@ -866,7 +873,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
/**
* fdt_get_alias_namelen - get alias based on substring
* @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
+ * @name: name of the alias to look up
* @namelen: number of characters of name to consider
*
* Identical to fdt_get_alias(), but only examine the first @namelen
@@ -883,7 +890,7 @@ const char *fdt_get_alias_namelen(const void *fdt,
/**
* fdt_get_alias - retrieve the path referenced by a given alias
* @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
+ * @name: name of the alias to look up
*
* fdt_get_alias() retrieves the value of a given alias. That is, the
* value of the property named @name in the node /aliases.
@@ -1259,8 +1266,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
- * 2, if the node has no #address-cells property
- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ * 2, if the node has no #address-cells property
+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #address-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
@@ -1280,8 +1287,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
- * 1, if the node has no #size-cells property
- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ * 1, if the node has no #size-cells property
+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
@@ -1562,7 +1569,7 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
* @fdt: pointer to the device tree blob
* @name: name of property to add
* @len: length of property value in bytes
- * @valp: returns a pointer to where where the value should be placed
+ * @valp: returns a pointer to where the value should be placed
*
* returns:
* 0, on success
@@ -1660,6 +1667,38 @@ int fdt_del_mem_rsv(void *fdt, int n);
int fdt_set_name(void *fdt, int nodeoffset, const char *name);
/**
+ * fdt_setprop_namelen - create or change a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: length of the name
+ * @val: pointer to data to set the property value to
+ * @len: length of the property value
+ *
+ * fdt_setprop_namelen() sets the value of the named property in the given
+ * node to the given value and length, creating the property if it
+ * does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, const void *val, int len);
+
+/**
* fdt_setprop - create or change a property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
@@ -1687,8 +1726,44 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name);
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
+static inline int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ return fdt_setprop_namelen(fdt, nodeoffset, name, strlen(name), val,
+ len);
+}
+
+/**
+ * fdt_setprop_placeholder_namelen - allocate space for a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: length of the name
+ * @len: length of the property value
+ * @prop_data: return pointer to property data
+ *
+ * fdt_setprop_placeholder_namelen() allocates the named property in the given node.
+ * If the property exists it is resized. In either case a pointer to the
+ * property data is returned.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, int len, void **prop_data);
/**
* fdt_setprop_placeholder - allocate space for a property
@@ -1698,7 +1773,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
* @len: length of the property value
* @prop_data: return pointer to property data
*
- * fdt_setprop_placeholer() allocates the named property in the given node.
+ * fdt_setprop_placeholder() allocates the named property in the given node.
* If the property exists it is resized. In either case a pointer to the
* property data is returned.
*
@@ -1718,8 +1793,13 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
- int len, void **prop_data);
+static inline int fdt_setprop_placeholder(void *fdt, int nodeoffset,
+ const char *name, int len,
+ void **prop_data)
+{
+ return fdt_setprop_placeholder_namelen(fdt, nodeoffset, name,
+ strlen(name), len, prop_data);
+}
/**
* fdt_setprop_u32 - set a property to a 32-bit integer
@@ -1839,6 +1919,38 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
#define fdt_setprop_string(fdt, nodeoffset, name, str) \
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+/**
+ * fdt_setprop_namelen_string - set a property to a string value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: number of characters of name to consider
+ * @str: string value for the property
+ *
+ * fdt_setprop_namelen_string() sets the value of the named property in the
+ * given node to the given string value (using the length of the
+ * string to determine the new length of the property), or creates a
+ * new property with that value if it does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_setprop_namelen_string(fdt, nodeoffset, name, namelen, str) \
+ fdt_setprop_namelen((fdt), (nodeoffset), (name), (namelen), (str), \
+ strlen(str) + 1)
/**
* fdt_setprop_empty - set a property to an empty value
@@ -2059,7 +2171,7 @@ int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
* @nodeoffset: offset of the node whose property to nop
* @name: name of the property to nop
*
- * fdt_del_property() will delete the given property.
+ * fdt_delprop() will delete the given property.
*
* This function will delete data from the blob, and will therefore
* change the offsets of some existing nodes.
@@ -2111,8 +2223,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
* change the offsets of some existing nodes.
*
* returns:
- * structure block offset of the created nodeequested subnode (>=0), on
- * success
+ * structure block offset of the created subnode (>=0), on success
* -FDT_ERR_NOTFOUND, if the requested subnode does not exist
* -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
* tag
@@ -2122,7 +2233,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
* blob to contain the new node
* -FDT_ERR_NOSPACE
* -FDT_ERR_BADLAYOUT
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
@@ -2167,7 +2278,7 @@ int fdt_del_node(void *fdt, int nodeoffset);
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, there's not enough space in the base device tree
- * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
+ * -FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or
* properties in the base DT
* -FDT_ERR_BADPHANDLE,
* -FDT_ERR_BADOVERLAY,
diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h
index 16bda1906a7b..b60b5456f596 100644
--- a/scripts/dtc/libfdt/libfdt_internal.h
+++ b/scripts/dtc/libfdt/libfdt_internal.h
@@ -20,7 +20,15 @@ int32_t fdt_ro_probe_(const void *fdt);
int fdt_check_node_offset_(const void *fdt, int offset);
int fdt_check_prop_offset_(const void *fdt, int offset);
-const char *fdt_find_string_(const char *strtab, int tabsize, const char *s);
+
+const char *fdt_find_string_len_(const char *strtab, int tabsize, const char *s,
+ int s_len);
+static inline const char *fdt_find_string_(const char *strtab, int tabsize,
+ const char *s)
+{
+ return fdt_find_string_len_(strtab, tabsize, s, strlen(s));
+}
+
int fdt_node_end_offset_(void *fdt, int nodeoffset);
static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
@@ -47,8 +55,8 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
}
/*
- * Internal helpers to access tructural elements of the device tree
- * blob (rather than for exaple reading integers from within property
+ * Internal helpers to access structural elements of the device tree
+ * blob (rather than for example reading integers from within property
* values). We assume that we are either given a naturally aligned
* address for the platform or if we are not, we are on a platform
* where unaligned memory reads will be handled in a graceful manner.
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 49f723002f85..d51d05830b18 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -174,7 +174,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
old_prop->val = new_prop->val;
old_prop->deleted = 0;
- free(old_prop->srcpos);
+ srcpos_free(old_prop->srcpos);
old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
@@ -504,7 +504,7 @@ struct node *get_subnode(struct node *node, const char *nodename)
struct node *child;
for_each_child(node, child)
- if (streq(child->name, nodename))
+ if (streq(child->name, nodename) && !child->deleted)
return child;
return NULL;
@@ -1014,9 +1014,7 @@ static void add_local_fixup_entry(struct dt_info *dti,
/* walk the path components creating nodes if they don't exist */
for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
/* if no node exists, create it */
- nwn = get_subnode(wn, compp[i]);
- if (!nwn)
- nwn = build_and_name_child_node(wn, compp[i]);
+ nwn = build_root_node(wn, compp[i]);
}
free(compp);
@@ -1058,16 +1056,29 @@ void generate_label_tree(struct dt_info *dti, const char *name, bool allocph)
void generate_fixups_tree(struct dt_info *dti, const char *name)
{
+ struct node *n = get_subnode(dti->dt, name);
+
+ /* Start with an empty __fixups__ node to not get duplicates */
+ if (n)
+ n->deleted = true;
+
if (!any_fixup_tree(dti, dti->dt))
return;
- generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+ generate_fixups_tree_internal(dti,
+ build_and_name_child_node(dti->dt, name),
dti->dt);
}
void generate_local_fixups_tree(struct dt_info *dti, const char *name)
{
+ struct node *n = get_subnode(dti->dt, name);
+
+ /* Start with an empty __local_fixups__ node to not get duplicates */
+ if (n)
+ n->deleted = true;
if (!any_local_fixup_tree(dti, dti->dt))
return;
- generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+ generate_local_fixups_tree_internal(dti,
+ build_and_name_child_node(dti->dt, name),
dti->dt);
}
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 8e4d18a90b47..5bb57bf6856c 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -160,8 +160,10 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep)
strerror(errno));
}
- if (depfile)
- fprintf(depfile, " %s", fullname);
+ if (depfile) {
+ fputc(' ', depfile);
+ fprint_path_escaped(depfile, fullname);
+ }
if (fullnamep)
*fullnamep = fullname;
@@ -285,6 +287,17 @@ struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
return pos;
}
+void srcpos_free(struct srcpos *pos)
+{
+ struct srcpos *p_next;
+
+ while (pos) {
+ p_next = pos->next;
+ free(pos);
+ pos = p_next;
+ }
+}
+
char *
srcpos_string(struct srcpos *pos)
{
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index 4318d7ad34d9..4d60b50e3119 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -88,6 +88,7 @@ extern void srcpos_update(struct srcpos *pos, const char *text, int len);
extern struct srcpos *srcpos_copy(struct srcpos *pos);
extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
struct srcpos *old_srcpos);
+extern void srcpos_free(struct srcpos *pos);
extern char *srcpos_string(struct srcpos *pos);
extern char *srcpos_string_first(struct srcpos *pos, int level);
extern char *srcpos_string_last(struct srcpos *pos, int level);
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index ae15839ba6a5..d25f01fc6937 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -139,26 +139,48 @@ static const char *delim_end[] = {
[TYPE_STRING] = "",
};
+/*
+ * The invariants in the marker list are:
+ * - offsets are non-strictly monotonically increasing
+ * - for a single offset there is at most one type marker
+ * - for a single offset that has both a type marker and non-type markers, the
+ * type marker appears before the others.
+ */
+static struct marker **add_marker(struct marker **mi,
+ enum markertype type, unsigned int offset, char *ref)
+{
+ struct marker *nm;
+
+ while (*mi && (*mi)->offset < offset)
+ mi = &(*mi)->next;
+
+ if (*mi && (*mi)->offset == offset && is_type_marker((*mi)->type)) {
+ if (is_type_marker(type))
+ return mi;
+ mi = &(*mi)->next;
+ }
+
+ if (*mi && (*mi)->offset == offset && type == (*mi)->type)
+ return mi;
+
+ nm = xmalloc(sizeof(*nm));
+ nm->type = type;
+ nm->offset = offset;
+ nm->ref = ref;
+ nm->next = *mi;
+ *mi = nm;
+
+ return &nm->next;
+}
+
static void add_string_markers(struct property *prop)
{
int l, len = prop->val.len;
const char *p = prop->val.val;
+ struct marker **mi = &prop->val.markers;
- 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;
- }
+ for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1)
+ mi = add_marker(mi, TYPE_STRING, l, NULL);
}
static enum markertype guess_value_type(struct property *prop)
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
index 507f0120cd13..412592320265 100644
--- a/scripts/dtc/util.c
+++ b/scripts/dtc/util.c
@@ -23,6 +23,22 @@
#include "util.h"
#include "version_gen.h"
+void fprint_path_escaped(FILE *fp, const char *path)
+{
+ const char *p = path;
+
+ while (*p) {
+ if (*p == ' ') {
+ fputc('\\', fp);
+ fputc(' ', fp);
+ } else {
+ fputc(*p, fp);
+ }
+
+ p++;
+ }
+}
+
char *xstrdup(const char *s)
{
int len = strlen(s) + 1;
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index b448cd79efd3..800f2e2c55b1 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -42,6 +42,11 @@ static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
exit(1);
}
+/**
+ * Writes path to fp, escaping spaces with a backslash.
+ */
+void fprint_path_escaped(FILE *fp, const char *path);
+
static inline void *xmalloc(size_t len)
{
void *new = malloc(len);
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index bf81ce593685..226c48bf75dc 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.7.0-gbcd02b52"
+#define DTC_VERSION "DTC 1.7.2-g52f07dcc"
diff --git a/scripts/extract-vmlinux b/scripts/extract-vmlinux
index 189956b5a5c8..266df9bc7a48 100755
--- a/scripts/extract-vmlinux
+++ b/scripts/extract-vmlinux
@@ -10,12 +10,15 @@
#
# ----------------------------------------------------------------------
+me=${0##*/}
+
check_vmlinux()
{
if file "$1" | grep -q 'Linux kernel.*boot executable' ||
readelf -h "$1" > /dev/null 2>&1
then
cat "$1"
+ echo "$me: Extracted vmlinux using '$2' from offset $3" >&2
exit 0
fi
}
@@ -30,12 +33,11 @@ try_decompress()
do
pos=${pos%%:*}
tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
- check_vmlinux $tmp
+ check_vmlinux $tmp "$3" $pos
done
}
# Check invocation:
-me=${0##*/}
img=$1
if [ $# -ne 1 -o ! -s "$img" ]
then
@@ -57,7 +59,7 @@ try_decompress '\002!L\030' xxx 'lz4 -d'
try_decompress '(\265/\375' xxx unzstd
# Finally check for uncompressed images or objects:
-check_vmlinux $img
+check_vmlinux "$img" cat 0
# Bail out:
echo "$me: Cannot find vmlinux." >&2
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index 6cb6d1051815..8f1b3500f8e2 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -173,10 +173,17 @@ static inline opt_pass *get_pass_for_id(int id)
return g->get_passes()->get_pass_for_id(id);
}
+#if BUILDING_GCC_VERSION < 16000
#define TODO_verify_ssa TODO_verify_il
#define TODO_verify_flow TODO_verify_il
#define TODO_verify_stmts TODO_verify_il
#define TODO_verify_rtl_sharing TODO_verify_il
+#else
+#define TODO_verify_ssa 0
+#define TODO_verify_flow 0
+#define TODO_verify_stmts 0
+#define TODO_verify_rtl_sharing 0
+#endif
#define INSN_DELETED_P(insn) (insn)->deleted()
diff --git a/scripts/gdb/linux/timerlist.py b/scripts/gdb/linux/timerlist.py
index 98445671fe83..ccc24d30de80 100644
--- a/scripts/gdb/linux/timerlist.py
+++ b/scripts/gdb/linux/timerlist.py
@@ -56,8 +56,6 @@ def print_base(base):
text += " .index: {}\n".format(base['index'])
text += " .resolution: {} nsecs\n".format(constants.LX_hrtimer_resolution)
-
- text += " .get_time: {}\n".format(base['get_time'])
if constants.LX_CONFIG_HIGH_RES_TIMERS:
text += " .offset: {} nsecs\n".format(base['offset'])
text += "active timers:\n"
diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index 7c3ea2b55041..fc27f0cca752 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -139,8 +139,8 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit
"exclude_dirs": [],
}
- append_crate_with_generated("bindings", ["core", "ffi"])
- append_crate_with_generated("uapi", ["core", "ffi"])
+ append_crate_with_generated("bindings", ["core", "ffi", "pin_init"])
+ append_crate_with_generated("uapi", ["core", "ffi", "pin_init"])
append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"])
def is_root_crate(build_file, target):
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 39c82908ff3a..38b3416bb979 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -225,7 +225,11 @@ fn main() {
ts.push("features", features);
ts.push("llvm-target", "x86_64-linux-gnu");
ts.push("supported-sanitizers", ["kcfi", "kernel-address"]);
- ts.push("target-pointer-width", "64");
+ if cfg.rustc_version_atleast(1, 91, 0) {
+ ts.push("target-pointer-width", 64);
+ } else {
+ ts.push("target-pointer-width", "64");
+ }
} else if cfg.has("X86_32") {
// This only works on UML, as i386 otherwise needs regparm support in rustc
if !cfg.has("UML") {
@@ -245,7 +249,11 @@ fn main() {
}
ts.push("features", features);
ts.push("llvm-target", "i386-unknown-linux-gnu");
- ts.push("target-pointer-width", "32");
+ if cfg.rustc_version_atleast(1, 91, 0) {
+ ts.push("target-pointer-width", 32);
+ } else {
+ ts.push("target-pointer-width", "32");
+ }
} else if cfg.has("LOONGARCH") {
panic!("loongarch uses the builtin rustc loongarch64-unknown-none-softfloat target");
} else {
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index fe2231e0e6a4..5f900d18dae0 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -145,6 +145,7 @@ struct symbol {
#define SYMBOL_CONST 0x0001 /* symbol is const */
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */
+#define SYMBOL_TRANS 0x0100 /* symbol is transitional only (not visible)*/
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
#define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */
#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 9c2cdfc33c6f..6d2c92c6095d 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -126,6 +126,7 @@ n [A-Za-z0-9_-]
"select" return T_SELECT;
"source" return T_SOURCE;
"string" return T_STRING;
+"transitional" return T_TRANSITIONAL;
"tristate" return T_TRISTATE;
"visible" return T_VISIBLE;
"||" return T_OR;
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 7206437e784a..2d097bc7ef1a 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -173,12 +173,10 @@ void fill_window(WINDOW *win, const char *text)
/* do not go over end of line */
total_lines = min(total_lines, y);
for (i = 0; i < total_lines; i++) {
- char tmp[x+10];
const char *line = get_line(text, i);
- int len = get_line_length(line);
- strncpy(tmp, line, min(len, x));
- tmp[len] = '\0';
- mvwprintw(win, i, 0, "%s", tmp);
+ int len = min(get_line_length(line), x);
+
+ mvwprintw(win, i, 0, "%.*s", len, line);
}
}
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index e9c3c664e925..49b79dde1725 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -75,6 +75,7 @@ struct menu *current_menu, *current_entry, *current_choice;
%token T_SELECT
%token T_SOURCE
%token T_STRING
+%token T_TRANSITIONAL
%token T_TRISTATE
%token T_VISIBLE
%token T_EOL
@@ -205,6 +206,12 @@ config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
};
+config_option: T_TRANSITIONAL T_EOL
+{
+ current_entry->sym->flags |= SYMBOL_TRANS;
+ printd(DEBUG_PARSE, "%s:%d:transitional\n", cur_filename, cur_lineno);
+};
+
config_option: default expr if_expr T_EOL
{
menu_add_expr(P_DEFAULT, $2, $3);
@@ -483,6 +490,43 @@ assign_val:
%%
/**
+ * transitional_check_sanity - check transitional symbols have no other
+ * properties
+ *
+ * @menu: menu of the potentially transitional symbol
+ *
+ * Return: -1 if an error is found, 0 otherwise.
+ */
+static int transitional_check_sanity(const struct menu *menu)
+{
+ struct property *prop;
+
+ if (!menu->sym || !(menu->sym->flags & SYMBOL_TRANS))
+ return 0;
+
+ /* Check for depends and visible conditions. */
+ if ((menu->dep && !expr_is_yes(menu->dep)) ||
+ (menu->visibility && !expr_is_yes(menu->visibility))) {
+ fprintf(stderr, "%s:%d: error: %s",
+ menu->filename, menu->lineno,
+ "transitional symbols can only have help sections\n");
+ return -1;
+ }
+
+ /* Check for any property other than "help". */
+ for (prop = menu->sym->prop; prop; prop = prop->next) {
+ if (prop->type != P_COMMENT) {
+ fprintf(stderr, "%s:%d: error: %s",
+ prop->filename, prop->lineno,
+ "transitional symbols can only have help sections\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
* choice_check_sanity - check sanity of a choice member
*
* @menu: menu of the choice member
@@ -558,6 +602,9 @@ void conf_parse(const char *name)
if (menu->sym && sym_check_deps(menu->sym))
yynerrs++;
+ if (transitional_check_sanity(menu))
+ yynerrs++;
+
if (menu->sym && sym_is_choice(menu->sym)) {
menu_for_each_sub_entry(child, menu)
if (child->sym && choice_check_sanity(child))
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index f8992db1870a..b84c9f2485d1 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1377,6 +1377,19 @@ ConfigMainWindow::ConfigMainWindow(void)
ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
ConfigList::showPromptAction->setCheckable(true);
+ switch (configList->optMode) {
+ case allOpt:
+ ConfigList::showAllAction->setChecked(true);
+ break;
+ case promptOpt:
+ ConfigList::showPromptAction->setChecked(true);
+ break;
+ case normalOpt:
+ default:
+ ConfigList::showNormalAction->setChecked(true);
+ break;
+ }
+
QAction *showDebugAction = new QAction("Show Debug Info", this);
showDebugAction->setCheckable(true);
connect(showDebugAction, &QAction::toggled,
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 26ab10c0fd76..760cac998381 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -214,6 +214,11 @@ static void sym_calc_visibility(struct symbol *sym)
struct property *prop;
tristate tri;
+ if (sym->flags & SYMBOL_TRANS) {
+ sym->visible = yes;
+ return;
+ }
+
/* any prompt visible? */
tri = no;
for_all_prompts(sym, prop) {
@@ -526,7 +531,7 @@ void sym_calc_value(struct symbol *sym)
}
}
- if (sym_is_choice(sym))
+ if (sym_is_choice(sym) || sym->flags & SYMBOL_TRANS)
sym->flags &= ~SYMBOL_WRITE;
}
diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py
index 2a2a7e2da060..d94b79e012c0 100644
--- a/scripts/kconfig/tests/conftest.py
+++ b/scripts/kconfig/tests/conftest.py
@@ -81,7 +81,22 @@ class Conf:
# For interactive modes such as oldaskconfig, oldconfig,
# send 'Enter' key until the program finishes.
if interactive:
- ps.stdin.write(b'\n')
+ try:
+ ps.stdin.write(b'\n')
+ ps.stdin.flush()
+ except (BrokenPipeError, OSError):
+ # Process has exited, stop sending input
+ break
+
+ # Close stdin gracefully
+ try:
+ ps.stdin.close()
+ except (BrokenPipeError, OSError):
+ # Ignore broken pipe on close
+ pass
+
+ # Wait for process to complete
+ ps.wait()
self.retcode = ps.returncode
self.stdout = ps.stdout.read().decode()
diff --git a/scripts/kconfig/tests/err_transitional/Kconfig b/scripts/kconfig/tests/err_transitional/Kconfig
new file mode 100644
index 000000000000..a75ed3b2fe5e
--- /dev/null
+++ b/scripts/kconfig/tests/err_transitional/Kconfig
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0
+# Test that transitional symbols cannot have properties other than help
+
+config BAD_DEFAULT
+ bool
+ transitional
+ default y
+ help
+ This transitional symbol illegally has a default property.
+
+config BAD_PROMPT
+ bool
+ transitional
+ prompt "Bad prompt"
+ help
+ This transitional symbol illegally has a prompt.
+
+config BAD_SELECT
+ bool
+ transitional
+ select OTHER_SYMBOL
+ help
+ This transitional symbol illegally has a select.
+
+config BAD_IMPLY
+ bool
+ transitional
+ imply OTHER_SYMBOL
+ help
+ This transitional symbol illegally has an imply.
+
+config BAD_DEPENDS
+ bool
+ transitional
+ depends on OTHER_SYMBOL
+ help
+ This transitional symbol illegally has a depends.
+
+config BAD_RANGE
+ int
+ transitional
+ range 1 10
+ help
+ This transitional symbol illegally has a range.
+
+config BAD_NO_TYPE
+ transitional
+ help
+ This transitional symbol illegally has no type specified.
+
+config OTHER_SYMBOL
+ bool
diff --git a/scripts/kconfig/tests/err_transitional/__init__.py b/scripts/kconfig/tests/err_transitional/__init__.py
new file mode 100644
index 000000000000..7dffb5b0833f
--- /dev/null
+++ b/scripts/kconfig/tests/err_transitional/__init__.py
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Test that transitional symbols with invalid properties are rejected.
+
+Transitional symbols can only have help sections. Any other properties
+(default, select, depends, etc.) should cause a parser error.
+"""
+
+def test(conf):
+ # This should fail with exit code 1 due to invalid transitional symbol
+ assert conf.olddefconfig() == 1
+
+ # Check that the error message is about transitional symbols
+ assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/err_transitional/expected_stderr b/scripts/kconfig/tests/err_transitional/expected_stderr
new file mode 100644
index 000000000000..b52db4f680f4
--- /dev/null
+++ b/scripts/kconfig/tests/err_transitional/expected_stderr
@@ -0,0 +1,7 @@
+Kconfig:46:warning: config symbol defined without type
+Kconfig:7: error: transitional symbols can only have help sections
+Kconfig:14: error: transitional symbols can only have help sections
+Kconfig:21: error: transitional symbols can only have help sections
+Kconfig:28: error: transitional symbols can only have help sections
+Kconfig:32: error: transitional symbols can only have help sections
+Kconfig:42: error: transitional symbols can only have help sections
diff --git a/scripts/kconfig/tests/transitional/Kconfig b/scripts/kconfig/tests/transitional/Kconfig
new file mode 100644
index 000000000000..62c3b24665b9
--- /dev/null
+++ b/scripts/kconfig/tests/transitional/Kconfig
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: GPL-2.0
+# Test transitional symbols for config migration with all Kconfig types
+
+# Enable module support for tristate testing
+config MODULES
+ bool "Enable loadable module support"
+ modules
+ default y
+
+# Basic migration tests for all types
+config NEW_BOOL
+ bool "New bool option"
+ default OLD_BOOL
+
+config OLD_BOOL
+ bool
+ transitional
+
+config NEW_TRISTATE
+ tristate "New tristate option"
+ default OLD_TRISTATE
+
+config OLD_TRISTATE
+ tristate
+ transitional
+
+config NEW_STRING
+ string "New string option"
+ default OLD_STRING
+
+config OLD_STRING
+ string
+ transitional
+
+config NEW_HEX
+ hex "New hex option"
+ default OLD_HEX
+
+config OLD_HEX
+ hex
+ transitional
+
+config NEW_INT
+ int "New int option"
+ default OLD_INT
+
+config OLD_INT
+ int
+ transitional
+
+# Precedence tests for all types
+config NEW_BOOL_PRECEDENCE
+ bool "New bool option with precedence"
+ default OLD_BOOL_PRECEDENCE
+
+config OLD_BOOL_PRECEDENCE
+ bool
+ transitional
+
+config NEW_STRING_PRECEDENCE
+ string "New string option with precedence"
+ default OLD_STRING_PRECEDENCE
+
+config OLD_STRING_PRECEDENCE
+ string
+ transitional
+
+config NEW_TRISTATE_PRECEDENCE
+ tristate "New tristate option with precedence"
+ default OLD_TRISTATE_PRECEDENCE
+
+config OLD_TRISTATE_PRECEDENCE
+ tristate
+ transitional
+
+config NEW_HEX_PRECEDENCE
+ hex "New hex option with precedence"
+ default OLD_HEX_PRECEDENCE
+
+config OLD_HEX_PRECEDENCE
+ hex
+ transitional
+
+config NEW_INT_PRECEDENCE
+ int "New int option with precedence"
+ default OLD_INT_PRECEDENCE
+
+config OLD_INT_PRECEDENCE
+ int
+ transitional
+
+# Test that help sections are allowed for transitional symbols
+config OLD_WITH_HELP
+ bool
+ transitional
+ help
+ This transitional symbol has a help section to validate that help is allowed.
+
+config REGULAR_OPTION
+ bool "Regular option"
diff --git a/scripts/kconfig/tests/transitional/__init__.py b/scripts/kconfig/tests/transitional/__init__.py
new file mode 100644
index 000000000000..61937d10edf1
--- /dev/null
+++ b/scripts/kconfig/tests/transitional/__init__.py
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Test transitional symbol migration functionality for all Kconfig types.
+
+This tests that:
+- OLD_* options in existing .config cause NEW_* options to be set
+- OLD_* options are not written to the new .config file
+- NEW_* options appear in the new .config file with correct values
+- All Kconfig types work correctly: bool, tristate, string, hex, int
+- User-set NEW values take precedence over conflicting OLD transitional values
+"""
+
+def test(conf):
+ # Run olddefconfig to process the migration with the initial config
+ assert conf.olddefconfig(dot_config='initial_config') == 0
+
+ # Check that the configuration matches expected output
+ assert conf.config_contains('expected_config')
diff --git a/scripts/kconfig/tests/transitional/expected_config b/scripts/kconfig/tests/transitional/expected_config
new file mode 100644
index 000000000000..846e9ddcab91
--- /dev/null
+++ b/scripts/kconfig/tests/transitional/expected_config
@@ -0,0 +1,12 @@
+CONFIG_MODULES=y
+CONFIG_NEW_BOOL=y
+CONFIG_NEW_TRISTATE=m
+CONFIG_NEW_STRING="test string"
+CONFIG_NEW_HEX=0x1234
+CONFIG_NEW_INT=42
+# CONFIG_NEW_BOOL_PRECEDENCE is not set
+CONFIG_NEW_STRING_PRECEDENCE="user value"
+CONFIG_NEW_TRISTATE_PRECEDENCE=y
+CONFIG_NEW_HEX_PRECEDENCE=0xABCD
+CONFIG_NEW_INT_PRECEDENCE=100
+# CONFIG_REGULAR_OPTION is not set
diff --git a/scripts/kconfig/tests/transitional/initial_config b/scripts/kconfig/tests/transitional/initial_config
new file mode 100644
index 000000000000..e648a65e504c
--- /dev/null
+++ b/scripts/kconfig/tests/transitional/initial_config
@@ -0,0 +1,16 @@
+CONFIG_MODULES=y
+CONFIG_OLD_BOOL=y
+CONFIG_OLD_TRISTATE=m
+CONFIG_OLD_STRING="test string"
+CONFIG_OLD_HEX=0x1234
+CONFIG_OLD_INT=42
+# CONFIG_NEW_BOOL_PRECEDENCE is not set
+CONFIG_OLD_BOOL_PRECEDENCE=y
+CONFIG_NEW_STRING_PRECEDENCE="user value"
+CONFIG_OLD_STRING_PRECEDENCE="old value"
+CONFIG_NEW_TRISTATE_PRECEDENCE=y
+CONFIG_OLD_TRISTATE_PRECEDENCE=m
+CONFIG_NEW_HEX_PRECEDENCE=0xABCD
+CONFIG_OLD_HEX_PRECEDENCE=0x5678
+CONFIG_NEW_INT_PRECEDENCE=100
+CONFIG_OLD_INT_PRECEDENCE=200
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 51367c2bfc21..433849ff7529 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -73,10 +73,7 @@ vmlinux_link()
objs="${objs} .builtin-dtbs.o"
fi
- if is_enabled CONFIG_MODULES; then
- objs="${objs} .vmlinux.export.o"
- fi
-
+ objs="${objs} .vmlinux.export.o"
objs="${objs} init/version-timestamp.o"
if [ "${SRCARCH}" = "um" ]; then
diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh
index 0d223b4a9445..99b5575c1ef7 100755
--- a/scripts/min-tool-version.sh
+++ b/scripts/min-tool-version.sh
@@ -24,12 +24,10 @@ gcc)
fi
;;
llvm)
- if [ "$SRCARCH" = s390 -o "$SRCARCH" = x86 ]; then
- echo 15.0.0
- elif [ "$SRCARCH" = loongarch ]; then
+ if [ "$SRCARCH" = loongarch ]; then
echo 18.0.0
else
- echo 13.0.1
+ echo 15.0.0
fi
;;
rustc)
diff --git a/scripts/misc-check b/scripts/misc-check
index 84f08da17b2c..40e5a4b01ff4 100755
--- a/scripts/misc-check
+++ b/scripts/misc-check
@@ -45,7 +45,7 @@ check_tracked_ignored_files () {
# does not automatically fix it.
check_missing_include_linux_export_h () {
- git -C "${srctree:-.}" grep --files-with-matches -E 'EXPORT_SYMBOL((_NS)?(_GPL)?|_GPL_FOR_MODULES)\(.*\)' \
+ git -C "${srctree:-.}" grep --files-with-matches -E 'EXPORT_SYMBOL((_NS)?(_GPL)?|_FOR_MODULES)\(.*\)' \
-- '*.[ch]' :^tools/ :^include/linux/export.h |
xargs -r git -C "${srctree:-.}" grep --files-without-match '#include[[:space:]]*<linux/export\.h>' |
xargs -r printf "%s: warning: EXPORT_SYMBOL() is used, but #include <linux/export.h> is missing\n" >&2
@@ -58,7 +58,7 @@ check_unnecessary_include_linux_export_h () {
git -C "${srctree:-.}" grep --files-with-matches '#include[[:space:]]*<linux/export\.h>' \
-- '*.[c]' :^tools/ |
- xargs -r git -C "${srctree:-.}" grep --files-without-match -E 'EXPORT_SYMBOL((_NS)?(_GPL)?|_GPL_FOR_MODULES)\(.*\)' |
+ xargs -r git -C "${srctree:-.}" grep --files-without-match -E 'EXPORT_SYMBOL((_NS)?(_GPL)?|_FOR_MODULES)\(.*\)' |
xargs -r printf "%s: warning: EXPORT_SYMBOL() is not used, but #include <linux/export.h> is present\n" >&2
}
diff --git a/scripts/mksysmap b/scripts/mksysmap
index 3accbdb269ac..c4531eacde20 100755
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -59,6 +59,9 @@
# EXPORT_SYMBOL (namespace)
/ __kstrtabns_/d
+# MODULE_DEVICE_TABLE (symbol name)
+/ __mod_device_table__/d
+
# ---------------------------------------------------------------------------
# Ignored suffixes
# (do not forget '$' after each pattern)
@@ -79,6 +82,9 @@
/ _SDA_BASE_$/d
/ _SDA2_BASE_$/d
+# MODULE_INFO()
+/ __UNIQUE_ID_modinfo[0-9]*$/d
+
# ---------------------------------------------------------------------------
# Ignored patterns
# (symbols that contain the pattern are ignored)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 00586119a25b..b3333560b95e 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -94,6 +94,7 @@ module_alias_printf(struct module *mod, bool append_wildcard,
}
}
+ new->builtin_modname = NULL;
list_add_tail(&new->node, &mod->aliases);
}
@@ -1476,8 +1477,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
{
void *symval;
char *zeros = NULL;
- const char *type, *name;
- size_t typelen;
+ const char *type, *name, *modname;
+ size_t typelen, modnamelen;
static const char *prefix = "__mod_device_table__";
/* We're looking for a section relative symbol */
@@ -1488,10 +1489,20 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
return;
- /* All our symbols are of form __mod_device_table__<type>__<name>. */
+ /* All our symbols are of form __mod_device_table__kmod_<modname>__<type>__<name>. */
if (!strstarts(symname, prefix))
return;
- type = symname + strlen(prefix);
+
+ modname = strstr(symname, "__kmod_");
+ if (!modname)
+ return;
+ modname += strlen("__kmod_");
+
+ type = strstr(modname, "__");
+ if (!type)
+ return;
+ modnamelen = type - modname;
+ type += strlen("__");
name = strstr(type, "__");
if (!name)
@@ -1517,5 +1528,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
}
}
+ if (mod->is_vmlinux) {
+ struct module_alias *alias;
+
+ /*
+ * If this is vmlinux, record the name of the builtin module.
+ * Traverse the linked list in the reverse order, and set the
+ * builtin_modname unless it has already been set in the
+ * previous call.
+ */
+ list_for_each_entry_reverse(alias, &mod->aliases, node) {
+ if (alias->builtin_modname)
+ break;
+ alias->builtin_modname = xstrndup(modname, modnamelen);
+ }
+ }
+
free(zeros);
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 5ca7c268294e..47c8aa2a6939 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, const char *fname)
static void write_vmlinux_export_c_file(struct module *mod)
{
struct buffer buf = { };
+ struct module_alias *alias, *next;
buf_printf(&buf,
"#include <linux/export-internal.h>\n");
add_exported_symbols(&buf, mod);
+
+ buf_printf(&buf,
+ "#include <linux/module.h>\n"
+ "#undef __MODULE_INFO_PREFIX\n"
+ "#define __MODULE_INFO_PREFIX\n");
+
+ list_for_each_entry_safe(alias, next, &mod->aliases, node) {
+ buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n",
+ alias->builtin_modname, alias->str);
+ list_del(&alias->node);
+ free(alias->builtin_modname);
+ free(alias);
+ }
+
write_if_changed(&buf, ".vmlinux.export.c");
free(buf.p);
}
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 9133e4c3803f..2aecb8f25c87 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len);
* struct module_alias - auto-generated MODULE_ALIAS()
*
* @node: linked to module::aliases
+ * @modname: name of the builtin module (only for vmlinux)
* @str: a string for MODULE_ALIAS()
*/
struct module_alias {
struct list_head node;
+ char *builtin_modname;
char str[];
};
diff --git a/scripts/rustdoc_test_gen.rs b/scripts/rustdoc_test_gen.rs
index abb34ada2508..c8f9dc2ab976 100644
--- a/scripts/rustdoc_test_gen.rs
+++ b/scripts/rustdoc_test_gen.rs
@@ -202,7 +202,7 @@ pub extern "C" fn {kunit_name}(__kunit_test: *mut ::kernel::bindings::kunit) {{
// This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may
// be used for the proposed KUnit test attributes API. Thus hopefully this will make migration
// easier later on.
- ::kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n"));
+ ::kernel::kunit::info(fmt!(" # {kunit_name}.location: {real_path}:{line}\n"));
/// The anchor where the test code body starts.
#[allow(unused)]