From 98051ba2b28be8a8ec5e22c01f464cff2d6d5f7c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 29 Jul 2019 22:38:45 -0700 Subject: coccinelle: Add script to check for platform_get_irq() excessive prints Add a coccinelle script to check for the usage of dev_err() after a call to platform_get_irq{,_byname}() as it's redundant now that the function already prints an error when it fails. Cc: Greg Kroah-Hartman Cc: Rob Herring Cc: Bartlomiej Zolnierkiewicz Cc: Javier Martinez Canillas Cc: Andrzej Hajda Cc: Mark Brown Cc: Russell King - ARM Linux Cc: Marek Szyprowski Cc: Rafael J. Wysocki Cc: Andy Shevchenko Cc: Markus Elfring Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20190730053845.126834-4-swboyd@chromium.org Signed-off-by: Greg Kroah-Hartman --- scripts/coccinelle/api/platform_get_irq.cocci | 102 ++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 scripts/coccinelle/api/platform_get_irq.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/platform_get_irq.cocci b/scripts/coccinelle/api/platform_get_irq.cocci new file mode 100644 index 000000000000..f6e1afc08c0b --- /dev/null +++ b/scripts/coccinelle/api/platform_get_irq.cocci @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 +/// Remove dev_err() messages after platform_get_irq*() failures +// +// Confidence: Medium +// Options: --include-headers + +virtual patch +virtual context +virtual org +virtual report + +@depends on context@ +expression ret; +struct platform_device *E; +@@ + +ret = +( +platform_get_irq +| +platform_get_irq_byname +)(E, ...); + +if ( ret \( < \| <= \) 0 ) +{ +( +if (ret != -EPROBE_DEFER) +{ ... +*dev_err(...); +... } +| +... +*dev_err(...); +) +... +} + +@depends on patch@ +expression ret; +struct platform_device *E; +@@ + +ret = +( +platform_get_irq +| +platform_get_irq_byname +)(E, ...); + +if ( ret \( < \| <= \) 0 ) +{ +( +-if (ret != -EPROBE_DEFER) +-{ ... +-dev_err(...); +-... } +| +... +-dev_err(...); +) +... +} + +@r depends on org || report@ +position p1; +expression ret; +struct platform_device *E; +@@ + +ret = +( +platform_get_irq +| +platform_get_irq_byname +)(E, ...); + +if ( ret \( < \| <= \) 0 ) +{ +( +if (ret != -EPROBE_DEFER) +{ ... +dev_err@p1(...); +... } +| +... +dev_err@p1(...); +) +... +} + +@script:python depends on org@ +p1 << r.p1; +@@ + +cocci.print_main(p1) + +@script:python depends on report@ +p1 << r.p1; +@@ + +msg = "line %s is redundant because platform_get_irq() already prints an error" % (p1[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From ef349abd91c1b37f87639170bcd9d11fe3ac58ff Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Thu, 25 Jul 2019 11:17:04 +0100 Subject: coccinelle: api/atomic_as_refcounter: add SPDX License Identifier Add the missing GPLv2 SPDX license identifier. It appears this single file was missing from 7f904d7e1f3e ("treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 505"), which addressed all other files in scripts/coccinelle. Hence I added GPL-2.0-only consitently with the mentioned patch. Cc: linux-spdx@vger.kernel.org Cc: Elena Reshetova Signed-off-by: Matthias Maennich Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- scripts/coccinelle/api/atomic_as_refcounter.cocci | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/coccinelle/api/atomic_as_refcounter.cocci b/scripts/coccinelle/api/atomic_as_refcounter.cocci index 988120e0fd67..0f78d94abc35 100644 --- a/scripts/coccinelle/api/atomic_as_refcounter.cocci +++ b/scripts/coccinelle/api/atomic_as_refcounter.cocci @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only // Check if refcount_t type and API should be used // instead of atomic_t type when dealing with refcounters // -- cgit v1.2.3 From 60f2c82ed20bde57c362e66f796cf9e0e38a6dbb Mon Sep 17 00:00:00 2001 From: Joonwon Kang Date: Sun, 28 Jul 2019 00:58:41 +0900 Subject: randstruct: Check member structs in is_pure_ops_struct() While no uses in the kernel triggered this case, it was possible to have a false negative where a struct contains other structs which contain only function pointers because of unreachable code in is_pure_ops_struct(). Signed-off-by: Joonwon Kang Link: https://lore.kernel.org/r/20190727155841.GA13586@host Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook --- scripts/gcc-plugins/randomize_layout_plugin.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index 6d5bbd31db7f..bd29e4e7a524 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -443,13 +443,13 @@ static int is_pure_ops_struct(const_tree node) if (node == fieldtype) continue; - if (!is_fptr(fieldtype)) - return 0; - - if (code != RECORD_TYPE && code != UNION_TYPE) + if (code == RECORD_TYPE || code == UNION_TYPE) { + if (!is_pure_ops_struct(fieldtype)) + return 0; continue; + } - if (!is_pure_ops_struct(fieldtype)) + if (!is_fptr(fieldtype)) return 0; } -- cgit v1.2.3 From 5cf896fb6be3effd9aea455b22213e27be8bdb1d Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 31 Jul 2019 18:18:42 -0700 Subject: arm64: Add support for relocating the kernel with RELR relocations RELR is a relocation packing format for relative relocations. The format is described in a generic-abi proposal: https://groups.google.com/d/topic/generic-abi/bX460iggiKg/discussion The LLD linker can be instructed to pack relocations in the RELR format by passing the flag --pack-dyn-relocs=relr. This patch adds a new config option, CONFIG_RELR. Enabling this option instructs the linker to pack vmlinux's relative relocations in the RELR format, and causes the kernel to apply the relocations at startup along with the RELA relocations. RELA relocations still need to be applied because the linker will emit RELA relative relocations if they are unrepresentable in the RELR format (i.e. address not a multiple of 2). Enabling CONFIG_RELR reduces the size of a defconfig kernel image with CONFIG_RANDOMIZE_BASE by 3.5MB/16% uncompressed, or 550KB/5% compressed (lz4). Signed-off-by: Peter Collingbourne Tested-by: Nick Desaulniers Reviewed-by: Nick Desaulniers Signed-off-by: Will Deacon --- Makefile | 4 ++ arch/Kconfig | 14 ++++++ arch/arm64/Kconfig | 1 + arch/arm64/kernel/head.S | 96 ++++++++++++++++++++++++++++++++++++++--- arch/arm64/kernel/vmlinux.lds.S | 9 ++++ init/Kconfig | 3 ++ scripts/tools-support-relr.sh | 16 +++++++ 7 files changed, 137 insertions(+), 6 deletions(-) create mode 100755 scripts/tools-support-relr.sh (limited to 'scripts') diff --git a/Makefile b/Makefile index 23cdf1f41364..9e6ec0c9962c 100644 --- a/Makefile +++ b/Makefile @@ -912,6 +912,10 @@ ifeq ($(CONFIG_STRIP_ASM_SYMS),y) LDFLAGS_vmlinux += $(call ld-option, -X,) endif +ifeq ($(CONFIG_RELR),y) +LDFLAGS_vmlinux += --pack-dyn-relocs=relr +endif + # insure the checker run with the right endianness CHECKFLAGS += $(if $(CONFIG_CPU_BIG_ENDIAN),-mbig-endian,-mlittle-endian) diff --git a/arch/Kconfig b/arch/Kconfig index a7b57dd42c26..aa6bdb3df5c1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -925,6 +925,20 @@ config LOCK_EVENT_COUNTS the chance of application behavior change because of timing differences. The counts are reported via debugfs. +# Select if the architecture has support for applying RELR relocations. +config ARCH_HAS_RELR + bool + +config RELR + bool "Use RELR relocation packing" + depends on ARCH_HAS_RELR && TOOLS_SUPPORT_RELR + default y + help + Store the kernel's dynamic relocations in the RELR relocation packing + format. Requires a compatible linker (LLD supports this feature), as + well as compatible NM and OBJCOPY utilities (llvm-nm and llvm-objcopy + are compatible). + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3adcec05b1f6..2681eb79c40b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1467,6 +1467,7 @@ endif config RELOCATABLE bool + select ARCH_HAS_RELR help This builds the kernel as a Position Independent Executable (PIE), which retains all relocation metadata required to relocate the diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 2cdacd1c141b..cc23302e9d95 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -102,6 +102,8 @@ pe_header: * x23 stext() .. start_kernel() physical misalignment/KASLR offset * x28 __create_page_tables() callee preserved temp register * x19/x20 __primary_switch() callee preserved temp registers + * x24 __primary_switch() .. relocate_kernel() + * current RELR displacement */ ENTRY(stext) bl preserve_boot_args @@ -834,14 +836,93 @@ __relocate_kernel: 0: cmp x9, x10 b.hs 1f - ldp x11, x12, [x9], #24 - ldr x13, [x9, #-8] - cmp w12, #R_AARCH64_RELATIVE + ldp x12, x13, [x9], #24 + ldr x14, [x9, #-8] + cmp w13, #R_AARCH64_RELATIVE b.ne 0b - add x13, x13, x23 // relocate - str x13, [x11, x23] + add x14, x14, x23 // relocate + str x14, [x12, x23] b 0b -1: ret + +1: +#ifdef CONFIG_RELR + /* + * Apply RELR relocations. + * + * RELR is a compressed format for storing relative relocations. The + * encoded sequence of entries looks like: + * [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] + * + * i.e. start with an address, followed by any number of bitmaps. The + * address entry encodes 1 relocation. The subsequent bitmap entries + * encode up to 63 relocations each, at subsequent offsets following + * the last address entry. + * + * The bitmap entries must have 1 in the least significant bit. The + * assumption here is that an address cannot have 1 in lsb. Odd + * addresses are not supported. Any odd addresses are stored in the RELA + * section, which is handled above. + * + * Excluding the least significant bit in the bitmap, each non-zero + * bit in the bitmap represents a relocation to be applied to + * a corresponding machine word that follows the base address + * word. The second least significant bit represents the machine + * word immediately following the initial address, and each bit + * that follows represents the next word, in linear order. As such, + * a single bitmap can encode up to 63 relocations in a 64-bit object. + * + * In this implementation we store the address of the next RELR table + * entry in x9, the address being relocated by the current address or + * bitmap entry in x13 and the address being relocated by the current + * bit in x14. + * + * Because addends are stored in place in the binary, RELR relocations + * cannot be applied idempotently. We use x24 to keep track of the + * currently applied displacement so that we can correctly relocate if + * __relocate_kernel is called twice with non-zero displacements (i.e. + * if there is both a physical misalignment and a KASLR displacement). + */ + ldr w9, =__relr_offset // offset to reloc table + ldr w10, =__relr_size // size of reloc table + add x9, x9, x11 // __va(.relr) + add x10, x9, x10 // __va(.relr) + sizeof(.relr) + + sub x15, x23, x24 // delta from previous offset + cbz x15, 7f // nothing to do if unchanged + mov x24, x23 // save new offset + +2: cmp x9, x10 + b.hs 7f + ldr x11, [x9], #8 + tbnz x11, #0, 3f // branch to handle bitmaps + add x13, x11, x23 + ldr x12, [x13] // relocate address entry + add x12, x12, x15 + str x12, [x13], #8 // adjust to start of bitmap + b 2b + +3: mov x14, x13 +4: lsr x11, x11, #1 + cbz x11, 6f + tbz x11, #0, 5f // skip bit if not set + ldr x12, [x14] // relocate bit + add x12, x12, x15 + str x12, [x14] + +5: add x14, x14, #8 // move to next bit's address + b 4b + +6: /* + * Move to the next bitmap's address. 8 is the word size, and 63 is the + * number of significant bits in a bitmap entry. + */ + add x13, x13, #(8 * 63) + b 2b + +7: +#endif + ret + ENDPROC(__relocate_kernel) #endif @@ -854,6 +935,9 @@ __primary_switch: adrp x1, init_pg_dir bl __enable_mmu #ifdef CONFIG_RELOCATABLE +#ifdef CONFIG_RELR + mov x24, #0 // no RELR displacement yet +#endif bl __relocate_kernel #ifdef CONFIG_RANDOMIZE_BASE ldr x8, =__primary_switched diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 7fa008374907..31716afa30f6 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -200,6 +200,15 @@ SECTIONS __rela_offset = ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR); __rela_size = SIZEOF(.rela.dyn); +#ifdef CONFIG_RELR + .relr.dyn : ALIGN(8) { + *(.relr.dyn) + } + + __relr_offset = ABSOLUTE(ADDR(.relr.dyn) - KIMAGE_VADDR); + __relr_size = SIZEOF(.relr.dyn); +#endif + . = ALIGN(SEGMENT_ALIGN); __initdata_end = .; __init_end = .; diff --git a/init/Kconfig b/init/Kconfig index bd7d650d4a99..d96127ebc44e 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -30,6 +30,9 @@ config CC_CAN_LINK config CC_HAS_ASM_GOTO def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC)) +config TOOLS_SUPPORT_RELR + def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh) + config CC_HAS_WARN_MAYBE_UNINITIALIZED def_bool $(cc-option,-Wmaybe-uninitialized) help diff --git a/scripts/tools-support-relr.sh b/scripts/tools-support-relr.sh new file mode 100755 index 000000000000..97a2c844a95e --- /dev/null +++ b/scripts/tools-support-relr.sh @@ -0,0 +1,16 @@ +#!/bin/sh -eu +# SPDX-License-Identifier: GPL-2.0 + +tmp_file=$(mktemp) +trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT + +cat << "END" | "$CC" -c -x c - -o $tmp_file.o >/dev/null 2>&1 +void *p = &p; +END +"$LD" $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr -o $tmp_file + +# Despite printing an error message, GNU nm still exits with exit code 0 if it +# sees a relr section. So we need to check that nothing is printed to stderr. +test -z "$("$NM" $tmp_file 2>&1 >/dev/null)" + +"$OBJCOPY" -O binary $tmp_file $tmp_file.bin -- cgit v1.2.3 From c8424e776b093280d3fdd104d850706b3b229ac8 Mon Sep 17 00:00:00 2001 From: Thiago Jung Bauermann Date: Thu, 4 Jul 2019 15:57:34 -0300 Subject: MODSIGN: Export module signature definitions IMA will use the module_signature format for append signatures, so export the relevant definitions and factor out the code which verifies that the appended signature trailer is valid. Also, create a CONFIG_MODULE_SIG_FORMAT option so that IMA can select it and be able to use mod_check_sig() without having to depend on either CONFIG_MODULE_SIG or CONFIG_MODULES. s390 duplicated the definition of struct module_signature so now they can use the new header instead. Signed-off-by: Thiago Jung Bauermann Acked-by: Jessica Yu Reviewed-by: Philipp Rudo Cc: Heiko Carstens Signed-off-by: Mimi Zohar --- arch/s390/Kconfig | 2 +- arch/s390/kernel/machine_kexec_file.c | 24 +-------------- include/linux/module.h | 3 -- include/linux/module_signature.h | 44 +++++++++++++++++++++++++++ init/Kconfig | 6 +++- kernel/Makefile | 1 + kernel/module.c | 1 + kernel/module_signature.c | 46 ++++++++++++++++++++++++++++ kernel/module_signing.c | 56 +++++------------------------------ scripts/Makefile | 2 +- 10 files changed, 108 insertions(+), 77 deletions(-) create mode 100644 include/linux/module_signature.h create mode 100644 kernel/module_signature.c (limited to 'scripts') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a4ad2733eedf..e0ae0d51f985 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -538,7 +538,7 @@ config ARCH_HAS_KEXEC_PURGATORY config KEXEC_VERIFY_SIG bool "Verify kernel signature during kexec_file_load() syscall" - depends on KEXEC_FILE && SYSTEM_DATA_VERIFICATION + depends on KEXEC_FILE && MODULE_SIG_FORMAT help This option makes kernel signature verification mandatory for the kexec_file_load() syscall. diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index fbdd3ea73667..1ac9fbc6e01e 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -23,28 +23,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = { }; #ifdef CONFIG_KEXEC_VERIFY_SIG -/* - * Module signature information block. - * - * The constituents of the signature section are, in order: - * - * - Signer's name - * - Key identifier - * - Signature data - * - Information block - */ -struct module_signature { - u8 algo; /* Public-key crypto algorithm [0] */ - u8 hash; /* Digest algorithm [0] */ - u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ - u8 signer_len; /* Length of signer's name [0] */ - u8 key_id_len; /* Length of key identifier [0] */ - u8 __pad[3]; - __be32 sig_len; /* Length of signature data */ -}; - -#define PKEY_ID_PKCS7 2 - int s390_verify_sig(const char *kernel, unsigned long kernel_len) { const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; diff --git a/include/linux/module.h b/include/linux/module.h index 1455812dd325..f6fc1dae74f4 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -26,9 +26,6 @@ #include #include -/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ -#define MODULE_SIG_STRING "~Module signature appended~\n" - /* Not Yet Implemented */ #define MODULE_SUPPORTED_DEVICE(name) diff --git a/include/linux/module_signature.h b/include/linux/module_signature.h new file mode 100644 index 000000000000..523617fc5b6a --- /dev/null +++ b/include/linux/module_signature.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Module signature handling. + * + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#ifndef _LINUX_MODULE_SIGNATURE_H +#define _LINUX_MODULE_SIGNATURE_H + +/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ +#define MODULE_SIG_STRING "~Module signature appended~\n" + +enum pkey_id_type { + PKEY_ID_PGP, /* OpenPGP generated key ID */ + PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ + PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ +}; + +/* + * Module signature information block. + * + * The constituents of the signature section are, in order: + * + * - Signer's name + * - Key identifier + * - Signature data + * - Information block + */ +struct module_signature { + u8 algo; /* Public-key crypto algorithm [0] */ + u8 hash; /* Digest algorithm [0] */ + u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ + u8 signer_len; /* Length of signer's name [0] */ + u8 key_id_len; /* Length of key identifier [0] */ + u8 __pad[3]; + __be32 sig_len; /* Length of signature data */ +}; + +int mod_check_sig(const struct module_signature *ms, size_t file_len, + const char *name); + +#endif /* _LINUX_MODULE_SIGNATURE_H */ diff --git a/init/Kconfig b/init/Kconfig index bd7d650d4a99..2dca877c9ed7 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1930,6 +1930,10 @@ config BASE_SMALL default 0 if BASE_FULL default 1 if !BASE_FULL +config MODULE_SIG_FORMAT + def_bool n + select SYSTEM_DATA_VERIFICATION + menuconfig MODULES bool "Enable loadable module support" option modules @@ -2007,7 +2011,7 @@ config MODULE_SRCVERSION_ALL config MODULE_SIG bool "Module signature verification" depends on MODULES - select SYSTEM_DATA_VERIFICATION + select MODULE_SIG_FORMAT help Check modules for valid signatures upon load: the signature is simply appended to the module. For more information see diff --git a/kernel/Makefile b/kernel/Makefile index a8d923b5481b..179b44ab8b46 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -58,6 +58,7 @@ endif obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULE_SIG) += module_signing.o +obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_CRASH_CORE) += crash_core.o diff --git a/kernel/module.c b/kernel/module.c index 5933395af9a0..5ac22efc3685 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/kernel/module_signature.c b/kernel/module_signature.c new file mode 100644 index 000000000000..4224a1086b7d --- /dev/null +++ b/kernel/module_signature.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Module signature checker + * + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#include +#include +#include +#include + +/** + * mod_check_sig - check that the given signature is sane + * + * @ms: Signature to check. + * @file_len: Size of the file to which @ms is appended. + * @name: What is being checked. Used for error messages. + */ +int mod_check_sig(const struct module_signature *ms, size_t file_len, + const char *name) +{ + if (be32_to_cpu(ms->sig_len) >= file_len - sizeof(*ms)) + return -EBADMSG; + + if (ms->id_type != PKEY_ID_PKCS7) { + pr_err("%s: Module is not signed with expected PKCS#7 message\n", + name); + return -ENOPKG; + } + + if (ms->algo != 0 || + ms->hash != 0 || + ms->signer_len != 0 || + ms->key_id_len != 0 || + ms->__pad[0] != 0 || + ms->__pad[1] != 0 || + ms->__pad[2] != 0) { + pr_err("%s: PKCS#7 signature info has unexpected non-zero params\n", + name); + return -EBADMSG; + } + + return 0; +} diff --git a/kernel/module_signing.c b/kernel/module_signing.c index b10fb1986ca9..9d9fc678c91d 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -7,37 +7,13 @@ #include #include +#include +#include #include #include #include #include "module-internal.h" -enum pkey_id_type { - PKEY_ID_PGP, /* OpenPGP generated key ID */ - PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ - PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ -}; - -/* - * Module signature information block. - * - * The constituents of the signature section are, in order: - * - * - Signer's name - * - Key identifier - * - Signature data - * - Information block - */ -struct module_signature { - u8 algo; /* Public-key crypto algorithm [0] */ - u8 hash; /* Digest algorithm [0] */ - u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */ - u8 signer_len; /* Length of signer's name [0] */ - u8 key_id_len; /* Length of key identifier [0] */ - u8 __pad[3]; - __be32 sig_len; /* Length of signature data */ -}; - /* * Verify the signature on a module. */ @@ -45,6 +21,7 @@ int mod_verify_sig(const void *mod, struct load_info *info) { struct module_signature ms; size_t sig_len, modlen = info->len; + int ret; pr_devel("==>%s(,%zu)\n", __func__, modlen); @@ -52,32 +29,15 @@ int mod_verify_sig(const void *mod, struct load_info *info) return -EBADMSG; memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); - modlen -= sizeof(ms); + + ret = mod_check_sig(&ms, modlen, info->name); + if (ret) + return ret; sig_len = be32_to_cpu(ms.sig_len); - if (sig_len >= modlen) - return -EBADMSG; - modlen -= sig_len; + modlen -= sig_len + sizeof(ms); info->len = modlen; - if (ms.id_type != PKEY_ID_PKCS7) { - pr_err("%s: Module is not signed with expected PKCS#7 message\n", - info->name); - return -ENOPKG; - } - - if (ms.algo != 0 || - ms.hash != 0 || - ms.signer_len != 0 || - ms.key_id_len != 0 || - ms.__pad[0] != 0 || - ms.__pad[1] != 0 || - ms.__pad[2] != 0) { - pr_err("%s: PKCS#7 signature info has unexpected non-zero params\n", - info->name); - return -EBADMSG; - } - return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, VERIFY_USE_SECONDARY_KEYRING, VERIFYING_MODULE_SIGNATURE, diff --git a/scripts/Makefile b/scripts/Makefile index 16bcb8087899..532f7e0915c3 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -17,7 +17,7 @@ hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable hostprogs-$(CONFIG_ASN1) += asn1_compiler -hostprogs-$(CONFIG_MODULE_SIG) += sign-file +hostprogs-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert -- cgit v1.2.3 From 95e760cbf62755bd3d8999bee1e6579f0ff1425e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 5 Aug 2019 09:29:50 -0700 Subject: kernel-doc: ignore __printf attribute Ignore __printf() function attributes just as other __attribute__ strings are ignored. Fixes this kernel-doc warning message: include/kunit/kunit-stream.h:58: warning: Function parameter or member '2' not described in '__printf' Reported-by: kbuild test robot Signed-off-by: Randy Dunlap Cc: Brendan Higgins Tested-by: Brendan Higgins Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 6b03012750da..32e793ca5e95 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1580,6 +1580,7 @@ sub dump_function($$) { $prototype =~ s/__must_check +//; $prototype =~ s/__weak +//; $prototype =~ s/__sched +//; + $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; my $define = $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\( (?: -- cgit v1.2.3 From 15e2544ed38a1e39b702277bdcd2bb1275e78925 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 12 Aug 2019 19:06:31 +0300 Subject: kernel-doc: Allow anonymous enum In C is a valid construction to have an anonymous enumerator. Though we have now: drivers/pinctrl/intel/pinctrl-intel.c:240: error: Cannot parse enum! Support it in the kernel-doc script. Signed-off-by: Andy Shevchenko Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 32e793ca5e95..81dc91760b23 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1245,7 +1245,7 @@ sub dump_enum($$) { # strip #define macros inside enums $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; - if ($x =~ /enum\s+(\w+)\s*\{(.*)\}/) { + if ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) { $declaration_name = $1; my $members = $2; my %_members; -- cgit v1.2.3 From 341dfcf8d78eaa3a2dc96dea06f0392eb2978364 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Mon, 12 Aug 2019 11:39:47 -0700 Subject: btf: expose BTF info through sysfs Make .BTF section allocated and expose its contents through sysfs. /sys/kernel/btf directory is created to contain all the BTFs present inside kernel. Currently there is only kernel's main BTF, represented as /sys/kernel/btf/kernel file. Once kernel modules' BTFs are supported, each module will expose its BTF as /sys/kernel/btf/ file. Current approach relies on a few pieces coming together: 1. pahole is used to take almost final vmlinux image (modulo .BTF and kallsyms) and generate .BTF section by converting DWARF info into BTF. This section is not allocated and not mapped to any segment, though, so is not yet accessible from inside kernel at runtime. 2. objcopy dumps .BTF contents into binary file and subsequently convert binary file into linkable object file with automatically generated symbols _binary__btf_kernel_bin_start and _binary__btf_kernel_bin_end, pointing to start and end, respectively, of BTF raw data. 3. final vmlinux image is generated by linking this object file (and kallsyms, if necessary). sysfs_btf.c then creates /sys/kernel/btf/kernel file and exposes embedded BTF contents through it. This allows, e.g., libbpf and bpftool access BTF info at well-known location, without resorting to searching for vmlinux image on disk (location of which is not standardized and vmlinux image might not be even available in some scenarios, e.g., inside qemu during testing). Alternative approach using .incbin assembler directive to embed BTF contents directly was attempted but didn't work, because sysfs_proc.o is not re-compiled during link-vmlinux.sh stage. This is required, though, to update embedded BTF data (initially empty data is embedded, then pahole generates BTF info and we need to regenerate sysfs_btf.o with updated contents, but it's too late at that point). If BTF couldn't be generated due to missing or too old pahole, sysfs_btf.c handles that gracefully by detecting that _binary__btf_kernel_bin_start (weak symbol) is 0 and not creating /sys/kernel/btf at all. v2->v3: - added Documentation/ABI/testing/sysfs-kernel-btf (Greg K-H); - created proper kobject (btf_kobj) for btf directory (Greg K-H); - undo v2 change of reusing vmlinux, as it causes extra kallsyms pass due to initially missing __binary__btf_kernel_bin_{start/end} symbols; v1->v2: - allow kallsyms stage to re-use vmlinux generated by gen_btf(); Reviewed-by: Greg Kroah-Hartman Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- Documentation/ABI/testing/sysfs-kernel-btf | 17 ++++++++++ kernel/bpf/Makefile | 3 ++ kernel/bpf/sysfs_btf.c | 51 +++++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 52 +++++++++++++++++++----------- 4 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-kernel-btf create mode 100644 kernel/bpf/sysfs_btf.c (limited to 'scripts') diff --git a/Documentation/ABI/testing/sysfs-kernel-btf b/Documentation/ABI/testing/sysfs-kernel-btf new file mode 100644 index 000000000000..5390f8001f96 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-btf @@ -0,0 +1,17 @@ +What: /sys/kernel/btf +Date: Aug 2019 +KernelVersion: 5.5 +Contact: bpf@vger.kernel.org +Description: + Contains BTF type information and related data for kernel and + kernel modules. + +What: /sys/kernel/btf/kernel +Date: Aug 2019 +KernelVersion: 5.5 +Contact: bpf@vger.kernel.org +Description: + Read-only binary attribute exposing kernel's own BTF type + information with description of all internal kernel types. See + Documentation/bpf/btf.rst for detailed description of format + itself. diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile index 29d781061cd5..e1d9adb212f9 100644 --- a/kernel/bpf/Makefile +++ b/kernel/bpf/Makefile @@ -22,3 +22,6 @@ obj-$(CONFIG_CGROUP_BPF) += cgroup.o ifeq ($(CONFIG_INET),y) obj-$(CONFIG_BPF_SYSCALL) += reuseport_array.o endif +ifeq ($(CONFIG_SYSFS),y) +obj-$(CONFIG_DEBUG_INFO_BTF) += sysfs_btf.o +endif diff --git a/kernel/bpf/sysfs_btf.c b/kernel/bpf/sysfs_btf.c new file mode 100644 index 000000000000..092e63b9758b --- /dev/null +++ b/kernel/bpf/sysfs_btf.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Provide kernel BTF information for introspection and use by eBPF tools. + */ +#include +#include +#include +#include +#include + +/* See scripts/link-vmlinux.sh, gen_btf() func for details */ +extern char __weak _binary__btf_kernel_bin_start[]; +extern char __weak _binary__btf_kernel_bin_end[]; + +static ssize_t +btf_kernel_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t len) +{ + memcpy(buf, _binary__btf_kernel_bin_start + off, len); + return len; +} + +static struct bin_attribute bin_attr_btf_kernel __ro_after_init = { + .attr = { .name = "kernel", .mode = 0444, }, + .read = btf_kernel_read, +}; + +static struct kobject *btf_kobj; + +static int __init btf_kernel_init(void) +{ + int err; + + if (!_binary__btf_kernel_bin_start) + return 0; + + btf_kobj = kobject_create_and_add("btf", kernel_kobj); + if (IS_ERR(btf_kobj)) { + err = PTR_ERR(btf_kobj); + btf_kobj = NULL; + return err; + } + + bin_attr_btf_kernel.size = _binary__btf_kernel_bin_end - + _binary__btf_kernel_bin_start; + + return sysfs_create_bin_file(btf_kobj, &bin_attr_btf_kernel); +} + +subsys_initcall(btf_kernel_init); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index a7124f895b24..cb93832c6ad7 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -56,8 +56,8 @@ modpost_link() } # Link of vmlinux -# ${1} - optional extra .o files -# ${2} - output file +# ${1} - output file +# ${@:2} - optional extra .o files vmlinux_link() { local lds="${objtree}/${KBUILD_LDS}" @@ -70,9 +70,9 @@ vmlinux_link() --start-group \ ${KBUILD_VMLINUX_LIBS} \ --end-group \ - ${1}" + ${@:2}" - ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ + ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${1} \ -T ${lds} ${objects} else objects="-Wl,--whole-archive \ @@ -81,9 +81,9 @@ vmlinux_link() -Wl,--start-group \ ${KBUILD_VMLINUX_LIBS} \ -Wl,--end-group \ - ${1}" + ${@:2}" - ${CC} ${CFLAGS_vmlinux} -o ${2} \ + ${CC} ${CFLAGS_vmlinux} -o ${1} \ -Wl,-T,${lds} \ ${objects} \ -lutil -lrt -lpthread @@ -92,23 +92,34 @@ vmlinux_link() } # generate .BTF typeinfo from DWARF debuginfo +# ${1} - vmlinux image +# ${2} - file to dump raw BTF data into gen_btf() { - local pahole_ver; + local pahole_ver + local bin_arch if ! [ -x "$(command -v ${PAHOLE})" ]; then info "BTF" "${1}: pahole (${PAHOLE}) is not available" - return 0 + return 1 fi pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/') if [ "${pahole_ver}" -lt "113" ]; then info "BTF" "${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13" - return 0 + return 1 fi - info "BTF" ${1} + info "BTF" ${2} + vmlinux_link ${1} LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} + + # dump .BTF section into raw binary file to link with final vmlinux + bin_arch=$(${OBJDUMP} -f ${1} | grep architecture | \ + cut -d, -f1 | cut -d' ' -f2) + ${OBJCOPY} --dump-section .BTF=.btf.kernel.bin ${1} 2>/dev/null + ${OBJCOPY} -I binary -O ${CONFIG_OUTPUT_FORMAT} -B ${bin_arch} \ + --rename-section .data=.BTF .btf.kernel.bin ${2} } # Create ${2} .o file with all symbols from the ${1} object file @@ -153,6 +164,7 @@ sortextable() # Delete output files in case of error cleanup() { + rm -f .btf.* rm -f .tmp_System.map rm -f .tmp_kallsyms* rm -f .tmp_vmlinux* @@ -215,6 +227,13 @@ ${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o info MODINFO modules.builtin.modinfo ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo +btf_kernel_bin_o="" +if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then + if gen_btf .tmp_vmlinux.btf .btf.kernel.bin.o ; then + btf_kernel_bin_o=.btf.kernel.bin.o + fi +fi + kallsymso="" kallsyms_vmlinux="" if [ -n "${CONFIG_KALLSYMS}" ]; then @@ -246,11 +265,11 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then kallsyms_vmlinux=.tmp_vmlinux2 # step 1 - vmlinux_link "" .tmp_vmlinux1 + vmlinux_link .tmp_vmlinux1 ${btf_kernel_bin_o} kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o # step 2 - vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 + vmlinux_link .tmp_vmlinux2 .tmp_kallsyms1.o ${btf_kernel_bin_o} kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o # step 3 @@ -261,18 +280,13 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then kallsymso=.tmp_kallsyms3.o kallsyms_vmlinux=.tmp_vmlinux3 - vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 - + vmlinux_link .tmp_vmlinux3 .tmp_kallsyms2.o ${btf_kernel_bin_o} kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o fi fi info LD vmlinux -vmlinux_link "${kallsymso}" vmlinux - -if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then - gen_btf vmlinux -fi +vmlinux_link vmlinux "${kallsymso}" "${btf_kernel_bin_o}" if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then info SORTEX vmlinux -- cgit v1.2.3 From 15bfc2348d549b44bdca266747f71c0d54bc0e5f Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Thu, 1 Aug 2019 09:06:57 +0300 Subject: modpost: check for static EXPORT_SYMBOL* functions This patch adds a check to warn about static EXPORT_SYMBOL* functions during the modpost. In most of the cases, a static symbol marked for exporting is an odd combination that should be fixed either by deleting the exporting mark or by removing the static attribute and adding the appropriate declaration to headers. This check could help to detect the following problems: 1. 550113d4e9f5 ("i2c: add newly exported functions to the header, too") 2. 54638c6eaf44 ("net: phy: make exported variables non-static") 3. 98ef2046f28b ("mm: remove the exporting of totalram_pages") 4. 73df167c819e ("s390/zcrypt: remove the exporting of ap_query_configuration") 5. a57caf8c527f ("sunrpc/cache: remove the exporting of cache_seq_next") 6. e4e4730698c9 ("crypto: skcipher - remove the exporting of skcipher_walk_next") 7. 14b4c48bb1ce ("gve: Remove the exporting of gve_probe") 8. 9b79ee9773a8 ("scsi: libsas: remove the exporting of sas_wait_eh") 9. ... The build time impact is very limited and is almost at the unnoticeable level (< 1 sec). Acked-by: Emil Velikov Signed-off-by: Denis Efremov Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f277e116e0eb..2773f9f9bae2 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -169,6 +169,7 @@ struct symbol { unsigned int kernel:1; /* 1 if symbol is from kernel * (only for external modules) **/ unsigned int preloaded:1; /* 1 if symbol from Module.symvers, or crc */ + unsigned int is_static:1; /* 1 if symbol is not global */ enum export export; /* Type of export */ char name[0]; }; @@ -201,6 +202,7 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, strcpy(s->name, name); s->weak = weak; s->next = next; + s->is_static = 1; return s; } @@ -1980,6 +1982,21 @@ static void read_symbols(const char *modname) handle_modversions(mod, &info, sym, symname); handle_moddevtable(mod, &info, sym, symname); } + + // check for static EXPORT_SYMBOL_* functions && global vars + for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { + unsigned char bind = ELF_ST_BIND(sym->st_info); + + if (bind == STB_GLOBAL || bind == STB_WEAK) { + struct symbol *s = + find_symbol(remove_dot(info.strtab + + sym->st_name)); + + if (s) + s->is_static = 0; + } + } + if (!is_vmlinux(modname) || vmlinux_section_warnings) check_sec_ref(mod, modname, &info); @@ -2369,6 +2386,7 @@ static void read_dump(const char *fname, unsigned int kernel) s = sym_add_exported(symname, mod, export_no(export)); s->kernel = kernel; s->preloaded = 1; + s->is_static = 0; sym_update_crc(symname, mod, crc, export_no(export)); } release_file(file, size); @@ -2425,6 +2443,7 @@ int main(int argc, char **argv) char *dump_write = NULL, *files_source = NULL; int opt; int err; + int n; struct ext_sym_list *extsym_iter; struct ext_sym_list *extsym_start = NULL; @@ -2520,6 +2539,19 @@ int main(int argc, char **argv) if (sec_mismatch_count && sec_mismatch_fatal) fatal("modpost: Section mismatches detected.\n" "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); + for (n = 0; n < SYMBOL_HASH_SIZE; n++) { + struct symbol *s = symbolhash[n]; + + while (s) { + if (s->is_static) + warn("\"%s\" [%s] is a static %s\n", + s->name, s->module->name, + export_str(s->export)); + + s = s->next; + } + } + free(buf.p); return err; -- cgit v1.2.3 From 75959d44f9dc8e44410667009724e4e238515502 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 16 Jul 2019 21:47:27 +0200 Subject: kbuild: Fail if gold linker is detected The gold linker has known issues of failing the build both in random and in predictible ways: - The x86/X32 VDSO build fails with: arch/x86/entry/vdso/vclock_gettime-x32.o:vclock_gettime.c:function do_hres: error: relocation overflow: reference to 'hvclock_page' That's a known issue for years and the usual workaround is to disable CONFIG_X86_32 - A recent build failure is caused by turning a relocation into an absolute one for unknown reasons. See link below. - There are a couple of gold workarounds applied already, but reports about broken builds with ld.gold keep coming in on a regular base and in most cases the root cause is unclear. In context of the most recent fail H.J. stated: "Since building a workable kernel for different kernel configurations isn't a requirement for gold, I don't recommend gold for kernel." So instead of dealing with attempts to duct tape gold support without understanding the root cause and without support from the gold folks, fail the build when gold is detected. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Acked-by: Ingo Molnar Link: https://lore.kernel.org/r/CAMe9rOqMqkQ0LNpm25yE_Yt0FKp05WmHOrwc0aRDb53miFKM+w@mail.gmail.com Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- scripts/Kconfig.include | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index 4bbf4fc163a2..d4adfbe42690 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -35,5 +35,8 @@ ld-option = $(success,$(LD) -v $(1)) $(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found) $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) +# Fail if the linker is gold as it's not capable of linking the kernel proper +$(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supported) + # gcc version including patch level gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) -- cgit v1.2.3 From 49d5089d926c2bf0c76410bf32e5c48b296ec6f6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 21 Jul 2019 01:27:38 +0900 Subject: kbuild: use $(basename ...) for cmd_asn1_compiler $(basename ...) trims the last suffix. Using it is more intuitive in my opinion. This pattern rule makes %.asn1.c and %.asn1.h at the same time. Previously, the short log showed only either of them, depending on the target file in question. To clarify that two files are being generated by the single recipe, I changed the log as follows: Before: ASN.1 crypto/asymmetric_keys/x509.asn1.c After: ASN.1 crypto/asymmetric_keys/x509.asn1.[ch] Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 2f66ed388d1c..edf84ede803c 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -395,9 +395,9 @@ $(obj)/%.lds: $(src)/%.lds.S FORCE # ASN.1 grammar # --------------------------------------------------------------------------- -quiet_cmd_asn1_compiler = ASN.1 $@ +quiet_cmd_asn1_compiler = ASN.1 $(basename $@).[ch] cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \ - $(subst .h,.c,$@) $(subst .c,.h,$@) + $(basename $@).c $(basename $@).h $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler $(call cmd,asn1_compiler) -- cgit v1.2.3 From 6ba7dc6616ce69ef667204df29597767c1c9ebcf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 21 Jul 2019 01:27:39 +0900 Subject: kbuild: make bison create C file and header in a single pattern rule We generally expect bison to create not only a C file, but also a header, which will be included from the lexer. Currently, Kbuild generates them in separate rules. So, for instance, when building Kconfig, you will notice bison is invoked twice: HOSTCC scripts/kconfig/conf.o HOSTCC scripts/kconfig/confdata.o HOSTCC scripts/kconfig/expr.o LEX scripts/kconfig/lexer.lex.c YACC scripts/kconfig/parser.tab.h HOSTCC scripts/kconfig/lexer.lex.o YACC scripts/kconfig/parser.tab.c HOSTCC scripts/kconfig/parser.tab.o HOSTCC scripts/kconfig/preprocess.o HOSTCC scripts/kconfig/symbol.o HOSTLD scripts/kconfig/conf Make handles such cases nicely in pattern rules [1]. Merge the two rules so that one invokcation of bison can generate both of them. HOSTCC scripts/kconfig/conf.o HOSTCC scripts/kconfig/confdata.o HOSTCC scripts/kconfig/expr.o LEX scripts/kconfig/lexer.lex.c YACC scripts/kconfig/parser.tab.[ch] HOSTCC scripts/kconfig/lexer.lex.o HOSTCC scripts/kconfig/parser.tab.o HOSTCC scripts/kconfig/preprocess.o HOSTCC scripts/kconfig/symbol.o HOSTLD scripts/kconfig/conf [1] Pattern rule GNU Make manual says: "Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and recipe. If a pattern rule has multiple targets, make knows that the rule's recipe is responsible for making all of the targets. The recipe is executed only once to make all the targets. When searching for a pattern rule to match a target, the target patterns of a rule other than the one that matches the target in need of a rule are incidental: make worries only about giving a recipe and prerequisites to the file presently in question. However, when this file's recipe is run, the other targets are marked as having been updated themselves." https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 12 +++--------- scripts/genksyms/Makefile | 9 +-------- 2 files changed, 4 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 41c50f9461e5..67d1165ab2ab 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -197,18 +197,12 @@ $(obj)/%.lex.c: $(src)/%.l FORCE # YACC # --------------------------------------------------------------------------- -quiet_cmd_bison = YACC $@ - cmd_bison = $(YACC) -o$@ -t -l $< +quiet_cmd_bison = YACC $(basename $@).[ch] + cmd_bison = $(YACC) -o $(basename $@).c --defines=$(basename $@).h -t -l $< -$(obj)/%.tab.c: $(src)/%.y FORCE +$(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE $(call if_changed,bison) -quiet_cmd_bison_h = YACC $@ - cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l $< - -$(obj)/%.tab.h: $(src)/%.y FORCE - $(call if_changed,bison_h) - # Shipped files # =========================================================================== diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index 66c314bc5933..baf44ed0a93a 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -18,16 +18,9 @@ quiet_cmd_bison_no_warn = $(quiet_cmd_bison) cmd_bison_no_warn = $(YACC) --version >/dev/null; \ $(cmd_bison) 2>/dev/null -$(obj)/parse.tab.c: $(src)/parse.y FORCE +$(obj)/pars%.tab.c $(obj)/pars%.tab.h: $(src)/pars%.y FORCE $(call if_changed,bison_no_warn) -quiet_cmd_bison_h_no_warn = $(quiet_cmd_bison_h) - cmd_bison_h_no_warn = $(YACC) --version >/dev/null; \ - $(cmd_bison_h) 2>/dev/null - -$(obj)/parse.tab.h: $(src)/parse.y FORCE - $(call if_changed,bison_h_no_warn) - endif # -I needed for generated C source (shipped source) -- cgit v1.2.3 From cf8dfd15e5fb280fa1e79e1d373456cb1e701222 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 21 Jul 2019 01:27:40 +0900 Subject: kbuild: move flex and bison rules to Makefile.host Flex and bison are used for kconfig, dtc, genksyms, all of which are host programs. I never imagine the kernel embeds a parser or a lexer. Move the flex and bison rules to scripts/Makefile.host. This file is included only when hostprogs-y etc. is present in the Makefile in the directory. So, parsing these rules are skipped in most of directories. Signed-off-by: Masahiro Yamada --- scripts/Makefile.host | 17 +++++++++++++++++ scripts/Makefile.lib | 16 ---------------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 2208ebbd8c4c..b402c619147d 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -1,4 +1,21 @@ # SPDX-License-Identifier: GPL-2.0 + +# LEX +# --------------------------------------------------------------------------- +quiet_cmd_flex = LEX $@ + cmd_flex = $(LEX) -o$@ -L $< + +$(obj)/%.lex.c: $(src)/%.l FORCE + $(call if_changed,flex) + +# YACC +# --------------------------------------------------------------------------- +quiet_cmd_bison = YACC $(basename $@).[ch] + cmd_bison = $(YACC) -o $(basename $@).c --defines=$(basename $@).h -t -l $< + +$(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE + $(call if_changed,bison) + # ========================================================================== # Building binaries on the host system # Binaries are used during the compilation of the kernel, for example diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 67d1165ab2ab..49d20f356263 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -187,22 +187,6 @@ $(foreach m, $(notdir $1), \ $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) endef -# LEX -# --------------------------------------------------------------------------- -quiet_cmd_flex = LEX $@ - cmd_flex = $(LEX) -o$@ -L $< - -$(obj)/%.lex.c: $(src)/%.l FORCE - $(call if_changed,flex) - -# YACC -# --------------------------------------------------------------------------- -quiet_cmd_bison = YACC $(basename $@).[ch] - cmd_bison = $(YACC) -o $(basename $@).c --defines=$(basename $@).h -t -l $< - -$(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE - $(call if_changed,bison) - # Shipped files # =========================================================================== -- cgit v1.2.3 From 4b950bb9ac0c7246dcf75060040577c3de60c166 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 28 Jul 2019 20:27:41 +0200 Subject: Kbuild: Handle PREEMPT_RT for version string and magic Update the build scripts and the version magic to reflect when CONFIG_PREEMPT_RT is enabled in the same way as CONFIG_PREEMPT is treated. The resulting version strings: Linux m 5.3.0-rc1+ #100 SMP Fri Jul 26 ... Linux m 5.3.0-rc1+ #101 SMP PREEMPT Fri Jul 26 ... Linux m 5.3.0-rc1+ #102 SMP PREEMPT_RT Fri Jul 26 ... The module vermagic: 5.3.0-rc1+ SMP mod_unload modversions 5.3.0-rc1+ SMP preempt mod_unload modversions 5.3.0-rc1+ SMP preempt_rt mod_unload modversions Signed-off-by: Thomas Gleixner Signed-off-by: Masahiro Yamada --- include/linux/vermagic.h | 2 ++ init/Makefile | 5 +++-- scripts/Makefile.modpost | 2 +- scripts/mkcompile_h | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h index bae807eb2933..9aced11e9000 100644 --- a/include/linux/vermagic.h +++ b/include/linux/vermagic.h @@ -9,6 +9,8 @@ #endif #ifdef CONFIG_PREEMPT #define MODULE_VERMAGIC_PREEMPT "preempt " +#elif defined(CONFIG_PREEMPT_RT) +#define MODULE_VERMAGIC_PREEMPT "preempt_rt " #else #define MODULE_VERMAGIC_PREEMPT "" #endif diff --git a/init/Makefile b/init/Makefile index a3e5ce2bcf08..6246a06364d0 100644 --- a/init/Makefile +++ b/init/Makefile @@ -33,5 +33,6 @@ $(obj)/version.o: include/generated/compile.h silent_chk_compile.h = : include/generated/compile.h: FORCE @$($(quiet)chk_compile.h) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ - "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ + "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" \ + "$(CONFIG_PREEMPT_RT)" "$(CC) $(KBUILD_CFLAGS)" diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 26e6574ecd08..e003350bc473 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -23,7 +23,7 @@ # Version magic (see include/linux/vermagic.h for full details) # - Kernel release # - SMP is CONFIG_SMP -# - PREEMPT is CONFIG_PREEMPT +# - PREEMPT is CONFIG_PREEMPT[_RT] # - GCC Version # Module info # - Module version (MODULE_VERSION) diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 2339f86126cb..d1d757c6edf4 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -5,7 +5,8 @@ TARGET=$1 ARCH=$2 SMP=$3 PREEMPT=$4 -CC=$5 +PREEMPT_RT=$5 +CC=$6 vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } @@ -53,6 +54,7 @@ UTS_VERSION="#$VERSION" CONFIG_FLAGS="" if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi +if [ -n "$PREEMPT_RT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_RT"; fi UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP" # Truncate to maximum length -- cgit v1.2.3 From f6545bec969358eace40419aff26a2a236e0b813 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 31 Jul 2019 15:13:58 +0900 Subject: kbuild: add [M] marker for build log of *.mod.o This builds module objects, so [M] makes sense. Signed-off-by: Masahiro Yamada --- scripts/Makefile.modpost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index e003350bc473..bf15818f6947 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -110,7 +110,7 @@ $(modules:.ko=.mod.c): modules-modpost # modname is set to make c_flags define KBUILD_MODNAME modname = $(notdir $(@:.mod.o=)) -quiet_cmd_cc_o_c = CC $@ +quiet_cmd_cc_o_c = CC [M] $@ cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \ -c -o $@ $< -- cgit v1.2.3 From 7fd785685e2243bb639b31557e258d11464c3489 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 13 Aug 2019 11:54:42 -0700 Subject: btf: rename /sys/kernel/btf/kernel into /sys/kernel/btf/vmlinux Expose kernel's BTF under the name vmlinux to be more uniform with using kernel module names as file names in the future. Fixes: 341dfcf8d78e ("btf: expose BTF info through sysfs") Suggested-by: Daniel Borkmann Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann --- Documentation/ABI/testing/sysfs-kernel-btf | 2 +- kernel/bpf/sysfs_btf.c | 30 +++++++++++++++--------------- scripts/link-vmlinux.sh | 18 +++++++++--------- 3 files changed, 25 insertions(+), 25 deletions(-) (limited to 'scripts') diff --git a/Documentation/ABI/testing/sysfs-kernel-btf b/Documentation/ABI/testing/sysfs-kernel-btf index 5390f8001f96..2c9744b2cd59 100644 --- a/Documentation/ABI/testing/sysfs-kernel-btf +++ b/Documentation/ABI/testing/sysfs-kernel-btf @@ -6,7 +6,7 @@ Description: Contains BTF type information and related data for kernel and kernel modules. -What: /sys/kernel/btf/kernel +What: /sys/kernel/btf/vmlinux Date: Aug 2019 KernelVersion: 5.5 Contact: bpf@vger.kernel.org diff --git a/kernel/bpf/sysfs_btf.c b/kernel/bpf/sysfs_btf.c index 092e63b9758b..4659349fc795 100644 --- a/kernel/bpf/sysfs_btf.c +++ b/kernel/bpf/sysfs_btf.c @@ -9,30 +9,30 @@ #include /* See scripts/link-vmlinux.sh, gen_btf() func for details */ -extern char __weak _binary__btf_kernel_bin_start[]; -extern char __weak _binary__btf_kernel_bin_end[]; +extern char __weak _binary__btf_vmlinux_bin_start[]; +extern char __weak _binary__btf_vmlinux_bin_end[]; static ssize_t -btf_kernel_read(struct file *file, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t len) +btf_vmlinux_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t len) { - memcpy(buf, _binary__btf_kernel_bin_start + off, len); + memcpy(buf, _binary__btf_vmlinux_bin_start + off, len); return len; } -static struct bin_attribute bin_attr_btf_kernel __ro_after_init = { - .attr = { .name = "kernel", .mode = 0444, }, - .read = btf_kernel_read, +static struct bin_attribute bin_attr_btf_vmlinux __ro_after_init = { + .attr = { .name = "vmlinux", .mode = 0444, }, + .read = btf_vmlinux_read, }; static struct kobject *btf_kobj; -static int __init btf_kernel_init(void) +static int __init btf_vmlinux_init(void) { int err; - if (!_binary__btf_kernel_bin_start) + if (!_binary__btf_vmlinux_bin_start) return 0; btf_kobj = kobject_create_and_add("btf", kernel_kobj); @@ -42,10 +42,10 @@ static int __init btf_kernel_init(void) return err; } - bin_attr_btf_kernel.size = _binary__btf_kernel_bin_end - - _binary__btf_kernel_bin_start; + bin_attr_btf_vmlinux.size = _binary__btf_vmlinux_bin_end - + _binary__btf_vmlinux_bin_start; - return sysfs_create_bin_file(btf_kobj, &bin_attr_btf_kernel); + return sysfs_create_bin_file(btf_kobj, &bin_attr_btf_vmlinux); } -subsys_initcall(btf_kernel_init); +subsys_initcall(btf_vmlinux_init); diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index cb93832c6ad7..f7933c606f27 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -117,9 +117,9 @@ gen_btf() # dump .BTF section into raw binary file to link with final vmlinux bin_arch=$(${OBJDUMP} -f ${1} | grep architecture | \ cut -d, -f1 | cut -d' ' -f2) - ${OBJCOPY} --dump-section .BTF=.btf.kernel.bin ${1} 2>/dev/null + ${OBJCOPY} --dump-section .BTF=.btf.vmlinux.bin ${1} 2>/dev/null ${OBJCOPY} -I binary -O ${CONFIG_OUTPUT_FORMAT} -B ${bin_arch} \ - --rename-section .data=.BTF .btf.kernel.bin ${2} + --rename-section .data=.BTF .btf.vmlinux.bin ${2} } # Create ${2} .o file with all symbols from the ${1} object file @@ -227,10 +227,10 @@ ${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o info MODINFO modules.builtin.modinfo ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo -btf_kernel_bin_o="" +btf_vmlinux_bin_o="" if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then - if gen_btf .tmp_vmlinux.btf .btf.kernel.bin.o ; then - btf_kernel_bin_o=.btf.kernel.bin.o + if gen_btf .tmp_vmlinux.btf .btf.vmlinux.bin.o ; then + btf_vmlinux_bin_o=.btf.vmlinux.bin.o fi fi @@ -265,11 +265,11 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then kallsyms_vmlinux=.tmp_vmlinux2 # step 1 - vmlinux_link .tmp_vmlinux1 ${btf_kernel_bin_o} + vmlinux_link .tmp_vmlinux1 ${btf_vmlinux_bin_o} kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o # step 2 - vmlinux_link .tmp_vmlinux2 .tmp_kallsyms1.o ${btf_kernel_bin_o} + vmlinux_link .tmp_vmlinux2 .tmp_kallsyms1.o ${btf_vmlinux_bin_o} kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o # step 3 @@ -280,13 +280,13 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then kallsymso=.tmp_kallsyms3.o kallsyms_vmlinux=.tmp_vmlinux3 - vmlinux_link .tmp_vmlinux3 .tmp_kallsyms2.o ${btf_kernel_bin_o} + vmlinux_link .tmp_vmlinux3 .tmp_kallsyms2.o ${btf_vmlinux_bin_o} kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o fi fi info LD vmlinux -vmlinux_link vmlinux "${kallsymso}" "${btf_kernel_bin_o}" +vmlinux_link vmlinux "${kallsymso}" "${btf_vmlinux_bin_o}" if [ -n "${CONFIG_BUILDTIME_EXTABLE_SORT}" ]; then info SORTEX vmlinux -- cgit v1.2.3 From 33e84f2e79659e410c379b530dac57779f201d15 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 6 Aug 2019 15:39:19 +0900 Subject: kbuild: treat an object as multi-used when $(foo-) is set Currently, Kbuild treats an object as multi-used when any of $(foo-objs), $(foo-y), $(foo-m) is set. It makes more sense to check $(foo-) as well. In the context of foo-$(CONFIG_FOO_FEATURE1), CONFIG_FOO_FEATURE1 could be unset. Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 49d20f356263..264611972c4a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -41,9 +41,9 @@ obj-m := $(filter-out %/, $(obj-m)) # Subdirectories we need to descend into subdir-ym := $(sort $(subdir-y) $(subdir-m)) -# if $(foo-objs), $(foo-y), or $(foo-m) exists, foo.o is a composite object -multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) -multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))), $(m)))) +# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object +multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))), $(m)))) +multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)) $($(m:.o=-))), $(m)))) multi-used := $(multi-used-y) $(multi-used-m) # $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to @@ -52,8 +52,8 @@ subdir-obj-y := $(filter %/built-in.a, $(obj-y)) # Replace multi-part objects by their individual parts, # including built-in.a from subdirectories -real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) -real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) +real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) +real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)) $($(m:.o=-))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) # DTB # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built -- cgit v1.2.3 From 986662b90352d79c4842dd7d4e678f50824ed729 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Aug 2019 00:52:58 +0900 Subject: kbuild: refactor part-of-module more Make it even shorter. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index edf84ede803c..c41206880bf2 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -98,8 +98,7 @@ endif # --------------------------------------------------------------------------- # Default is built-in, unless we know otherwise -$(foreach x, i ll lst o s symtypes, $(patsubst %.o,%.$(x),$(real-obj-m))): \ - part-of-module := y +part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) modkern_cflags = \ $(if $(part-of-module), \ -- cgit v1.2.3 From c2290f3286b6d1f2058b905cc954243c6027c37a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Aug 2019 00:52:59 +0900 Subject: kbuild: fix modkern_aflags implementation For the single target building %.symtypes from %.S, $(a_flags) is expanded into the _KERNEL flags even if the object is a part of a module. $(real-obj-m:.o=.symtypes): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) ... would fix the issue, but it is not nice to duplicate similar code for every suffix. Implement modkern_aflags in the same way as modkern_cflags. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index c41206880bf2..f84ccca8d74f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -309,10 +309,9 @@ $(obj)/%.h.s: $(src)/%.h FORCE # Compile assembler sources (.S) # --------------------------------------------------------------------------- -modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) - -$(real-obj-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) -$(real-obj-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) +modkern_aflags = $(if $(part-of-module), \ + $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ + $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) # .S file exports must have their C prototypes defined in asm/asm-prototypes.h # or a file that it includes, in order to get versioned symbols. We build a -- cgit v1.2.3 From 34b5560db40d2941cfbe82eca1641353d5aed1a9 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 14 Aug 2019 15:31:57 +0100 Subject: kasan/arm64: fix CONFIG_KASAN_SW_TAGS && KASAN_INLINE The generic Makefile.kasan propagates CONFIG_KASAN_SHADOW_OFFSET into KASAN_SHADOW_OFFSET, but only does so for CONFIG_KASAN_GENERIC. Since commit: 6bd1d0be0e97936d ("arm64: kasan: Switch to using KASAN_SHADOW_OFFSET") ... arm64 defines CONFIG_KASAN_SHADOW_OFFSET in Kconfig rather than defining KASAN_SHADOW_OFFSET in a Makefile. Thus, if CONFIG_KASAN_SW_TAGS && KASAN_INLINE are selected, we get build time splats due to KASAN_SHADOW_OFFSET not being set: | [mark@lakrids:~/src/linux]% usellvm 8.0.1 usekorg 8.1.0 make ARCH=arm64 CROSS_COMPILE=aarch64-linux- CC=clang | scripts/kconfig/conf --syncconfig Kconfig | CC scripts/mod/empty.o | clang (LLVM option parsing): for the -hwasan-mapping-offset option: '' value invalid for uint argument! | scripts/Makefile.build:273: recipe for target 'scripts/mod/empty.o' failed | make[1]: *** [scripts/mod/empty.o] Error 1 | Makefile:1123: recipe for target 'prepare0' failed | make: *** [prepare0] Error 2 Let's fix this by always propagating CONFIG_KASAN_SHADOW_OFFSET into KASAN_SHADOW_OFFSET if CONFIG_KASAN is selected, moving the existing common definition of +CFLAGS_KASAN_NOSANITIZE to the top of Makefile.kasan. Cc: Catalin Marinas Signed-off-by: Mark Rutland Acked-by: Andrey Ryabinin Tested-by Steve Capper Signed-off-by: Will Deacon --- scripts/Makefile.kasan | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan index 6410bd22fe38..03757cc60e06 100644 --- a/scripts/Makefile.kasan +++ b/scripts/Makefile.kasan @@ -1,4 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 +ifdef CONFIG_KASAN +CFLAGS_KASAN_NOSANITIZE := -fno-builtin +KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) +endif + ifdef CONFIG_KASAN_GENERIC ifdef CONFIG_KASAN_INLINE @@ -7,8 +12,6 @@ else call_threshold := 0 endif -KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) - CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) @@ -45,7 +48,3 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ $(instrumentation_flags) endif # CONFIG_KASAN_SW_TAGS - -ifdef CONFIG_KASAN -CFLAGS_KASAN_NOSANITIZE := -fno-builtin -endif -- cgit v1.2.3 From c7c0eecf894c3e353499fffd6f2ddaefc89bbd4a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 11 Aug 2019 02:01:35 +0900 Subject: kbuild: re-implement detection of CONFIG options leaked to user-space scripts/headers_check.pl can detect references to CONFIG options in exported headers, but it has been disabled for more than a decade. Reverting commit 7e3fa5614117 ("kbuild: drop check for CONFIG_ in headers_check") would emit the following warnings for headers_check on x86: usr/include/mtd/ubi-user.h:283: leaks CONFIG_MTD_UBI_BEB_LIMIT to userspace where it is not valid usr/include/linux/cm4000_cs.h:26: leaks CONFIG_COMPAT to userspace where it is not valid usr/include/linux/pkt_cls.h:301: leaks CONFIG_NET_CLS_ACT to userspace where it is not valid usr/include/linux/videodev2.h:2465: leaks CONFIG_VIDEO_ADV_DEBUG to userspace where it is not valid usr/include/linux/bpf.h:249: leaks CONFIG_EFFICIENT_UNALIGNED_ACCESS to userspace where it is not valid usr/include/linux/bpf.h:819: leaks CONFIG_CGROUP_NET_CLASSID to userspace where it is not valid usr/include/linux/bpf.h:1011: leaks CONFIG_IP_ROUTE_CLASSID to userspace where it is not valid usr/include/linux/bpf.h:1742: leaks CONFIG_BPF_KPROBE_OVERRIDE to userspace where it is not valid usr/include/linux/bpf.h:1747: leaks CONFIG_FUNCTION_ERROR_INJECTION to userspace where it is not valid usr/include/linux/bpf.h:1936: leaks CONFIG_XFRM to userspace where it is not valid usr/include/linux/bpf.h:2184: leaks CONFIG_BPF_LIRC_MODE2 to userspace where it is not valid usr/include/linux/bpf.h:2210: leaks CONFIG_BPF_LIRC_MODE2 to userspace where it is not valid usr/include/linux/bpf.h:2227: leaks CONFIG_SOCK_CGROUP_DATA to userspace where it is not valid usr/include/linux/bpf.h:2311: leaks CONFIG_NET to userspace where it is not valid usr/include/linux/bpf.h:2348: leaks CONFIG_NET to userspace where it is not valid usr/include/linux/bpf.h:2422: leaks CONFIG_BPF_LIRC_MODE2 to userspace where it is not valid usr/include/linux/bpf.h:2528: leaks CONFIG_NET to userspace where it is not valid usr/include/linux/pktcdvd.h:37: leaks CONFIG_CDROM_PKTCDVD_WCACHE to userspace where it is not valid usr/include/linux/hw_breakpoint.h:27: leaks CONFIG_HAVE_MIXED_BREAKPOINTS_REGS to userspace where it is not valid usr/include/linux/raw.h:17: leaks CONFIG_MAX_RAW_DEVS to userspace where it is not valid usr/include/linux/elfcore.h:62: leaks CONFIG_BINFMT_ELF_FDPIC to userspace where it is not valid usr/include/linux/eventpoll.h:82: leaks CONFIG_PM_SLEEP to userspace where it is not valid usr/include/linux/atmdev.h:104: leaks CONFIG_COMPAT to userspace where it is not valid usr/include/asm-generic/unistd.h:651: leaks CONFIG_MMU to userspace where it is not valid usr/include/asm-generic/bitsperlong.h:9: leaks CONFIG_64BIT to userspace where it is not valid usr/include/asm-generic/fcntl.h:119: leaks CONFIG_64BIT to userspace where it is not valid usr/include/asm/auxvec.h:14: leaks CONFIG_IA32_EMULATION to userspace where it is not valid usr/include/asm/e820.h:14: leaks CONFIG_NODES_SHIFT to userspace where it is not valid usr/include/asm/e820.h:39: leaks CONFIG_X86_PMEM_LEGACY to userspace where it is not valid usr/include/asm/e820.h:49: leaks CONFIG_INTEL_TXT to userspace where it is not valid usr/include/asm/mman.h:7: leaks CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS to userspace where it is not valid Most of these are false positives because scripts/headers_check.pl parses comment lines. It is also false negative. arch/x86/include/uapi/asm/auxvec.h contains CONFIG_IA32_EMULATION and CONFIG_X86_64, but the only former is reported. It would be possible to fix scripts/headers_check.pl, of course. However, we already have some duplicated checks between headers_check and CONFIG_UAPI_HEADER_TEST. At this moment of time, there are still dozens of headers excluded from the header test (usr/include/Makefile), but we might be able to remove headers_check eventually. I re-implemented it in scripts/headers_install.sh by using sed because the most of code in scripts/headers_install.sh is written in sed. This patch works like this: [1] Run scripts/unifdef first because we need to drop the code surrounded by #ifdef __KERNEL__ ... #endif [2] Remove all C style comments. The sed code is somewhat complicated since we need to deal with both single and multi line comments. Precisely speaking, a comment block is replaced with a space just in case. CONFIG_FOO/* this is a comment */CONFIG_BAR should be converted into: CONFIG_FOO CONFIG_BAR instead of: CONFIG_FOOCONFIG_BAR [3] Match CONFIG_... pattern. It correctly matches to all CONFIG options that appear in a single line. After this commit, this would detect the following warnings, all of which are real ones. warning: include/uapi/linux/pktcdvd.h: leak CONFIG_CDROM_PKTCDVD_WCACHE to user-space warning: include/uapi/linux/hw_breakpoint.h: leak CONFIG_HAVE_MIXED_BREAKPOINTS_REGS to user-space warning: include/uapi/linux/raw.h: leak CONFIG_MAX_RAW_DEVS to user-space warning: include/uapi/linux/elfcore.h: leak CONFIG_BINFMT_ELF_FDPIC to user-space warning: include/uapi/linux/eventpoll.h: leak CONFIG_PM_SLEEP to user-space warning: include/uapi/linux/atmdev.h: leak CONFIG_COMPAT to user-space warning: include/uapi/asm-generic/fcntl.h: leak CONFIG_64BIT to user-space warning: arch/x86/include/uapi/asm/auxvec.h: leak CONFIG_IA32_EMULATION to user-space warning: arch/x86/include/uapi/asm/auxvec.h: leak CONFIG_X86_64 to user-space warning: arch/x86/include/uapi/asm/mman.h: leak CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS to user-space However, it is not nice to show them right now. I created a list of existing leakages. They are not warned, but a new leakage will be blocked by the 0-day bot. Signed-off-by: Masahiro Yamada Acked-by: Sam Ravnborg --- scripts/headers_install.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'scripts') diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index bbaf29386995..a07668a5c36b 100755 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh @@ -41,5 +41,77 @@ sed -E -e ' scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ $TMPFILE > $OUTFILE [ $? -gt 1 ] && exit 1 +# Remove /* ... */ style comments, and find CONFIG_ references in code +configs=$(sed -e ' +:comment + s:/\*[^*][^*]*:/*: + s:/\*\*\**\([^/]\):/*\1: + t comment + s:/\*\*/: : + t comment + /\/\*/! b check + N + b comment +:print + P + D +:check + s:^\(CONFIG_[[:alnum:]_]*\):\1\n: + t print + s:^[[:alnum:]_][[:alnum:]_]*:: + s:^[^[:alnum:]_][^[:alnum:]_]*:: + t check + d +' $OUTFILE) + +# The entries in the following list are not warned. +# Please do not add a new entry. This list is only for existing ones. +# The list will be reduced gradually, and deleted eventually. (hopefully) +# +# The format is : in each line. +config_leak_ignores=" +arch/alpha/include/uapi/asm/setup.h:CONFIG_ALPHA_LEGACY_START_ADDRESS +arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_16K +arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_4K +arch/arc/include/uapi/asm/swab.h:CONFIG_ARC_HAS_SWAPE +arch/arm/include/uapi/asm/ptrace.h:CONFIG_CPU_ENDIAN_BE8 +arch/hexagon/include/uapi/asm/ptrace.h:CONFIG_HEXAGON_ARCH_VERSION +arch/hexagon/include/uapi/asm/user.h:CONFIG_HEXAGON_ARCH_VERSION +arch/ia64/include/uapi/asm/cmpxchg.h:CONFIG_IA64_DEBUG_CMPXCHG +arch/m68k/include/uapi/asm/ptrace.h:CONFIG_COLDFIRE +arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_NO +arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_SUPPORT +arch/sh/include/uapi/asm/ptrace.h:CONFIG_CPU_SH5 +arch/sh/include/uapi/asm/sigcontext.h:CONFIG_CPU_SH5 +arch/sh/include/uapi/asm/stat.h:CONFIG_CPU_SH5 +arch/x86/include/uapi/asm/auxvec.h:CONFIG_IA32_EMULATION +arch/x86/include/uapi/asm/auxvec.h:CONFIG_X86_64 +arch/x86/include/uapi/asm/mman.h:CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +include/uapi/asm-generic/fcntl.h:CONFIG_64BIT +include/uapi/linux/atmdev.h:CONFIG_COMPAT +include/uapi/linux/elfcore.h:CONFIG_BINFMT_ELF_FDPIC +include/uapi/linux/eventpoll.h:CONFIG_PM_SLEEP +include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS +include/uapi/linux/pktcdvd.h:CONFIG_CDROM_PKTCDVD_WCACHE +include/uapi/linux/raw.h:CONFIG_MAX_RAW_DEVS +" + +for c in $configs +do + warn=1 + + for ignore in $config_leak_ignores + do + if echo "$INFILE:$c" | grep -q "$ignore$"; then + warn= + break + fi + done + + if [ "$warn" = 1 ]; then + echo "warning: $INFILE: leak $c to user-space" >&2 + fi +done + rm -f $TMPFILE trap - EXIT -- cgit v1.2.3 From 8959e39272d6e625da1cd62f2e7622d79e04447d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 13 Aug 2019 08:15:32 -0700 Subject: kbuild: Parameterize kallsyms generation and correct reporting When kallsyms generation happens, temporary vmlinux outputs are linked but the quiet make output didn't report it, giving the impression that the prior command is taking longer than expected. Instead, report the linking step explicitly. While at it, this consolidates the repeated "kallsyms generation step" into a single function and removes the existing copy/pasting. Signed-off-by: Kees Cook Signed-off-by: Masahiro Yamada --- scripts/link-vmlinux.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 915775eb2921..2438a9faf3f1 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -60,6 +60,7 @@ modpost_link() # ${2} - output file vmlinux_link() { + info LD ${2} local lds="${objtree}/${KBUILD_LDS}" local objects @@ -138,6 +139,18 @@ kallsyms() ${CC} ${aflags} -c -o ${2} ${afile} } +# Perform one step in kallsyms generation, including temporary linking of +# vmlinux. +kallsyms_step() +{ + kallsymso_prev=${kallsymso} + kallsymso=.tmp_kallsyms${1}.o + kallsyms_vmlinux=.tmp_vmlinux${1} + + vmlinux_link "${kallsymso_prev}" ${kallsyms_vmlinux} + kallsyms ${kallsyms_vmlinux} ${kallsymso} +} + # Create map file with all symbols from ${1} # See mksymap for additional details mksysmap() @@ -216,6 +229,7 @@ info MODINFO modules.builtin.modinfo ${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo kallsymso="" +kallsymso_prev="" kallsyms_vmlinux="" if [ -n "${CONFIG_KALLSYMS}" ]; then @@ -242,32 +256,18 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then # a) Verify that the System.map from vmlinux matches the map from # ${kallsymso}. - kallsymso=.tmp_kallsyms2.o - kallsyms_vmlinux=.tmp_vmlinux2 - - # step 1 - vmlinux_link "" .tmp_vmlinux1 - kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o - - # step 2 - vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 - kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o + kallsyms_step 1 + kallsyms_step 2 # step 3 - size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" .tmp_kallsyms1.o) - size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" .tmp_kallsyms2.o) + size1=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso_prev}) + size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso}) if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then - kallsymso=.tmp_kallsyms3.o - kallsyms_vmlinux=.tmp_vmlinux3 - - vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 - - kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o + kallsyms_step 3 fi fi -info LD vmlinux vmlinux_link "${kallsymso}" vmlinux if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then -- cgit v1.2.3 From 394053f4a4b3e3eeeaa67b67fc886a9a75bd9e4d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 15 Aug 2019 00:19:18 +0900 Subject: kbuild: make single targets work more correctly Currently, the single target build directly descends into the directory of the target. For example, $ make foo/bar/baz.o ... directly descends into foo/bar/. On the other hand, the normal build usually descends one directory at a time, i.e. descends into foo/, and then foo/bar/. This difference causes some problems. [1] miss subdir-asflags-y, subdir-ccflags-y in upper Makefiles The options in subdir-{as,cc}flags-y take effect in the current and its sub-directories. In other words, they are inherited downward. In the example above, the single target will miss subdir-{as,cc}flags-y if they are defined in foo/Makefile. [2] could be built in a different directory As Documentation/kbuild/modules.rst section 4.3 says, Kbuild can handle files that are spread over several sub-directories. The build rule of foo/bar/baz.o may not necessarily be specified in foo/bar/Makefile. It might be specifies in foo/Makefile as follows: [foo/Makefile] obj-y := bar/baz.o This often happens when a module is so big that its source files are divided into sub-directories. In this case, there is no Makefile in the foo/bar/ directory, yet the single target descends into foo/bar/, then fails due to the missing Makefile. You can still do 'make foo/bar/' for partial building, but cannot do 'make foo/bar/baz.s'. I believe the single target '%.s' is a useful feature for inspecting the compiler output. Some modules work around this issue by putting an empty Makefile in every sub-directory. This commit fixes those problems by making the single target build descend in the same way as the normal build does. Another change is the single target build will observe the CONFIG options. Previously, it allowed users to build the foo.o even when the corresponding CONFIG_FOO is disabled: obj-$(CONFIG_FOO) += foo.o In the new behavior, the single target build will just fail and show "No rule to make target ..." (or "Nothing to be done for ..." if the stale object already exists, but cannot be updated). The disadvantage of this commit is the build speed. Now that the single target build visits every directory and parses lots of Makefiles, it is slower than before. (But, I hope it will not be too slow.) Signed-off-by: Masahiro Yamada --- Makefile | 81 +++++++++++++++++++++++++++++++------------------- scripts/Makefile.build | 45 ++++++++++++++++++++++++---- 2 files changed, 89 insertions(+), 37 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index 9661fa37158f..68e7ac654f4c 100644 --- a/Makefile +++ b/Makefile @@ -230,6 +230,8 @@ endif export KBUILD_CHECKSRC KBUILD_EXTMOD +extmod-prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/) + ifeq ($(abs_srctree),$(abs_objtree)) # building in the source tree srctree := . @@ -271,11 +273,13 @@ no-dot-config-targets := $(clean-targets) \ %asm-generic kernelversion %src-pkg no-sync-config-targets := $(no-dot-config-targets) install %install \ kernelrelease +single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ config-build := mixed-build := need-config := 1 may-sync-config := 1 +single-build := ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) @@ -302,6 +306,14 @@ ifeq ($(KBUILD_EXTMOD),) endif endif +# We cannot build single targets and the others at the same time +ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),) + single-build := 1 + ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),) + mixed-build := 1 + endif +endif + # For "make -j clean all", "make -j mrproper defconfig all", etc. ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),) ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),) @@ -1003,7 +1015,7 @@ endif PHONY += prepare0 -export MODORDER := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order +export MODORDER := $(extmod-prefix)modules.order ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ @@ -1655,7 +1667,7 @@ endif # KBUILD_EXTMOD PHONY += descend $(build-dirs) descend: $(build-dirs) $(build-dirs): prepare - $(Q)$(MAKE) $(build)=$@ need-builtin=1 need-modorder=1 + $(Q)$(MAKE) $(build)=$@ single-build=$(single-build) need-builtin=1 need-modorder=1 clean-dirs := $(addprefix _clean_, $(clean-dirs)) PHONY += $(clean-dirs) clean @@ -1752,40 +1764,47 @@ tools/%: FORCE # Single targets # --------------------------------------------------------------------------- -# Single targets are compatible with: -# - build with mixed source and output -# - build with separate output dir 'make O=...' -# - external modules +# To build individual files in subdirectories, you can do like this: +# +# make foo/bar/baz.s # -# target-dir => where to store outputfile -# build-dir => directory in kernel source tree to use - -build-target = $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD)/)$@ -build-dir = $(patsubst %/,%,$(dir $(build-target))) - -%.i: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) -%.ll: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) -%.lst: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) -%.o: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) -%.s: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) -%.symtypes: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +# The supported suffixes for single-target are listed in 'single-targets' +# +# To build only under specific subdirectories, you can do like this: +# +# make foo/bar/baz/ + +ifdef single-build + +single-all := $(filter $(single-targets), $(MAKECMDGOALS)) + +# .ko is special because modpost is needed +single-ko := $(sort $(filter %.ko, $(single-all))) +single-no-ko := $(sort $(patsubst %.ko,%.mod, $(single-all))) + +$(single-ko): single_modpost + @: +$(single-no-ko): descend + @: + ifeq ($(KBUILD_EXTMOD),) -# For the single build of an in-tree module, use a temporary file to avoid +# For the single build of in-tree modules, use a temporary file to avoid # the situation of modules_install installing an invalid modules.order. -%.ko: MODORDER := .modules.tmp +MODORDER := .modules.tmp endif -%.ko: prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(build-target:.ko=.mod) - $(Q)echo $(build-target) > $(MODORDER) + +PHONY += single_modpost +single_modpost: $(single-no-ko) + $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost -%/: prepare FORCE - $(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir) need-modorder=1 + +KBUILD_MODULES := 1 + +export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko)) + +single-build = $(if $(filter-out $@/, $(single-no-ko)),1) + +endif # FIXME Should go into a make.lib or something # =========================================================================== diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f84ccca8d74f..10adf3b558de 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -52,7 +52,7 @@ ifndef obj $(warning kbuild: Makefile.build is included improperly) endif -ifeq ($(MAKECMDGOALS)$(need-modorder),) +ifeq ($(need-modorder),) ifneq ($(obj-m),) $(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is specified.) $(warning You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.) @@ -76,11 +76,6 @@ endif mod-targets := $(patsubst %.o, %.mod, $(obj-m)) -__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ - $(if $(KBUILD_MODULES),$(obj-m) $(mod-targets) $(modorder-target)) \ - $(subdir-ym) $(always) - @: - # Linus' kernel sanity checking tool ifeq ($(KBUILD_CHECKSRC),1) quiet_cmd_checksrc = CHECK $< @@ -487,12 +482,50 @@ targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ $(call intermediate_targets, .lex.o, .lex.c) \ $(call intermediate_targets, .tab.o, .tab.c .tab.h) +# Build +# --------------------------------------------------------------------------- + +ifdef single-build + +curdir-single := $(sort $(foreach x, $(KBUILD_SINGLE_TARGETS), \ + $(if $(filter $(x) $(basename $(x)).o, $(targets)), $(x)))) + +# Handle single targets without any rule: show "Nothing to be done for ..." or +# "No rule to make target ..." depending on whether the target exists. +unknown-single := $(filter-out $(addsuffix /%, $(subdir-ym)), \ + $(filter $(obj)/%, \ + $(filter-out $(curdir-single), \ + $(KBUILD_SINGLE_TARGETS)))) + +__build: $(curdir-single) $(subdir-ym) +ifneq ($(unknown-single),) + $(Q)$(MAKE) -f /dev/null $(unknown-single) +endif + @: + +ifeq ($(curdir-single),) +# Nothing to do in this directory. Do not include any .*.cmd file for speed-up +targets := +else +targets += $(curdir-single) +endif + +else + +__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ + $(if $(KBUILD_MODULES),$(obj-m) $(mod-targets) $(modorder-target)) \ + $(subdir-ym) $(always) + @: + +endif + # Descending # --------------------------------------------------------------------------- PHONY += $(subdir-ym) $(subdir-ym): $(Q)$(MAKE) $(build)=$@ \ + $(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \ need-builtin=$(if $(filter $@/built-in.a, $(subdir-obj-y)),1) \ need-modorder=$(if $(need-modorder),$(if $(filter $@/modules.order, $(modorder)),1)) -- cgit v1.2.3 From 10df063855822fcea3c0f51dbf534ad643d3cb1b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 15 Aug 2019 01:06:22 +0900 Subject: kbuild: rebuild modules when module linker scripts are updated Currently, the timestamp of module linker scripts are not checked. Add them to the dependency of modules so they are correctly rebuilt. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/makefiles.rst | 5 +++++ Makefile | 3 ++- arch/arm/Makefile | 2 +- arch/arm64/Makefile | 2 +- arch/ia64/Makefile | 2 +- arch/m68k/Makefile | 2 +- arch/parisc/Makefile | 2 +- arch/powerpc/Makefile | 2 +- arch/riscv/Makefile | 2 +- scripts/Makefile.modpost | 5 +++-- 10 files changed, 17 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 88c384da592e..68ed20ef37dd 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -993,6 +993,11 @@ When kbuild executes, the following steps are followed (roughly): The linker script with full path. Assigned by the top-level Makefile. + KBUILD_LDS_MODULE + + The module linker script with full path. Assigned by the top-level + Makefile and additionally by the arch Makefile. + KBUILD_VMLINUX_OBJS All object files for vmlinux. They are linked to vmlinux in the same diff --git a/Makefile b/Makefile index 68e7ac654f4c..9c524950f4b3 100644 --- a/Makefile +++ b/Makefile @@ -482,7 +482,8 @@ KBUILD_AFLAGS_KERNEL := KBUILD_CFLAGS_KERNEL := KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE -KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds +KBUILD_LDFLAGS_MODULE := +export KBUILD_LDS_MODULE := $(srctree)/scripts/module-common.lds KBUILD_LDFLAGS := GCC_PLUGINS_CFLAGS := CLANG_FLAGS := diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c3624ca6c0bc..fbe50eec8f34 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -17,7 +17,7 @@ KBUILD_LDFLAGS_MODULE += --be8 endif ifeq ($(CONFIG_ARM_MODULE_PLTS),y) -KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/arm/kernel/module.lds +KBUILD_LDS_MODULE += $(srctree)/arch/arm/kernel/module.lds endif GZFLAGS :=-9 diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 61de992bbea3..d4ed1869e536 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -101,7 +101,7 @@ endif CHECKFLAGS += -D__aarch64__ ifeq ($(CONFIG_ARM64_MODULE_PLTS),y) -KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/arm64/kernel/module.lds +KBUILD_LDS_MODULE += $(srctree)/arch/arm64/kernel/module.lds endif # Default value diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 171290f9f1de..5c3bcaee5980 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -20,7 +20,7 @@ CHECKFLAGS += -D__ia64=1 -D__ia64__=1 -D_LP64 -D__LP64__ OBJCOPYFLAGS := --strip-all LDFLAGS_vmlinux := -static -KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/ia64/module.lds +KBUILD_LDS_MODULE += $(srctree)/arch/ia64/module.lds KBUILD_AFLAGS_KERNEL := -mconstant-gp EXTRA := diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 482513b9af2c..5d9288384096 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -73,7 +73,7 @@ KBUILD_AFLAGS += -D__uClinux__ endif KBUILD_LDFLAGS := -m m68kelf -KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds +KBUILD_LDS_MODULE += $(srctree)/arch/m68k/kernel/module.lds ifdef CONFIG_SUN3 LDFLAGS_vmlinux = -N diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 3b77d729057f..36b834f1c933 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -60,7 +60,7 @@ KBUILD_CFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY=1 \ -DFTRACE_PATCHABLE_FUNCTION_SIZE=$(NOP_COUNT) CC_FLAGS_FTRACE := -fpatchable-function-entry=$(NOP_COUNT),$(shell echo $$(($(NOP_COUNT)-1))) -KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/parisc/kernel/module.lds +KBUILD_LDS_MODULE += $(srctree)/arch/parisc/kernel/module.lds endif OBJCOPY_FLAGS =-O binary -R .note -R .comment -S diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index c345b79414a9..b2227855de20 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -67,7 +67,7 @@ UTS_MACHINE := $(subst $(space),,$(machine-y)) ifdef CONFIG_PPC32 KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o else -KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/powerpc/kernel/module.lds +KBUILD_LDS_MODULE += $(srctree)/arch/powerpc/kernel/module.lds ifeq ($(call ld-ifversion, -ge, 225000000, y),y) # Have the linker provide sfpr if possible. # There is a corresponding test in arch/powerpc/lib/Makefile diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 7a117be8297c..426d989125a8 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -52,7 +52,7 @@ ifeq ($(CONFIG_CMODEL_MEDANY),y) KBUILD_CFLAGS += -mcmodel=medany endif ifeq ($(CONFIG_MODULE_SECTIONS),y) - KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/riscv/kernel/module.lds + KBUILD_LDS_MODULE += $(srctree)/arch/riscv/kernel/module.lds endif KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index bf15818f6947..905db30d6622 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -126,10 +126,11 @@ quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ - -o $@ $(real-prereqs) ; \ + $(addprefix -T , $(KBUILD_LDS_MODULE)) \ + -o $@ $(filter %.o, $^); \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -$(modules): %.ko :%.o %.mod.o FORCE +$(modules): %.ko :%.o %.mod.o $(KBUILD_LDS_MODULE) FORCE +$(call if_changed,ld_ko_o) targets += $(modules) -- cgit v1.2.3 From fdf37037664041cfdbcab6cf54ddb2c1c219034b Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 20 Aug 2019 13:29:39 +0200 Subject: btf: do not use CONFIG_OUTPUT_FORMAT Building s390 kernel with CONFIG_DEBUG_INFO_BTF fails, because CONFIG_OUTPUT_FORMAT is not defined. As a matter of fact, this variable appears to be x86-only, so other arches might be affected as well. Fix by obtaining this value from objdump output, just like it's already done for bin_arch. The exact objdump invocation is "inspired" by arch/powerpc/boot/wrapper. Also, use LANG=C for the existing bin_arch objdump invocation to avoid potential build issues on systems with non-English locale. Fixes: 341dfcf8d78e ("btf: expose BTF info through sysfs") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann --- scripts/link-vmlinux.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index c31193340108..0d8f41db8cd6 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -115,10 +115,12 @@ gen_btf() LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} # dump .BTF section into raw binary file to link with final vmlinux - bin_arch=$(${OBJDUMP} -f ${1} | grep architecture | \ + bin_arch=$(LANG=C ${OBJDUMP} -f ${1} | grep architecture | \ cut -d, -f1 | cut -d' ' -f2) + bin_format=$(LANG=C ${OBJDUMP} -f ${1} | grep 'file format' | \ + awk '{print $4}') ${OBJCOPY} --dump-section .BTF=.btf.vmlinux.bin ${1} 2>/dev/null - ${OBJCOPY} -I binary -O ${CONFIG_OUTPUT_FORMAT} -B ${bin_arch} \ + ${OBJCOPY} -I binary -O ${bin_format} -B ${bin_arch} \ --rename-section .data=.BTF .btf.vmlinux.bin ${2} } -- cgit v1.2.3 From 9b9a3f20cbe0ba9269cde6fff9f9c69907e150cf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 15 Aug 2019 01:06:23 +0900 Subject: kbuild: split final module linking out into Makefile.modfinal I think splitting the modpost and linking modules into separate Makefiles will be useful especially when more complex build steps come in. The main motivation of this commit is to integrate the proposed klp-convert feature cleanly. I moved the logging 'Building modules, stage 2.' to Makefile.modpost to avoid the code duplication although I do not know whether or not this message is needed in the first place. Signed-off-by: Masahiro Yamada --- Makefile | 2 -- scripts/Makefile.modfinal | 60 +++++++++++++++++++++++++++++++++++ scripts/Makefile.modpost | 79 +++++++---------------------------------------- 3 files changed, 71 insertions(+), 70 deletions(-) create mode 100644 scripts/Makefile.modfinal (limited to 'scripts') diff --git a/Makefile b/Makefile index 9c524950f4b3..db2ddd53d557 100644 --- a/Makefile +++ b/Makefile @@ -1304,7 +1304,6 @@ all: modules PHONY += modules modules: $(if $(KBUILD_BUILTIN),vmlinux) modules.order modules.builtin - @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh @@ -1624,7 +1623,6 @@ $(objtree)/Module.symvers: build-dirs := $(KBUILD_EXTMOD) PHONY += modules modules: descend $(objtree)/Module.symvers - @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost PHONY += modules_install diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal new file mode 100644 index 000000000000..c8875f62dd96 --- /dev/null +++ b/scripts/Makefile.modfinal @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-only +# =========================================================================== +# Module final link +# =========================================================================== + +PHONY := __modfinal +__modfinal: + +include $(srctree)/scripts/Kbuild.include + +# for c_flags +include $(srctree)/scripts/Makefile.lib + +# find all modules listed in modules.order +modules := $(sort $(shell cat $(MODORDER))) + +__modfinal: $(modules) + @: + +# modname is set to make c_flags define KBUILD_MODNAME +modname = $(notdir $(@:.mod.o=)) + +quiet_cmd_cc_o_c = CC [M] $@ + cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \ + -c -o $@ $< + +%.mod.o: %.mod.c FORCE + $(call if_changed_dep,cc_o_c) + +ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) + +quiet_cmd_ld_ko_o = LD [M] $@ + cmd_ld_ko_o = \ + $(LD) -r $(KBUILD_LDFLAGS) \ + $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ + $(addprefix -T , $(KBUILD_LDS_MODULE)) \ + -o $@ $(filter %.o, $^); \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) + +$(modules): %.ko: %.o %.mod.o $(KBUILD_LDS_MODULE) FORCE + +$(call if_changed,ld_ko_o) + +targets += $(modules) $(modules:.ko=.mod.o) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 905db30d6622..9800a3988f23 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -15,8 +15,6 @@ # 2) modpost is then used to # 3) create one .mod.c file pr. module # 4) create one Module.symvers file with CRC for all exported symbols -# 5) compile all .mod.c files -# 6) final link of the module to a file # Step 3 is used to place certain information in the module's ELF # section, including information such as: @@ -60,13 +58,10 @@ MODPOST = scripts/mod/modpost \ ifdef MODPOST_VMLINUX -__modpost: vmlinux.o +quiet_cmd_modpost = MODPOST vmlinux.o + cmd_modpost = $(MODPOST) vmlinux.o -quiet_cmd_modpost = MODPOST $@ - cmd_modpost = $(MODPOST) $@ - -PHONY += vmlinux.o -vmlinux.o: +__modpost: $(call cmd,modpost) else @@ -83,74 +78,22 @@ include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \ $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile) endif -include scripts/Makefile.lib +MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - $(wildcard vmlinux) # find all modules listed in modules.order modules := $(sort $(shell cat $(MODORDER))) -# Stop after building .o files if NOFINAL is set. Makes compile tests quicker -__modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) - @: - -MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - $(wildcard vmlinux) - -# We can go over command line length here, so be careful. +# Read out modules.order instead of expanding $(modules) to pass in modpost. +# Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $(words $(modules)) modules cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST) -PHONY += modules-modpost -modules-modpost: +__modpost: + @$(kecho) ' Building modules, stage 2.' $(call cmd,modpost) - -# Declare generated files as targets for modpost -$(modules:.ko=.mod.c): modules-modpost - -# Step 5), compile all *.mod.c files - -# modname is set to make c_flags define KBUILD_MODNAME -modname = $(notdir $(@:.mod.o=)) - -quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \ - -c -o $@ $< - -$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE - $(call if_changed_dep,cc_o_c) - -targets += $(modules:.ko=.mod.o) - -ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) - -# Step 6), final link of the modules with optional arch pass after final link -quiet_cmd_ld_ko_o = LD [M] $@ - cmd_ld_ko_o = \ - $(LD) -r $(KBUILD_LDFLAGS) \ - $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ - $(addprefix -T , $(KBUILD_LDS_MODULE)) \ - -o $@ $(filter %.o, $^); \ - $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) - -$(modules): %.ko :%.o %.mod.o $(KBUILD_LDS_MODULE) FORCE - +$(call if_changed,ld_ko_o) - -targets += $(modules) - - -# Add FORCE to the prequisites of a target to force it to be always rebuilt. -# --------------------------------------------------------------------------- - -PHONY += FORCE - -FORCE: - -# Read all saved command lines and dependencies for the $(targets) we -# may be building above, using $(if_changed{,_dep}). As an -# optimization, we don't need to read them if the target does not -# exist, we will rebuild anyway in that case. - -existing-targets := $(wildcard $(sort $(targets))) - --include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) +ifneq ($(KBUILD_MODPOST_NOFINAL),1) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal +endif endif -- cgit v1.2.3 From 2ff2b7ec65dcea2261bdf404654975f44ad6323d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 19 Aug 2019 14:54:20 +0900 Subject: kbuild: add CONFIG_ASM_MODVERSIONS Add CONFIG_ASM_MODVERSIONS. This allows to remove one if-conditional nesting in scripts/Makefile.build. scripts/Makefile.build is run every time Kbuild descends into a sub-directory. So, I want to avoid $(wildcard ...) evaluation where possible although computing $(wildcard ...) is so cheap that it may not make measurable performance difference. Signed-off-by: Masahiro Yamada Acked-by: Geert Uytterhoeven --- arch/Kconfig | 7 +++++++ arch/alpha/Kconfig | 1 + arch/arm64/Kconfig | 1 + arch/ia64/Kconfig | 1 + arch/m68k/Kconfig | 1 + arch/mips/Kconfig | 1 + arch/powerpc/Kconfig | 1 + arch/riscv/Kconfig | 1 + arch/s390/Kconfig | 1 + arch/sparc/Kconfig | 1 + arch/um/Kconfig | 1 + arch/x86/Kconfig | 1 + init/Kconfig | 8 ++++++++ scripts/Makefile.build | 7 +------ 14 files changed, 27 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/arch/Kconfig b/arch/Kconfig index a7b57dd42c26..7d7b1b6af851 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -289,6 +289,13 @@ config ARCH_32BIT_OFF_T still support 32-bit off_t. This option is enabled for all such architectures explicitly. +config HAVE_ASM_MODVERSIONS + bool + help + This symbol should be selected by an architecure if it provides + to support the module versioning for symbols + exported from assembly code. + config HAVE_REGS_AND_STACK_ACCESS_API bool help diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index f7b19b813a70..ef179033a7c2 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -11,6 +11,7 @@ config ALPHA select PCI_DOMAINS if PCI select PCI_SYSCALL if PCI select HAVE_AOUT + select HAVE_ASM_MODVERSIONS select HAVE_IDE select HAVE_OPROFILE select HAVE_PCSPKR_PLATFORM diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3adcec05b1f6..cb16d4ade6aa 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -135,6 +135,7 @@ config ARM64 select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_VMAP_STACK select HAVE_ARM_SMCCC + select HAVE_ASM_MODVERSIONS select HAVE_EBPF_JIT select HAVE_C_RECORDMCOUNT select HAVE_CMPXCHG_DOUBLE diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 7468d8e50467..3dead116a6d7 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -17,6 +17,7 @@ config IA64 select FORCE_PCI if (!IA64_HP_SIM) select PCI_DOMAINS if PCI select PCI_SYSCALL if PCI + select HAVE_ASM_MODVERSIONS select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_EXIT_THREAD select HAVE_IDE diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index c518d695c376..00a20fa0bdcc 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -14,6 +14,7 @@ config M68K select DMA_DIRECT_REMAP if HAS_DMA && MMU && !COLDFIRE select HAVE_IDE select HAVE_AOUT if MMU + select HAVE_ASM_MODVERSIONS select HAVE_DEBUG_BUGVERBOSE select GENERIC_IRQ_SHOW select GENERIC_ATOMIC64 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d50fafd7bf3a..3db919b5c93a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -44,6 +44,7 @@ config MIPS select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT + select HAVE_ASM_MODVERSIONS select HAVE_EBPF_JIT if (!CPU_MICROMIPS) select HAVE_CONTEXT_TRACKING select HAVE_COPY_THREAD_TLS diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 77f6ebf97113..5be32ad8f47b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -178,6 +178,7 @@ config PPC select HAVE_ARCH_NVRAM_OPS select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK + select HAVE_ASM_MODVERSIONS select HAVE_C_RECORDMCOUNT select HAVE_CBPF_JIT if !PPC64 select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 59a4727ecd6c..66603f02675a 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -31,6 +31,7 @@ config RISCV select GENERIC_SMP_IDLE_THREAD select GENERIC_ATOMIC64 if !64BIT select HAVE_ARCH_AUDITSYSCALL + select HAVE_ASM_MODVERSIONS select HAVE_MEMBLOCK_NODE_MAP select HAVE_DMA_CONTIGUOUS select HAVE_FUTEX_CMPXCHG if FUTEX diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a4ad2733eedf..c06ebe34e0f9 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -131,6 +131,7 @@ config S390 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_VMAP_STACK + select HAVE_ASM_MODVERSIONS select HAVE_EBPF_JIT if PACK_STACK && HAVE_MARCH_Z196_FEATURES select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 7926a2e11bdc..fbc1aecf0f94 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -17,6 +17,7 @@ config SPARC select ARCH_MIGHT_HAVE_PC_SERIO select OF select OF_PROMTREE + select HAVE_ASM_MODVERSIONS select HAVE_IDE select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 3c3adfc486f2..fec6b4ca2b6e 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -9,6 +9,7 @@ config UML select ARCH_NO_PREEMPT select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ASM_MODVERSIONS select HAVE_UID16 select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_DEBUG_KMEMLEAK diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 222855cc0158..66bb9f25e9df 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -147,6 +147,7 @@ config X86 select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64 select HAVE_ARCH_VMAP_STACK if X86_64 select HAVE_ARCH_WITHIN_STACK_FRAMES + select HAVE_ASM_MODVERSIONS select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL select HAVE_CONTEXT_TRACKING if X86_64 diff --git a/init/Kconfig b/init/Kconfig index bd7d650d4a99..bf971b5c707d 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1989,6 +1989,14 @@ config MODVERSIONS make them incompatible with the kernel you are running. If unsure, say N. +config ASM_MODVERSIONS + bool + default HAVE_ASM_MODVERSIONS && MODVERSIONS + help + This enables module versioning for exported symbols also from + assembly. This can be enabled only when the target architecture + supports it. + config MODULE_REL_CRCS bool depends on MODVERSIONS diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 10adf3b558de..9fa09361aa5d 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -349,11 +349,7 @@ $(obj)/%.s: $(src)/%.S FORCE quiet_cmd_as_o_S = AS $(quiet_modtag) $@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< -ifdef CONFIG_MODVERSIONS - -ASM_PROTOTYPES := $(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/asm-prototypes.h) - -ifneq ($(ASM_PROTOTYPES),) +ifdef CONFIG_ASM_MODVERSIONS # versioning matches the C process described above, with difference that # we parse asm-prototypes.h C header to get function definitions. @@ -369,7 +365,6 @@ cmd_modversions_S = \ rm -f $(@D)/.tmp_$(@F:.o=.ver); \ fi endif -endif $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE $(call if_changed_rule,as_o_S) -- cgit v1.2.3 From eb27ea5ce7f367b185953cc9bc6e606004cfd8c4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 19 Aug 2019 17:58:43 +0900 Subject: kbuild: move modkern_{c,a}flags to Makefile.lib from Makefile.build Makefile.lib is included by Makefile.modfinal as well as Makefile.build. Move modkern_cflags to Makefile.lib in order to simplify cmd_cc_o_c in Makefile.modfinal. Move modkern_cflags as well for consistency. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 13 ------------- scripts/Makefile.lib | 12 ++++++++++++ scripts/Makefile.modfinal | 6 +++--- 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 9fa09361aa5d..2a21ca86b720 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -92,15 +92,6 @@ endif # Compile C sources (.c) # --------------------------------------------------------------------------- -# Default is built-in, unless we know otherwise -part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) - -modkern_cflags = \ - $(if $(part-of-module), \ - $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ - $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL)) -quiet_modtag = $(if $(part-of-module),[M], ) - quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< @@ -304,10 +295,6 @@ $(obj)/%.h.s: $(src)/%.h FORCE # Compile assembler sources (.S) # --------------------------------------------------------------------------- -modkern_aflags = $(if $(part-of-module), \ - $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ - $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) - # .S file exports must have their C prototypes defined in asm/asm-prototypes.h # or a file that it includes, in order to get versioned symbols. We build a # dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 264611972c4a..888e5c830646 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -159,6 +159,18 @@ _cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) endif endif +part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) +quiet_modtag = $(if $(part-of-module),[M], ) + +modkern_cflags = \ + $(if $(part-of-module), \ + $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ + $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL)) + +modkern_aflags = $(if $(part-of-module), \ + $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ + $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) + c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ -include $(srctree)/include/linux/compiler_types.h \ $(_c_flags) $(modkern_cflags) \ diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index c8875f62dd96..411c1e600e7d 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -17,12 +17,12 @@ modules := $(sort $(shell cat $(MODORDER))) __modfinal: $(modules) @: -# modname is set to make c_flags define KBUILD_MODNAME +# modname and part-of-module are set to make c_flags define proper module flags modname = $(notdir $(@:.mod.o=)) +part-of-module = y quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \ - -c -o $@ $< + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) -- cgit v1.2.3 From cdfca821571dfad27434b71cb43e0654667c0fd1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 19 Aug 2019 21:06:50 +0100 Subject: merge_config.sh: Check error codes from make When we execute make after merging the configurations we ignore any errors it produces causing whatever is running merge_config.sh to be unaware of any failures. This issue was noticed by Guillaume Tucker while looking at problems with testing of clang only builds in KernelCI which caused Kbuild to be unable to find a working host compiler. This implementation was suggested by Yamada-san. Suggested-by: Masahiro Yamada Reported-by: Guillaume Tucker Signed-off-by: Mark Brown Signed-off-by: Masahiro Yamada --- scripts/kconfig/merge_config.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index d924c51d28b7..bec246719aea 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -13,12 +13,12 @@ # Copyright (c) 2009-2010 Wind River Systems, Inc. # Copyright 2011 Linaro +set -e + clean_up() { rm -f $TMP_FILE rm -f $MERGE_FILE - exit } -trap clean_up HUP INT TERM usage() { echo "Usage: $0 [OPTIONS] [CONFIG [...]]" @@ -110,6 +110,9 @@ TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) echo "Using $INITFILE as base" + +trap clean_up EXIT + cat $INITFILE > $TMP_FILE # Merge files, printing warnings on overridden values @@ -155,7 +158,6 @@ if [ "$RUNMAKE" = "false" ]; then echo "#" echo "# merged configuration written to $KCONFIG_CONFIG (needs make)" echo "#" - clean_up exit fi @@ -185,5 +187,3 @@ for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do echo "" fi done - -clean_up -- cgit v1.2.3 From 46a63d4b0d79cf9e8afa3879acf9f6cf74a84a08 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 21 Aug 2019 16:02:02 +0900 Subject: kbuild: pkg: clean up package files/dirs from the top Makefile I am not a big fan of the $(objtree)/ hack for clean-files/clean-dirs. These are created in the top of $(objtree), so let's clean them up from the top Makefile. Signed-off-by: Masahiro Yamada --- Makefile | 6 ++++-- scripts/Makefile | 2 +- scripts/package/Makefile | 9 --------- 3 files changed, 5 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index db2ddd53d557..69cb3ec35d3c 100644 --- a/Makefile +++ b/Makefile @@ -1386,12 +1386,14 @@ CLEAN_FILES += modules.builtin.modinfo # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config include/generated \ - arch/$(SRCARCH)/include/generated .tmp_objdiff + arch/$(SRCARCH)/include/generated .tmp_objdiff \ + debian/ snap/ tar-install/ MRPROPER_FILES += .config .config.old .version \ Module.symvers \ signing_key.pem signing_key.priv signing_key.x509 \ x509.genkey extra_certificates signing_key.x509.keyid \ - signing_key.x509.signer vmlinux-gdb.py + signing_key.x509.signer vmlinux-gdb.py \ + *.spec # Directories & files removed with 'make distclean' DISTCLEAN_DIRS += diff --git a/scripts/Makefile b/scripts/Makefile index 16bcb8087899..c42891e10ba3 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -36,4 +36,4 @@ subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-$(CONFIG_SECURITY_SELINUX) += selinux # Let clean descend into subdirs -subdir- += basic dtc gdb kconfig mod package +subdir- += basic dtc gdb kconfig mod diff --git a/scripts/package/Makefile b/scripts/package/Makefile index ca7f46b562a4..a2d8830f54be 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -65,8 +65,6 @@ binrpm-pkg: FORCE +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ $(UTS_MACHINE) -bb $(objtree)/binkernel.spec -clean-files += $(objtree)/*.spec - deb-pkg: FORCE $(MAKE) clean $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian @@ -82,8 +80,6 @@ bindeb-pkg: FORCE intdeb-pkg: FORCE +$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb -clean-dirs += $(objtree)/debian/ - # snap-pkg # --------------------------------------------------------------------------- snap-pkg: FORCE @@ -98,17 +94,12 @@ snap-pkg: FORCE cd $(objtree)/snap && \ snapcraft --target-arch=$(UTS_MACHINE) -clean-dirs += $(objtree)/snap/ - # tarball targets # --------------------------------------------------------------------------- tar%pkg: FORCE $(MAKE) -f $(srctree)/Makefile +$(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ -clean-dirs += $(objtree)/tar-install/ - - # perf-pkg - generate a source tarball with perf source # --------------------------------------------------------------------------- -- cgit v1.2.3 From 6a4f6a26d32abb5d5f61861ab3cf5880d9556ff5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 21 Aug 2019 16:02:03 +0900 Subject: kbuild: pkg: add package targets to PHONY instead of FORCE These are not real targets. Adding them to PHONY is preferred. Signed-off-by: Masahiro Yamada --- scripts/package/Makefile | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/package/Makefile b/scripts/package/Makefile index a2d8830f54be..407189d9942a 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -50,7 +50,8 @@ rm -f $(objtree)/.scmversion # rpm-pkg # --------------------------------------------------------------------------- -rpm-pkg: FORCE +PHONY += rpm-pkg +rpm-pkg: $(MAKE) clean $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec $(call cmd,src_tar,$(KERNELPATH),kernel.spec) @@ -59,13 +60,15 @@ rpm-pkg: FORCE # binrpm-pkg # --------------------------------------------------------------------------- -binrpm-pkg: FORCE +PHONY += binrpm-pkg +binrpm-pkg: $(MAKE) -f $(srctree)/Makefile $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ $(UTS_MACHINE) -bb $(objtree)/binkernel.spec -deb-pkg: FORCE +PHONY += deb-pkg +deb-pkg: $(MAKE) clean $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian $(call cmd,src_tar,$(KDEB_SOURCENAME)) @@ -73,16 +76,19 @@ deb-pkg: FORCE mv $(KDEB_SOURCENAME).tar.gz ../$(KDEB_SOURCENAME)_$${origversion}.orig.tar.gz +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -i.git -us -uc -bindeb-pkg: FORCE +PHONY += bindeb-pkg +bindeb-pkg: $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -b -nc -uc -intdeb-pkg: FORCE +PHONY += intdeb-pkg +intdeb-pkg: +$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb # snap-pkg # --------------------------------------------------------------------------- -snap-pkg: FORCE +PHONY += snap-pkg +snap-pkg: rm -rf $(objtree)/snap mkdir $(objtree)/snap $(MAKE) clean @@ -96,7 +102,9 @@ snap-pkg: FORCE # tarball targets # --------------------------------------------------------------------------- -tar%pkg: FORCE +tar-pkgs := tar-pkg targz-pkg tarbz2-pkg tarxz-pkg +PHONY += $(tar-pkgs) +$(tar-pkgs): $(MAKE) -f $(srctree)/Makefile +$(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ @@ -124,12 +132,15 @@ $(if $(findstring xz,$@),xz, \ $(error unknown target $@)))) \ -f -9 $(perf-tar).tar) -perf-%pkg: FORCE +perf-tar-pkgs := perf-tar-src-pkg perf-targz-src-pkg perf-tarbz2-src-pkg perf-tarxz-src-pkg +PHONY += $(perf-tar-pkgs) +$(perf-tar-pkgs): $(call cmd,perf_tar) # Help text displayed when executing 'make help' # --------------------------------------------------------------------------- -help: FORCE +PHONY += help +help: @echo ' rpm-pkg - Build both source and binary RPM kernel packages' @echo ' binrpm-pkg - Build only the binary kernel RPM package' @echo ' deb-pkg - Build both source and binary deb kernel packages' -- cgit v1.2.3 From 000ec95fbe757401b5da1c9904840085204e5b3d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 21 Aug 2019 16:02:04 +0900 Subject: kbuild: pkg: rename scripts/package/Makefile to scripts/Makefile.package scripts/package/Makefile does not use $(obj) or $(src) at all. It actually generates files and directories in the top of $(objtree). I do not see much sense in descending into scripts/package/. Signed-off-by: Masahiro Yamada --- Makefile | 8 +-- scripts/Makefile.package | 159 +++++++++++++++++++++++++++++++++++++++++++++++ scripts/package/Makefile | 156 ---------------------------------------------- 3 files changed, 162 insertions(+), 161 deletions(-) create mode 100644 scripts/Makefile.package delete mode 100644 scripts/package/Makefile (limited to 'scripts') diff --git a/Makefile b/Makefile index 69cb3ec35d3c..668e65c47ee1 100644 --- a/Makefile +++ b/Makefile @@ -1445,13 +1445,11 @@ distclean: mrproper # Packaging of the kernel to various formats # --------------------------------------------------------------------------- -package-dir := scripts/package %src-pkg: FORCE - $(Q)$(MAKE) $(build)=$(package-dir) $@ + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@ %pkg: include/config/kernel.release FORCE - $(Q)$(MAKE) $(build)=$(package-dir) $@ - + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@ # Brief documentation of the typical targets used # --------------------------------------------------------------------------- @@ -1523,7 +1521,7 @@ help: @echo ' or "cd tools; make help"' @echo '' @echo 'Kernel packaging:' - @$(MAKE) $(build)=$(package-dir) help + @$(MAKE) -f $(srctree)/scripts/Makefile.package help @echo '' @echo 'Documentation targets:' @$(MAKE) -f $(srctree)/Documentation/Makefile dochelp diff --git a/scripts/Makefile.package b/scripts/Makefile.package new file mode 100644 index 000000000000..56eadcc48d46 --- /dev/null +++ b/scripts/Makefile.package @@ -0,0 +1,159 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Makefile for the different targets used to generate full packages of a kernel + +include $(srctree)/scripts/Kbuild.include + +# RPM target +# --------------------------------------------------------------------------- +# The rpm target generates two rpm files: +# /usr/src/packages/SRPMS/kernel-2.6.7rc2-1.src.rpm +# /usr/src/packages/RPMS/i386/kernel-2.6.7rc2-1..rpm +# The src.rpm files includes all source for the kernel being built +# The .rpm includes kernel configuration, modules etc. +# +# Process to create the rpm files +# a) clean the kernel +# b) Generate .spec file +# c) Build a tar ball, using symlink to make kernel version +# first entry in the path +# d) and pack the result to a tar.gz file +# e) generate the rpm files, based on kernel.spec +# - Use /. to avoid tar packing just the symlink + +# Note that the rpm-pkg target cannot be used with KBUILD_OUTPUT, +# but the binrpm-pkg target can; for some reason O= gets ignored. + +# Remove hyphens since they have special meaning in RPM filenames +KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) +KDEB_SOURCENAME ?= linux-$(KERNELRELEASE) +KBUILD_PKG_ROOTCMD ?="fakeroot -u" +export KDEB_SOURCENAME +# Include only those top-level files that are needed by make, plus the GPL copy +TAR_CONTENT := $(KBUILD_ALLDIRS) .config .scmversion Makefile \ + Kbuild Kconfig COPYING $(wildcard localversion*) +MKSPEC := $(srctree)/scripts/package/mkspec + +quiet_cmd_src_tar = TAR $(2).tar.gz + cmd_src_tar = \ +if test "$(objtree)" != "$(srctree)"; then \ + echo >&2; \ + echo >&2 " ERROR:"; \ + echo >&2 " Building source tarball is not possible outside the"; \ + echo >&2 " kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \ + echo >&2 " binrpm-pkg or bindeb-pkg target instead."; \ + echo >&2; \ + false; \ +fi ; \ +$(srctree)/scripts/setlocalversion --save-scmversion; \ +tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ + --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3); \ +rm -f $(objtree)/.scmversion + +# rpm-pkg +# --------------------------------------------------------------------------- +PHONY += rpm-pkg +rpm-pkg: + $(MAKE) clean + $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec + $(call cmd,src_tar,$(KERNELPATH),kernel.spec) + +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \ + --define='_smp_mflags %{nil}' + +# binrpm-pkg +# --------------------------------------------------------------------------- +PHONY += binrpm-pkg +binrpm-pkg: + $(MAKE) -f $(srctree)/Makefile + $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec + +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ + $(UTS_MACHINE) -bb $(objtree)/binkernel.spec + +PHONY += deb-pkg +deb-pkg: + $(MAKE) clean + $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian + $(call cmd,src_tar,$(KDEB_SOURCENAME)) + origversion=$$(dpkg-parsechangelog -SVersion |sed 's/-[^-]*$$//');\ + mv $(KDEB_SOURCENAME).tar.gz ../$(KDEB_SOURCENAME)_$${origversion}.orig.tar.gz + +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -i.git -us -uc + +PHONY += bindeb-pkg +bindeb-pkg: + $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian + +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -b -nc -uc + +PHONY += intdeb-pkg +intdeb-pkg: + +$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb + +# snap-pkg +# --------------------------------------------------------------------------- +PHONY += snap-pkg +snap-pkg: + rm -rf $(objtree)/snap + mkdir $(objtree)/snap + $(MAKE) clean + $(call cmd,src_tar,$(KERNELPATH)) + sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \ + s@SRCTREE@$(shell realpath $(KERNELPATH).tar.gz)@" \ + $(srctree)/scripts/package/snapcraft.template > \ + $(objtree)/snap/snapcraft.yaml + cd $(objtree)/snap && \ + snapcraft --target-arch=$(UTS_MACHINE) + +# tarball targets +# --------------------------------------------------------------------------- +tar-pkgs := tar-pkg targz-pkg tarbz2-pkg tarxz-pkg +PHONY += $(tar-pkgs) +$(tar-pkgs): + $(MAKE) -f $(srctree)/Makefile + +$(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ + +# perf-pkg - generate a source tarball with perf source +# --------------------------------------------------------------------------- + +perf-tar=perf-$(KERNELVERSION) + +quiet_cmd_perf_tar = TAR + cmd_perf_tar = \ +git --git-dir=$(srctree)/.git archive --prefix=$(perf-tar)/ \ + HEAD^{tree} $$(cd $(srctree); \ + echo $$(cat tools/perf/MANIFEST)) \ + -o $(perf-tar).tar; \ +mkdir -p $(perf-tar); \ +git --git-dir=$(srctree)/.git rev-parse HEAD > $(perf-tar)/HEAD; \ +(cd $(srctree)/tools/perf; \ +util/PERF-VERSION-GEN $(CURDIR)/$(perf-tar)/); \ +tar rf $(perf-tar).tar $(perf-tar)/HEAD $(perf-tar)/PERF-VERSION-FILE; \ +rm -r $(perf-tar); \ +$(if $(findstring tar-src,$@),, \ +$(if $(findstring bz2,$@),bzip2, \ +$(if $(findstring gz,$@),gzip, \ +$(if $(findstring xz,$@),xz, \ +$(error unknown target $@)))) \ + -f -9 $(perf-tar).tar) + +perf-tar-pkgs := perf-tar-src-pkg perf-targz-src-pkg perf-tarbz2-src-pkg perf-tarxz-src-pkg +PHONY += $(perf-tar-pkgs) +$(perf-tar-pkgs): + $(call cmd,perf_tar) + +# Help text displayed when executing 'make help' +# --------------------------------------------------------------------------- +PHONY += help +help: + @echo ' rpm-pkg - Build both source and binary RPM kernel packages' + @echo ' binrpm-pkg - Build only the binary kernel RPM package' + @echo ' deb-pkg - Build both source and binary deb kernel packages' + @echo ' bindeb-pkg - Build only the binary kernel deb package' + @echo ' snap-pkg - Build only the binary kernel snap package (will connect to external hosts)' + @echo ' tar-pkg - Build the kernel as an uncompressed tarball' + @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' + @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' + @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball' + @echo ' perf-tar-src-pkg - Build $(perf-tar).tar source tarball' + @echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball' + @echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball' + @echo ' perf-tarxz-src-pkg - Build $(perf-tar).tar.xz source tarball' + +.PHONY: $(PHONY) diff --git a/scripts/package/Makefile b/scripts/package/Makefile deleted file mode 100644 index 407189d9942a..000000000000 --- a/scripts/package/Makefile +++ /dev/null @@ -1,156 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# Makefile for the different targets used to generate full packages of a kernel -# It uses the generic clean infrastructure of kbuild - -# RPM target -# --------------------------------------------------------------------------- -# The rpm target generates two rpm files: -# /usr/src/packages/SRPMS/kernel-2.6.7rc2-1.src.rpm -# /usr/src/packages/RPMS/i386/kernel-2.6.7rc2-1..rpm -# The src.rpm files includes all source for the kernel being built -# The .rpm includes kernel configuration, modules etc. -# -# Process to create the rpm files -# a) clean the kernel -# b) Generate .spec file -# c) Build a tar ball, using symlink to make kernel version -# first entry in the path -# d) and pack the result to a tar.gz file -# e) generate the rpm files, based on kernel.spec -# - Use /. to avoid tar packing just the symlink - -# Note that the rpm-pkg target cannot be used with KBUILD_OUTPUT, -# but the binrpm-pkg target can; for some reason O= gets ignored. - -# Remove hyphens since they have special meaning in RPM filenames -KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) -KDEB_SOURCENAME ?= linux-$(KERNELRELEASE) -KBUILD_PKG_ROOTCMD ?="fakeroot -u" -export KDEB_SOURCENAME -# Include only those top-level files that are needed by make, plus the GPL copy -TAR_CONTENT := $(KBUILD_ALLDIRS) .config .scmversion Makefile \ - Kbuild Kconfig COPYING $(wildcard localversion*) -MKSPEC := $(srctree)/scripts/package/mkspec - -quiet_cmd_src_tar = TAR $(2).tar.gz - cmd_src_tar = \ -if test "$(objtree)" != "$(srctree)"; then \ - echo >&2; \ - echo >&2 " ERROR:"; \ - echo >&2 " Building source tarball is not possible outside the"; \ - echo >&2 " kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \ - echo >&2 " binrpm-pkg or bindeb-pkg target instead."; \ - echo >&2; \ - false; \ -fi ; \ -$(srctree)/scripts/setlocalversion --save-scmversion; \ -tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \ - --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3); \ -rm -f $(objtree)/.scmversion - -# rpm-pkg -# --------------------------------------------------------------------------- -PHONY += rpm-pkg -rpm-pkg: - $(MAKE) clean - $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec - $(call cmd,src_tar,$(KERNELPATH),kernel.spec) - +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \ - --define='_smp_mflags %{nil}' - -# binrpm-pkg -# --------------------------------------------------------------------------- -PHONY += binrpm-pkg -binrpm-pkg: - $(MAKE) -f $(srctree)/Makefile - $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec - +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ - $(UTS_MACHINE) -bb $(objtree)/binkernel.spec - -PHONY += deb-pkg -deb-pkg: - $(MAKE) clean - $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian - $(call cmd,src_tar,$(KDEB_SOURCENAME)) - origversion=$$(dpkg-parsechangelog -SVersion |sed 's/-[^-]*$$//');\ - mv $(KDEB_SOURCENAME).tar.gz ../$(KDEB_SOURCENAME)_$${origversion}.orig.tar.gz - +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -i.git -us -uc - -PHONY += bindeb-pkg -bindeb-pkg: - $(CONFIG_SHELL) $(srctree)/scripts/package/mkdebian - +dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -b -nc -uc - -PHONY += intdeb-pkg -intdeb-pkg: - +$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb - -# snap-pkg -# --------------------------------------------------------------------------- -PHONY += snap-pkg -snap-pkg: - rm -rf $(objtree)/snap - mkdir $(objtree)/snap - $(MAKE) clean - $(call cmd,src_tar,$(KERNELPATH)) - sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \ - s@SRCTREE@$(shell realpath $(KERNELPATH).tar.gz)@" \ - $(srctree)/scripts/package/snapcraft.template > \ - $(objtree)/snap/snapcraft.yaml - cd $(objtree)/snap && \ - snapcraft --target-arch=$(UTS_MACHINE) - -# tarball targets -# --------------------------------------------------------------------------- -tar-pkgs := tar-pkg targz-pkg tarbz2-pkg tarxz-pkg -PHONY += $(tar-pkgs) -$(tar-pkgs): - $(MAKE) -f $(srctree)/Makefile - +$(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@ - -# perf-pkg - generate a source tarball with perf source -# --------------------------------------------------------------------------- - -perf-tar=perf-$(KERNELVERSION) - -quiet_cmd_perf_tar = TAR - cmd_perf_tar = \ -git --git-dir=$(srctree)/.git archive --prefix=$(perf-tar)/ \ - HEAD^{tree} $$(cd $(srctree); \ - echo $$(cat tools/perf/MANIFEST)) \ - -o $(perf-tar).tar; \ -mkdir -p $(perf-tar); \ -git --git-dir=$(srctree)/.git rev-parse HEAD > $(perf-tar)/HEAD; \ -(cd $(srctree)/tools/perf; \ -util/PERF-VERSION-GEN $(CURDIR)/$(perf-tar)/); \ -tar rf $(perf-tar).tar $(perf-tar)/HEAD $(perf-tar)/PERF-VERSION-FILE; \ -rm -r $(perf-tar); \ -$(if $(findstring tar-src,$@),, \ -$(if $(findstring bz2,$@),bzip2, \ -$(if $(findstring gz,$@),gzip, \ -$(if $(findstring xz,$@),xz, \ -$(error unknown target $@)))) \ - -f -9 $(perf-tar).tar) - -perf-tar-pkgs := perf-tar-src-pkg perf-targz-src-pkg perf-tarbz2-src-pkg perf-tarxz-src-pkg -PHONY += $(perf-tar-pkgs) -$(perf-tar-pkgs): - $(call cmd,perf_tar) - -# Help text displayed when executing 'make help' -# --------------------------------------------------------------------------- -PHONY += help -help: - @echo ' rpm-pkg - Build both source and binary RPM kernel packages' - @echo ' binrpm-pkg - Build only the binary kernel RPM package' - @echo ' deb-pkg - Build both source and binary deb kernel packages' - @echo ' bindeb-pkg - Build only the binary kernel deb package' - @echo ' snap-pkg - Build only the binary kernel snap package (will connect to external hosts)' - @echo ' tar-pkg - Build the kernel as an uncompressed tarball' - @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' - @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' - @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball' - @echo ' perf-tar-src-pkg - Build $(perf-tar).tar source tarball' - @echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball' - @echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball' - @echo ' perf-tarxz-src-pkg - Build $(perf-tar).tar.xz source tarball' -- cgit v1.2.3 From fc01adc41679b19ee35a79e2bd2e9176aeba20c8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 22 Aug 2019 02:32:47 +0900 Subject: kbuild: remove unneeded comments and code from scripts/basic/Makefile Kbuild descends into scripts/basic/ even before the Kconfig. I do not expect any other host programs added to this Makefile. Signed-off-by: Masahiro Yamada --- scripts/basic/Makefile | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index 548aeb592806..7c9cb80d097b 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -1,16 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -### -# This Makefile lists the most basic programs used during the build process. -# The programs listed herein are what are needed to do the basic stuff, -# such as fix file dependencies. -# This initial step is needed to avoid files to be recompiled -# when kernel configuration changes (which is what happens when -# .config is included by main Makefile. -# --------------------------------------------------------------------------- -# fixdep: Used to generate dependency information during build process +# +# fixdep: used to generate dependency information during build process hostprogs-y := fixdep always := $(hostprogs-y) - -# fixdep is needed to compile other host programs -$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep -- cgit v1.2.3 From 9c3ad4c14f7a3ac870d660bbc5f9961a8a79f356 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 22 Aug 2019 12:59:11 +0900 Subject: kbuild: get rid of $(realpath ...) from scripts/mkmakefile Both relative path and absolute path have pros and cons. For example, we can move the source and objtree around together by using the relative path to the source tree. Do not force the absolute path to the source tree. If you prefer the absolute path, you can specify KBUILD_ABS_SRCTREE=1. Signed-off-by: Masahiro Yamada --- scripts/mkmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 4d0faebb1719..1cb174751429 100755 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -12,6 +12,6 @@ if [ "${quiet}" != "silent_" ]; then fi cat << EOF > Makefile -# Automatically generated by $(realpath $0): don't edit -include $(realpath $1/Makefile) +# Automatically generated by $0: don't edit +include $1/Makefile EOF -- cgit v1.2.3 From 1634f2bfdb846ed0a8b73131a9dff7c420fb3fe1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Aug 2019 10:31:27 +0900 Subject: kbuild: remove clean-dirs syntax The only the difference between clean-files and clean-dirs is the -r option passed to the 'rm' command. You can always pass -r, and then remove the clean-dirs syntax. Signed-off-by: Masahiro Yamada --- Documentation/kbuild/makefiles.rst | 16 ++++------------ scripts/Makefile.clean | 16 ++-------------- scripts/kconfig/Makefile | 2 +- usr/include/Makefile | 4 +--- 4 files changed, 8 insertions(+), 30 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 9fb2de94c3e2..e9ffdffa3641 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -750,7 +750,8 @@ Files matching the patterns "*.[oas]", "*.ko", plus some additional files generated by kbuild are deleted all over the kernel src tree when "make clean" is executed. -Additional files can be specified in kbuild makefiles by use of $(clean-files). +Additional files or directories can be specified in kbuild makefiles by use of +$(clean-files). Example:: @@ -761,17 +762,8 @@ When executing "make clean", the file "crc32table.h" will be deleted. Kbuild will assume files to be in the same relative directory as the Makefile, except if prefixed with $(objtree). -To delete a directory hierarchy use: - - Example:: - - #scripts/package/Makefile - clean-dirs := $(objtree)/debian/ - -This will delete the directory debian in the toplevel directory, including all -subdirectories. - -To exclude certain files from make clean, use the $(no-clean-files) variable. +To exclude certain files or directories from make clean, use the +$(no-clean-files) variable. Usually kbuild descends down in subdirectories due to "obj-* := dir/", but in the architecture makefiles where the kbuild infrastructure diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 0b80e3207b20..cbfbe13dc87d 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -52,26 +52,14 @@ __clean-files := $(wildcard \ $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \ $(filter $(objtree)/%, $(__clean-files))) -# same as clean-files - -__clean-dirs := $(wildcard \ - $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) \ - $(filter $(objtree)/%, $(clean-dirs))) - # ========================================================================== -quiet_cmd_clean = CLEAN $(obj) - cmd_clean = rm -f $(__clean-files) -quiet_cmd_cleandir = CLEAN $(__clean-dirs) - cmd_cleandir = rm -rf $(__clean-dirs) - +quiet_cmd_clean = CLEAN $(obj) + cmd_clean = rm -rf $(__clean-files) __clean: $(subdir-ymn) ifneq ($(strip $(__clean-files)),) +$(call cmd,clean) -endif -ifneq ($(strip $(__clean-dirs)),) - +$(call cmd,cleandir) endif @: diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 7656e1137b6b..bed7a5a2fbe9 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -114,7 +114,7 @@ testconfig: $(obj)/conf $(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ -o cache_dir=$(abspath $(obj)/tests/.cache) \ $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) -clean-dirs += tests/.cache +clean-files += tests/.cache # Help text used by make help help: diff --git a/usr/include/Makefile b/usr/include/Makefile index 1fb6abe29b2f..05c71ef42f51 100644 --- a/usr/include/Makefile +++ b/usr/include/Makefile @@ -115,6 +115,4 @@ header-test-y += $(filter-out $(header-test-), \ $(patsubst $(obj)/%,%, $(wildcard \ $(addprefix $(obj)/, *.h */*.h */*/*.h */*/*/*.h)))) -# For GNU Make <= 4.2.1, $(wildcard $(obj)/*/) matches to not only directories -# but also regular files. Use $(filter %/, ...) just in case. -clean-dirs += $(patsubst $(obj)/%/,%,$(filter %/, $(wildcard $(obj)/*/))) +clean-files += $(filter-out Makefile, $(notdir $(wildcard $(obj)/*))) -- cgit v1.2.3 From 687ac1fa3164c75a3e1053ed8609f3a4e7a6186e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Aug 2019 10:31:28 +0900 Subject: kbuild: remove unneeded '+' marker from cmd_clean This '+' was added a long time ago: | commit c23e6bf05f7802e92fd3da69a1ed35e56f9c85bb (HEAD) | Author: Kai Germaschewski | Date: Mon Oct 28 01:16:34 2002 -0600 | | kbuild: Fix a "make -j" warning | | diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean | index 2c843e0380bc..e7c392fd5788 100644 | --- a/scripts/Makefile.clean | +++ b/scripts/Makefile.clean | @@ -42,7 +42,7 @@ quiet_cmd_clean = CLEAN $(obj) | | __clean: $(subdir-ymn) | ifneq ($(strip $(__clean-files) $(clean-rule)),) | - $(call cmd,clean) | + +$(call cmd,clean) | else | @: | endif At that time, cmd_clean contained $(clean-rule), which was able to invoke sub-make. That was why cleaning with the -j option showed: warning: jobserver unavailable: using -j1. Add '+' to parent make rule. It is not the case any more; cmd_clean now just runs the 'rm' command. The '+' marker is pointless. Signed-off-by: Masahiro Yamada --- scripts/Makefile.clean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index cbfbe13dc87d..fc38a34128d4 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -59,7 +59,7 @@ quiet_cmd_clean = CLEAN $(obj) __clean: $(subdir-ymn) ifneq ($(strip $(__clean-files)),) - +$(call cmd,clean) + $(call cmd,clean) endif @: -- cgit v1.2.3 From 4ca76945b037cf93648170ff8cb958dbf1040374 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Aug 2019 10:31:39 +0900 Subject: kbuild: clean up subdir-ymn calculation in Makefile.clean Remove some variables. Signed-off-by: Masahiro Yamada --- scripts/Makefile.clean | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index fc38a34128d4..e367eb95c5c0 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -17,17 +17,8 @@ include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-di # Figure out what we need to build from the various variables # ========================================================================== -__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) -subdir-y += $(__subdir-y) -__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) -subdir-m += $(__subdir-m) -__subdir- := $(patsubst %/,%,$(filter %/, $(obj-))) -subdir- += $(__subdir-) - -# Subdirectories we need to descend into - -subdir-ym := $(sort $(subdir-y) $(subdir-m)) -subdir-ymn := $(sort $(subdir-ym) $(subdir-)) +subdir-ymn := $(sort $(subdir-y) $(subdir-m) $(subdir-) \ + $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m) $(obj-)))) # Add subdir path -- cgit v1.2.3 From 1bd95be204aa3c9456e950d5ab36588dbdbb05f1 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 24 Jul 2019 14:04:55 -0700 Subject: recordmcount: Remove redundant strcmp The strcmp is unnecessary since .text is already accepted as a prefix in the strncmp(). Link: http://lkml.kernel.org/r/358e590b49adbe4185e161a8b364e323f3d52857.1563992889.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 8387a9bc064a..ebe98c39f3cd 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -405,8 +405,7 @@ is_mcounted_section_name(char const *const txtname) strcmp(".irqentry.text", txtname) == 0 || strcmp(".softirqentry.text", txtname) == 0 || strcmp(".kprobes.text", txtname) == 0 || - strcmp(".cpuidle.text", txtname) == 0 || - strcmp(".text.unlikely", txtname) == 0; + strcmp(".cpuidle.text", txtname) == 0; } /* 32 bit and 64 bit are very similar */ -- cgit v1.2.3 From a146207916092a49bd01ef861ac9582fd318c21a Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 24 Jul 2019 14:04:56 -0700 Subject: recordmcount: Remove uread() uread() is only used to initialize the ELF file's pseudo private-memory mapping while uwrite() and ulseek() work within the pseudo-mapping and extend it as necessary. Thus it is not a complementary function to uwrite() and ulseek(). It also makes no sense to do cleanups inside uread() when its only caller, mmap_file(), is doing the relevant allocations and associated initializations. Therefore it's clearer to use a plain read() call to initialize the data in mmap_file() and remove uread(). Link: http://lkml.kernel.org/r/31a87c22b19150cec1c8dc800c8b0873a2741703.1563992889.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index ebe98c39f3cd..c0dd46344063 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -89,7 +89,7 @@ succeed_file(void) longjmp(jmpenv, SJ_SUCCEED); } -/* ulseek, uread, ...: Check return value for errors. */ +/* ulseek, uwrite, ...: Check return value for errors. */ static off_t ulseek(int const fd, off_t const offset, int const whence) @@ -112,17 +112,6 @@ ulseek(int const fd, off_t const offset, int const whence) return file_ptr - file_map; } -static size_t -uread(int const fd, void *const buf, size_t const count) -{ - size_t const n = read(fd, buf, count); - if (n != count) { - perror("read"); - fail_file(); - } - return n; -} - static size_t uwrite(int const fd, void const *const buf, size_t const count) { @@ -298,7 +287,10 @@ static void *mmap_file(char const *fname) if (file_map == MAP_FAILED) { mmap_failed = 1; file_map = umalloc(sb.st_size); - uread(fd_map, file_map, sb.st_size); + if (read(fd_map, file_map, sb.st_size) != sb.st_size) { + perror(fname); + fail_file(); + } } close(fd_map); -- cgit v1.2.3 From 17e262e9954bc3b6c857670f60b5b015f53509a7 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 24 Jul 2019 14:04:57 -0700 Subject: recordmcount: Remove unused fd from uwrite() and ulseek() uwrite() works within the pseudo-mapping and extends it as necessary without needing the file descriptor (fd) parameter passed to it. Similarly, ulseek() doesn't need its fd parameter. These parameters were only added because the functions bear a conceptual resemblance to write() and lseek(). Worse, they obscure the fact that at the time uwrite() and ulseek() are called fd_map is not a valid file descriptor. Remove the unused file descriptor parameters that make it look like fd_map is still valid. Link: http://lkml.kernel.org/r/2a136e820ee208469d375265c7b8eb28570749a0.1563992889.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 16 ++++++++-------- scripts/recordmcount.h | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index c0dd46344063..1fe5fba99959 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -92,7 +92,7 @@ succeed_file(void) /* ulseek, uwrite, ...: Check return value for errors. */ static off_t -ulseek(int const fd, off_t const offset, int const whence) +ulseek(off_t const offset, int const whence) { switch (whence) { case SEEK_SET: @@ -113,7 +113,7 @@ ulseek(int const fd, off_t const offset, int const whence) } static size_t -uwrite(int const fd, void const *const buf, size_t const count) +uwrite(void const *const buf, size_t const count) { size_t cnt = count; off_t idx = 0; @@ -183,8 +183,8 @@ static int make_nop_x86(void *map, size_t const offset) return -1; /* convert to nop */ - ulseek(fd_map, offset - 1, SEEK_SET); - uwrite(fd_map, ideal_nop, 5); + ulseek(offset - 1, SEEK_SET); + uwrite(ideal_nop, 5); return 0; } @@ -232,10 +232,10 @@ static int make_nop_arm(void *map, size_t const offset) return -1; /* Convert to nop */ - ulseek(fd_map, off, SEEK_SET); + ulseek(off, SEEK_SET); do { - uwrite(fd_map, ideal_nop, nop_size); + uwrite(ideal_nop, nop_size); } while (--cnt > 0); return 0; @@ -252,8 +252,8 @@ static int make_nop_arm64(void *map, size_t const offset) return -1; /* Convert to nop */ - ulseek(fd_map, offset, SEEK_SET); - uwrite(fd_map, ideal_nop, 4); + ulseek(offset, SEEK_SET); + uwrite(ideal_nop, 4); return 0; } diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 47fca2c69a73..c1e1b04b4871 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -202,14 +202,14 @@ static void append_func(Elf_Ehdr *const ehdr, new_e_shoff = t; /* body for new shstrtab */ - ulseek(fd_map, sb.st_size, SEEK_SET); - uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); - uwrite(fd_map, mc_name, 1 + strlen(mc_name)); + ulseek(sb.st_size, SEEK_SET); + uwrite(old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); + uwrite(mc_name, 1 + strlen(mc_name)); /* old(modified) Elf_Shdr table, word-byte aligned */ - ulseek(fd_map, t, SEEK_SET); + ulseek(t, SEEK_SET); t += sizeof(Elf_Shdr) * old_shnum; - uwrite(fd_map, old_shoff + (void *)ehdr, + uwrite(old_shoff + (void *)ehdr, sizeof(Elf_Shdr) * old_shnum); /* new sections __mcount_loc and .rel__mcount_loc */ @@ -225,7 +225,7 @@ static void append_func(Elf_Ehdr *const ehdr, mcsec.sh_info = 0; mcsec.sh_addralign = _w(_size); mcsec.sh_entsize = _w(_size); - uwrite(fd_map, &mcsec, sizeof(mcsec)); + uwrite(&mcsec, sizeof(mcsec)); mcsec.sh_name = w(old_shstr_sh_size); mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize) @@ -239,15 +239,15 @@ static void append_func(Elf_Ehdr *const ehdr, mcsec.sh_info = w(old_shnum); mcsec.sh_addralign = _w(_size); mcsec.sh_entsize = _w(rel_entsize); - uwrite(fd_map, &mcsec, sizeof(mcsec)); + uwrite(&mcsec, sizeof(mcsec)); - uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); - uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); + uwrite(mloc0, (void *)mlocp - (void *)mloc0); + uwrite(mrel0, (void *)mrelp - (void *)mrel0); ehdr->e_shoff = _w(new_e_shoff); ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ - ulseek(fd_map, 0, SEEK_SET); - uwrite(fd_map, ehdr, sizeof(*ehdr)); + ulseek(0, SEEK_SET); + uwrite(ehdr, sizeof(*ehdr)); } static unsigned get_mcountsym(Elf_Sym const *const sym0, @@ -396,8 +396,8 @@ static void nop_mcount(Elf_Shdr const *const relhdr, Elf_Rel rel; rel = *(Elf_Rel *)relp; Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop); - ulseek(fd_map, (void *)relp - (void *)ehdr, SEEK_SET); - uwrite(fd_map, &rel, sizeof(rel)); + ulseek((void *)relp - (void *)ehdr, SEEK_SET); + uwrite(&rel, sizeof(rel)); } relp = (Elf_Rel const *)(rel_entsize + (void *)relp); } -- cgit v1.2.3 From 3f1df12019f333442b12c3b5d110b8fc43eb0b36 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 31 Jul 2019 11:24:12 -0700 Subject: recordmcount: Rewrite error/success handling Recordmcount uses setjmp/longjmp to manage control flow as it reads and then writes the ELF file. This unusual control flow is hard to follow and check in addition to being unlike kernel coding style. So we rewrite these paths to use regular return values to indicate error/success. When an error or previously-completed object file is found we return an error code following kernel coding conventions -- negative error values and 0 for success when we're not returning a pointer. We return NULL for those that fail and return non-NULL pointers otherwise. One oddity is already_has_rel_mcount -- there we use pointer comparison rather than string comparison to differentiate between previously-processed object files and returning the name of a text section. Link: http://lkml.kernel.org/r/8ba8633d4afe444931f363c8d924bf9565b89a86.1564596289.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 162 ++++++++++++++++++++++++++----------------------- scripts/recordmcount.h | 141 +++++++++++++++++++++++++++++------------- 2 files changed, 184 insertions(+), 119 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 1fe5fba99959..c6d395b8ff29 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ static int fd_map; /* File descriptor for file being modified. */ static int mmap_failed; /* Boolean flag. */ static char gpfx; /* prefix for global symbol name (sometimes '_') */ static struct stat sb; /* Remember .st_size, etc. */ -static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ static const char *altmcount; /* alternate mcount symbol name */ static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */ static void *file_map; /* pointer of the mapped file */ @@ -53,13 +51,6 @@ static void *file_ptr; /* current file pointer location */ static void *file_append; /* added to the end of the file */ static size_t file_append_size; /* how much is added to end of file */ -/* setjmp() return values */ -enum { - SJ_SETJMP = 0, /* hardwired first return */ - SJ_FAIL, - SJ_SUCCEED -}; - /* Per-file resource cleanup when multiple files. */ static void cleanup(void) @@ -75,20 +66,6 @@ cleanup(void) file_updated = 0; } -static void __attribute__((noreturn)) -fail_file(void) -{ - cleanup(); - longjmp(jmpenv, SJ_FAIL); -} - -static void __attribute__((noreturn)) -succeed_file(void) -{ - cleanup(); - longjmp(jmpenv, SJ_SUCCEED); -} - /* ulseek, uwrite, ...: Check return value for errors. */ static off_t @@ -107,12 +84,12 @@ ulseek(off_t const offset, int const whence) } if (file_ptr < file_map) { fprintf(stderr, "lseek: seek before file\n"); - fail_file(); + return -1; } return file_ptr - file_map; } -static size_t +static ssize_t uwrite(void const *const buf, size_t const count) { size_t cnt = count; @@ -129,7 +106,8 @@ uwrite(void const *const buf, size_t const count) } if (!file_append) { perror("write"); - fail_file(); + cleanup(); + return -1; } if (file_ptr < file_end) { cnt = file_end - file_ptr; @@ -155,7 +133,8 @@ umalloc(size_t size) void *const addr = malloc(size); if (addr == 0) { fprintf(stderr, "malloc failed: %zu bytes\n", size); - fail_file(); + cleanup(); + return NULL; } return addr; } @@ -183,8 +162,10 @@ static int make_nop_x86(void *map, size_t const offset) return -1; /* convert to nop */ - ulseek(offset - 1, SEEK_SET); - uwrite(ideal_nop, 5); + if (ulseek(offset - 1, SEEK_SET) < 0) + return -1; + if (uwrite(ideal_nop, 5) < 0) + return -1; return 0; } @@ -232,10 +213,12 @@ static int make_nop_arm(void *map, size_t const offset) return -1; /* Convert to nop */ - ulseek(off, SEEK_SET); + if (ulseek(off, SEEK_SET) < 0) + return -1; do { - uwrite(ideal_nop, nop_size); + if (uwrite(ideal_nop, nop_size) < 0) + return -1; } while (--cnt > 0); return 0; @@ -252,8 +235,10 @@ static int make_nop_arm64(void *map, size_t const offset) return -1; /* Convert to nop */ - ulseek(offset, SEEK_SET); - uwrite(ideal_nop, 4); + if (ulseek(offset, SEEK_SET) < 0) + return -1; + if (uwrite(ideal_nop, 4) < 0) + return -1; return 0; } @@ -272,14 +257,23 @@ static int make_nop_arm64(void *map, size_t const offset) */ static void *mmap_file(char const *fname) { + file_map = NULL; + sb.st_size = 0; fd_map = open(fname, O_RDONLY); - if (fd_map < 0 || fstat(fd_map, &sb) < 0) { + if (fd_map < 0) { + perror(fname); + cleanup(); + return NULL; + } + if (fstat(fd_map, &sb) < 0) { perror(fname); - fail_file(); + cleanup(); + goto out; } if (!S_ISREG(sb.st_mode)) { fprintf(stderr, "not a regular file: %s\n", fname); - fail_file(); + cleanup(); + goto out; } file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd_map, 0); @@ -287,11 +281,18 @@ static void *mmap_file(char const *fname) if (file_map == MAP_FAILED) { mmap_failed = 1; file_map = umalloc(sb.st_size); + if (!file_map) { + perror(fname); + goto out; + } if (read(fd_map, file_map, sb.st_size) != sb.st_size) { perror(fname); - fail_file(); + free(file_map); + file_map = NULL; + goto out; } } +out: close(fd_map); file_end = file_map + sb.st_size; @@ -299,13 +300,13 @@ static void *mmap_file(char const *fname) return file_map; } -static void write_file(const char *fname) +static int write_file(const char *fname) { char tmp_file[strlen(fname) + 4]; size_t n; if (!file_updated) - return; + return 0; sprintf(tmp_file, "%s.rc", fname); @@ -317,25 +318,32 @@ static void write_file(const char *fname) fd_map = open(tmp_file, O_WRONLY | O_TRUNC | O_CREAT, sb.st_mode); if (fd_map < 0) { perror(fname); - fail_file(); + cleanup(); + return -1; } n = write(fd_map, file_map, sb.st_size); if (n != sb.st_size) { perror("write"); - fail_file(); + cleanup(); + close(fd_map); + return -1; } if (file_append_size) { n = write(fd_map, file_append, file_append_size); if (n != file_append_size) { perror("write"); - fail_file(); + cleanup(); + close(fd_map); + return -1; } } close(fd_map); if (rename(tmp_file, fname) < 0) { perror(fname); - fail_file(); + cleanup(); + return -1; } + return 0; } /* w8rev, w8nat, ...: Handle endianness. */ @@ -400,6 +408,8 @@ is_mcounted_section_name(char const *const txtname) strcmp(".cpuidle.text", txtname) == 0; } +static char const *already_has_rel_mcount = "success"; /* our work here is done! */ + /* 32 bit and 64 bit are very similar */ #include "recordmcount.h" #define RECORD_MCOUNT_64 @@ -438,11 +448,15 @@ static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type) }).r_info; } -static void +static int do_file(char const *const fname) { Elf32_Ehdr *const ehdr = mmap_file(fname); unsigned int reltype = 0; + int rc = -1; + + if (!ehdr) + goto out; w = w4nat; w2 = w2nat; @@ -452,8 +466,8 @@ do_file(char const *const fname) default: fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", ehdr->e_ident[EI_DATA], fname); - fail_file(); - break; + cleanup(); + goto out; case ELFDATA2LSB: if (*(unsigned char const *)&endian != 1) { /* main() is big endian, file.o is little endian. */ @@ -485,7 +499,8 @@ do_file(char const *const fname) || w2(ehdr->e_type) != ET_REL || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { fprintf(stderr, "unrecognized ET_REL file %s\n", fname); - fail_file(); + cleanup(); + goto out; } gpfx = 0; @@ -493,8 +508,8 @@ do_file(char const *const fname) default: fprintf(stderr, "unrecognized e_machine %u %s\n", w2(ehdr->e_machine), fname); - fail_file(); - break; + cleanup(); + goto out; case EM_386: reltype = R_386_32; rel_type_nop = R_386_NONE; @@ -534,20 +549,22 @@ do_file(char const *const fname) default: fprintf(stderr, "unrecognized ELF class %d %s\n", ehdr->e_ident[EI_CLASS], fname); - fail_file(); - break; + cleanup(); + goto out; case ELFCLASS32: if (w2(ehdr->e_ehsize) != sizeof(Elf32_Ehdr) || w2(ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { fprintf(stderr, "unrecognized ET_REL file: %s\n", fname); - fail_file(); + cleanup(); + goto out; } if (w2(ehdr->e_machine) == EM_MIPS) { reltype = R_MIPS_32; is_fake_mcount32 = MIPS32_is_fake_mcount; } - do32(ehdr, fname, reltype); + if (do32(ehdr, fname, reltype) < 0) + goto out; break; case ELFCLASS64: { Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; @@ -555,7 +572,8 @@ do_file(char const *const fname) || w2(ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { fprintf(stderr, "unrecognized ET_REL file: %s\n", fname); - fail_file(); + cleanup(); + goto out; } if (w2(ghdr->e_machine) == EM_S390) { reltype = R_390_64; @@ -567,13 +585,16 @@ do_file(char const *const fname) Elf64_r_info = MIPS64_r_info; is_fake_mcount64 = MIPS64_is_fake_mcount; } - do64(ghdr, fname, reltype); + if (do64(ghdr, fname, reltype) < 0) + goto out; break; } } /* end switch */ - write_file(fname); + rc = write_file(fname); +out: cleanup(); + return rc; } int @@ -604,7 +625,6 @@ main(int argc, char *argv[]) /* Process each file in turn, allowing deep failure. */ for (i = optind; i < argc; i++) { char *file = argv[i]; - int const sjval = setjmp(jmpenv); int len; /* @@ -617,28 +637,16 @@ main(int argc, char *argv[]) strcmp(file + (len - ftrace_size), ftrace) == 0) continue; - switch (sjval) { - default: - fprintf(stderr, "internal error: %s\n", file); - exit(1); - break; - case SJ_SETJMP: /* normal sequence */ - /* Avoid problems if early cleanup() */ - fd_map = -1; - mmap_failed = 1; - file_map = NULL; - file_ptr = NULL; - file_updated = 0; - do_file(file); - break; - case SJ_FAIL: /* error in do_file or below */ + /* Avoid problems if early cleanup() */ + fd_map = -1; + mmap_failed = 1; + file_map = NULL; + file_ptr = NULL; + file_updated = 0; + if (do_file(file)) { fprintf(stderr, "%s: failed\n", file); ++n_error; - break; - case SJ_SUCCEED: /* premature success */ - /* do nothing */ - break; - } /* end switch */ + } } return !!n_error; } diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index c1e1b04b4871..3796eb37fb12 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -174,7 +174,7 @@ static int MIPS_is_fake_mcount(Elf_Rel const *rp) } /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ -static void append_func(Elf_Ehdr *const ehdr, +static int append_func(Elf_Ehdr *const ehdr, Elf_Shdr *const shstr, uint_t const *const mloc0, uint_t const *const mlocp, @@ -202,15 +202,20 @@ static void append_func(Elf_Ehdr *const ehdr, new_e_shoff = t; /* body for new shstrtab */ - ulseek(sb.st_size, SEEK_SET); - uwrite(old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); - uwrite(mc_name, 1 + strlen(mc_name)); + if (ulseek(sb.st_size, SEEK_SET) < 0) + return -1; + if (uwrite(old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size) < 0) + return -1; + if (uwrite(mc_name, 1 + strlen(mc_name)) < 0) + return -1; /* old(modified) Elf_Shdr table, word-byte aligned */ - ulseek(t, SEEK_SET); + if (ulseek(t, SEEK_SET) < 0) + return -1; t += sizeof(Elf_Shdr) * old_shnum; - uwrite(old_shoff + (void *)ehdr, - sizeof(Elf_Shdr) * old_shnum); + if (uwrite(old_shoff + (void *)ehdr, + sizeof(Elf_Shdr) * old_shnum) < 0) + return -1; /* new sections __mcount_loc and .rel__mcount_loc */ t += 2*sizeof(mcsec); @@ -225,7 +230,8 @@ static void append_func(Elf_Ehdr *const ehdr, mcsec.sh_info = 0; mcsec.sh_addralign = _w(_size); mcsec.sh_entsize = _w(_size); - uwrite(&mcsec, sizeof(mcsec)); + if (uwrite(&mcsec, sizeof(mcsec)) < 0) + return -1; mcsec.sh_name = w(old_shstr_sh_size); mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize) @@ -239,15 +245,22 @@ static void append_func(Elf_Ehdr *const ehdr, mcsec.sh_info = w(old_shnum); mcsec.sh_addralign = _w(_size); mcsec.sh_entsize = _w(rel_entsize); - uwrite(&mcsec, sizeof(mcsec)); - uwrite(mloc0, (void *)mlocp - (void *)mloc0); - uwrite(mrel0, (void *)mrelp - (void *)mrel0); + if (uwrite(&mcsec, sizeof(mcsec)) < 0) + return -1; + + if (uwrite(mloc0, (void *)mlocp - (void *)mloc0) < 0) + return -1; + if (uwrite(mrel0, (void *)mrelp - (void *)mrel0) < 0) + return -1; ehdr->e_shoff = _w(new_e_shoff); ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ - ulseek(0, SEEK_SET); - uwrite(ehdr, sizeof(*ehdr)); + if (ulseek(0, SEEK_SET) < 0) + return -1; + if (uwrite(ehdr, sizeof(*ehdr)) < 0) + return -1; + return 0; } static unsigned get_mcountsym(Elf_Sym const *const sym0, @@ -351,9 +364,9 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, * that are not going to be traced. The mcount calls here will be converted * into nops. */ -static void nop_mcount(Elf_Shdr const *const relhdr, - Elf_Ehdr const *const ehdr, - const char *const txtname) +static int nop_mcount(Elf_Shdr const *const relhdr, + Elf_Ehdr const *const ehdr, + const char *const txtname) { Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) + (void *)ehdr); @@ -376,15 +389,18 @@ static void nop_mcount(Elf_Shdr const *const relhdr, mcountsym = get_mcountsym(sym0, relp, str0); if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { - if (make_nop) + if (make_nop) { ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + _w(relp->r_offset)); + if (ret < 0) + return -1; + } if (warn_on_notrace_sect && !once) { printf("Section %s has mcount callers being ignored\n", txtname); once = 1; /* just warn? */ if (!make_nop) - return; + return 0; } } @@ -396,14 +412,16 @@ static void nop_mcount(Elf_Shdr const *const relhdr, Elf_Rel rel; rel = *(Elf_Rel *)relp; Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop); - ulseek((void *)relp - (void *)ehdr, SEEK_SET); - uwrite(&rel, sizeof(rel)); + if (ulseek((void *)relp - (void *)ehdr, SEEK_SET) < 0) + return -1; + if (uwrite(&rel, sizeof(rel)) < 0) + return -1; } relp = (Elf_Rel const *)(rel_entsize + (void *)relp); } + return 0; } - /* * Find a symbol in the given section, to be used as the base for relocating * the table of offsets of calls to mcount. A local or global symbol suffices, @@ -414,9 +432,10 @@ static void nop_mcount(Elf_Shdr const *const relhdr, * Num: Value Size Type Bind Vis Ndx Name * 2: 00000000 0 SECTION LOCAL DEFAULT 1 */ -static unsigned find_secsym_ndx(unsigned const txtndx, +static int find_secsym_ndx(unsigned const txtndx, char const *const txtname, uint_t *const recvalp, + unsigned int *sym_index, Elf_Shdr const *const symhdr, Elf_Ehdr const *const ehdr) { @@ -438,15 +457,16 @@ static unsigned find_secsym_ndx(unsigned const txtndx, continue; *recvalp = _w(symp->st_value); - return symp - sym0; + *sym_index = symp - sym0; + return 0; } } fprintf(stderr, "Cannot find symbol for section %u: %s.\n", txtndx, txtname); - fail_file(); + cleanup(); + return -1; } - /* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */ static char const * __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ @@ -461,7 +481,8 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ if (strcmp("__mcount_loc", txtname) == 0) { fprintf(stderr, "warning: __mcount_loc already exists: %s\n", fname); - succeed_file(); + cleanup(); + return already_has_rel_mcount; } if (w(txthdr->sh_type) != SHT_PROGBITS || !(_w(txthdr->sh_flags) & SHF_EXECINSTR)) @@ -491,6 +512,10 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0, for (; nhdr; --nhdr, ++shdrp) { txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname); + if (txtname == already_has_rel_mcount) { + totrelsz = 0; + break; + } if (txtname && is_mcounted_section_name(txtname)) totrelsz += _w(shdrp->sh_size); } @@ -499,7 +524,7 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0, /* Overall supervision for Elf32 ET_REL file. */ -static void +static int do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) { Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) @@ -513,26 +538,54 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) unsigned k; /* Upper bound on space: assume all relevant relocs are for mcount. */ - unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname); - Elf_Rel *const mrel0 = umalloc(totrelsz); - Elf_Rel * mrelp = mrel0; + unsigned totrelsz; - /* 2*sizeof(address) <= sizeof(Elf_Rel) */ - uint_t *const mloc0 = umalloc(totrelsz>>1); - uint_t * mlocp = mloc0; + Elf_Rel * mrel0; + Elf_Rel * mrelp; + + uint_t * mloc0; + uint_t * mlocp; unsigned rel_entsize = 0; unsigned symsec_sh_link = 0; + int result = 0; + + totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname); + if (totrelsz == 0) + return 0; + mrel0 = umalloc(totrelsz); + mrelp = mrel0; + if (!mrel0) + return -1; + + /* 2*sizeof(address) <= sizeof(Elf_Rel) */ + mloc0 = umalloc(totrelsz>>1); + mlocp = mloc0; + if (!mloc0) { + free(mrel0); + return -1; + } + for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { char const *const txtname = has_rel_mcount(relhdr, shdr0, shstrtab, fname); + if (txtname == already_has_rel_mcount) { + result = 0; + file_updated = 0; + goto out; /* Nothing to be done; don't append! */ + } if (txtname && is_mcounted_section_name(txtname)) { + unsigned int recsym; uint_t recval = 0; - unsigned const recsym = find_secsym_ndx( - w(relhdr->sh_info), txtname, &recval, - &shdr0[symsec_sh_link = w(relhdr->sh_link)], - ehdr); + + symsec_sh_link = w(relhdr->sh_link); + result = find_secsym_ndx(w(relhdr->sh_info), txtname, + &recval, &recsym, + &shdr0[symsec_sh_link], + ehdr); + if (result) + goto out; rel_entsize = _w(relhdr->sh_entsize); mlocp = sift_rel_mcount(mlocp, @@ -543,13 +596,17 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) * This section is ignored by ftrace, but still * has mcount calls. Convert them to nops now. */ - nop_mcount(relhdr, ehdr, txtname); + if (nop_mcount(relhdr, ehdr, txtname) < 0) { + result = -1; + goto out; + } } } - if (mloc0 != mlocp) { - append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, - rel_entsize, symsec_sh_link); - } + if (!result && mloc0 != mlocp) + result = append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, + rel_entsize, symsec_sh_link); +out: free(mrel0); free(mloc0); + return result; } -- cgit v1.2.3 From 3aec8638246ff284e4075aac4f72ab160ebccaf2 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 31 Jul 2019 11:24:13 -0700 Subject: recordmcount: Kernel style function signature formatting The uwrite() and ulseek() functions are formatted inconsistently with the rest of the file and the kernel overall. While we're making other changes here let's fix this. Link: http://lkml.kernel.org/r/4c67698f734be9867a2aba7035fe0ce59e1e4423.1564596289.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 21 +++++++-------------- scripts/recordmcount.h | 13 ++++++------- 2 files changed, 13 insertions(+), 21 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index c6d395b8ff29..67f9c45b824f 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -52,8 +52,7 @@ static void *file_append; /* added to the end of the file */ static size_t file_append_size; /* how much is added to end of file */ /* Per-file resource cleanup when multiple files. */ -static void -cleanup(void) +static void cleanup(void) { if (!mmap_failed) munmap(file_map, sb.st_size); @@ -68,8 +67,7 @@ cleanup(void) /* ulseek, uwrite, ...: Check return value for errors. */ -static off_t -ulseek(off_t const offset, int const whence) +static off_t ulseek(off_t const offset, int const whence) { switch (whence) { case SEEK_SET: @@ -89,8 +87,7 @@ ulseek(off_t const offset, int const whence) return file_ptr - file_map; } -static ssize_t -uwrite(void const *const buf, size_t const count) +static ssize_t uwrite(void const *const buf, size_t const count) { size_t cnt = count; off_t idx = 0; @@ -127,8 +124,7 @@ uwrite(void const *const buf, size_t const count) return count; } -static void * -umalloc(size_t size) +static void * umalloc(size_t size) { void *const addr = malloc(size); if (addr == 0) { @@ -394,8 +390,7 @@ static uint32_t (*w)(uint32_t); static uint32_t (*w2)(uint16_t); /* Names of the sections that could contain calls to mcount. */ -static int -is_mcounted_section_name(char const *const txtname) +static int is_mcounted_section_name(char const *const txtname) { return strncmp(".text", txtname, 5) == 0 || strcmp(".init.text", txtname) == 0 || @@ -448,8 +443,7 @@ static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type) }).r_info; } -static int -do_file(char const *const fname) +static int do_file(char const *const fname) { Elf32_Ehdr *const ehdr = mmap_file(fname); unsigned int reltype = 0; @@ -597,8 +591,7 @@ out: return rc; } -int -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { const char ftrace[] = "/ftrace.o"; int ftrace_size = sizeof(ftrace) - 1; diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 3796eb37fb12..ca9aaac89bfb 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -468,11 +468,10 @@ static int find_secsym_ndx(unsigned const txtndx, } /* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */ -static char const * -__has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ - Elf_Shdr const *const shdr0, - char const *const shstrtab, - char const *const fname) +static char const * __has_rel_mcount(Elf_Shdr const *const relhdr, /* reltype */ + Elf_Shdr const *const shdr0, + char const *const shstrtab, + char const *const fname) { /* .sh_info depends on .sh_type == SHT_REL[,A] */ Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; @@ -524,8 +523,8 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0, /* Overall supervision for Elf32 ET_REL file. */ -static int -do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) +static int do_func(Elf_Ehdr *const ehdr, char const *const fname, + unsigned const reltype) { Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) + (void *)ehdr); -- cgit v1.2.3 From 2e63152bc1909e10b7bc844bbbef5a815f585b45 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 31 Jul 2019 11:24:14 -0700 Subject: recordmcount: Kernel style formatting Fix up the whitespace irregularity in the ELF switch blocks. Swapping the initial value of gpfx allows us to simplify all but one of the one-line switch cases even further. Link: http://lkml.kernel.org/r/647f21f43723d3e831cedd3238c893db03eea6f0.1564596289.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 67f9c45b824f..273ca8b42b20 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -489,15 +489,15 @@ static int do_file(char const *const fname) push_bl_mcount_thumb = push_bl_mcount_thumb_be; break; } /* end switch */ - if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 - || w2(ehdr->e_type) != ET_REL - || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { + if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 || + w2(ehdr->e_type) != ET_REL || + ehdr->e_ident[EI_VERSION] != EV_CURRENT) { fprintf(stderr, "unrecognized ET_REL file %s\n", fname); cleanup(); goto out; } - gpfx = 0; + gpfx = '_'; switch (w2(ehdr->e_machine)) { default: fprintf(stderr, "unrecognized e_machine %u %s\n", @@ -510,32 +510,35 @@ static int do_file(char const *const fname) make_nop = make_nop_x86; ideal_nop = ideal_nop5_x86_32; mcount_adjust_32 = -1; + gpfx = 0; + break; + case EM_ARM: + reltype = R_ARM_ABS32; + altmcount = "__gnu_mcount_nc"; + make_nop = make_nop_arm; + rel_type_nop = R_ARM_NONE; + gpfx = 0; break; - case EM_ARM: reltype = R_ARM_ABS32; - altmcount = "__gnu_mcount_nc"; - make_nop = make_nop_arm; - rel_type_nop = R_ARM_NONE; - break; case EM_AARCH64: - reltype = R_AARCH64_ABS64; - make_nop = make_nop_arm64; - rel_type_nop = R_AARCH64_NONE; - ideal_nop = ideal_nop4_arm64; - gpfx = '_'; - break; - case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; - case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; - case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; - case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; - case EM_S390: /* reltype: e_class */ gpfx = '_'; break; - case EM_SH: reltype = R_SH_DIR32; break; - case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break; + reltype = R_AARCH64_ABS64; + make_nop = make_nop_arm64; + rel_type_nop = R_AARCH64_NONE; + ideal_nop = ideal_nop4_arm64; + break; + case EM_IA_64: reltype = R_IA64_IMM64; break; + case EM_MIPS: /* reltype: e_class */ break; + case EM_PPC: reltype = R_PPC_ADDR32; break; + case EM_PPC64: reltype = R_PPC64_ADDR64; break; + case EM_S390: /* reltype: e_class */ break; + case EM_SH: reltype = R_SH_DIR32; gpfx = 0; break; + case EM_SPARCV9: reltype = R_SPARC_64; break; case EM_X86_64: make_nop = make_nop_x86; ideal_nop = ideal_nop5_x86_64; reltype = R_X86_64_64; rel_type_nop = R_X86_64_NONE; mcount_adjust_64 = -1; + gpfx = 0; break; } /* end switch */ -- cgit v1.2.3 From c97fea26254b284c93a67b788968622f9cc03b30 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 31 Jul 2019 11:24:15 -0700 Subject: recordmcount: Remove redundant cleanup() calls Redundant cleanup calls were introduced when transitioning from the old error/success handling via setjmp/longjmp -- the longjmp ensured the cleanup() call only happened once but replacing the success_file()/fail_file() calls with cleanup() meant that multiple cleanup() calls can happen as we return from function calls. In do_file(), looking just before and after the "goto out" jumps we can see that multiple cleanups() are being performed. We remove cleanup() calls from the nested functions because it makes the code easier to review -- the resources being cleaned up are generally allocated and initialized in the callers so freeing them there makes more sense. Other redundant cleanup() calls: mmap_file() is only called from do_file() and, if mmap_file() fails, then we goto out and do cleanup() there too. write_file() is only called from do_file() and do_file() calls cleanup() unconditionally after returning from write_file() therefore the cleanup() calls in write_file() are not necessary. find_secsym_ndx(), called from do_func()'s for-loop, when we are cleaning up here it's obvious that we break out of the loop and do another cleanup(). __has_rel_mcount() is called from two parts of do_func() and calls cleanup(). In theory we move them into do_func(), however these in turn prove redundant so another simplification step removes them as well. Link: http://lkml.kernel.org/r/de197e17fc5426623a847ea7cf3a1560a7402a4b.1564596289.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 13 ------------- scripts/recordmcount.h | 2 -- 2 files changed, 15 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 273ca8b42b20..5677fcc88a72 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -258,17 +258,14 @@ static void *mmap_file(char const *fname) fd_map = open(fname, O_RDONLY); if (fd_map < 0) { perror(fname); - cleanup(); return NULL; } if (fstat(fd_map, &sb) < 0) { perror(fname); - cleanup(); goto out; } if (!S_ISREG(sb.st_mode)) { fprintf(stderr, "not a regular file: %s\n", fname); - cleanup(); goto out; } file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, @@ -314,13 +311,11 @@ static int write_file(const char *fname) fd_map = open(tmp_file, O_WRONLY | O_TRUNC | O_CREAT, sb.st_mode); if (fd_map < 0) { perror(fname); - cleanup(); return -1; } n = write(fd_map, file_map, sb.st_size); if (n != sb.st_size) { perror("write"); - cleanup(); close(fd_map); return -1; } @@ -328,7 +323,6 @@ static int write_file(const char *fname) n = write(fd_map, file_append, file_append_size); if (n != file_append_size) { perror("write"); - cleanup(); close(fd_map); return -1; } @@ -336,7 +330,6 @@ static int write_file(const char *fname) close(fd_map); if (rename(tmp_file, fname) < 0) { perror(fname); - cleanup(); return -1; } return 0; @@ -460,7 +453,6 @@ static int do_file(char const *const fname) default: fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", ehdr->e_ident[EI_DATA], fname); - cleanup(); goto out; case ELFDATA2LSB: if (*(unsigned char const *)&endian != 1) { @@ -493,7 +485,6 @@ static int do_file(char const *const fname) w2(ehdr->e_type) != ET_REL || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { fprintf(stderr, "unrecognized ET_REL file %s\n", fname); - cleanup(); goto out; } @@ -502,7 +493,6 @@ static int do_file(char const *const fname) default: fprintf(stderr, "unrecognized e_machine %u %s\n", w2(ehdr->e_machine), fname); - cleanup(); goto out; case EM_386: reltype = R_386_32; @@ -546,14 +536,12 @@ static int do_file(char const *const fname) default: fprintf(stderr, "unrecognized ELF class %d %s\n", ehdr->e_ident[EI_CLASS], fname); - cleanup(); goto out; case ELFCLASS32: if (w2(ehdr->e_ehsize) != sizeof(Elf32_Ehdr) || w2(ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { fprintf(stderr, "unrecognized ET_REL file: %s\n", fname); - cleanup(); goto out; } if (w2(ehdr->e_machine) == EM_MIPS) { @@ -569,7 +557,6 @@ static int do_file(char const *const fname) || w2(ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { fprintf(stderr, "unrecognized ET_REL file: %s\n", fname); - cleanup(); goto out; } if (w2(ghdr->e_machine) == EM_S390) { diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index ca9aaac89bfb..8f0a278ce0af 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -463,7 +463,6 @@ static int find_secsym_ndx(unsigned const txtndx, } fprintf(stderr, "Cannot find symbol for section %u: %s.\n", txtndx, txtname); - cleanup(); return -1; } @@ -480,7 +479,6 @@ static char const * __has_rel_mcount(Elf_Shdr const *const relhdr, /* reltype */ if (strcmp("__mcount_loc", txtname) == 0) { fprintf(stderr, "warning: __mcount_loc already exists: %s\n", fname); - cleanup(); return already_has_rel_mcount; } if (w(txthdr->sh_type) != SHT_PROGBITS || -- cgit v1.2.3 From 4fbcf0741697a75eb766835cb34836cf4f3803da Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Wed, 31 Jul 2019 11:24:16 -0700 Subject: recordmcount: Clarify what cleanup() does cleanup() mostly frees/unmaps the malloc'd/privately-mapped copy of the ELF file recordmcount is working on, which is set up in mmap_file(). It also deals with positioning within the pseduo prive-mapping of the file and appending to the ELF file. Split into two steps: mmap_cleanup() for the mapping itself file_append_cleanup() for allocations storing the appended ELF data. Also, move the global variable initializations out of the main, per-object-file loop and nearer to the alloc/init (mmap_file()) and two cleanup functions so we can more clearly see how they're related. Link: http://lkml.kernel.org/r/2a387ac86d133d22c68f57b9933c32bab1d09a2d.1564596289.git.mhelsley@vmware.com Signed-off-by: Matt Helsley Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.c | 151 ++++++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 70 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 5677fcc88a72..612268eabef4 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -48,21 +48,26 @@ static void *file_map; /* pointer of the mapped file */ static void *file_end; /* pointer to the end of the mapped file */ static int file_updated; /* flag to state file was changed */ static void *file_ptr; /* current file pointer location */ + static void *file_append; /* added to the end of the file */ static size_t file_append_size; /* how much is added to end of file */ /* Per-file resource cleanup when multiple files. */ -static void cleanup(void) +static void file_append_cleanup(void) +{ + free(file_append); + file_append = NULL; + file_append_size = 0; + file_updated = 0; +} + +static void mmap_cleanup(void) { if (!mmap_failed) munmap(file_map, sb.st_size); else free(file_map); file_map = NULL; - free(file_append); - file_append = NULL; - file_append_size = 0; - file_updated = 0; } /* ulseek, uwrite, ...: Check return value for errors. */ @@ -103,7 +108,8 @@ static ssize_t uwrite(void const *const buf, size_t const count) } if (!file_append) { perror("write"); - cleanup(); + file_append_cleanup(); + mmap_cleanup(); return -1; } if (file_ptr < file_end) { @@ -129,12 +135,76 @@ static void * umalloc(size_t size) void *const addr = malloc(size); if (addr == 0) { fprintf(stderr, "malloc failed: %zu bytes\n", size); - cleanup(); + file_append_cleanup(); + mmap_cleanup(); return NULL; } return addr; } +/* + * Get the whole file as a programming convenience in order to avoid + * malloc+lseek+read+free of many pieces. If successful, then mmap + * avoids copying unused pieces; else just read the whole file. + * Open for both read and write; new info will be appended to the file. + * Use MAP_PRIVATE so that a few changes to the in-memory ElfXX_Ehdr + * do not propagate to the file until an explicit overwrite at the last. + * This preserves most aspects of consistency (all except .st_size) + * for simultaneous readers of the file while we are appending to it. + * However, multiple writers still are bad. We choose not to use + * locking because it is expensive and the use case of kernel build + * makes multiple writers unlikely. + */ +static void *mmap_file(char const *fname) +{ + /* Avoid problems if early cleanup() */ + fd_map = -1; + mmap_failed = 1; + file_map = NULL; + file_ptr = NULL; + file_updated = 0; + sb.st_size = 0; + + fd_map = open(fname, O_RDONLY); + if (fd_map < 0) { + perror(fname); + return NULL; + } + if (fstat(fd_map, &sb) < 0) { + perror(fname); + goto out; + } + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "not a regular file: %s\n", fname); + goto out; + } + file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, + fd_map, 0); + if (file_map == MAP_FAILED) { + mmap_failed = 1; + file_map = umalloc(sb.st_size); + if (!file_map) { + perror(fname); + goto out; + } + if (read(fd_map, file_map, sb.st_size) != sb.st_size) { + perror(fname); + free(file_map); + file_map = NULL; + goto out; + } + } else + mmap_failed = 0; +out: + close(fd_map); + fd_map = -1; + + file_end = file_map + sb.st_size; + + return file_map; +} + + static unsigned char ideal_nop5_x86_64[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 }; static unsigned char ideal_nop5_x86_32[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 }; static unsigned char *ideal_nop; @@ -238,61 +308,6 @@ static int make_nop_arm64(void *map, size_t const offset) return 0; } -/* - * Get the whole file as a programming convenience in order to avoid - * malloc+lseek+read+free of many pieces. If successful, then mmap - * avoids copying unused pieces; else just read the whole file. - * Open for both read and write; new info will be appended to the file. - * Use MAP_PRIVATE so that a few changes to the in-memory ElfXX_Ehdr - * do not propagate to the file until an explicit overwrite at the last. - * This preserves most aspects of consistency (all except .st_size) - * for simultaneous readers of the file while we are appending to it. - * However, multiple writers still are bad. We choose not to use - * locking because it is expensive and the use case of kernel build - * makes multiple writers unlikely. - */ -static void *mmap_file(char const *fname) -{ - file_map = NULL; - sb.st_size = 0; - fd_map = open(fname, O_RDONLY); - if (fd_map < 0) { - perror(fname); - return NULL; - } - if (fstat(fd_map, &sb) < 0) { - perror(fname); - goto out; - } - if (!S_ISREG(sb.st_mode)) { - fprintf(stderr, "not a regular file: %s\n", fname); - goto out; - } - file_map = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, - fd_map, 0); - mmap_failed = 0; - if (file_map == MAP_FAILED) { - mmap_failed = 1; - file_map = umalloc(sb.st_size); - if (!file_map) { - perror(fname); - goto out; - } - if (read(fd_map, file_map, sb.st_size) != sb.st_size) { - perror(fname); - free(file_map); - file_map = NULL; - goto out; - } - } -out: - close(fd_map); - - file_end = file_map + sb.st_size; - - return file_map; -} - static int write_file(const char *fname) { char tmp_file[strlen(fname) + 4]; @@ -438,10 +453,11 @@ static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type) static int do_file(char const *const fname) { - Elf32_Ehdr *const ehdr = mmap_file(fname); unsigned int reltype = 0; + Elf32_Ehdr *ehdr; int rc = -1; + ehdr = mmap_file(fname); if (!ehdr) goto out; @@ -577,7 +593,8 @@ static int do_file(char const *const fname) rc = write_file(fname); out: - cleanup(); + file_append_cleanup(); + mmap_cleanup(); return rc; } @@ -620,12 +637,6 @@ int main(int argc, char *argv[]) strcmp(file + (len - ftrace_size), ftrace) == 0) continue; - /* Avoid problems if early cleanup() */ - fd_map = -1; - mmap_failed = 1; - file_map = NULL; - file_ptr = NULL; - file_updated = 0; if (do_file(file)) { fprintf(stderr, "%s: failed\n", file); ++n_error; -- cgit v1.2.3 From 858805b336be1cabb3d9033adaa3676574d12e37 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Aug 2019 22:28:37 +0900 Subject: kbuild: add $(BASH) to run scripts with bash-extension CONFIG_SHELL falls back to sh when bash is not installed on the system, but nobody is testing such a case since bash is usually installed. So, shell scripts invoked by CONFIG_SHELL are only tested with bash. It makes it difficult to test whether the hashbang #!/bin/sh is real. For example, #!/bin/sh in arch/powerpc/kernel/prom_init_check.sh is false. (I fixed it up) Besides, some shell scripts invoked by CONFIG_SHELL use bash-extension and #!/bin/bash is specified as the hashbang, while CONFIG_SHELL may not always be set to bash. Probably, the right thing to do is to introduce BASH, which is bash by default, and always set CONFIG_SHELL to sh. Replace $(CONFIG_SHELL) with $(BASH) for bash scripts. If somebody tries to add bash-extension to a #!/bin/sh script, it will be caught in testing because /bin/sh is a symlink to dash on some major distributions. Signed-off-by: Masahiro Yamada --- Makefile | 11 +++++------ arch/mips/boot/Makefile | 2 +- arch/powerpc/Makefile.postlink | 2 +- arch/powerpc/kernel/prom_init_check.sh | 2 +- kernel/Makefile | 2 +- scripts/Makefile.lib | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/Makefile b/Makefile index db5706ceecad..06e1e21c0f45 100644 --- a/Makefile +++ b/Makefile @@ -404,9 +404,7 @@ KCONFIG_CONFIG ?= .config export KCONFIG_CONFIG # SHELL used by kbuild -CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ - else if [ -x /bin/bash ]; then echo /bin/bash; \ - else echo sh; fi ; fi) +CONFIG_SHELL := sh HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null) HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null) @@ -443,6 +441,7 @@ PYTHON = python PYTHON2 = python2 PYTHON3 = python3 CHECK = sparse +BASH = bash CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) @@ -488,7 +487,7 @@ KBUILD_LDFLAGS := GCC_PLUGINS_CFLAGS := CLANG_FLAGS := -export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC +export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL export PERL PYTHON PYTHON2 PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE @@ -1687,7 +1686,7 @@ clean: $(clean-dirs) # Generate tags for editors # --------------------------------------------------------------------------- quiet_cmd_tags = GEN $@ - cmd_tags = $(CONFIG_SHELL) $(srctree)/scripts/tags.sh $@ + cmd_tags = $(BASH) $(srctree)/scripts/tags.sh $@ tags TAGS cscope gtags: FORCE $(call cmd,tags) @@ -1708,7 +1707,7 @@ versioncheck: | xargs $(PERL) -w $(srctree)/scripts/checkversion.pl coccicheck: - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@ + $(Q)$(BASH) $(srctree)/scripts/$@ namespacecheck: $(PERL) $(srctree)/scripts/namespace.pl diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index 3ce4dd578370..528bd73d530a 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -160,7 +160,7 @@ targets += vmlinux.lzo.itb quiet_cmd_itb-image = ITB $@ cmd_itb-image = \ env PATH="$(objtree)/scripts/dtc:$(PATH)" \ - $(CONFIG_SHELL) $(MKIMAGE) \ + $(BASH) $(MKIMAGE) \ -D "-I dts -O dtb -p 500 \ --include $(objtree)/arch/mips \ --warning no-unit_address_vs_reg" \ diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink index 83f8e5ba2722..134f12f89b92 100644 --- a/arch/powerpc/Makefile.postlink +++ b/arch/powerpc/Makefile.postlink @@ -18,7 +18,7 @@ quiet_cmd_relocs_check = CHKREL $@ ifdef CONFIG_PPC_BOOK3S_64 cmd_relocs_check = \ $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \ - $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@" + $(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@" else cmd_relocs_check = \ $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 160bef0d553d..78bab17b1396 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh @@ -33,7 +33,7 @@ OBJ="$2" ERROR=0 -function check_section() +check_section() { file=$1 section=$2 diff --git a/kernel/Makefile b/kernel/Makefile index ef0d95a190b4..6027677f89e8 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -126,7 +126,7 @@ $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz -cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_kheaders.sh $@ + cmd_genikh = $(BASH) $(srctree)/kernel/gen_kheaders.sh $@ $(obj)/kheaders_data.tar.xz: FORCE $(call cmd,genikh) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 888e5c830646..7ab17712ab24 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -364,7 +364,7 @@ UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR) UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)' quiet_cmd_uimage = UIMAGE $@ - cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \ + cmd_uimage = $(BASH) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \ -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \ -T $(UIMAGE_TYPE) \ -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ -- cgit v1.2.3 From 389c9af7f1a1e564c18ab744528b7f64759b7875 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 27 Aug 2019 14:14:37 +0300 Subject: modpost: add guid_t type definition Since guid_t is the recommended data type for UUIDs in kernel (and I guess uuid_le is meant to be ultimately replaced with it), it should be made available here as well. Signed-off-by: Heikki Krogerus Signed-off-by: Masahiro Yamada --- scripts/mod/file2alias.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index e17a29ae2e97..c91eba751804 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -34,6 +34,11 @@ typedef Elf64_Addr kernel_ulong_t; typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; +typedef struct { + __u8 b[16]; +} guid_t; + +/* backwards compatibility, don't use in new code */ typedef struct { __u8 b[16]; } uuid_le; -- cgit v1.2.3 From 6f02bdfc995f098bde87216c122ade2b46f971b5 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Tue, 27 Aug 2019 15:20:23 +0300 Subject: modpost: add NOFAIL to strndup Add NOFAIL check for the strndup call, because the function allocates memory and can return NULL. All calls to strdup in modpost are checked with NOFAIL. Signed-off-by: Denis Efremov Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2773f9f9bae2..76c221dd9b2b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -797,9 +797,9 @@ static int match(const char *sym, const char * const pat[]) /* "*foo*" */ if (*p == '*' && *endp == '*') { - char *here, *bare = strndup(p + 1, strlen(p) - 2); + char *bare = NOFAIL(strndup(p + 1, strlen(p) - 2)); + char *here = strstr(sym, bare); - here = strstr(sym, bare); free(bare); if (here != NULL) return 1; -- cgit v1.2.3 From 54b8ae66ae1a3454a7645d159a482c31cd89ab33 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 30 Aug 2019 13:34:01 +0900 Subject: kbuild: change *FLAGS_.o to take the path relative to $(obj) Kbuild provides per-file compiler flag addition/removal: CFLAGS_.o CFLAGS_REMOVE_.o AFLAGS_.o AFLAGS_REMOVE_.o CPPFLAGS_.lds HOSTCFLAGS_.o HOSTCXXFLAGS_.o The is the filename of the target with its directory and suffix stripped. This syntax comes into a trouble when two files with the same basename appear in one Makefile, for example: obj-y += foo.o obj-y += dir/foo.o CFLAGS_foo.o := Here, the applies to both foo.o and dir/foo.o The real world problem is: scripts/kconfig/util.c scripts/kconfig/lxdialog/util.c Both files are compiled into scripts/kconfig/mconf, but only the latter should be given with the ncurses flags. It is more sensible to use the relative path to the Makefile, like this: obj-y += foo.o CFLAGS_foo.o := obj-y += dir/foo.o CFLAGS_dir/foo.o := At first, I attempted to replace $(basetarget) with $*. The $* variable is replaced with the stem ('%') part in a pattern rule. This works with most of cases, but does not for explicit rules. For example, arch/ia64/lib/Makefile reuses rule_as_o_S in its own explicit rules, so $* will be empty, resulting in ignoring the per-file AFLAGS. I introduced a new variable, target-stem, which can be used also from explicit rules. Signed-off-by: Masahiro Yamada Acked-by: Marc Zyngier --- arch/arm/kvm/Makefile | 5 +++-- arch/x86/entry/vdso/Makefile | 3 ++- drivers/gpu/drm/amd/display/dc/calcs/Makefile | 6 +++--- drivers/gpu/drm/amd/display/dc/dcn20/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/dml/Makefile | 17 +++++++---------- drivers/gpu/drm/amd/display/dc/dsc/Makefile | 7 +++---- drivers/gpu/drm/i915/Makefile | 2 +- scripts/Makefile.host | 22 +++++++++++----------- scripts/Makefile.lib | 13 ++++++++----- scripts/kconfig/Makefile | 8 ++++---- 10 files changed, 43 insertions(+), 42 deletions(-) (limited to 'scripts') diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 531e59f5be9c..b76b75bd9e00 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -8,13 +8,14 @@ ifeq ($(plus_virt),+virt) plus_virt_def := -DREQUIRES_VIRT=1 endif +KVM := ../../../virt/kvm + ccflags-y += -I $(srctree)/$(src) -I $(srctree)/virt/kvm/arm/vgic -CFLAGS_arm.o := $(plus_virt_def) +CFLAGS_$(KVM)/arm/arm.o := $(plus_virt_def) AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt) AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) -KVM := ../../../virt/kvm kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o obj-$(CONFIG_KVM_ARM_HOST) += hyp/ diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 8df549138193..0f2154106d01 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -89,6 +89,7 @@ $(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS # CFLAGS_REMOVE_vdso-note.o = -pg CFLAGS_REMOVE_vclock_gettime.o = -pg +CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg CFLAGS_REMOVE_vgetcpu.o = -pg CFLAGS_REMOVE_vvar.o = -pg @@ -128,7 +129,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE $(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE $(call if_changed,vdso_and_check) -CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) +CPPFLAGS_vdso32/vdso32.lds = $(CPPFLAGS_vdso.lds) VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1 targets += vdso32/vdso32.lds diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index 95f332ee3e7e..d930df63772c 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -32,9 +32,9 @@ endif calcs_ccflags := -mhard-float -msse $(cc_stack_align) -CFLAGS_dcn_calcs.o := $(calcs_ccflags) -CFLAGS_dcn_calc_auto.o := $(calcs_ccflags) -CFLAGS_dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare +CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calcs.o := $(calcs_ccflags) +CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calc_auto.o := $(calcs_ccflags) +CFLAGS_$(AMDDALPATH)/dc/calcs/dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile index e9721a906592..83635ad9124e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile @@ -16,7 +16,7 @@ else ifneq ($(call cc-option, -mstack-alignment=16),) cc_stack_align := -mstack-alignment=16 endif -CFLAGS_dcn20_resource.o := -mhard-float -msse $(cc_stack_align) +CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse $(cc_stack_align) AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20)) diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index 0bb7a20675c4..83792e2c0f0e 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -32,19 +32,16 @@ endif dml_ccflags := -mhard-float -msse $(cc_stack_align) -CFLAGS_display_mode_lib.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) ifdef CONFIG_DRM_AMD_DC_DCN2_0 -CFLAGS_display_mode_vba.o := $(dml_ccflags) -CFLAGS_display_mode_vba_20.o := $(dml_ccflags) -CFLAGS_display_rq_dlg_calc_20.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags) endif -ifdef CONFIG_DRM_AMD_DCN3AG -CFLAGS_display_mode_vba_3ag.o := $(dml_ccflags) -endif -CFLAGS_dml1_display_rq_dlg_calc.o := $(dml_ccflags) -CFLAGS_display_rq_dlg_helpers.o := $(dml_ccflags) -CFLAGS_dml_common_defs.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dml_common_defs.o := $(dml_ccflags) DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ dml_common_defs.o diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile index e019cd9447e8..c3922d6e7696 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile @@ -9,10 +9,9 @@ endif dsc_ccflags := -mhard-float -msse $(cc_stack_align) -CFLAGS_rc_calc.o := $(dsc_ccflags) -CFLAGS_rc_calc_dpi.o := $(dsc_ccflags) -CFLAGS_codec_main_amd.o := $(dsc_ccflags) -CFLAGS_dc_dsc.o := $(dsc_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc_dpi.o := $(dsc_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dsc/dc_dsc.o := $(dsc_ccflags) DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 8cace65f50ce..69c75484cc26 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -26,7 +26,7 @@ subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror # Fine grained warnings disable CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init) -CFLAGS_intel_fbdev.o = $(call cc-disable-warning, override-init) +CFLAGS_display/intel_fbdev.o = $(call cc-disable-warning, override-init) subdir-ccflags-y += \ $(call as-instr,movntdqa (%eax)$(comma)%xmm0,-DCONFIG_AS_MOVNTDQA) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index b402c619147d..4c51c95d40f4 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -80,9 +80,9 @@ host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs)) # Handle options to gcc. Support building with separate output directory _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ - $(HOSTCFLAGS_$(basetarget).o) + $(HOSTCFLAGS_$(target-stem).o) _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ - $(HOSTCXXFLAGS_$(basetarget).o) + $(HOSTCXXFLAGS_$(target-stem).o) # $(objtree)/$(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) @@ -102,7 +102,7 @@ hostcxx_flags = -Wp,-MD,$(depfile) $(_hostcxx_flags) # host-csingle -> Executable quiet_cmd_host-csingle = HOSTCC $@ cmd_host-csingle = $(HOSTCC) $(hostc_flags) $(KBUILD_HOSTLDFLAGS) -o $@ $< \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F)) + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) $(host-csingle): $(obj)/%: $(src)/%.c FORCE $(call if_changed_dep,host-csingle) @@ -110,8 +110,8 @@ $(host-csingle): $(obj)/%: $(src)/%.c FORCE # host-cmulti -> executable quiet_cmd_host-cmulti = HOSTLD $@ cmd_host-cmulti = $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ \ - $(addprefix $(obj)/,$($(@F)-objs)) \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F)) + $(addprefix $(obj)/, $($(target-stem)-objs)) \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) $(host-cmulti): FORCE $(call if_changed,host-cmulti) $(call multi_depend, $(host-cmulti), , -objs) @@ -128,8 +128,8 @@ $(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE quiet_cmd_host-cxxmulti = HOSTLD $@ cmd_host-cxxmulti = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -o $@ \ $(foreach o,objs cxxobjs,\ - $(addprefix $(obj)/,$($(@F)-$(o)))) \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F)) + $(addprefix $(obj)/, $($(target-stem)-$(o)))) \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) $(host-cxxmulti): FORCE $(call if_changed,host-cxxmulti) $(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs) @@ -161,8 +161,8 @@ $(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE # *.o -> .so shared library (host-cshlib) quiet_cmd_host-cshlib = HOSTLLD -shared $@ cmd_host-cshlib = $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \ - $(addprefix $(obj)/,$($(@F:.so=-objs))) \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F)) + $(addprefix $(obj)/, $($(target-stem)-objs)) \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem).so) $(host-cshlib): FORCE $(call if_changed,host-cshlib) $(call multi_depend, $(host-cshlib), .so, -objs) @@ -171,8 +171,8 @@ $(call multi_depend, $(host-cshlib), .so, -objs) # *.o -> .so shared library (host-cxxshlib) quiet_cmd_host-cxxshlib = HOSTLLD -shared $@ cmd_host-cxxshlib = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \ - $(addprefix $(obj)/,$($(@F:.so=-objs))) \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F)) + $(addprefix $(obj)/, $($(target-stem)-objs)) \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem).so) $(host-cxxshlib): FORCE $(call if_changed,host-cxxshlib) $(call multi_depend, $(host-cxxshlib), .so, -objs) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 7ab17712ab24..380a7d11a573 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -101,6 +101,9 @@ modname-multi = $(subst $(space),:,$(sort $(foreach m,$(multi-used),\ modname = $(if $(modname-multi),$(modname-multi),$(basetarget)) +# target with $(obj)/ and its suffix stripped +target-stem = $(basename $(patsubst $(obj)/%,%,$@)) + # These flags are needed for modversions and compiling, so we define them here # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) @@ -109,12 +112,12 @@ basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ - $(ccflags-y) $(CFLAGS_$(basetarget).o) -_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) + $(ccflags-y) $(CFLAGS_$(target-stem).o) +_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), $(orig_c_flags)) orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \ - $(asflags-y) $(AFLAGS_$(basetarget).o) -_a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags)) -_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) + $(asflags-y) $(AFLAGS_$(target-stem).o) +_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), $(orig_a_flags)) +_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds) # # Enable gcov profiling flags for a file, directory or for all files depending diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index bed7a5a2fbe9..ef2f2336c469 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -166,15 +166,15 @@ $(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/nconf-cfg # mconf: Used for the menuconfig target based on lxdialog hostprogs-y += mconf -lxdialog := checklist.o inputbox.o menubox.o textbox.o util.o yesno.o -mconf-objs := mconf.o $(addprefix lxdialog/, $(lxdialog)) $(common-objs) +lxdialog := $(addprefix lxdialog/, \ + checklist.o inputbox.o menubox.o textbox.o util.o yesno.o) +mconf-objs := mconf.o $(lxdialog) $(common-objs) HOSTLDLIBS_mconf = $(shell . $(obj)/mconf-cfg && echo $$libs) $(foreach f, mconf.o $(lxdialog), \ $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/mconf-cfg && echo $$$$cflags))) -$(obj)/mconf.o: $(obj)/mconf-cfg -$(addprefix $(obj)/lxdialog/, $(lxdialog)): $(obj)/mconf-cfg +$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg # qconf: Used for the xconfig target based on Qt hostprogs-y += qconf -- cgit v1.2.3 From 60bef52c7a68257048f34ce32b8300def71a3de0 Mon Sep 17 00:00:00 2001 From: Guillaume Tucker Date: Mon, 2 Sep 2019 16:18:36 +0100 Subject: merge_config.sh: ignore unwanted grep errors The merge_config.sh script verifies that all the config options have their expected value in the resulting file and prints any issues as warnings. These checks aren't intended to be treated as errors given the current implementation. However, since "set -e" was added, if the grep command to look for a config option does not find it the script will then abort prematurely. Handle the case where the grep exit status is non-zero by setting ACTUAL_VAL to an empty string to restore previous functionality. Fixes: cdfca821571d ("merge_config.sh: Check error codes from make") Signed-off-by: Guillaume Tucker Acked-by: Jon Hunter Tested-by: Jon Hunter Signed-off-by: Masahiro Yamada --- scripts/kconfig/merge_config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index bec246719aea..63c8565206a4 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -179,7 +179,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) - ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG") + ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then echo "Value requested for $CFG not in final .config" echo "Requested value: $REQUESTED_VAL" -- cgit v1.2.3 From ca7ce5a2710ad2a57bf7d0c4c712590bb69a5e1c Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 6 Sep 2019 11:30:06 +0800 Subject: coccinelle: platform_get_irq: Fix parse error When do coccicheck, I get this error: spatch -D report --no-show-diff --very-quiet --cocci-file ./scripts/coccinelle/api/platform_get_irq.cocci --include-headers --dir . -I ./arch/x86/include -I ./arch/x86/include/generated -I ./include -I ./arch/x86/include/uapi -I ./arch/x86/include/generated/uapi -I ./include/uapi -I ./include/generated/uapi --include ./include/linux/kconfig.h --jobs 192 --chunksize 1 minus: parse error: File "./scripts/coccinelle/api/platform_get_irq.cocci", line 24, column 9, charpos = 355 around = '\(', whole content = if ( ret \( < \| <= \) 0 ) In commit e56476897448 ("fpga: Remove dev_err() usage after platform_get_irq()") log, I found the semantic patch, it fix this issue. Fixes: 98051ba2b28b ("coccinelle: Add script to check for platform_get_irq() excessive prints") Signed-off-by: YueHaibing Reviewed-by: Stephen Boyd Acked-by: Julia Lawall Link: https://lore.kernel.org/r/20190906033006.17616-1-yuehaibing@huawei.com Signed-off-by: Greg Kroah-Hartman --- scripts/coccinelle/api/platform_get_irq.cocci | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/api/platform_get_irq.cocci b/scripts/coccinelle/api/platform_get_irq.cocci index f6e1afc08c0b..06b6a95e2bfc 100644 --- a/scripts/coccinelle/api/platform_get_irq.cocci +++ b/scripts/coccinelle/api/platform_get_irq.cocci @@ -21,7 +21,7 @@ platform_get_irq platform_get_irq_byname )(E, ...); -if ( ret \( < \| <= \) 0 ) +if ( \( ret < 0 \| ret <= 0 \) ) { ( if (ret != -EPROBE_DEFER) @@ -47,7 +47,7 @@ platform_get_irq platform_get_irq_byname )(E, ...); -if ( ret \( < \| <= \) 0 ) +if ( \( ret < 0 \| ret <= 0 \) ) { ( -if (ret != -EPROBE_DEFER) @@ -74,7 +74,7 @@ platform_get_irq platform_get_irq_byname )(E, ...); -if ( ret \( < \| <= \) 0 ) +if ( \( ret < 0 \| ret <= 0 \) ) { ( if (ret != -EPROBE_DEFER) -- cgit v1.2.3 From 64a91907c896247c19f8314add2c9baa573fbd3c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 Sep 2019 01:25:54 +0900 Subject: kbuild: refactor scripts/Makefile.extrawarn Instead of the warning-[123] magic, let's accumulate compiler options to KBUILD_CFLAGS directly as the top Makefile does. I think this makes it easier to understand what is going on in this file. This commit slightly changes the behavior, I think all of which are OK. [1] Currently, cc-option calls are needlessly evaluated. For example, warning-3 += $(call cc-option, -Wpacked-bitfield-compat) needs evaluating only when W=3, but it is actually evaluated for W=1, W=2 as well. With this commit, only relevant cc-option calls will be evaluated. This is a slight optimization. [2] Currently, unsupported level like W=4 is checked by: $(error W=$(KBUILD_ENABLE_EXTRA_GCC_CHECKS) is unknown) This will no longer be checked, but I do not think it is a big deal. [3] Currently, 4 Clang warnings (Winitializer-overrides, Wformat, Wsign-compare, Wformat-zero-length) are shown by any of W=1, W=2, and W=3. With this commit, they will be warned only by W=1. I think this is a more correct behavior since each warning belongs to only one group. For understanding this commit correctly: We have 3 warning groups, W=1, W=2, and W=3. You may think W=3 has a higher level than W=1, but they are actually independent. If you like, you can combine them like W=13. To enable all the warnings, you can pass W=123. It is shown by 'make help', but not noticed much. Since we support W= combination, there should not exist intersection among the three groups. If we enable Winitializer-overrides for W=1, we do not need to for W=2 or W=3. This is the reason why I think the change [3] makes sense. The documentation says -Winitializer-overrides is enabled by default. (https://clang.llvm.org/docs/DiagnosticsReference.html#winitializer-overrides) We negate it by passing -Wno-initializer-overrides for the normal build, but we do not do that for W=1. This means, W=1 effectively enables -Winitializer-overrides by the clang's default. The same for the other three. Add comments in case people are confused with the code. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Tested-by: Sedat Dilek Acked-by: Nick Desaulniers Acked-by: Miguel Ojeda --- scripts/Makefile.extrawarn | 106 ++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 50 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index a74ce2e3c33e..d226c5fb13e2 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -1,14 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 # ========================================================================== -# # make W=... settings # -# W=1 - warnings that may be relevant and does not occur too often -# W=2 - warnings that occur quite often but may still be relevant -# W=3 - the more obscure warnings, can most likely be ignored -# -# $(call cc-option, -W...) handles gcc -W.. options which -# are not supported by all versions of the compiler +# There are three warning groups enabled by W=1, W=2, W=3. +# They are independent, and can be combined like W=12 or W=123. # ========================================================================== KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) @@ -17,58 +12,69 @@ ifeq ("$(origin W)", "command line") export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W) endif -ifdef KBUILD_ENABLE_EXTRA_GCC_CHECKS -warning- := $(empty) +# +# W=1 - warnings which may be relevant and do not occur too often +# +ifneq ($(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) -warning-1 := -Wextra -Wunused -Wno-unused-parameter -warning-1 += -Wmissing-declarations -warning-1 += -Wmissing-format-attribute -warning-1 += -Wmissing-prototypes -warning-1 += -Wold-style-definition -warning-1 += -Wmissing-include-dirs -warning-1 += $(call cc-option, -Wunused-but-set-variable) -warning-1 += $(call cc-option, -Wunused-const-variable) -warning-1 += $(call cc-option, -Wpacked-not-aligned) -warning-1 += $(call cc-option, -Wstringop-truncation) +KBUILD_CFLAGS += -Wextra -Wunused -Wno-unused-parameter +KBUILD_CFLAGS += -Wmissing-declarations +KBUILD_CFLAGS += -Wmissing-format-attribute +KBUILD_CFLAGS += -Wmissing-prototypes +KBUILD_CFLAGS += -Wold-style-definition +KBUILD_CFLAGS += -Wmissing-include-dirs +KBUILD_CFLAGS += $(call cc-option, -Wunused-but-set-variable) +KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) +KBUILD_CFLAGS += $(call cc-option, -Wpacked-not-aligned) +KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation) # The following turn off the warnings enabled by -Wextra -warning-1 += -Wno-missing-field-initializers -warning-1 += -Wno-sign-compare - -warning-2 += -Wcast-align -warning-2 += -Wdisabled-optimization -warning-2 += -Wnested-externs -warning-2 += -Wshadow -warning-2 += $(call cc-option, -Wlogical-op) -warning-2 += -Wmissing-field-initializers -warning-2 += -Wsign-compare -warning-2 += $(call cc-option, -Wmaybe-uninitialized) -warning-2 += $(call cc-option, -Wunused-macros) - -warning-3 := -Wbad-function-cast -warning-3 += -Wcast-qual -warning-3 += -Wconversion -warning-3 += -Wpacked -warning-3 += -Wpadded -warning-3 += -Wpointer-arith -warning-3 += -Wredundant-decls -warning-3 += -Wswitch-default -warning-3 += $(call cc-option, -Wpacked-bitfield-compat) - -warning := $(warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) -warning += $(warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) -warning += $(warning-$(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS))) - -ifeq ("$(strip $(warning))","") - $(error W=$(KBUILD_ENABLE_EXTRA_GCC_CHECKS) is unknown) -endif +KBUILD_CFLAGS += -Wno-missing-field-initializers +KBUILD_CFLAGS += -Wno-sign-compare -KBUILD_CFLAGS += $(warning) else +# Some diagnostics enabled by default are noisy. +# Suppress them by using -Wno... except for W=1. + ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length endif + +endif + +# +# W=2 - warnings which occur quite often but may still be relevant +# +ifneq ($(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) + +KBUILD_CFLAGS += -Wcast-align +KBUILD_CFLAGS += -Wdisabled-optimization +KBUILD_CFLAGS += -Wnested-externs +KBUILD_CFLAGS += -Wshadow +KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) +KBUILD_CFLAGS += -Wmissing-field-initializers +KBUILD_CFLAGS += -Wsign-compare +KBUILD_CFLAGS += $(call cc-option, -Wmaybe-uninitialized) +KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) + +endif + +# +# W=3 - more obscure warnings, can most likely be ignored +# +ifneq ($(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) + +KBUILD_CFLAGS += -Wbad-function-cast +KBUILD_CFLAGS += -Wcast-qual +KBUILD_CFLAGS += -Wconversion +KBUILD_CFLAGS += -Wpacked +KBUILD_CFLAGS += -Wpadded +KBUILD_CFLAGS += -Wpointer-arith +KBUILD_CFLAGS += -Wredundant-decls +KBUILD_CFLAGS += -Wswitch-default +KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat) + endif -- cgit v1.2.3 From e27128db62834c5b906585c2d97f0ddd431fa28f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 Sep 2019 01:25:55 +0900 Subject: kbuild: rename KBUILD_ENABLE_EXTRA_GCC_CHECKS to KBUILD_EXTRA_WARN KBUILD_ENABLE_EXTRA_GCC_CHECKS started as a switch to add extra warning options for GCC, but now it is a historical misnomer since we use it also for Clang, DTC, and even kernel-doc. Rename it to more sensible, shorter KBUILD_EXTRA_WARN. For the backward compatibility, KBUILD_ENABLE_EXTRA_GCC_CHECKS is still supported (but not advertised in the documentation). I also fixed up 'make help', and updated the documentation. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Reviewed-by: Sedat Dilek --- Documentation/kbuild/kbuild.rst | 14 +++++++++----- Makefile | 2 +- scripts/Makefile.build | 2 +- scripts/Makefile.extrawarn | 13 +++++++++---- scripts/Makefile.lib | 4 ++-- scripts/genksyms/Makefile | 2 +- 6 files changed, 23 insertions(+), 14 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst index 62f9d86c082c..f1e5dce86af7 100644 --- a/Documentation/kbuild/kbuild.rst +++ b/Documentation/kbuild/kbuild.rst @@ -105,6 +105,15 @@ The output directory can also be specified using "O=...". Setting "O=..." takes precedence over KBUILD_OUTPUT. +KBUILD_EXTRA_WARN +----------------- +Specify the extra build checks. The same value can be assigned by passing +W=... from the command line. + +See `make help` for the list of the supported values. + +Setting "W=..." takes precedence over KBUILD_EXTRA_WARN. + KBUILD_DEBARCH -------------- For the deb-pkg target, allows overriding the normal heuristics deployed by @@ -241,11 +250,6 @@ To get all available archs you can also specify all. E.g.:: $ make ALLSOURCE_ARCHS=all tags -KBUILD_ENABLE_EXTRA_GCC_CHECKS ------------------------------- -If enabled over the make command line with "W=1", it turns on additional -gcc -W... options for more extensive build-time checking. - KBUILD_BUILD_TIMESTAMP ---------------------- Setting this to a date string overrides the timestamp used in the diff --git a/Makefile b/Makefile index 06e1e21c0f45..adc0cabe2382 100644 --- a/Makefile +++ b/Makefile @@ -1538,7 +1538,7 @@ help: @echo ' make C=1 [targets] Check re-compiled c source with $$CHECK (sparse by default)' @echo ' make C=2 [targets] Force check of all c source with $$CHECK' @echo ' make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections' - @echo ' make W=n [targets] Enable extra gcc checks, n=1,2,3 where' + @echo ' make W=n [targets] Enable extra build checks, n=1,2,3 where' @echo ' 1: warnings which may be relevant and do not occur too often' @echo ' 2: warnings which occur quite often but may still be relevant' @echo ' 3: more obscure warnings, can most likely be ignored' diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 2a21ca86b720..f72aba64d611 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -85,7 +85,7 @@ else ifeq ($(KBUILD_CHECKSRC),2) cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< endif -ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) +ifneq ($(KBUILD_EXTRA_WARN),) cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< endif diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index d226c5fb13e2..53eb7e0c6a5a 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -8,14 +8,19 @@ KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) +# backward compatibility +KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS) + ifeq ("$(origin W)", "command line") - export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W) + KBUILD_EXTRA_WARN := $(W) endif +export KBUILD_EXTRA_WARN + # # W=1 - warnings which may be relevant and do not occur too often # -ifneq ($(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) +ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wextra -Wunused -Wno-unused-parameter KBUILD_CFLAGS += -Wmissing-declarations @@ -48,7 +53,7 @@ endif # # W=2 - warnings which occur quite often but may still be relevant # -ifneq ($(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) +ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wcast-align KBUILD_CFLAGS += -Wdisabled-optimization @@ -65,7 +70,7 @@ endif # # W=3 - more obscure warnings, can most likely be ignored # -ifneq ($(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) +ifneq ($(findstring 3, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wbad-function-cast KBUILD_CFLAGS += -Wcast-qual diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 380a7d11a573..4a0cdd6f5909 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -251,7 +251,7 @@ quiet_cmd_gzip = GZIP $@ DTC ?= $(objtree)/scripts/dtc/dtc # Disable noisy checks by default -ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) +ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) DTC_FLAGS += -Wno-unit_address_vs_reg \ -Wno-unit_address_format \ -Wno-avoid_unnecessary_addr_size \ @@ -262,7 +262,7 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \ -Wno-pci_device_reg endif -ifneq ($(findstring 2,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) +ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),) DTC_FLAGS += -Wnode_name_chars_strict \ -Wproperty_name_chars_strict endif diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index baf44ed0a93a..78629f515e78 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -12,7 +12,7 @@ genksyms-objs := genksyms.o parse.tab.o lex.lex.o # # Just in case, run "$(YACC) --version" without suppressing stderr # so that 'bison: not found' will be displayed if it is missing. -ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) +ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) quiet_cmd_bison_no_warn = $(quiet_cmd_bison) cmd_bison_no_warn = $(YACC) --version >/dev/null; \ -- cgit v1.2.3 From 618916a4bf169450e4680173a4b105a1816a7d6d Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Thu, 5 Sep 2019 10:59:38 -0700 Subject: kbuild: replace BASH-specific ${@:2} with shift and ${@} ${@:2} is BASH-specific extension, which makes link-vmlinux.sh rely on BASH. Use shift and ${@} instead to fix this issue. Reported-by: Stephen Rothwell Fixes: 341dfcf8d78e ("btf: expose BTF info through sysfs") Cc: Stephen Rothwell Cc: Masahiro Yamada Signed-off-by: Andrii Nakryiko Acked-by: Yonghong Song Reviewed-by: Masahiro Yamada Signed-off-by: Alexei Starovoitov --- scripts/link-vmlinux.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 0d8f41db8cd6..8c59970a09dc 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -57,12 +57,16 @@ modpost_link() # Link of vmlinux # ${1} - output file -# ${@:2} - optional extra .o files +# ${2}, ${3}, ... - optional extra .o files vmlinux_link() { local lds="${objtree}/${KBUILD_LDS}" + local output=${1} local objects + # skip output file argument + shift + if [ "${SRCARCH}" != "um" ]; then objects="--whole-archive \ ${KBUILD_VMLINUX_OBJS} \ @@ -70,9 +74,10 @@ vmlinux_link() --start-group \ ${KBUILD_VMLINUX_LIBS} \ --end-group \ - ${@:2}" + ${@}" - ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${1} \ + ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \ + -o ${output} \ -T ${lds} ${objects} else objects="-Wl,--whole-archive \ @@ -81,9 +86,10 @@ vmlinux_link() -Wl,--start-group \ ${KBUILD_VMLINUX_LIBS} \ -Wl,--end-group \ - ${@:2}" + ${@}" - ${CC} ${CFLAGS_vmlinux} -o ${1} \ + ${CC} ${CFLAGS_vmlinux} \ + -o ${output} \ -Wl,-T,${lds} \ ${objects} \ -lutil -lrt -lpthread -- cgit v1.2.3 From 6863f5643dd717376c2fdc85a47a00f9d738a834 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Sep 2019 11:52:36 +0900 Subject: kbuild: allow Clang to find unused static inline functions for W=1 build GCC and Clang have different policy for -Wunused-function; GCC does not warn unused static inline functions at all whereas Clang does if they are defined in source files instead of included headers although it has been suppressed since commit abb2ea7dfd82 ("compiler, clang: suppress warning for unused static inline functions"). We often miss to delete unused functions where 'static inline' is used in *.c files since there is no tool to detect them. Unused code remains until somebody notices. For example, commit 075ddd75680f ("regulator: core: remove unused rdev_get_supply()"). Let's remove __maybe_unused from the inline macro to allow Clang to start finding unused static inline functions. For now, we do this only for W=1 build since it is not a good idea to sprinkle warnings for the normal build (e.g. 35 warnings for arch/x86/configs/x86_64_defconfig). My initial attempt was to add -Wno-unused-function for no W= build (https://lore.kernel.org/patchwork/patch/1120594/) Nathan Chancellor pointed out that would weaken Clang's checks since we would no longer get -Wunused-function without W=1. It is true GCC would catch unused static non-inline functions, but it would weaken Clang as a standalone compiler, at least. Hence, here is a counter implementation. The current problem is, W=... only controls compiler flags, which are globally effective. There is no way to address only 'static inline' functions. This commit defines KBUILD_EXTRA_WARN[123] corresponding to W=[123]. When KBUILD_EXTRA_WARN1 is defined, __maybe_unused is omitted from the 'inline' macro. The new macro __inline_maybe_unused makes the code a bit uglier, so I hope we can remove it entirely after fixing most of the warnings. If you contribute to code clean-up, please run "make CC=clang W=1" and check -Wunused-function warnings. You will find lots of unused functions. Some of them are false-positives because the call-sites are disabled by #ifdef. I do not like to abuse the inline keyword for suppressing unused-function warnings because it is intended to be a hint for the compiler optimization. I prefer #ifdef around the definition, or __maybe_unused if #ifdef would make the code too ugly. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor --- include/linux/compiler_types.h | 20 ++++++++++++++------ scripts/Makefile.extrawarn | 6 ++++++ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 599c27b56c29..b056a40116da 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -130,10 +130,6 @@ struct ftrace_likely_data { /* * Force always-inline if the user requests it so via the .config. - * GCC does not warn about unused static inline functions for - * -Wunused-function. This turns out to avoid the need for complex #ifdef - * directives. Suppress the warning in clang as well by using "unused" - * function attribute, which is redundant but not harmful for gcc. * Prefer gnu_inline, so that extern inline functions do not emit an * externally visible function. This makes extern inline behave as per gnu89 * semantics rather than c99. This prevents multiple symbol definition errors @@ -144,15 +140,27 @@ struct ftrace_likely_data { */ #if !defined(CONFIG_OPTIMIZE_INLINING) #define inline inline __attribute__((__always_inline__)) __gnu_inline \ - __maybe_unused notrace + __inline_maybe_unused notrace #else #define inline inline __gnu_inline \ - __maybe_unused notrace + __inline_maybe_unused notrace #endif #define __inline__ inline #define __inline inline +/* + * GCC does not warn about unused static inline functions for -Wunused-function. + * Suppress the warning in clang as well by using __maybe_unused, but enable it + * for W=1 build. This will allow clang to find unused functions. Remove the + * __inline_maybe_unused entirely after fixing most of -Wunused-function warnings. + */ +#ifdef KBUILD_EXTRA_WARN1 +#define __inline_maybe_unused +#else +#define __inline_maybe_unused __maybe_unused +#endif + /* * Rather then using noinline to prevent stack consumption, use * noinline_for_stack instead. For documentation reasons. diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 53eb7e0c6a5a..ecddf83ac142 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -36,6 +36,8 @@ KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation) KBUILD_CFLAGS += -Wno-missing-field-initializers KBUILD_CFLAGS += -Wno-sign-compare +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 + else # Some diagnostics enabled by default are noisy. @@ -65,6 +67,8 @@ KBUILD_CFLAGS += -Wsign-compare KBUILD_CFLAGS += $(call cc-option, -Wmaybe-uninitialized) KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 + endif # @@ -82,4 +86,6 @@ KBUILD_CFLAGS += -Wredundant-decls KBUILD_CFLAGS += -Wswitch-default KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat) +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3 + endif -- cgit v1.2.3 From cb9b55d21fe06ca5e4ba244bb5aac0afeb745c8e Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 6 Sep 2019 11:32:28 +0100 Subject: modpost: add support for symbol namespaces Add support for symbols that are exported into namespaces. For that, extract any namespace suffix from the symbol name. In addition, emit a warning whenever a module refers to an exported symbol without explicitly importing the namespace that it is defined in. This patch consistently adds the namespace suffix to symbol names exported into Module.symvers. Example warning emitted by modpost in case of the above violation: WARNING: module ums-usbat uses symbol usb_stor_resume from namespace USB_STORAGE, but does not import it. Co-developed-by: Martijn Coenen Signed-off-by: Martijn Coenen Reviewed-by: Joel Fernandes (Google) Reviewed-by: Greg Kroah-Hartman Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- Documentation/kbuild/modules.rst | 7 ++- scripts/export_report.pl | 2 +- scripts/mod/modpost.c | 104 +++++++++++++++++++++++++++++++++------ scripts/mod/modpost.h | 7 +++ 4 files changed, 101 insertions(+), 19 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/modules.rst b/Documentation/kbuild/modules.rst index 24e763482650..d2ae799237fd 100644 --- a/Documentation/kbuild/modules.rst +++ b/Documentation/kbuild/modules.rst @@ -470,9 +470,12 @@ build. The syntax of the Module.symvers file is:: - + - 0x2d036834 scsi_remove_host drivers/scsi/scsi_mod + 0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL + + The fields are separated by tabs and values may be empty (e.g. + if no namespace is defined for an exported symbol). For a kernel build without CONFIG_MODVERSIONS enabled, the CRC would read 0x00000000. diff --git a/scripts/export_report.pl b/scripts/export_report.pl index 7d3030d03a25..548330e8c4e7 100755 --- a/scripts/export_report.pl +++ b/scripts/export_report.pl @@ -94,7 +94,7 @@ if (defined $opt{'o'}) { # while ( <$module_symvers> ) { chomp; - my (undef, $symbol, $module, $gpl) = split; + my (undef, $symbol, $namespace, $module, $gpl) = split('\t'); $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; } close($module_symvers); diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f277e116e0eb..c2d49afaea1c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -164,6 +164,7 @@ struct symbol { struct module *module; unsigned int crc; int crc_valid; + const char *namespace; unsigned int weak:1; unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ unsigned int kernel:1; /* 1 if symbol is from kernel @@ -233,6 +234,37 @@ static struct symbol *find_symbol(const char *name) return NULL; } +static bool contains_namespace(struct namespace_list *list, + const char *namespace) +{ + struct namespace_list *ns_entry; + + for (ns_entry = list; ns_entry != NULL; ns_entry = ns_entry->next) + if (strcmp(ns_entry->namespace, namespace) == 0) + return true; + + return false; +} + +static void add_namespace(struct namespace_list **list, const char *namespace) +{ + struct namespace_list *ns_entry; + + if (!contains_namespace(*list, namespace)) { + ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) + + strlen(namespace) + 1)); + strcpy(ns_entry->namespace, namespace); + ns_entry->next = *list; + *list = ns_entry; + } +} + +static bool module_imports_namespace(struct module *module, + const char *namespace) +{ + return contains_namespace(module->imported_namespaces, namespace); +} + static const struct { const char *str; enum export export; @@ -312,23 +344,39 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) return export_unknown; } +static const char *sym_extract_namespace(const char **symname) +{ + size_t n; + char *dupsymname; + + n = strcspn(*symname, "."); + if (n < strlen(*symname) - 1) { + dupsymname = NOFAIL(strdup(*symname)); + dupsymname[n] = '\0'; + *symname = dupsymname; + return dupsymname + n + 1; + } + + return NULL; +} + /** * Add an exported symbol - it may have already been added without a * CRC, in this case just update the CRC **/ -static struct symbol *sym_add_exported(const char *name, struct module *mod, - enum export export) +static struct symbol *sym_add_exported(const char *name, const char *namespace, + struct module *mod, enum export export) { struct symbol *s = find_symbol(name); if (!s) { s = new_symbol(name, mod, export); + s->namespace = namespace; } else { if (!s->preloaded) { - warn("%s: '%s' exported twice. Previous export " - "was in %s%s\n", mod->name, name, - s->module->name, - is_vmlinux(s->module->name) ?"":".ko"); + warn("%s: '%s' exported twice. Previous export was in %s%s\n", + mod->name, name, s->module->name, + is_vmlinux(s->module->name) ? "" : ".ko"); } else { /* In case Module.symvers was out of date */ s->module = mod; @@ -620,6 +668,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, unsigned int crc; enum export export; bool is_crc = false; + const char *name, *namespace; if ((!is_vmlinux(mod->name) || mod->is_dot_o) && strstarts(symname, "__ksymtab")) @@ -691,8 +740,9 @@ static void handle_modversions(struct module *mod, struct elf_info *info, default: /* All exported symbols */ if (strstarts(symname, "__ksymtab_")) { - sym_add_exported(symname + strlen("__ksymtab_"), mod, - export); + name = symname + strlen("__ksymtab_"); + namespace = sym_extract_namespace(&name); + sym_add_exported(name, namespace, mod, export); } if (strcmp(symname, "init_module") == 0) mod->has_init = 1; @@ -1943,6 +1993,7 @@ static void read_symbols(const char *modname) const char *symname; char *version; char *license; + char *namespace; struct module *mod; struct elf_info info = { }; Elf_Sym *sym; @@ -1974,6 +2025,12 @@ static void read_symbols(const char *modname) license = get_next_modinfo(&info, "license", license); } + namespace = get_modinfo(&info, "import_ns"); + while (namespace) { + add_namespace(&mod->imported_namespaces, namespace); + namespace = get_next_modinfo(&info, "import_ns", namespace); + } + for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { symname = remove_dot(info.strtab + sym->st_name); @@ -2118,6 +2175,13 @@ static int check_exports(struct module *mod) basename++; else basename = mod->name; + + if (exp->namespace && + !module_imports_namespace(mod, exp->namespace)) { + warn("module %s uses symbol %s from namespace %s, but does not import it.\n", + basename, exp->name, exp->namespace); + } + if (!mod->gpl_compatible) check_for_gpl_usage(exp->export, basename, exp->name); check_for_unused(exp->export, basename, exp->name); @@ -2341,7 +2405,7 @@ static void read_dump(const char *fname, unsigned int kernel) return; while ((line = get_next_line(&pos, file, size))) { - char *symname, *modname, *d, *export, *end; + char *symname, *namespace, *modname, *d, *export, *end; unsigned int crc; struct module *mod; struct symbol *s; @@ -2349,7 +2413,10 @@ static void read_dump(const char *fname, unsigned int kernel) if (!(symname = strchr(line, '\t'))) goto fail; *symname++ = '\0'; - if (!(modname = strchr(symname, '\t'))) + if (!(namespace = strchr(symname, '\t'))) + goto fail; + *namespace++ = '\0'; + if (!(modname = strchr(namespace, '\t'))) goto fail; *modname++ = '\0'; if ((export = strchr(modname, '\t')) != NULL) @@ -2366,7 +2433,8 @@ static void read_dump(const char *fname, unsigned int kernel) mod = new_module(modname); mod->skip = 1; } - s = sym_add_exported(symname, mod, export_no(export)); + s = sym_add_exported(symname, namespace, mod, + export_no(export)); s->kernel = kernel; s->preloaded = 1; sym_update_crc(symname, mod, crc, export_no(export)); @@ -2395,16 +2463,20 @@ static void write_dump(const char *fname) { struct buffer buf = { }; struct symbol *symbol; + const char *namespace; int n; for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { symbol = symbolhash[n]; while (symbol) { - if (dump_sym(symbol)) - buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n", - symbol->crc, symbol->name, - symbol->module->name, - export_str(symbol->export)); + if (dump_sym(symbol)) { + namespace = symbol->namespace; + buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", + symbol->crc, symbol->name, + namespace ? namespace : "", + symbol->module->name, + export_str(symbol->export)); + } symbol = symbol->next; } } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 8453d6ac2f77..9626bf3e7424 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -109,6 +109,11 @@ buf_printf(struct buffer *buf, const char *fmt, ...); void buf_write(struct buffer *buf, const char *s, int len); +struct namespace_list { + struct namespace_list *next; + char namespace[0]; +}; + struct module { struct module *next; const char *name; @@ -121,6 +126,8 @@ struct module { struct buffer dev_table_buf; char srcversion[25]; int is_dot_o; + // Actual imported namespaces + struct namespace_list *imported_namespaces; }; struct elf_info { -- cgit v1.2.3 From 1d082773ff30e97c8bc10b65c4aa0d073664caac Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 6 Sep 2019 11:32:31 +0100 Subject: modpost: add support for generating namespace dependencies This patch adds an option to modpost to generate a .ns_deps file per module, containing the namespace dependencies for that module. E.g. if the linked module my-module.ko would depend on the symbol myfunc.MY_NS in the namespace MY_NS, the my-module.ns_deps file created by modpost would contain the entry MY_NS to express the namespace dependency of my-module imposed by using the symbol myfunc. These files can subsequently be used by static analysis tools (like coccinelle scripts) to address issues with missing namespace imports. A later patch of this series will introduce such a script 'nsdeps' and a corresponding make target to automatically add missing MODULE_IMPORT_NS() definitions to the module's sources. For that it uses the information provided in the generated .ns_deps files. Co-developed-by: Martijn Coenen Signed-off-by: Martijn Coenen Reviewed-by: Greg Kroah-Hartman Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- .gitignore | 1 + Makefile | 2 +- scripts/mod/modpost.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++----- scripts/mod/modpost.h | 2 ++ 4 files changed, 53 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/.gitignore b/.gitignore index 2030c7a4d2f8..9ee63aa2a3fb 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ *.lzo *.mod *.mod.c +*.ns_deps *.o *.o.* *.order diff --git a/Makefile b/Makefile index 0cbe8717bdb3..0cdb957ae2c3 100644 --- a/Makefile +++ b/Makefile @@ -1669,7 +1669,7 @@ clean: $(clean-dirs) -o -name '*.ko.*' \ -o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ -o -name '*.dwo' -o -name '*.lst' \ - -o -name '*.su' -o -name '*.mod' \ + -o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.lex.c' -o -name '*.tab.[ch]' \ -o -name '*.asn1.[ch]' \ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c2d49afaea1c..be72da25fe7c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -38,6 +38,8 @@ static int sec_mismatch_count = 0; static int sec_mismatch_fatal = 0; /* ignore missing files */ static int ignore_missing_files; +/* write namespace dependencies */ +static int write_namespace_deps; enum export { export_plain, export_unused, export_gpl, @@ -2176,10 +2178,15 @@ static int check_exports(struct module *mod) else basename = mod->name; - if (exp->namespace && - !module_imports_namespace(mod, exp->namespace)) { - warn("module %s uses symbol %s from namespace %s, but does not import it.\n", - basename, exp->name, exp->namespace); + if (exp->namespace) { + add_namespace(&mod->required_namespaces, + exp->namespace); + + if (!write_namespace_deps && + !module_imports_namespace(mod, exp->namespace)) { + warn("module %s uses symbol %s from namespace %s, but does not import it.\n", + basename, exp->name, exp->namespace); + } } if (!mod->gpl_compatible) @@ -2484,6 +2491,31 @@ static void write_dump(const char *fname) free(buf.p); } +static void write_namespace_deps_files(void) +{ + struct module *mod; + struct namespace_list *ns; + struct buffer ns_deps_buf = {}; + + for (mod = modules; mod; mod = mod->next) { + char fname[PATH_MAX]; + + if (mod->skip) + continue; + + ns_deps_buf.pos = 0; + + for (ns = mod->required_namespaces; ns; ns = ns->next) + buf_printf(&ns_deps_buf, "%s\n", ns->namespace); + + if (ns_deps_buf.pos == 0) + continue; + + sprintf(fname, "%s.ns_deps", mod->name); + write_if_changed(&ns_deps_buf, fname); + } +} + struct ext_sym_list { struct ext_sym_list *next; const char *file; @@ -2500,7 +2532,7 @@ int main(int argc, char **argv) struct ext_sym_list *extsym_iter; struct ext_sym_list *extsym_start = NULL; - while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awE")) != -1) { + while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) { switch (opt) { case 'i': kernel_read = optarg; @@ -2541,6 +2573,9 @@ int main(int argc, char **argv) case 'E': sec_mismatch_fatal = 1; break; + case 'd': + write_namespace_deps = 1; + break; default: exit(1); } @@ -2575,6 +2610,9 @@ int main(int argc, char **argv) err |= check_modname_len(mod); err |= check_exports(mod); + if (write_namespace_deps) + continue; + add_header(&buf, mod); add_intree_flag(&buf, !external_module); add_retpoline(&buf); @@ -2587,6 +2625,12 @@ int main(int argc, char **argv) sprintf(fname, "%s.mod.c", mod->name); write_if_changed(&buf, fname); } + + if (write_namespace_deps) { + write_namespace_deps_files(); + return 0; + } + if (dump_write) write_dump(dump_write); if (sec_mismatch_count && sec_mismatch_fatal) diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9626bf3e7424..92a926d375d2 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -126,6 +126,8 @@ struct module { struct buffer dev_table_buf; char srcversion[25]; int is_dot_o; + // Required namespace dependencies + struct namespace_list *required_namespaces; // Actual imported namespaces struct namespace_list *imported_namespaces; }; -- cgit v1.2.3 From eb8305aecb958e8787e7d603c7765c1dcace3a2b Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 6 Sep 2019 11:32:32 +0100 Subject: scripts: Coccinelle script for namespace dependencies. A script that uses the '.ns_deps' files generated by modpost to automatically add the required symbol namespace dependencies to each module. Usage: 1) Move some symbols to a namespace with EXPORT_SYMBOL_NS() or define DEFAULT_SYMBOL_NAMESPACE 2) Run 'make' (or 'make modules') and get warnings about modules not importing that namespace. 3) Run 'make nsdeps' to automatically add required import statements to said modules. This makes it easer for subsystem maintainers to introduce and maintain symbol namespaces into their codebase. Co-developed-by: Martijn Coenen Signed-off-by: Martijn Coenen Acked-by: Julia Lawall Reviewed-by: Greg Kroah-Hartman Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- MAINTAINERS | 5 +++ Makefile | 12 ++++++ scripts/Makefile.modpost | 4 +- scripts/coccinelle/misc/add_namespace.cocci | 23 ++++++++++++ scripts/nsdeps | 58 +++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 scripts/coccinelle/misc/add_namespace.cocci create mode 100644 scripts/nsdeps (limited to 'scripts') diff --git a/MAINTAINERS b/MAINTAINERS index e7a47b5210fd..3b170c11a0e6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11436,6 +11436,11 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git F: tools/include/nolibc/ +NSDEPS +M: Matthias Maennich +S: Maintained +F: scripts/nsdeps + NTB AMD DRIVER M: Shyam Sundar S K L: linux-ntb@googlegroups.com diff --git a/Makefile b/Makefile index 0cdb957ae2c3..014d55b400ca 100644 --- a/Makefile +++ b/Makefile @@ -1500,6 +1500,9 @@ help: @echo ' headerdep - Detect inclusion cycles in headers' @echo ' coccicheck - Check with Coccinelle' @echo '' + @echo 'Tools:' + @echo ' nsdeps - Generate missing symbol namespace dependencies' + @echo '' @echo 'Kernel selftest:' @echo ' kselftest - Build and run kernel selftest (run as root)' @echo ' Build, install, and boot kernel before' @@ -1687,6 +1690,15 @@ quiet_cmd_tags = GEN $@ tags TAGS cscope gtags: FORCE $(call cmd,tags) +# Script to generate missing namespace dependencies +# --------------------------------------------------------------------------- + +PHONY += nsdeps + +nsdeps: modules + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost nsdeps + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@ + # Scripts to check various things for consistency # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 26e6574ecd08..743fe3a2e885 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -56,7 +56,8 @@ MODPOST = scripts/mod/modpost \ $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ - $(if $(KBUILD_MODPOST_WARN),-w) + $(if $(KBUILD_MODPOST_WARN),-w) \ + $(if $(filter nsdeps,$(MAKECMDGOALS)),-d) ifdef MODPOST_VMLINUX @@ -134,6 +135,7 @@ $(modules): %.ko :%.o %.mod.o FORCE targets += $(modules) +nsdeps: __modpost # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci new file mode 100644 index 000000000000..c832bb6445a8 --- /dev/null +++ b/scripts/coccinelle/misc/add_namespace.cocci @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +/// Adds missing MODULE_IMPORT_NS statements to source files +/// +/// This script is usually called from scripts/nsdeps with -D ns= to +/// add a missing namespace tag to a module source file. +/// + +@has_ns_import@ +declarer name MODULE_IMPORT_NS; +identifier virtual.ns; +@@ +MODULE_IMPORT_NS(ns); + +// Add missing imports, but only adjacent to a MODULE_LICENSE statement. +// That ensures we are adding it only to the main module source file. +@do_import depends on !has_ns_import@ +declarer name MODULE_LICENSE; +expression license; +identifier virtual.ns; +@@ +MODULE_LICENSE(license); ++ MODULE_IMPORT_NS(ns); diff --git a/scripts/nsdeps b/scripts/nsdeps new file mode 100644 index 000000000000..ac2b6031dd13 --- /dev/null +++ b/scripts/nsdeps @@ -0,0 +1,58 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Linux kernel symbol namespace import generator +# +# This script requires a minimum spatch version. +SPATCH_REQ_VERSION="1.0.4" + +DIR="$(dirname $(readlink -f $0))/.." +SPATCH="`which ${SPATCH:=spatch}`" +if [ ! -x "$SPATCH" ]; then + echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/' + exit 1 +fi + +SPATCH_REQ_VERSION_NUM=$(echo $SPATCH_REQ_VERSION | ${DIR}/scripts/ld-version.sh) +SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}') +SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh) + +if [ "$SPATCH_VERSION_NUM" -lt "$SPATCH_REQ_VERSION_NUM" ] ; then + echo "spatch needs to be version $SPATCH_REQ_VERSION or higher" + exit 1 +fi + +generate_deps_for_ns() { + $SPATCH --very-quiet --in-place --sp-file \ + $srctree/scripts/coccinelle/misc/add_namespace.cocci -D ns=$1 $2 +} + +generate_deps() { + local mod_name=`basename $@ .ko` + local mod_file=`echo $@ | sed -e 's/\.ko/\.mod/'` + local ns_deps_file=`echo $@ | sed -e 's/\.ko/\.ns_deps/'` + if [ ! -f "$ns_deps_file" ]; then return; fi + local mod_source_files=`cat $mod_file | sed -n 1p \ + | sed -e 's/\.o/\.c/g' \ + | sed "s/[^ ]* */${srctree}\/&/g"` + for ns in `cat $ns_deps_file`; do + echo "Adding namespace $ns to module $mod_name (if needed)." + generate_deps_for_ns $ns $mod_source_files + # sort the imports + for source_file in $mod_source_files; do + sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp + offset=$(wc -l ${source_file}.tmp | awk '{print $1;}') + cat $source_file | grep MODULE_IMPORT_NS | sort -u >> ${source_file}.tmp + tail -n +$((offset +1)) ${source_file} | grep -v MODULE_IMPORT_NS >> ${source_file}.tmp + if ! diff -q ${source_file} ${source_file}.tmp; then + mv ${source_file}.tmp ${source_file} + else + rm ${source_file}.tmp + fi + done + done +} + +for f in `cat $objtree/modules.order`; do + generate_deps $f +done + -- cgit v1.2.3 From 69a94abb82eed2789d52b58665ddf4b454d9adb9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 Sep 2019 19:53:17 +0900 Subject: export.h, genksyms: do not make genksyms calculate CRC of trimmed symbols Arnd Bergmann reported false-positive modpost warnings detected by his randconfig testing of linux-next. Actually, this happens under the combination of CONFIG_MODVERSIONS and CONFIG_TRIM_UNUSED_KSYMS since commit 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions"). For example, arch/arm/config/multi_v7_defconfig + CONFIG_MODVERSIONS + CONFIG_TRIM_UNUSED_KSYMS produces the following false-positives: WARNING: "__lshrdi3" [vmlinux] is a static (unknown) WARNING: "__ashrdi3" [vmlinux] is a static (unknown) WARNING: "__aeabi_lasr" [vmlinux] is a static (unknown) WARNING: "__aeabi_llsr" [vmlinux] is a static (unknown) WARNING: "ftrace_set_clr_event" [vmlinux] is a static (unknown) WARNING: "__muldi3" [vmlinux] is a static (unknown) WARNING: "__aeabi_ulcmp" [vmlinux] is a static (unknown) WARNING: "__ucmpdi2" [vmlinux] is a static (unknown) WARNING: "__aeabi_lmul" [vmlinux] is a static (unknown) WARNING: "__bswapsi2" [vmlinux] is a static (unknown) WARNING: "__bswapdi2" [vmlinux] is a static (unknown) WARNING: "__ashldi3" [vmlinux] is a static (unknown) WARNING: "__aeabi_llsl" [vmlinux] is a static (unknown) The root cause of the problem is not in the modpost, but in the implementation of CONFIG_TRIM_UNUSED_KSYMS. If there is at least one untrimmed symbol in the file, genksyms is invoked to calculate CRC of *all* the exported symbols in that file even if some of them have been trimmed due to no caller existing. As a result, .tmp_*.ver files contain CRC of trimmed symbols, thus unneeded, orphan __crc* symbols are added to objects. It had been harmless until recently. With commit 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions"), it is now harmful because the bogus __crc* symbols make modpost call sym_update_crc() to add the symbols to the hash table, but there is no one that clears the ->is_static member. I gave Fixes to the first commit that uncovered the issue, but the potential problem has long existed since commit f235541699bc ("export.h: allow for per-symbol configurable EXPORT_SYMBOL()"). Fixes: 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions") Reported-by: Arnd Bergmann Signed-off-by: Masahiro Yamada Tested-by: Arnd Bergmann --- include/linux/export.h | 42 ++++++++++++++++-------------------------- scripts/genksyms/keywords.c | 6 +----- 2 files changed, 17 insertions(+), 31 deletions(-) (limited to 'scripts') diff --git a/include/linux/export.h b/include/linux/export.h index cdd98a0d918c..7d8c112a8b61 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -18,9 +18,6 @@ extern struct module __this_module; #define THIS_MODULE ((struct module *)0) #endif -#ifdef CONFIG_MODULES - -#if !defined(__GENKSYMS__) #ifdef CONFIG_MODVERSIONS /* Mark the CRC weak since genksyms apparently decides not to * generate a checksums for some symbols */ @@ -74,6 +71,12 @@ struct kernel_symbol { }; #endif +#ifdef __GENKSYMS__ + +#define ___EXPORT_SYMBOL(sym, sec) __GENKSYMS_EXPORT_SYMBOL(sym) + +#else + /* For every exported symbol, place a struct in the __ksymtab section */ #define ___EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ @@ -83,7 +86,9 @@ struct kernel_symbol { = #sym; \ __KSYMTAB_ENTRY(sym, sec) -#if defined(__DISABLE_EXPORTS) +#endif + +#if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS) /* * Allow symbol exports to be disabled completely so that C code may @@ -117,37 +122,22 @@ struct kernel_symbol { #define __cond_export_sym_0(sym, sec) /* nothing */ #else -#define __EXPORT_SYMBOL ___EXPORT_SYMBOL -#endif -#define EXPORT_SYMBOL(sym) \ - __EXPORT_SYMBOL(sym, "") +#define __EXPORT_SYMBOL(sym, sec) ___EXPORT_SYMBOL(sym, sec) -#define EXPORT_SYMBOL_GPL(sym) \ - __EXPORT_SYMBOL(sym, "_gpl") - -#define EXPORT_SYMBOL_GPL_FUTURE(sym) \ - __EXPORT_SYMBOL(sym, "_gpl_future") +#endif /* CONFIG_MODULES */ +#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") +#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") +#define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future") #ifdef CONFIG_UNUSED_SYMBOLS -#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") -#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") +#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") +#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") #else #define EXPORT_UNUSED_SYMBOL(sym) #define EXPORT_UNUSED_SYMBOL_GPL(sym) #endif -#endif /* __GENKSYMS__ */ - -#else /* !CONFIG_MODULES... */ - -#define EXPORT_SYMBOL(sym) -#define EXPORT_SYMBOL_GPL(sym) -#define EXPORT_SYMBOL_GPL_FUTURE(sym) -#define EXPORT_UNUSED_SYMBOL(sym) -#define EXPORT_UNUSED_SYMBOL_GPL(sym) - -#endif /* CONFIG_MODULES */ #endif /* !__ASSEMBLY__ */ #endif /* _LINUX_EXPORT_H */ diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c index c586d32dd2c3..7a85c4e21175 100644 --- a/scripts/genksyms/keywords.c +++ b/scripts/genksyms/keywords.c @@ -3,11 +3,7 @@ static struct resword { const char *name; int token; } keywords[] = { - { "EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW }, - { "EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW }, - { "EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW }, - { "EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW }, - { "EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW }, + { "__GENKSYMS_EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW }, { "__asm", ASM_KEYW }, { "__asm__", ASM_KEYW }, { "__attribute", ATTRIBUTE_KEYW }, -- cgit v1.2.3 From 6df7e1ec932a330c931ed747ed824639fb04133e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 Sep 2019 20:34:22 +0900 Subject: modpost: use MODULE_INFO() for __module_depends This makes *.mod.c much more readable. I confirmed depmod still produced the same modules.dep file. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 76c221dd9b2b..25036947bcb8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2267,10 +2267,7 @@ static void add_depends(struct buffer *b, struct module *mod) s->module->seen = is_vmlinux(s->module->name); buf_printf(b, "\n"); - buf_printf(b, "static const char __module_depends[]\n"); - buf_printf(b, "__used\n"); - buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); - buf_printf(b, "\"depends="); + buf_printf(b, "MODULE_INFO(depends, \""); for (s = mod->unres; s; s = s->next) { const char *p; if (!s->module) @@ -2288,7 +2285,7 @@ static void add_depends(struct buffer *b, struct module *mod) buf_printf(b, "%s%s", first ? "" : ",", p); first = 0; } - buf_printf(b, "\";\n"); + buf_printf(b, "\");\n"); } static void add_srcversion(struct buffer *b, struct module *mod) -- cgit v1.2.3 From a3d0cb04f7df257b4dffec5e352b8e192824619c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 Sep 2019 20:34:23 +0900 Subject: modpost: use __section in the output to *.mod.c Use the __section() shorthand. This avoids escaping double-quotes, and improves the readability. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 25036947bcb8..820eed87fb43 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2176,7 +2176,7 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); buf_printf(b, "\n"); buf_printf(b, "__visible struct module __this_module\n"); - buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); + buf_printf(b, "__section(.gnu.linkonce.this_module) = {\n"); buf_printf(b, "\t.name = KBUILD_MODNAME,\n"); if (mod->has_init) buf_printf(b, "\t.init = init_module,\n"); @@ -2230,8 +2230,7 @@ static int add_versions(struct buffer *b, struct module *mod) buf_printf(b, "\n"); buf_printf(b, "static const struct modversion_info ____versions[]\n"); - buf_printf(b, "__used\n"); - buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); + buf_printf(b, "__used __section(__versions) = {\n"); for (s = mod->unres; s; s = s->next) { if (!s->module) -- cgit v1.2.3 From 77564a4829ef6d309331d443ea6ceb065f3dc371 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Sep 2019 20:45:07 +0900 Subject: genksyms: convert to SPDX License Identifier for lex.l and parse.y I used the C comment style (/* ... */) for the flex and bison files as in Kconfig (scripts/kconfig/{lexer.l,parser.y}) Signed-off-by: Masahiro Yamada --- scripts/genksyms/lex.l | 32 ++++++++++---------------------- scripts/genksyms/parse.y | 32 ++++++++++---------------------- 2 files changed, 20 insertions(+), 44 deletions(-) (limited to 'scripts') diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index d29c774f51b6..e265c5d96861 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -1,25 +1,13 @@ -/* Lexical analysis for genksyms. - Copyright 1996, 1997 Linux International. - - New implementation contributed by Richard Henderson - Based on original work by Bjorn Ekwall - - Taken from Linux modutils 2.4.22. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Lexical analysis for genksyms. + * Copyright 1996, 1997 Linux International. + * + * New implementation contributed by Richard Henderson + * Based on original work by Bjorn Ekwall + * + * Taken from Linux modutils 2.4.22. + */ %{ diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 1ebcf52cd0f9..e22b42245bcc 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -1,25 +1,13 @@ -/* C global declaration parser for genksyms. - Copyright 1996, 1997 Linux International. - - New implementation contributed by Richard Henderson - Based on original work by Bjorn Ekwall - - This file is part of the Linux modutils. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * C global declaration parser for genksyms. + * Copyright 1996, 1997 Linux International. + * + * New implementation contributed by Richard Henderson + * Based on original work by Bjorn Ekwall + * + * This file is part of the Linux modutils. + */ %{ -- cgit v1.2.3 From 634cffcc9478e954d121c3e27e53de4f0d917ac8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 25 Sep 2019 16:46:32 -0700 Subject: checkpatch: don't interpret stack dumps as commit IDs Add more types of lines that appear to be stack dumps that also include hex lines that might otherwise be interpreted as commit IDs. Link: http://lkml.kernel.org/r/ff00208289224f0ca4eaf4ff7c9c6e087dad0a63.camel@perches.com Link: http://lkml.kernel.org/r/f7dc9727795db3802809a24162abe0b67e14123b.1563575364.git.joe@perches.com Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 93a7edfe0f05..3c0ee0dde850 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2725,8 +2725,10 @@ sub process { ($line =~ /^\s*(?:WARNING:|BUG:)/ || $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || # timestamp - $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { - # stack dump address + $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || + $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || + $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { + # stack dump address styles $commit_log_possible_stack_dump = 1; } -- cgit v1.2.3 From ffbce8974d90efb5ced95fabc61283467c80cb0d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 25 Sep 2019 16:46:35 -0700 Subject: checkpatch: improve SPDX license checking Use perl's m@@ match and not // comparisons to avoid an error using c90's // comment style. Miscellanea: o Use normal tab indentation and alignment Link: http://lkml.kernel.org/r/5e4a8fa7901148fbcd77ab391e6dd0e6bf95777f.camel@perches.com Link: http://lkml.kernel.org/r/f08eb62458407a145cfedf959d1091af151cd665.1563575364.git.joe@perches.com Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3c0ee0dde850..6cb99ec62000 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3071,21 +3071,21 @@ sub process { # check SPDX comment style for .[chsS] files if ($realfile =~ /\.[chsS]$/ && $rawline =~ /SPDX-License-Identifier:/ && - $rawline !~ /^\+\s*\Q$comment\E\s*/) { + $rawline !~ m@^\+\s*\Q$comment\E\s*@) { WARN("SPDX_LICENSE_TAG", "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); } if ($comment !~ /^$/ && - $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) { - WARN("SPDX_LICENSE_TAG", - "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); + $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { + WARN("SPDX_LICENSE_TAG", + "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { - my $spdx_license = $1; - if (!is_SPDX_License_valid($spdx_license)) { - WARN("SPDX_LICENSE_TAG", - "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); - } + my $spdx_license = $1; + if (!is_SPDX_License_valid($spdx_license)) { + WARN("SPDX_LICENSE_TAG", + "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); + } } } } -- cgit v1.2.3 From a8dd86bf746256fbf68f82bc13356244c5ad8efa Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Wed, 25 Sep 2019 16:46:38 -0700 Subject: checkpatch.pl: warn on invalid commit id It can happen that a commit message refers to an invalid commit id, because the referenced hash changed following a rebase, or simply by mistake. Add a check in checkpatch.pl which checks that an hash referenced by a Fixes tag, or just cited in the commit message, is a valid commit id. $ scripts/checkpatch.pl <<'EOF' Subject: [PATCH] test commit Sample test commit to test checkpatch.pl Commit 1da177e4c3f4 ("Linux-2.6.12-rc2") really exists, commit 0bba044c4ce7 ("tree") is valid but not a commit, while commit b4cc0b1c0cca ("unknown") is invalid. Fixes: f0cacc14cade ("unknown") Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") EOF WARNING: Unknown commit id '0bba044c4ce7', maybe rebased or not pulled? #8: commit 0bba044c4ce7 ("tree") is valid but not a commit, WARNING: Unknown commit id 'b4cc0b1c0cca', maybe rebased or not pulled? #9: while commit b4cc0b1c0cca ("unknown") is invalid. WARNING: Unknown commit id 'f0cacc14cade', maybe rebased or not pulled? #11: Fixes: f0cacc14cade ("unknown") total: 0 errors, 3 warnings, 4 lines checked Link: http://lkml.kernel.org/r/20190711001640.13398-1-mcroce@redhat.com Signed-off-by: Matteo Croce Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6cb99ec62000..0b1388078b69 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2900,6 +2900,17 @@ sub process { } } +# check for invalid commit id + if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { + my $id; + my $description; + ($id, $description) = git_commit_info($2, undef, undef); + if (!defined($id)) { + WARN("UNKNOWN_COMMIT_ID", + "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); + } + } + # ignore non-hunk lines and lines being removed next if (!$hunk_line || $line =~ /^-/); -- cgit v1.2.3 From 6dba824e9ef7155f58f11b268b0f98ecec31b723 Mon Sep 17 00:00:00 2001 From: Brendan Jackman Date: Wed, 25 Sep 2019 16:46:41 -0700 Subject: checkpatch: exclude sizeof sub-expressions from MACRO_ARG_REUSE The arguments of sizeof are not evaluated so arguments are safe to re-use in that context. Excluding sizeof subexpressions means macros like ARRAY_SIZE can pass checkpatch. Link: http://lkml.kernel.org/r/20190806070833.24423-1-brendan.jackman@bluwireless.co.uk Signed-off-by: Brendan Jackman Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 0b1388078b69..d7466879d505 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5204,7 +5204,7 @@ sub process { next if ($arg =~ /\.\.\./); next if ($arg =~ /^type$/i); my $tmp_stmt = $define_stmt; - $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; + $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; $tmp_stmt =~ s/\#+\s*$arg\b//g; $tmp_stmt =~ s/\b$arg\s*\#\#//g; my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; -- cgit v1.2.3 From 462811d9d4007abe229c4cede0c124ed631da0cc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 25 Sep 2019 16:46:44 -0700 Subject: checkpatch: prefer __section over __attribute__((section(...))) Add another test for __attribute__((section("foo"))) uses that should be __section(foo) Link: http://lkml.kernel.org/r/2f374c3c27054b7f978115270d587c624d9962fc.camel@perches.com Suggested-by: Nick Desaulniers Signed-off-by: Joe Perches Tested-by: Nick Desaulniers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d7466879d505..1f85a3abbd17 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5886,6 +5886,18 @@ sub process { "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); } +# Check for __attribute__ section, prefer __section + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { + my $old = substr($rawline, $-[1], $+[1] - $-[1]); + my $new = substr($old, 1, -1); + if (WARN("PREFER_SECTION", + "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + } + } + # Check for __attribute__ format(printf, prefer __printf if ($realfile !~ m@\binclude/uapi/@ && $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { -- cgit v1.2.3 From 94fb98450456da82a16a378816390d99b85edb55 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 25 Sep 2019 16:46:47 -0700 Subject: checkpatch: allow consecutive close braces checkpatch allows consecutive open braces, so it should also allow consecutive close braces. Link: http://lkml.kernel.org/r/bfdb49ae2c3fa7b52fa168769e38b48f959880e2.camel@perches.com Signed-off-by: Joe Perches Acked-by: Jeff Kirsher Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1f85a3abbd17..7603711503ea 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4673,7 +4673,7 @@ sub process { # closing brace should have a space following it when it has anything # on the line - if ($line =~ /}(?!(?:,|;|\)))\S/) { + if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { if (ERROR("SPACING", "space required after that close brace '}'\n" . $herecurr) && $fix) { -- cgit v1.2.3 From 5a7f4455ad321400e1361ab94fd6858c5b2fe0cf Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 25 Sep 2019 16:46:49 -0700 Subject: checkpatch: remove obsolete period from "ambiguous SHA1" query Git dropped the period from its "ambiguous SHA1" error message in commit 0c99171ad2 ("get_short_sha1: mark ambiguity error for translation"), circa 2016. Drop the period from checkpatch's associated query so as to match both the old and new error messages. Link: http://lkml.kernel.org/r/20190830163103.15914-1-sean.j.christopherson@intel.com Signed-off-by: Sean Christopherson Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7603711503ea..4b25a94cfc36 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -962,7 +962,7 @@ sub git_commit_info { return ($id, $desc) if ($#lines < 0); - if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { + if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { # Maybe one day convert this block of bash into something that returns # all matching commit ids, but it's very slow... # -- cgit v1.2.3 From dbbf869da3adeba4a6beae4ecc184e47a16d078d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 25 Sep 2019 16:46:52 -0700 Subject: checkpatch: make git output use LANGUAGE=en_US.utf8 git output parsing depends on the language being en_US english. Make the backtick execution of all `git ` commands set the LANGUAGE of the process to en_US.utf8 before executing the actual command using `export LANGUAGE=en_US.utf8; git `. Because the command is executed in a child process, the parent LANGUAGE is unchanged. Link: http://lkml.kernel.org/r/bb9f29988f3258281956680ff39c3e19e37dc0b8.camel@perches.com Signed-off-by: Joe Perches Reported-by: Sean Christopherson Reviewed-by: Sean Christopherson Tested-by: Sean Christopherson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4b25a94cfc36..4eb355d8ae73 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -62,6 +62,8 @@ my $conststructsfile = "$D/const_structs.checkpatch"; my $typedefsfile = ""; my $color = "auto"; my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE +# git output parsing needs US English output, so first set backtick child process LANGUAGE +my $git_command ='export LANGUAGE=en_US.UTF-8; git'; sub help { my ($exitcode) = @_; @@ -904,7 +906,7 @@ sub seed_camelcase_includes { $camelcase_seeded = 1; if (-e ".git") { - my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; + my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; chomp $git_last_include_commit; $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; } else { @@ -932,7 +934,7 @@ sub seed_camelcase_includes { } if (-e ".git") { - $files = `git ls-files "include/*.h"`; + $files = `${git_command} ls-files "include/*.h"`; @include_files = split('\n', $files); } @@ -956,7 +958,7 @@ sub git_commit_info { return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); - my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; + my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; $output =~ s/^\s*//gm; my @lines = split("\n", $output); @@ -1006,7 +1008,7 @@ if ($git) { } else { $git_range = "-1 $commit_expr"; } - my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; + my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; foreach my $line (split(/\n/, $lines)) { $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; next if (!defined($1) || !defined($2)); -- cgit v1.2.3 From da036ae147624b70f7d3784ff3a53bd4fda20d2a Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 25 Sep 2019 16:47:48 -0700 Subject: scripts/gdb: handle split debug Some systems (like Chrome OS) may use "split debug" for kernel modules. That means that the debug symbols are in a different file than the main elf file. Let's handle that by also searching for debug symbols that end in ".ko.debug". This is a packaging topic. You can take a normal elf file and split the debug out of it using objcopy. Try "man objcopy" and then take a look at the "--only-keep-debug" option. It'll give you a whole recipe for doing splitdebug. The suffix used for the debug symbols is arbitrary. If people have other another suffix besides ".ko.debug" then we could presumably support that too... For portage (which is the packaging system used by Chrome OS) split debug is supported by default (and the suffix is .ko.debug). ...and so in Chrome OS we always get the installed elf files stripped and then the symbols stashed away. At the moment we don't actually use the normal portage magic to do this for the kernel though since it affects our ability to get good stack dumps in the kernel. We instead pass a script as "strip" [1]. [1] https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/refs/heads/master/eclass/cros-kernel/strip_splitdebug Link: http://lkml.kernel.org/r/20190730234052.148744-1-dianders@chromium.org Signed-off-by: Douglas Anderson Reviewed-by: Stephen Boyd Reviewed-by: Jan Kiszka Cc: Kieran Bingham Cc: Jason Wessel Cc: Daniel Thompson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/symbols.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 2f5b95f09fa0..34e40e96dee2 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -77,12 +77,12 @@ lx-symbols command.""" gdb.write("scanning for modules in {0}\n".format(path)) for root, dirs, files in os.walk(path): for name in files: - if name.endswith(".ko"): + if name.endswith(".ko") or name.endswith(".ko.debug"): self.module_files.append(root + "/" + name) self.module_files_updated = True def _get_module_file(self, module_name): - module_pattern = ".*/{0}\.ko$".format( + module_pattern = ".*/{0}\.ko(?:.debug)?$".format( module_name.replace("_", r"[_\-]")) for name in self.module_files: if re.match(module_pattern, name) and os.path.exists(name): -- cgit v1.2.3 From de3f186f87cf15bed8d13fedafb5bcad0167fc6d Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Wed, 25 Sep 2019 16:49:25 -0700 Subject: checkpatch: check for nested (un)?likely() calls IS_ERR(), IS_ERR_OR_NULL(), IS_ERR_VALUE() and WARN*() already contain unlikely() optimization internally. Thus, there is no point in calling these functions and defines under likely()/unlikely(). This check is based on the coccinelle rule developed by Enrico Weigelt https://lore.kernel.org/lkml/1559767582-11081-1-git-send-email-info@metux.net/ Link: http://lkml.kernel.org/r/20190829165025.15750-1-efremov@linux.com Signed-off-by: Denis Efremov Cc: Joe Perches Cc: Alexander Viro Cc: Anton Altaparmakov Cc: Boris Ostrovsky Cc: Boris Pismenny Cc: Darrick J. Wong Cc: "David S. Miller" Cc: Denis Efremov Cc: Dennis Dalessandro Cc: Inaky Perez-Gonzalez Cc: Juergen Gross Cc: Leon Romanovsky Cc: Mike Marciniszyn Cc: Rob Clark Cc: Saeed Mahameed Cc: Sean Paul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4eb355d8ae73..6fcc66afb088 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6507,6 +6507,12 @@ sub process { "Using $1 should generally have parentheses around the comparison\n" . $herecurr); } +# nested likely/unlikely calls + if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { + WARN("LIKELY_MISUSE", + "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); + } + # whine mightly about in_atomic if ($line =~ /\bin_atomic\s*\(/) { if ($realfile =~ m@^drivers/@) { -- cgit v1.2.3 From 13dc8c029cabf52ba95f60c56eb104d4d95d5889 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 21 Sep 2019 15:49:54 +0900 Subject: kbuild: remove ar-option and KBUILD_ARFLAGS Commit 40df759e2b9e ("kbuild: Fix build with binutils <= 2.19") introduced ar-option and KBUILD_ARFLAGS to deal with old binutils. According to Documentation/process/changes.rst, the current minimal supported version of binutils is 2.21 so you can assume the 'D' option is always supported. Not only GNU ar but also llvm-ar supports it. With the 'D' option hard-coded, there is no more user of ar-option or KBUILD_ARFLAGS. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Tested-by: Nick Desaulniers --- Documentation/kbuild/makefiles.rst | 5 ----- Makefile | 4 ---- arch/powerpc/boot/Makefile | 2 +- scripts/Kbuild.include | 5 ----- scripts/Makefile.build | 2 +- scripts/Makefile.lib | 2 +- 6 files changed, 3 insertions(+), 17 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 6ba9d5365ff3..b89c88168d6a 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -954,11 +954,6 @@ When kbuild executes, the following steps are followed (roughly): From commandline LDFLAGS_MODULE shall be used (see kbuild.txt). - KBUILD_ARFLAGS Options for $(AR) when creating archives - - $(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic - mode) if this option is supported by $(AR). - KBUILD_LDS The linker script with full path. Assigned by the top-level Makefile. diff --git a/Makefile b/Makefile index 6f54f2f95743..7452174f5b21 100644 --- a/Makefile +++ b/Makefile @@ -498,7 +498,6 @@ export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL -export KBUILD_ARFLAGS # Files to ignore in find ... statements @@ -914,9 +913,6 @@ ifdef CONFIG_RETPOLINE KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) endif -# use the deterministic mode of AR if available -KBUILD_ARFLAGS := $(call ar-option,D) - include scripts/Makefile.kasan include scripts/Makefile.extrawarn include scripts/Makefile.ubsan diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 6841bd52738b..dfbd7f22eef5 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -50,7 +50,7 @@ endif BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc -BOOTARFLAGS := -cr$(KBUILD_ARFLAGS) +BOOTARFLAGS := -crD ifdef CONFIG_CC_IS_CLANG BOOTCFLAGS += $(CLANG_FLAGS) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 4b0432e095ae..10ba926ae292 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -143,11 +143,6 @@ cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || e # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) -# ar-option -# Usage: KBUILD_ARFLAGS := $(call ar-option,D) -# Important: no spaces around options -ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2)) - # ld-version # Note this is mainly for HJ Lu's 3 number binutil versions ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index f72aba64d611..a9e47953ca53 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -389,7 +389,7 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ; ifdef builtin-target quiet_cmd_ar_builtin = AR $@ - cmd_ar_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(real-prereqs) + cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) $(builtin-target): $(real-obj-y) FORCE $(call if_changed,ar_builtin) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 4a0cdd6f5909..179d55af5852 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -232,7 +232,7 @@ quiet_cmd_ld = LD $@ # --------------------------------------------------------------------------- quiet_cmd_ar = AR $@ - cmd_ar = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs) + cmd_ar = rm -f $@; $(AR) cDPrsT $@ $(real-prereqs) # Objcopy # --------------------------------------------------------------------------- -- cgit v1.2.3 From 47346e96f004eca07720e1e2b24fc7f0b0df4092 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 24 Sep 2019 21:07:40 +0900 Subject: modpost: fix static EXPORT_SYMBOL warnings for UML build Johannes Berg reports lots of modpost warnings on ARCH=um builds: WARNING: "rename" [vmlinux] is a static EXPORT_SYMBOL WARNING: "lseek" [vmlinux] is a static EXPORT_SYMBOL WARNING: "ftruncate64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "getuid" [vmlinux] is a static EXPORT_SYMBOL WARNING: "lseek64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "unlink" [vmlinux] is a static EXPORT_SYMBOL WARNING: "pwrite64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "close" [vmlinux] is a static EXPORT_SYMBOL WARNING: "opendir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "pread64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "syscall" [vmlinux] is a static EXPORT_SYMBOL WARNING: "readdir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "readdir64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "futimes" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__lxstat" [vmlinux] is a static EXPORT_SYMBOL WARNING: "write" [vmlinux] is a static EXPORT_SYMBOL WARNING: "closedir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__xstat" [vmlinux] is a static EXPORT_SYMBOL WARNING: "fsync" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__lxstat64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__fxstat64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "telldir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "printf" [vmlinux] is a static EXPORT_SYMBOL WARNING: "readlink" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__sprintf_chk" [vmlinux] is a static EXPORT_SYMBOL WARNING: "link" [vmlinux] is a static EXPORT_SYMBOL WARNING: "rmdir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "fdatasync" [vmlinux] is a static EXPORT_SYMBOL WARNING: "truncate" [vmlinux] is a static EXPORT_SYMBOL WARNING: "statfs" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__errno_location" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__xmknod" [vmlinux] is a static EXPORT_SYMBOL WARNING: "open64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "truncate64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "open" [vmlinux] is a static EXPORT_SYMBOL WARNING: "read" [vmlinux] is a static EXPORT_SYMBOL WARNING: "chown" [vmlinux] is a static EXPORT_SYMBOL WARNING: "chmod" [vmlinux] is a static EXPORT_SYMBOL WARNING: "utime" [vmlinux] is a static EXPORT_SYMBOL WARNING: "fchmod" [vmlinux] is a static EXPORT_SYMBOL WARNING: "seekdir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "ioctl" [vmlinux] is a static EXPORT_SYMBOL WARNING: "dup2" [vmlinux] is a static EXPORT_SYMBOL WARNING: "statfs64" [vmlinux] is a static EXPORT_SYMBOL WARNING: "utimes" [vmlinux] is a static EXPORT_SYMBOL WARNING: "mkdir" [vmlinux] is a static EXPORT_SYMBOL WARNING: "fchown" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__guard" [vmlinux] is a static EXPORT_SYMBOL WARNING: "symlink" [vmlinux] is a static EXPORT_SYMBOL WARNING: "access" [vmlinux] is a static EXPORT_SYMBOL WARNING: "__stack_smash_handler" [vmlinux] is a static EXPORT_SYMBOL When you run "make", the modpost is run twice; before linking vmlinux, and before building modules. All the warnings above are from the second modpost. The offending symbols are defined not in vmlinux, but in the C library. The first modpost is run against the relocatable vmlinux.o, and those warnings are nicely suppressed because the SH_UNDEF entries from the symbol table clear the ->is_static flag. The second modpost is run against the executable vmlinux (+ modules), where those symbols have been resolved, but the definitions do not exist. This commit fixes it in a straightforward way; suppress the static EXPORT_SYMBOL warnings from "vmlinux". Without this commit, we see valid warnings twice anyway. For example, ARCH=arm64 defconfig shows the following warning twice: WARNING: "HYPERVISOR_platform_op" [vmlinux] is a static EXPORT_SYMBOL_GPL So, it is reasonable to suppress the second one. Fixes: 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions") Reported-by: Johannes Berg Signed-off-by: Masahiro Yamada Tested-by: Johannes Berg Tested-by: Denis Efremov --- scripts/mod/modpost.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3961941e8e7a..442d5e2ad688 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2652,15 +2652,20 @@ int main(int argc, char **argv) fatal("modpost: Section mismatches detected.\n" "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); for (n = 0; n < SYMBOL_HASH_SIZE; n++) { - struct symbol *s = symbolhash[n]; + struct symbol *s; + + for (s = symbolhash[n]; s; s = s->next) { + /* + * Do not check "vmlinux". This avoids the same warnings + * shown twice, and false-positives for ARCH=um. + */ + if (is_vmlinux(s->module->name) && !s->module->is_dot_o) + continue; - while (s) { if (s->is_static) warn("\"%s\" [%s] is a static %s\n", s->name, s->module->name, export_str(s->export)); - - s = s->next; } } -- cgit v1.2.3 From 82fdd12b95727640c9a8233c09d602e4518e71f7 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Fri, 27 Sep 2019 16:30:27 -0700 Subject: namespace: fix namespace.pl script to support relative paths The namespace.pl script does not work properly if objtree is not set to an absolute path. The do_nm function is run from within the find function, which changes directories. Because of this, appending objtree, $File::Find::dir, and $source, will return a path which is not valid from the current directory. This used to work when objtree was set to an absolute path when using "make namespacecheck". It appears to have not worked when calling ./scripts/namespace.pl directly. This behavior was changed in 7e1c04779efd ("kbuild: Use relative path for $(objtree)", 2014-05-14) Rather than fixing the Makefile to set objtree to an absolute path, just fix namespace.pl to work when srctree and objtree are relative. Also fix the script to use an absolute path for these by default. Use the File::Spec module for this purpose. It's been part of perl 5 since 5.005. The curdir() function is used to get the current directory when the objtree and srctree aren't set in the environment. rel2abs() is used to convert possibly relative objtree and srctree environment variables to absolute paths. Finally, the catfile() function is used instead of string appending paths together, since this is more robust when joining paths together. Signed-off-by: Jacob Keller Acked-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Masahiro Yamada --- scripts/namespace.pl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 6135574a6f39..1da7bca201a4 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl @@ -65,13 +65,14 @@ use warnings; use strict; use File::Find; +use File::Spec; my $nm = ($ENV{'NM'} || "nm") . " -p"; my $objdump = ($ENV{'OBJDUMP'} || "objdump") . " -s -j .comment"; -my $srctree = ""; -my $objtree = ""; -$srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'})); -$objtree = "$ENV{'objtree'}/" if (exists($ENV{'objtree'})); +my $srctree = File::Spec->curdir(); +my $objtree = File::Spec->curdir(); +$srctree = File::Spec->rel2abs($ENV{'srctree'}) if (exists($ENV{'srctree'})); +$objtree = File::Spec->rel2abs($ENV{'objtree'}) if (exists($ENV{'objtree'})); if ($#ARGV != -1) { print STDERR "usage: $0 takes no parameters\n"; @@ -231,9 +232,9 @@ sub do_nm } ($source = $basename) =~ s/\.o$//; if (-e "$source.c" || -e "$source.S") { - $source = "$objtree$File::Find::dir/$source"; + $source = File::Spec->catfile($objtree, $File::Find::dir, $source) } else { - $source = "$srctree$File::Find::dir/$source"; + $source = File::Spec->catfile($srctree, $File::Find::dir, $source) } if (! -e "$source.c" && ! -e "$source.S") { # No obvious source, exclude the object if it is conglomerate -- cgit v1.2.3 From 7a82e3fa28f174ba23c9faca544c65986e3025f1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 1 Oct 2019 21:17:24 +0900 Subject: scripts/setlocalversion: clear local variable to make it work for sh Geert Uytterhoeven reports a strange side-effect of commit 858805b336be ("kbuild: add $(BASH) to run scripts with bash-extension"), which inserts the contents of a localversion file in the build directory twice. [Steps to Reproduce] $ echo bar > localversion $ mkdir build $ cd build/ $ echo foo > localversion $ make -s -f ../Makefile defconfig include/config/kernel.release $ cat include/config/kernel.release 5.4.0-rc1foofoobar This comes down to the behavior change of local variables. The 'man sh' on my Ubuntu machine, where sh is an alias to dash, explains as follows: When a variable is made local, it inherits the initial value and exported and readonly flags from the variable with the same name in the surrounding scope, if there is one. Otherwise, the variable is initially unset. [Test Code] foo () { local res echo "res: $res" } res=1 foo [Result] $ sh test.sh res: 1 $ bash test.sh res: So, scripts/setlocalversion correctly works only for bash in spite of its hashbang being #!/bin/sh. Nobody had noticed it before because CONFIG_SHELL was previously set to bash almost all the time. Now that CONFIG_SHELL is set to sh, we must write portable and correct code. I gave the Fixes tag to the commit that uncovered the issue. Clear the variable 'res' in collect_files() to make it work for sh (and it also works on distributions where sh is an alias to bash). Fixes: 858805b336be ("kbuild: add $(BASH) to run scripts with bash-extension") Reported-by: Geert Uytterhoeven Signed-off-by: Masahiro Yamada Tested-by: Geert Uytterhoeven --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 365b3c2b8f43..220dae0db3f1 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -126,7 +126,7 @@ scm_version() collect_files() { - local file res + local file res= for file; do case "$file" in -- cgit v1.2.3 From c7c4e29fb5a422fd144b3fb0d3e32375d8f9b0ba Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sun, 6 Oct 2019 12:44:56 +0800 Subject: scripts: add_namespace: Fix coccicheck failed Now all scripts in scripts/coccinelle to be automatically called by coccicheck. However new adding add_namespace.cocci does not support report mode, which make coccicheck failed. This add "virtual report" to make the coccicheck go ahead smoothly. Fixes: eb8305aecb95 ("scripts: Coccinelle script for namespace dependencies.") Acked-by: Julia Lawall Acked-by: Matthias Maennich Signed-off-by: YueHaibing Signed-off-by: Jessica Yu --- scripts/coccinelle/misc/add_namespace.cocci | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci index c832bb6445a8..99e93a6c2e24 100644 --- a/scripts/coccinelle/misc/add_namespace.cocci +++ b/scripts/coccinelle/misc/add_namespace.cocci @@ -6,6 +6,8 @@ /// add a missing namespace tag to a module source file. /// +virtual report + @has_ns_import@ declarer name MODULE_IMPORT_NS; identifier virtual.ns; -- cgit v1.2.3 From bf70b0503abd19194dba25fe383d143d0229dc6a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 3 Oct 2019 16:58:21 +0900 Subject: module: swap the order of symbol.namespace Currently, EXPORT_SYMBOL_NS(_GPL) constructs the kernel symbol as follows: __ksymtab_SYMBOL.NAMESPACE The sym_extract_namespace() in modpost allocates memory for the part SYMBOL.NAMESPACE when '.' is contained. One problem is that the pointer returned by strdup() is lost because the symbol name will be copied to malloc'ed memory by alloc_symbol(). No one will keep track of the pointer of strdup'ed memory. sym->namespace still points to the NAMESPACE part. So, you can free it with complicated code like this: free(sym->namespace - strlen(sym->name) - 1); It complicates memory free. To fix it elegantly, I swapped the order of the symbol and the namespace as follows: __ksymtab_NAMESPACE.SYMBOL then, simplified sym_extract_namespace() so that it allocates memory only for the NAMESPACE part. I prefer this order because it is intuitive and also matches to major languages. For example, NAMESPACE::NAME in C++, MODULE.NAME in Python. Reviewed-by: Matthias Maennich Signed-off-by: Masahiro Yamada Signed-off-by: Jessica Yu --- include/linux/export.h | 4 ++-- scripts/mod/modpost.c | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'scripts') diff --git a/include/linux/export.h b/include/linux/export.h index 95f55b7f83a0..0695d4e847d9 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -52,7 +52,7 @@ extern struct module __this_module; __ADDRESSABLE(sym) \ asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ " .balign 4 \n" \ - "__ksymtab_" #sym NS_SEPARATOR #ns ": \n" \ + "__ksymtab_" #ns NS_SEPARATOR #sym ": \n" \ " .long " #sym "- . \n" \ " .long __kstrtab_" #sym "- . \n" \ " .long __kstrtab_ns_" #sym "- . \n" \ @@ -76,7 +76,7 @@ struct kernel_symbol { #else #define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ static const struct kernel_symbol __ksymtab_##sym##__##ns \ - asm("__ksymtab_" #sym NS_SEPARATOR #ns) \ + asm("__ksymtab_" #ns NS_SEPARATOR #sym) \ __attribute__((section("___ksymtab" sec "+" #sym), used)) \ __aligned(sizeof(void *)) \ = { (unsigned long)&sym, __kstrtab_##sym, __kstrtab_ns_##sym } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3961941e8e7a..c4b536ac1327 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -350,18 +350,16 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) static const char *sym_extract_namespace(const char **symname) { - size_t n; - char *dupsymname; + char *namespace = NULL; + char *ns_separator; - n = strcspn(*symname, "."); - if (n < strlen(*symname) - 1) { - dupsymname = NOFAIL(strdup(*symname)); - dupsymname[n] = '\0'; - *symname = dupsymname; - return dupsymname + n + 1; + ns_separator = strchr(*symname, '.'); + if (ns_separator) { + namespace = NOFAIL(strndup(*symname, ns_separator - *symname)); + *symname = ns_separator + 1; } - return NULL; + return namespace; } /** -- cgit v1.2.3 From 389eb3f5f4abbdb9810458ac9b87427336ba5b91 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 3 Oct 2019 16:58:22 +0900 Subject: modpost: fix broken sym->namespace for external module builds Currently, external module builds produce tons of false-positives: WARNING: module uses symbol from namespace , but does not import it. Here, the part shows a random string. When you build external modules, the symbol info of vmlinux and in-kernel modules are read from $(objtree)/Module.symvers, but read_dump() is buggy in multiple ways: [1] When the modpost is run for vmlinux and in-kernel modules, sym_extract_namespace() allocates memory for the namespace. On the other hand, read_dump() does not, then sym->namespace will point to somewhere in the line buffer of get_next_line(). The data in the buffer will be replaced soon, and sym->namespace will end up with pointing to unrelated data. As a result, check_exports() will show random strings in the warning messages. [2] When there is no namespace, sym_extract_namespace() returns NULL. On the other hand, read_dump() sets namespace to an empty string "". (but, it will be later replaced with unrelated data due to bug [1].) The check_exports() shows a warning unless exp->namespace is NULL, so every symbol read from read_dump() emits the warning, which is mostly false positive. To address [1], sym_add_exported() calls strdup() for s->namespace. The namespace from sym_extract_namespace() must be freed to avoid memory leak. For [2], I changed the if-conditional in check_exports(). This commit also fixes sym_add_exported() to set s->namespace correctly when the symbol is preloaded. Reviewed-by: Matthias Maennich Signed-off-by: Masahiro Yamada Signed-off-by: Jessica Yu --- scripts/mod/modpost.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c4b536ac1327..4d2cdb4d71e3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -166,7 +166,7 @@ struct symbol { struct module *module; unsigned int crc; int crc_valid; - const char *namespace; + char *namespace; unsigned int weak:1; unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ unsigned int kernel:1; /* 1 if symbol is from kernel @@ -348,7 +348,7 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) return export_unknown; } -static const char *sym_extract_namespace(const char **symname) +static char *sym_extract_namespace(const char **symname) { char *namespace = NULL; char *ns_separator; @@ -373,7 +373,6 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, if (!s) { s = new_symbol(name, mod, export); - s->namespace = namespace; } else { if (!s->preloaded) { warn("%s: '%s' exported twice. Previous export was in %s%s\n", @@ -384,6 +383,8 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, s->module = mod; } } + free(s->namespace); + s->namespace = namespace ? strdup(namespace) : NULL; s->preloaded = 0; s->vmlinux = is_vmlinux(mod->name); s->kernel = 0; @@ -670,7 +671,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, unsigned int crc; enum export export; bool is_crc = false; - const char *name, *namespace; + const char *name; + char *namespace; if ((!is_vmlinux(mod->name) || mod->is_dot_o) && strstarts(symname, "__ksymtab")) @@ -745,6 +747,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, name = symname + strlen("__ksymtab_"); namespace = sym_extract_namespace(&name); sym_add_exported(name, namespace, mod, export); + free(namespace); } if (strcmp(symname, "init_module") == 0) mod->has_init = 1; @@ -2193,7 +2196,7 @@ static int check_exports(struct module *mod) else basename = mod->name; - if (exp->namespace) { + if (exp->namespace && exp->namespace[0]) { add_namespace(&mod->required_namespaces, exp->namespace); -- cgit v1.2.3 From 40997fb8799dab048bd4fa538f62a11ed4224e2a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 3 Oct 2019 16:58:25 +0900 Subject: nsdeps: fix hashbang of scripts/nsdeps This script does not use bash-extension. I am guessing this hashbang was copied from scripts/coccicheck, which really uses bash-extension. /bin/sh is enough for this script. Reviewed-by: Matthias Maennich Signed-off-by: Masahiro Yamada Signed-off-by: Jessica Yu --- scripts/nsdeps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/nsdeps b/scripts/nsdeps index ac2b6031dd13..964b7fb8c546 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # SPDX-License-Identifier: GPL-2.0 # Linux kernel symbol namespace import generator # -- cgit v1.2.3 From df6f0987e55fd08ad2e93370eea12b5290705d4b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 3 Oct 2019 16:58:26 +0900 Subject: nsdeps: make generated patches independent of locale scripts/nsdeps automatically generates a patch to add MODULE_IMPORT_NS tags, and what is nicer, it sorts the lines alphabetically with the 'sort' command. However, the output from the 'sort' command depends on locale. For example, I got this: $ { echo usbstorage; echo usb_storage; } | LANG=en_US.UTF-8 sort usbstorage usb_storage $ { echo usbstorage; echo usb_storage; } | LANG=C sort usb_storage usbstorage So, this means people might potentially send different patches. This kind of issue was reported in the past, for example, commit f55f2328bb28 ("kbuild: make sorting initramfs contents independent of locale"). Adding 'LANG=C' is a conventional way of fixing when a deterministic result is desirable. I added 'LANG=C' very close to the 'sort' command since changing locale affects the language of error messages etc. We should respect users' choice as much as possible. Reviewed-by: Matthias Maennich Signed-off-by: Masahiro Yamada Signed-off-by: Jessica Yu --- scripts/nsdeps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/nsdeps b/scripts/nsdeps index 964b7fb8c546..3754dac13b31 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -41,7 +41,7 @@ generate_deps() { for source_file in $mod_source_files; do sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp offset=$(wc -l ${source_file}.tmp | awk '{print $1;}') - cat $source_file | grep MODULE_IMPORT_NS | sort -u >> ${source_file}.tmp + cat $source_file | grep MODULE_IMPORT_NS | LANG=C sort -u >> ${source_file}.tmp tail -n +$((offset +1)) ${source_file} | grep -v MODULE_IMPORT_NS >> ${source_file}.tmp if ! diff -q ${source_file} ${source_file}.tmp; then mv ${source_file}.tmp ${source_file} -- cgit v1.2.3 From 7f8557b88d6aa5bf31f25f6013d81355a1b1d48d Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 9 Oct 2019 11:05:38 -0400 Subject: recordmcount: Fix nop_mcount() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The removal of the longjmp code in recordmcount.c mistakenly made the return of make_nop() being negative an exit of nop_mcount(). It should not exit the routine, but instead just not process that part of the code. By exiting with an error code, it would cause the update of recordmcount to fail some files which would fail the build if ftrace function tracing was enabled. Link: http://lkml.kernel.org/r/20191009110538.5909fec6@gandalf.local.home Reported-by: Uwe Kleine-König Tested-by: Uwe Kleine-König Fixes: 3f1df12019f3 ("recordmcount: Rewrite error/success handling") Signed-off-by: Steven Rostedt (VMware) --- scripts/recordmcount.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 8f0a278ce0af..74eab03e31d4 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -389,11 +389,8 @@ static int nop_mcount(Elf_Shdr const *const relhdr, mcountsym = get_mcountsym(sym0, relp, str0); if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { - if (make_nop) { + if (make_nop) ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + _w(relp->r_offset)); - if (ret < 0) - return -1; - } if (warn_on_notrace_sect && !once) { printf("Section %s has mcount callers being ignored\n", txtname); -- cgit v1.2.3 From 991b78fbd2231175293bd1d7c0768fb4e4382e14 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 5 Oct 2019 08:01:59 -0700 Subject: scripts: setlocalversion: fix a bashism Fix bashism reported by checkbashisms by using only one '=': possible bashism in scripts/setlocalversion line 96 (should be 'b = a'): if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then Fixes: 38b3439d84f4 ("setlocalversion: update mercurial tag parsing") Signed-off-by: Randy Dunlap Cc: Mike Crowe Signed-off-by: Masahiro Yamada --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 220dae0db3f1..a2998b118ef9 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -93,7 +93,7 @@ scm_version() # Check for mercurial and a mercurial repo. if test -d .hg && hgid=`hg id 2>/dev/null`; then # Do we have an tagged version? If so, latesttagdistance == 1 - if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then + if [ "`hg log -r . --template '{latesttagdistance}'`" = "1" ]; then id=`hg log -r . --template '{latesttag}'` printf '%s%s' -hg "$id" else -- cgit v1.2.3 From 283ea345934d277e30c841c577e0e2142b4bfcae Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 17 Oct 2019 16:22:37 +0200 Subject: coccinelle: api/devm_platform_ioremap_resource: remove useless script While it is useful for new drivers to use devm_platform_ioremap_resource, this script is currently used to spam maintainers, often updating very old drivers. The net benefit is the removal of 2 lines of code in the driver but the review load for the maintainers is huge. As of now, more that 560 patches have been sent, some of them obviously broken, as in: https://lore.kernel.org/lkml/9bbcce19c777583815c92ce3c2ff2586@www.loen.fr/ Remove the script to reduce the spam. Signed-off-by: Alexandre Belloni Acked-by: Julia Lawall Signed-off-by: Linus Torvalds --- .../api/devm_platform_ioremap_resource.cocci | 60 ---------------------- 1 file changed, 60 deletions(-) delete mode 100644 scripts/coccinelle/api/devm_platform_ioremap_resource.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/devm_platform_ioremap_resource.cocci b/scripts/coccinelle/api/devm_platform_ioremap_resource.cocci deleted file mode 100644 index 56a2e261d61d..000000000000 --- a/scripts/coccinelle/api/devm_platform_ioremap_resource.cocci +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/// Use devm_platform_ioremap_resource helper which wraps -/// platform_get_resource() and devm_ioremap_resource() together. -/// -// Confidence: High -// Copyright: (C) 2019 Himanshu Jha GPLv2. -// Copyright: (C) 2019 Julia Lawall, Inria/LIP6. GPLv2. -// Keywords: platform_get_resource, devm_ioremap_resource, -// Keywords: devm_platform_ioremap_resource - -virtual patch -virtual report - -@r depends on patch && !report@ -expression e1, e2, arg1, arg2, arg3; -identifier id; -@@ - -( -- id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -| -- struct resource *id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -) - ... when != id -- e1 = devm_ioremap_resource(arg3, id); -+ e1 = devm_platform_ioremap_resource(arg1, arg2); - ... when != id -? id = e2 - -@r1 depends on patch && !report@ -identifier r.id; -type T; -@@ - -- T *id; - ...when != id - -@r2 depends on report && !patch@ -identifier id; -expression e1, e2, arg1, arg2, arg3; -position j0; -@@ - -( - id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -| - struct resource *id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -) - ... when != id - e1@j0 = devm_ioremap_resource(arg3, id); - ... when != id -? id = e2 - -@script:python depends on report && !patch@ -e1 << r2.e1; -j0 << r2.j0; -@@ - -msg = "WARNING: Use devm_platform_ioremap_resource for %s" % (e1) -coccilib.report.print_report(j0[0], msg) -- cgit v1.2.3 From a2b11184389489dcca4fa899b290fc2751ea55ac Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 18 Oct 2019 10:31:40 +0100 Subject: modpost: delegate updating namespaces to separate function Let the function 'sym_update_namespace' take care of updating the namespace for a symbol. While this currently only replaces one single location where namespaces are updated, in a following patch, this function will get more call sites. The function signature is intentionally close to sym_update_crc and taking the name by char* seems like unnecessary work as the symbol has to be looked up again. In a later patch of this series, this concern will be addressed. This function ensures that symbol::namespace is either NULL or has a valid non-empty value. Previously, the empty string was considered 'no namespace' as well and this lead to confusion. Acked-by: Will Deacon Reviewed-by: Greg Kroah-Hartman Reviewed-by: Masahiro Yamada Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- scripts/mod/modpost.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 936d3ad23c83..4041a265d2b6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -362,6 +362,25 @@ static char *sym_extract_namespace(const char **symname) return namespace; } +static void sym_update_namespace(const char *symname, const char *namespace) +{ + struct symbol *s = find_symbol(symname); + + /* + * That symbol should have been created earlier and thus this is + * actually an assertion. + */ + if (!s) { + merror("Could not update namespace(%s) for symbol %s\n", + namespace, symname); + return; + } + + free(s->namespace); + s->namespace = + namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL; +} + /** * Add an exported symbol - it may have already been added without a * CRC, in this case just update the CRC @@ -383,8 +402,7 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, s->module = mod; } } - free(s->namespace); - s->namespace = namespace ? strdup(namespace) : NULL; + sym_update_namespace(name, namespace); s->preloaded = 0; s->vmlinux = is_vmlinux(mod->name); s->kernel = 0; @@ -2196,7 +2214,7 @@ static int check_exports(struct module *mod) else basename = mod->name; - if (exp->namespace && exp->namespace[0]) { + if (exp->namespace) { add_namespace(&mod->required_namespaces, exp->namespace); -- cgit v1.2.3 From 9ae5bd1847566e079ffb7607394389ac54815f2b Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 18 Oct 2019 10:31:41 +0100 Subject: modpost: make updating the symbol namespace explicit Setting the symbol namespace of a symbol within sym_add_exported feels displaced and lead to issues in the current implementation of symbol namespaces. This patch makes updating the namespace an explicit call to decouple it from adding a symbol to the export list. Acked-by: Will Deacon Reviewed-by: Greg Kroah-Hartman Reviewed-by: Masahiro Yamada Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- scripts/mod/modpost.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4041a265d2b6..c43f1b1532f7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -385,8 +385,8 @@ static void sym_update_namespace(const char *symname, const char *namespace) * Add an exported symbol - it may have already been added without a * CRC, in this case just update the CRC **/ -static struct symbol *sym_add_exported(const char *name, const char *namespace, - struct module *mod, enum export export) +static struct symbol *sym_add_exported(const char *name, struct module *mod, + enum export export) { struct symbol *s = find_symbol(name); @@ -402,7 +402,6 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, s->module = mod; } } - sym_update_namespace(name, namespace); s->preloaded = 0; s->vmlinux = is_vmlinux(mod->name); s->kernel = 0; @@ -764,7 +763,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, if (strstarts(symname, "__ksymtab_")) { name = symname + strlen("__ksymtab_"); namespace = sym_extract_namespace(&name); - sym_add_exported(name, namespace, mod, export); + sym_add_exported(name, mod, export); + sym_update_namespace(name, namespace); free(namespace); } if (strcmp(symname, "init_module") == 0) @@ -2472,12 +2472,12 @@ static void read_dump(const char *fname, unsigned int kernel) mod = new_module(modname); mod->skip = 1; } - s = sym_add_exported(symname, namespace, mod, - export_no(export)); + s = sym_add_exported(symname, mod, export_no(export)); s->kernel = kernel; s->preloaded = 1; s->is_static = 0; sym_update_crc(symname, mod, crc, export_no(export)); + sym_update_namespace(symname, namespace); } release_file(file, size); return; -- cgit v1.2.3 From 69923208431e097ce3830647aee98e5bd3e889c8 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 18 Oct 2019 10:31:42 +0100 Subject: symbol namespaces: revert to previous __ksymtab name scheme The introduction of Symbol Namespaces changed the naming schema of the __ksymtab entries from __kysmtab__symbol to __ksymtab_NAMESPACE.symbol. That caused some breakages in tools that depend on the name layout in either the binaries(vmlinux,*.ko) or in System.map. E.g. kmod's depmod would not be able to read System.map without a patch to support symbol namespaces. A warning reported by depmod for namespaced symbols would look like depmod: WARNING: [...]/uas.ko needs unknown symbol usb_stor_adjust_quirks In order to address this issue, revert to the original naming scheme and rather read the __kstrtabns_ entries and their corresponding values from __ksymtab_strings to update the namespace values for symbols. After having read all symbols and handled them in handle_modversions(), the symbols are created. In a second pass, read the __kstrtabns_ entries and update the namespaces accordingly. Fixes: 8651ec01daed ("module: add support for symbol namespaces.") Reported-by: Stefan Wahren Suggested-by: Masahiro Yamada Acked-by: Will Deacon Reviewed-by: Greg Kroah-Hartman Reviewed-by: Masahiro Yamada Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- include/linux/export.h | 14 +++++--------- scripts/mod/modpost.c | 33 ++++++++++++++++++--------------- scripts/mod/modpost.h | 1 + 3 files changed, 24 insertions(+), 24 deletions(-) (limited to 'scripts') diff --git a/include/linux/export.h b/include/linux/export.h index 621158ecd2e2..941d075f03d6 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -18,8 +18,6 @@ extern struct module __this_module; #define THIS_MODULE ((struct module *)0) #endif -#define NS_SEPARATOR "." - #ifdef CONFIG_MODVERSIONS /* Mark the CRC weak since genksyms apparently decides not to * generate a checksums for some symbols */ @@ -48,11 +46,11 @@ extern struct module __this_module; * absolute relocations that require runtime processing on relocatable * kernels. */ -#define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ +#define __KSYMTAB_ENTRY_NS(sym, sec) \ __ADDRESSABLE(sym) \ asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ " .balign 4 \n" \ - "__ksymtab_" #ns NS_SEPARATOR #sym ": \n" \ + "__ksymtab_" #sym ": \n" \ " .long " #sym "- . \n" \ " .long __kstrtab_" #sym "- . \n" \ " .long __kstrtabns_" #sym "- . \n" \ @@ -74,16 +72,14 @@ struct kernel_symbol { int namespace_offset; }; #else -#define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ - static const struct kernel_symbol __ksymtab_##sym##__##ns \ - asm("__ksymtab_" #ns NS_SEPARATOR #sym) \ +#define __KSYMTAB_ENTRY_NS(sym, sec) \ + static const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("___ksymtab" sec "+" #sym), used)) \ __aligned(sizeof(void *)) \ = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym } #define __KSYMTAB_ENTRY(sym, sec) \ static const struct kernel_symbol __ksymtab_##sym \ - asm("__ksymtab_" #sym) \ __attribute__((section("___ksymtab" sec "+" #sym), used)) \ __aligned(sizeof(void *)) \ = { (unsigned long)&sym, __kstrtab_##sym, NULL } @@ -115,7 +111,7 @@ struct kernel_symbol { static const char __kstrtabns_##sym[] \ __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ = #ns; \ - __KSYMTAB_ENTRY_NS(sym, sec, ns) + __KSYMTAB_ENTRY_NS(sym, sec) #define ___EXPORT_SYMBOL(sym, sec) \ ___export_symbol_common(sym, sec); \ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c43f1b1532f7..d2a30a7b3f07 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -348,18 +348,11 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) return export_unknown; } -static char *sym_extract_namespace(const char **symname) +static const char *namespace_from_kstrtabns(struct elf_info *info, + Elf_Sym *kstrtabns) { - char *namespace = NULL; - char *ns_separator; - - ns_separator = strchr(*symname, '.'); - if (ns_separator) { - namespace = NOFAIL(strndup(*symname, ns_separator - *symname)); - *symname = ns_separator + 1; - } - - return namespace; + char *value = info->ksymtab_strings + kstrtabns->st_value; + return value[0] ? value : NULL; } static void sym_update_namespace(const char *symname, const char *namespace) @@ -600,6 +593,10 @@ static int parse_elf(struct elf_info *info, const char *filename) info->export_unused_gpl_sec = i; else if (strcmp(secname, "__ksymtab_gpl_future") == 0) info->export_gpl_future_sec = i; + else if (strcmp(secname, "__ksymtab_strings") == 0) + info->ksymtab_strings = (void *)hdr + + sechdrs[i].sh_offset - + sechdrs[i].sh_addr; if (sechdrs[i].sh_type == SHT_SYMTAB) { unsigned int sh_link_idx; @@ -689,7 +686,6 @@ static void handle_modversions(struct module *mod, struct elf_info *info, enum export export; bool is_crc = false; const char *name; - char *namespace; if ((!is_vmlinux(mod->name) || mod->is_dot_o) && strstarts(symname, "__ksymtab")) @@ -762,10 +758,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, /* All exported symbols */ if (strstarts(symname, "__ksymtab_")) { name = symname + strlen("__ksymtab_"); - namespace = sym_extract_namespace(&name); sym_add_exported(name, mod, export); - sym_update_namespace(name, namespace); - free(namespace); } if (strcmp(symname, "init_module") == 0) mod->has_init = 1; @@ -2061,6 +2054,16 @@ static void read_symbols(const char *modname) handle_moddevtable(mod, &info, sym, symname); } + /* Apply symbol namespaces from __kstrtabns_ entries. */ + for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { + symname = remove_dot(info.strtab + sym->st_name); + + if (strstarts(symname, "__kstrtabns_")) + sym_update_namespace(symname + strlen("__kstrtabns_"), + namespace_from_kstrtabns(&info, + sym)); + } + // check for static EXPORT_SYMBOL_* functions && global vars for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { unsigned char bind = ELF_ST_BIND(sym->st_info); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 92a926d375d2..ad271bc6c313 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -143,6 +143,7 @@ struct elf_info { Elf_Section export_gpl_sec; Elf_Section export_unused_gpl_sec; Elf_Section export_gpl_future_sec; + char *ksymtab_strings; char *strtab; char *modinfo; unsigned int modinfo_len; -- cgit v1.2.3 From ca210ba32ef7537b02731bfe255ed8eb1e4e2b59 Mon Sep 17 00:00:00 2001 From: Joel Colledge Date: Fri, 18 Oct 2019 20:19:26 -0700 Subject: scripts/gdb: fix lx-dmesg when CONFIG_PRINTK_CALLER is set When CONFIG_PRINTK_CALLER is set, struct printk_log contains an additional member caller_id. This affects the offset of the log text. Account for this by using the type information from gdb to determine all the offsets instead of using hardcoded values. This fixes following error: (gdb) lx-dmesg Python Exception embedded null character: Error occurred in Python command: embedded null character The read_u* utility functions now take an offset argument to make them easier to use. Link: http://lkml.kernel.org/r/20191011142500.2339-1-joel.colledge@linbit.com Signed-off-by: Joel Colledge Reviewed-by: Jan Kiszka Cc: Kieran Bingham Cc: Leonard Crestez Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/dmesg.py | 16 ++++++++++++---- scripts/gdb/linux/utils.py | 25 +++++++++++++------------ 2 files changed, 25 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index 6d2e09a2ad2f..2fa7bb83885f 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -16,6 +16,8 @@ import sys from linux import utils +printk_log_type = utils.CachedType("struct printk_log") + class LxDmesg(gdb.Command): """Print Linux kernel log buffer.""" @@ -42,9 +44,14 @@ class LxDmesg(gdb.Command): b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) log_buf = a.tobytes() + b.tobytes() + length_offset = printk_log_type.get_type()['len'].bitpos // 8 + text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8 + time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8 + text_offset = printk_log_type.get_type().sizeof + pos = 0 while pos < log_buf.__len__(): - length = utils.read_u16(log_buf[pos + 8:pos + 10]) + length = utils.read_u16(log_buf, pos + length_offset) if length == 0: if log_buf_2nd_half == -1: gdb.write("Corrupted log buffer!\n") @@ -52,10 +59,11 @@ class LxDmesg(gdb.Command): pos = log_buf_2nd_half continue - text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) - text = log_buf[pos + 16:pos + 16 + text_len].decode( + text_len = utils.read_u16(log_buf, pos + text_len_offset) + text_start = pos + text_offset + text = log_buf[text_start:text_start + text_len].decode( encoding='utf8', errors='replace') - time_stamp = utils.read_u64(log_buf[pos:pos + 8]) + time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format( diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index bc67126118c4..ea94221dbd39 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -92,15 +92,16 @@ def read_memoryview(inf, start, length): return memoryview(inf.read_memory(start, length)) -def read_u16(buffer): +def read_u16(buffer, offset): + buffer_val = buffer[offset:offset + 2] value = [0, 0] - if type(buffer[0]) is str: - value[0] = ord(buffer[0]) - value[1] = ord(buffer[1]) + if type(buffer_val[0]) is str: + value[0] = ord(buffer_val[0]) + value[1] = ord(buffer_val[1]) else: - value[0] = buffer[0] - value[1] = buffer[1] + value[0] = buffer_val[0] + value[1] = buffer_val[1] if get_target_endianness() == LITTLE_ENDIAN: return value[0] + (value[1] << 8) @@ -108,18 +109,18 @@ def read_u16(buffer): return value[1] + (value[0] << 8) -def read_u32(buffer): +def read_u32(buffer, offset): if get_target_endianness() == LITTLE_ENDIAN: - return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16) + return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16) else: - return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16) + return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16) -def read_u64(buffer): +def read_u64(buffer, offset): if get_target_endianness() == LITTLE_ENDIAN: - return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32) + return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32) else: - return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32) + return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32) target_arch = None -- cgit v1.2.3 From 585d730d41120926e3f79a601edad3930fa28366 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 18 Oct 2019 20:20:43 -0700 Subject: scripts/gdb: fix debugging modules on s390 Currently lx-symbols assumes that module text is always located at module->core_layout->base, but s390 uses the following layout: +------+ <- module->core_layout->base | GOT | +------+ <- module->core_layout->base + module->arch->plt_offset | PLT | +------+ <- module->core_layout->base + module->arch->plt_offset + | TEXT | module->arch->plt_size +------+ Therefore, when trying to debug modules on s390, all the symbol addresses are skewed by plt_offset + plt_size. Fix by adding plt_offset + plt_size to module_addr in load_module_symbols(). Link: http://lkml.kernel.org/r/20191017085917.81791-1-iii@linux.ibm.com Signed-off-by: Ilya Leoshkevich Reviewed-by: Jan Kiszka Cc: Kieran Bingham Cc: Heiko Carstens Cc: Vasily Gorbik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/symbols.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 34e40e96dee2..7b7c2fafbc68 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -15,7 +15,7 @@ import gdb import os import re -from linux import modules +from linux import modules, utils if hasattr(gdb, 'Breakpoint'): @@ -116,6 +116,12 @@ lx-symbols command.""" module_file = self._get_module_file(module_name) if module_file: + if utils.is_target_arch('s390'): + # Module text is preceded by PLT stubs on s390. + module_arch = module['arch'] + plt_offset = int(module_arch['plt_offset']) + plt_size = int(module_arch['plt_size']) + module_addr = hex(int(module_addr, 0) + plt_offset + plt_size) gdb.write("loading @{addr}: {filename}\n".format( addr=module_addr, filename=module_file)) cmdline = "add-symbol-file {filename} {addr}{sections}".format( -- cgit v1.2.3 From 09684950050be09ed6cd591e6fbf0c71d3473237 Mon Sep 17 00:00:00 2001 From: Jessica Yu Date: Mon, 21 Oct 2019 15:34:26 +0200 Subject: scripts/nsdeps: use alternative sed delimiter When doing an out of tree build with O=, the nsdeps script constructs the absolute pathname of the module source file so that it can insert MODULE_IMPORT_NS statements in the right place. However, ${srctree} contains an unescaped path to the source tree, which, when used in a sed substitution, makes sed complain: ++ sed 's/[^ ]* *//home/jeyu/jeyu-linux\/&/g' sed: -e expression #1, char 12: unknown option to `s' The sed substitution command 's' ends prematurely with the forward slashes in the pathname, and sed errors out when it encounters the 'h', which is an invalid sed substitution option. To avoid escaping forward slashes ${srctree}, we can use '|' as an alternative delimiter for sed instead to avoid this error. Reviewed-by: Masahiro Yamada Reviewed-by: Matthias Maennich Tested-by: Matthias Maennich Signed-off-by: Jessica Yu --- scripts/nsdeps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/nsdeps b/scripts/nsdeps index 3754dac13b31..dda6fbac016e 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -33,7 +33,7 @@ generate_deps() { if [ ! -f "$ns_deps_file" ]; then return; fi local mod_source_files=`cat $mod_file | sed -n 1p \ | sed -e 's/\.o/\.c/g' \ - | sed "s/[^ ]* */${srctree}\/&/g"` + | sed "s|[^ ]* *|${srctree}/&|g"` for ns in `cat $ns_deps_file`; do echo "Adding namespace $ns to module $mod_name (if needed)." generate_deps_for_ns $ns $mod_source_files -- cgit v1.2.3