History

Merge tag 'kbuild-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada: - Remove the support for -O3 (CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3) - Fix error of rpm-pkg cross-builds - Support riscv for checkstack tool - Re-enable -Wformwat warnings for Clang - Clean up modpost, Makefiles, and misc scripts * tag 'kbuild-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (30 commits) modpost: remove .symbol_white_list field entirely modpost: remove unneeded .symbol_white_list initializers modpost: add PATTERNS() helper macro modpost: shorten warning messages in report_sec_mismatch() Revert "Kbuild, lto, workaround: Don't warn for initcall_reference in modpost" modpost: use more reliable way to get fromsec in section_rel(a)() modpost: add array range check to sec_name() modpost: refactor get_secindex() kbuild: set EXIT trap before creating temporary directory modpost: remove unused Elf_Sword macro Makefile.extrawarn: re-enable -Wformat for clang kbuild: add dtbs_prepare target kconfig: Qt5: tell the user which packages are required modpost: use sym_get_data() to get module device_table data modpost: drop executable ELF support checkstack: add riscv support for scripts/checkstack.pl kconfig: shorten the temporary directory name for cc-option scripts: headers_install.sh: Update config leak ignore entries kbuild: error out if $(INSTALL_MOD_PATH) contains % or : kbuild: error out if $(KBUILD_EXTMOD) contains % or : ...

Linus Torvalds committed 4 years ago

Commit 0af5cb32 parents d425207 672fb6736 files · +111 −313Browse files

Showing the changes to scripts (16 of 36 files). Show all

Unified · Split

16 files
  1. scripts/Kconfig.include +1 −1
  2. scripts/Makefile.build +2 −3
  3. scripts/Makefile.compiler +1 −1
  4. scripts/Makefile.extrawarn +0 −1
  5. scripts/Makefile.modinst +3 −0
  6. scripts/Makefile.package +2 −2
  7. scripts/check-blacklist-hashes.awk +0 −37
  8. scripts/checkstack.pl +4 −0
  9. scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h +0 −0
  10. scripts/dummy-tools/gcc +2 −6
  11. scripts/headers_install.sh +0 −2
  12. scripts/kconfig/qconf-cfg.sh +1 −0
  13. scripts/mod/file2alias.c +1 −3
  14. scripts/mod/modpost.c +48 −233
  15. scripts/mod/modpost.h +19 −14
  16. scripts/package/mkspec +3 −0
scripts/Kconfig.include+1−1
@@ -25,7 +25,7 @@ failure = $(if-success,$(1),n,y) · 24 unmodified lines
25 25
26# $(cc-option,<flag>)26# $(cc-option,<flag>)
27# Return y if the compiler supports <flag>, n otherwise27# Return y if the compiler supports <flag>, n otherwise
28cc-option = $(success,mkdir .tmp_$$$$; trap "rm -rf .tmp_$$$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$$$/tmp.o)28cc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$/tmp.o)
29 29
30# $(ld-option,<flag>)30# $(ld-option,<flag>)
31# Return y if the linker supports <flag>, n otherwise31# Return y if the linker supports <flag>, n otherwise
scripts/Makefile.build+2−3
@@ -358,9 +358,8 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; · 357 unmodified lines
358 358
359quiet_cmd_ar_builtin = AR $@359quiet_cmd_ar_builtin = AR $@
360 cmd_ar_builtin = rm -f $@; \360 cmd_ar_builtin = rm -f $@; \
361 echo $(patsubst $(obj)/%,%,$(real-prereqs)) | \361 $(if $(real-prereqs), printf "$(obj)/%s " $(patsubst $(obj)/%,%,$(real-prereqs)) | xargs) \
362 sed -E 's:([^ ]+):$(obj)/\1:g' | \362 $(AR) cDPrST $@
363 xargs $(AR) cDPrST $@
364 363
365$(obj)/built-in.a: $(real-obj-y) FORCE364$(obj)/built-in.a: $(real-obj-y) FORCE
366 $(call if_changed,ar_builtin)365 $(call if_changed,ar_builtin)
scripts/Makefile.compiler+1−1
@@ -21,8 +21,8 @@ TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ · 20 unmodified lines
21# automatically cleaned up.21# automatically cleaned up.
22try-run = $(shell set -e; \22try-run = $(shell set -e; \
23 TMP=$(TMPOUT)/tmp; \23 TMP=$(TMPOUT)/tmp; \
24 mkdir -p $(TMPOUT); \
25 trap "rm -rf $(TMPOUT)" EXIT; \24 trap "rm -rf $(TMPOUT)" EXIT; \
25 mkdir -p $(TMPOUT); \
26 if ($(1)) >/dev/null 2>&1; \26 if ($(1)) >/dev/null 2>&1; \
27 then echo "$(2)"; \27 then echo "$(2)"; \
28 else echo "$(3)"; \28 else echo "$(3)"; \
scripts/Makefile.extrawarn+0−1
@@ -47,7 +47,6 @@ else · 46 unmodified lines
47 47
48ifdef CONFIG_CC_IS_CLANG48ifdef CONFIG_CC_IS_CLANG
49KBUILD_CFLAGS += -Wno-initializer-overrides49KBUILD_CFLAGS += -Wno-initializer-overrides
50KBUILD_CFLAGS += -Wno-format
51KBUILD_CFLAGS += -Wno-sign-compare50KBUILD_CFLAGS += -Wno-sign-compare
52KBUILD_CFLAGS += -Wno-format-zero-length51KBUILD_CFLAGS += -Wno-format-zero-length
53KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)52KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
scripts/Makefile.modinst+3−0
@@ -18,6 +18,9 @@ INSTALL_MOD_DIR ?= extra · 17 unmodified lines
18dst := $(MODLIB)/$(INSTALL_MOD_DIR)18dst := $(MODLIB)/$(INSTALL_MOD_DIR)
19endif19endif
20 20
21$(foreach x, % :, $(if $(findstring $x, $(dst)), \
22 $(error module installation path cannot contain '$x')))
23
21suffix-y :=24suffix-y :=
22suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz25suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
23suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz26suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
scripts/Makefile.package+2−2
@@ -56,7 +56,7 @@ rpm-pkg: · 55 unmodified lines
56 $(MAKE) clean56 $(MAKE) clean
57 $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec57 $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec
58 $(call cmd,src_tar,$(KERNELPATH),kernel.spec)58 $(call cmd,src_tar,$(KERNELPATH),kernel.spec)
59 +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \59 +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE)-linux -ta $(KERNELPATH).tar.gz \
60 --define='_smp_mflags %{nil}'60 --define='_smp_mflags %{nil}'
61 61
62# binrpm-pkg62# binrpm-pkg
@@ -66,7 +66,7 @@ binrpm-pkg: · 3 unmodified lines
66 $(MAKE) -f $(srctree)/Makefile66 $(MAKE) -f $(srctree)/Makefile
67 $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec67 $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec
68 +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \68 +rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
69 $(UTS_MACHINE) -bb $(objtree)/binkernel.spec69 $(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec
70 70
71PHONY += deb-pkg71PHONY += deb-pkg
72deb-pkg:72deb-pkg:
scripts/check-blacklist-hashes.awk+0−37
@@ -1,37 +0,0 @@
1#!/usr/bin/awk -f
2# SPDX-License-Identifier: GPL-2.0
3#
4# Copyright © 2020, Microsoft Corporation. All rights reserved.
5#
6# Author: Mickaël Salaün <mic@linux.microsoft.com>
7#
8# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of
9# hash strings. Such string must start with a prefix ("tbs" or "bin"), then a
10# colon (":"), and finally an even number of hexadecimal lowercase characters
11# (up to 128).
12
13BEGIN {
14 RS = ","
15}
16{
17 if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) {
18 print "Not a string (item " NR "):", $0;
19 exit 1;
20 }
21 if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) {
22 print "Unknown prefix (item " NR "):", part1[1];
23 exit 1;
24 }
25 if (!match(part2[2], "^([0-9a-f]+)$", part3)) {
26 print "Not a lowercase hexadecimal string (item " NR "):", part2[2];
27 exit 1;
28 }
29 if (length(part3[1]) > 128) {
30 print "Hash string too long (item " NR "):", part3[1];
31 exit 1;
32 }
33 if (length(part3[1]) % 2 == 1) {
34 print "Not an even number of hexadecimal characters (item " NR "):", part3[1];
35 exit 1;
36 }
37}
scripts/checkstack.pl+4−0
@@ -16,6 +16,7 @@ · 15 unmodified lines
16# AArch64, PARISC ports by Kyle McMartin16# AArch64, PARISC ports by Kyle McMartin
17# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>17# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
18# ppc64le port by Breno Leitao <leitao@debian.org>18# ppc64le port by Breno Leitao <leitao@debian.org>
19# riscv port by Wadim Mueller <wafgo01@gmail.com>
19#20#
20# Usage:21# Usage:
21# objdump -d vmlinux | scripts/checkstack.pl [arch]22# objdump -d vmlinux | scripts/checkstack.pl [arch]
@@ -108,6 +109,9 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); · 86 unmodified lines
108 } elsif ($arch eq 'sparc' || $arch eq 'sparc64') {109 } elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
109 # f0019d10: 9d e3 bf 90 save %sp, -112, %sp110 # f0019d10: 9d e3 bf 90 save %sp, -112, %sp
110 $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;111 $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
112 } elsif ($arch =~ /^riscv(64)?$/) {
113 #ffffffff8036e868: c2010113 addi sp,sp,-992
114 $re = qr/.*addi.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
111 } else {115 } else {
112 print("wrong or unknown architecture \"$arch\"\n");116 print("wrong or unknown architecture \"$arch\"\n");
113 exit117 exit
scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h+0−0

Empty file added.

scripts/dummy-tools/gcc+2−6
@@ -96,12 +96,8 @@ fi · 95 unmodified lines
96 96
97# To set GCC_PLUGINS97# To set GCC_PLUGINS
98if arg_contain -print-file-name=plugin "$@"; then98if arg_contain -print-file-name=plugin "$@"; then
99 plugin_dir=$(mktemp -d)99 # Use $0 to find the in-tree dummy directory
100 100 echo "$(dirname "$(readlink -f "$0")")/dummy-plugin-dir"
101 mkdir -p $plugin_dir/include
102 touch $plugin_dir/include/plugin-version.h
103
104 echo $plugin_dir
105 exit 0101 exit 0
106fi102fi
107 103
scripts/headers_install.sh+0−2
@@ -70,7 +70,6 @@ configs=$(sed -e ' · 69 unmodified lines
70#70#
71# The format is <file-name>:<CONFIG-option> in each line.71# The format is <file-name>:<CONFIG-option> in each line.
72config_leak_ignores="72config_leak_ignores="
73arch/alpha/include/uapi/asm/setup.h:CONFIG_ALPHA_LEGACY_START_ADDRESS
74arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_16K73arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_16K
75arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_4K74arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_4K
76arch/arc/include/uapi/asm/swab.h:CONFIG_ARC_HAS_SWAPE75arch/arc/include/uapi/asm/swab.h:CONFIG_ARC_HAS_SWAPE
@@ -84,7 +83,6 @@ arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_SUPPORT · 7 unmodified lines
84arch/x86/include/uapi/asm/auxvec.h:CONFIG_IA32_EMULATION83arch/x86/include/uapi/asm/auxvec.h:CONFIG_IA32_EMULATION
85arch/x86/include/uapi/asm/auxvec.h:CONFIG_X86_6484arch/x86/include/uapi/asm/auxvec.h:CONFIG_X86_64
86arch/x86/include/uapi/asm/mman.h:CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS85arch/x86/include/uapi/asm/mman.h:CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
87include/uapi/asm-generic/fcntl.h:CONFIG_64BIT
88include/uapi/linux/atmdev.h:CONFIG_COMPAT86include/uapi/linux/atmdev.h:CONFIG_COMPAT
89include/uapi/linux/eventpoll.h:CONFIG_PM_SLEEP87include/uapi/linux/eventpoll.h:CONFIG_PM_SLEEP
90include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS88include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
scripts/kconfig/qconf-cfg.sh+1−0
@@ -20,5 +20,6 @@ fi · 19 unmodified lines
20echo >&2 "*"20echo >&2 "*"
21echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}."21echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}."
22echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"22echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"
23echo >&2 "* You need $PKG"
23echo >&2 "*"24echo >&2 "*"
24exit 125exit 1
scripts/mod/file2alias.c+1−3
@@ -1571,9 +1571,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, · 1570 unmodified lines
1571 zeros = calloc(1, sym->st_size);1571 zeros = calloc(1, sym->st_size);
1572 symval = zeros;1572 symval = zeros;
1573 } else {1573 } else {
1574 symval = (void *)info->hdr1574 symval = sym_get_data(info, sym);
1575 + info->sechdrs[get_secindex(info, sym)].sh_offset
1576 + sym->st_value;
1577 }1575 }
1578 1576
1579 /* First handle the "special" cases */1577 /* First handle the "special" cases */
scripts/mod/modpost.c+48−233
@@ -321,13 +321,10 @@ static void *sym_get_data_by_offset(const struct elf_info *info, · 320 unmodified lines
321{321{
322 Elf_Shdr *sechdr = &info->sechdrs[secindex];322 Elf_Shdr *sechdr = &info->sechdrs[secindex];
323 323
324 if (info->hdr->e_type != ET_REL)
325 offset -= sechdr->sh_addr;
326
327 return (void *)info->hdr + sechdr->sh_offset + offset;324 return (void *)info->hdr + sechdr->sh_offset + offset;
328}325}
329 326
330static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)327void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
331{328{
332 return sym_get_data_by_offset(info, get_secindex(info, sym),329 return sym_get_data_by_offset(info, get_secindex(info, sym),
333 sym->st_value);330 sym->st_value);
@@ -339,8 +336,16 @@ static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr) · 5 unmodified lines
339 sechdr->sh_name);336 sechdr->sh_name);
340}337}
341 338
342static const char *sec_name(const struct elf_info *info, int secindex)339static const char *sec_name(const struct elf_info *info, unsigned int secindex)
343{340{
341 /*
342 * If sym->st_shndx is a special section index, there is no
343 * corresponding section header.
344 * Return "" if the index is out of range of info->sechdrs[] array.
345 */
346 if (secindex >= info->num_sections)
347 return "";
348
344 return sech_name(info, &info->sechdrs[secindex]);349 return sech_name(info, &info->sechdrs[secindex]);
345}350}
346 351
@@ -466,6 +471,10 @@ static int parse_elf(struct elf_info *info, const char *filename) · 119 unmodified lines
466 sechdrs = (void *)hdr + hdr->e_shoff;471 sechdrs = (void *)hdr + hdr->e_shoff;
467 info->sechdrs = sechdrs;472 info->sechdrs = sechdrs;
468 473
474 /* modpost only works for relocatable objects */
475 if (hdr->e_type != ET_REL)
476 fatal("%s: not relocatable object.", filename);
477
469 /* Check if file offset is correct */478 /* Check if file offset is correct */
470 if (hdr->e_shoff > info->size) {479 if (hdr->e_shoff > info->size) {
471 fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",480 fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
@@ -737,12 +746,18 @@ static bool match(const char *string, const char *const patterns[]) · 265 unmodified lines
737 return false;746 return false;
738}747}
739 748
749/* useful to pass patterns to match() directly */
750#define PATTERNS(...) \
751 ({ \
752 static const char *const patterns[] = {__VA_ARGS__, NULL}; \
753 patterns; \
754 })
755
740/* sections that we do not want to do full section mismatch check on */756/* sections that we do not want to do full section mismatch check on */
741static const char *const section_white_list[] =757static const char *const section_white_list[] =
742{758{
743 ".comment*",759 ".comment*",
744 ".debug*",760 ".debug*",
745 ".cranges", /* sh64 */
746 ".zdebug*", /* Compressed debug sections. */761 ".zdebug*", /* Compressed debug sections. */
747 ".GCC.command.line", /* record-gcc-switches */762 ".GCC.command.line", /* record-gcc-switches */
748 ".mdebug*", /* alpha, score, mips etc. */763 ".mdebug*", /* alpha, score, mips etc. */
@@ -830,28 +845,12 @@ static const char *const init_data_sections[] = · 81 unmodified lines
830/* all init sections */845/* all init sections */
831static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };846static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
832 847
833/* All init and exit sections (code + data) */
834static const char *const init_exit_sections[] =
835 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
836
837/* all text sections */848/* all text sections */
838static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };849static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
839 850
840/* data section */851/* data section */
841static const char *const data_sections[] = { DATA_SECTIONS, NULL };852static const char *const data_sections[] = { DATA_SECTIONS, NULL };
842 853
843
844/* symbols in .data that may refer to init/exit sections */
845#define DEFAULT_SYMBOL_WHITE_LIST \
846 "*driver", \
847 "*_template", /* scsi uses *_template a lot */ \
848 "*_timer", /* arm uses ops structures named _timer a lot */ \
849 "*_sht", /* scsi also used *_sht to some extent */ \
850 "*_ops", \
851 "*_probe", \
852 "*_probe_one", \
853 "*_console"
854
855static const char *const head_sections[] = { ".head.text*", NULL };854static const char *const head_sections[] = { ".head.text*", NULL };
856static const char *const linker_symbols[] =855static const char *const linker_symbols[] =
857 { "__init_begin", "_sinittext", "_einittext", NULL };856 { "__init_begin", "_sinittext", "_einittext", NULL };
@@ -883,9 +882,6 @@ enum mismatch { · 25 unmodified lines
883 *882 *
884 * @mismatch: Type of mismatch.883 * @mismatch: Type of mismatch.
885 *884 *
886 * @symbol_white_list: Do not match a relocation to a symbol in this list
887 * even if it is targeting a section in @bad_to_sec.
888 *
889 * @handler: Specific handler to call when a match is found. If NULL,885 * @handler: Specific handler to call when a match is found. If NULL,
890 * default_mismatch_handler() will be called.886 * default_mismatch_handler() will be called.
891 *887 *
@@ -895,7 +891,6 @@ struct sectioncheck { · 3 unmodified lines
895 const char *bad_tosec[20];891 const char *bad_tosec[20];
896 const char *good_tosec[20];892 const char *good_tosec[20];
897 enum mismatch mismatch;893 enum mismatch mismatch;
898 const char *symbol_white_list[20];
899 void (*handler)(const char *modname, struct elf_info *elf,894 void (*handler)(const char *modname, struct elf_info *elf,
900 const struct sectioncheck* const mismatch,895 const struct sectioncheck* const mismatch,
901 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);896 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
@@ -915,75 +910,61 @@ static const struct sectioncheck sectioncheck[] = { · 13 unmodified lines
915 .fromsec = { TEXT_SECTIONS, NULL },910 .fromsec = { TEXT_SECTIONS, NULL },
916 .bad_tosec = { ALL_INIT_SECTIONS, NULL },911 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
917 .mismatch = TEXT_TO_ANY_INIT,912 .mismatch = TEXT_TO_ANY_INIT,
918 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
919},913},
920{914{
921 .fromsec = { DATA_SECTIONS, NULL },915 .fromsec = { DATA_SECTIONS, NULL },
922 .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },916 .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
923 .mismatch = DATA_TO_ANY_INIT,917 .mismatch = DATA_TO_ANY_INIT,
924 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
925},918},
926{919{
927 .fromsec = { DATA_SECTIONS, NULL },920 .fromsec = { DATA_SECTIONS, NULL },
928 .bad_tosec = { INIT_SECTIONS, NULL },921 .bad_tosec = { INIT_SECTIONS, NULL },
929 .mismatch = DATA_TO_ANY_INIT,922 .mismatch = DATA_TO_ANY_INIT,
930 .symbol_white_list = {
931 "*_template", "*_timer", "*_sht", "*_ops",
932 "*_probe", "*_probe_one", "*_console", NULL
933 },
934},923},
935{924{
936 .fromsec = { TEXT_SECTIONS, NULL },925 .fromsec = { TEXT_SECTIONS, NULL },
937 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },926 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
938 .mismatch = TEXT_TO_ANY_EXIT,927 .mismatch = TEXT_TO_ANY_EXIT,
939 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
940},928},
941{929{
942 .fromsec = { DATA_SECTIONS, NULL },930 .fromsec = { DATA_SECTIONS, NULL },
943 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },931 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
944 .mismatch = DATA_TO_ANY_EXIT,932 .mismatch = DATA_TO_ANY_EXIT,
945 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
946},933},
947/* Do not reference init code/data from meminit code/data */934/* Do not reference init code/data from meminit code/data */
948{935{
949 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },936 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
950 .bad_tosec = { INIT_SECTIONS, NULL },937 .bad_tosec = { INIT_SECTIONS, NULL },
951 .mismatch = XXXINIT_TO_SOME_INIT,938 .mismatch = XXXINIT_TO_SOME_INIT,
952 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
953},939},
954/* Do not reference exit code/data from memexit code/data */940/* Do not reference exit code/data from memexit code/data */
955{941{
956 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },942 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
957 .bad_tosec = { EXIT_SECTIONS, NULL },943 .bad_tosec = { EXIT_SECTIONS, NULL },
958 .mismatch = XXXEXIT_TO_SOME_EXIT,944 .mismatch = XXXEXIT_TO_SOME_EXIT,
959 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
960},945},
961/* Do not use exit code/data from init code */946/* Do not use exit code/data from init code */
962{947{
963 .fromsec = { ALL_INIT_SECTIONS, NULL },948 .fromsec = { ALL_INIT_SECTIONS, NULL },
964 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },949 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
965 .mismatch = ANY_INIT_TO_ANY_EXIT,950 .mismatch = ANY_INIT_TO_ANY_EXIT,
966 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
967},951},
968/* Do not use init code/data from exit code */952/* Do not use init code/data from exit code */
969{953{
970 .fromsec = { ALL_EXIT_SECTIONS, NULL },954 .fromsec = { ALL_EXIT_SECTIONS, NULL },
971 .bad_tosec = { ALL_INIT_SECTIONS, NULL },955 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
972 .mismatch = ANY_EXIT_TO_ANY_INIT,956 .mismatch = ANY_EXIT_TO_ANY_INIT,
973 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
974},957},
975{958{
976 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },959 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
977 .bad_tosec = { INIT_SECTIONS, NULL },960 .bad_tosec = { INIT_SECTIONS, NULL },
978 .mismatch = ANY_INIT_TO_ANY_EXIT,961 .mismatch = ANY_INIT_TO_ANY_EXIT,
979 .symbol_white_list = { NULL },
980},962},
981/* Do not export init/exit functions or data */963/* Do not export init/exit functions or data */
982{964{
983 .fromsec = { "___ksymtab*", NULL },965 .fromsec = { "___ksymtab*", NULL },
984 .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },966 .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
985 .mismatch = EXPORT_TO_INIT_EXIT,967 .mismatch = EXPORT_TO_INIT_EXIT,
986 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
987},968},
988{969{
989 .fromsec = { "__ex_table", NULL },970 .fromsec = { "__ex_table", NULL },
@@ -1044,15 +1025,6 @@ static const struct sectioncheck *section_mismatch( · 54 unmodified lines
1044 * fromsec = .data*1025 * fromsec = .data*
1045 * atsym = __param_ops_*1026 * atsym = __param_ops_*
1046 *1027 *
1047 * Pattern 2:
1048 * Many drivers utilise a *driver container with references to
1049 * add, remove, probe functions etc.
1050 * the pattern is identified by:
1051 * tosec = init or exit section
1052 * fromsec = data section
1053 * atsym = *driver, *_template, *_sht, *_ops, *_probe,
1054 * *probe_one, *_console, *_timer
1055 *
1056 * Pattern 3:1028 * Pattern 3:
1057 * Whitelist all references from .head.text to any init section1029 * Whitelist all references from .head.text to any init section
1058 *1030 *
@@ -1101,10 +1073,22 @@ static int secref_whitelist(const struct sectioncheck *mismatch, · 42 unmodified lines
1101 strstarts(fromsym, "__param_ops_"))1073 strstarts(fromsym, "__param_ops_"))
1102 return 0;1074 return 0;
1103 1075
1104 /* Check for pattern 2 */1076 /* symbols in data sections that may refer to any init/exit sections */
1105 if (match(tosec, init_exit_sections) &&1077 if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
1106 match(fromsec, data_sections) &&1078 match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
1107 match(fromsym, mismatch->symbol_white_list))1079 match(fromsym, PATTERNS("*_template", // scsi uses *_template a lot
1080 "*_timer", // arm uses ops structures named _timer a lot
1081 "*_sht", // scsi also used *_sht to some extent
1082 "*_ops",
1083 "*_probe",
1084 "*_probe_one",
1085 "*_console")))
1086 return 0;
1087
1088 /* symbols in data sections that may refer to meminit/exit sections */
1089 if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
1090 match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
1091 match(fromsym, PATTERNS("*driver")))
1108 return 0;1092 return 0;
1109 1093
1110 /* Check for pattern 3 */1094 /* Check for pattern 3 */
@@ -1230,42 +1214,6 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, · 119 unmodified lines
1230 return near;1214 return near;
1231}1215}
1232 1216
1233/*
1234 * Convert a section name to the function/data attribute
1235 * .init.text => __init
1236 * .memexitconst => __memconst
1237 * etc.
1238 *
1239 * The memory of returned value has been allocated on a heap. The user of this
1240 * method should free it after usage.
1241*/
1242static char *sec2annotation(const char *s)
1243{
1244 if (match(s, init_exit_sections)) {
1245 char *p = NOFAIL(malloc(20));
1246 char *r = p;
1247
1248 *p++ = '_';
1249 *p++ = '_';
1250 if (*s == '.')
1251 s++;
1252 while (*s && *s != '.')
1253 *p++ = *s++;
1254 *p = '\0';
1255 if (*s == '.')
1256 s++;
1257 if (strstr(s, "rodata") != NULL)
1258 strcat(p, "const ");
1259 else if (strstr(s, "data") != NULL)
1260 strcat(p, "data ");
1261 else
1262 strcat(p, " ");
1263 return r;
1264 } else {
1265 return NOFAIL(strdup(""));
1266 }
1267}
1268
1269static int is_function(Elf_Sym *sym)1217static int is_function(Elf_Sym *sym)
1270{1218{
1271 if (sym)1219 if (sym)
@@ -1274,19 +1222,6 @@ static int is_function(Elf_Sym *sym) · 2 unmodified lines
1274 return -1;1222 return -1;
1275}1223}
1276 1224
1277static void print_section_list(const char * const list[20])
1278{
1279 const char *const *s = list;
1280
1281 while (*s) {
1282 fprintf(stderr, "%s", *s);
1283 s++;
1284 if (*s)
1285 fprintf(stderr, ", ");
1286 }
1287 fprintf(stderr, "\n");
1288}
1289
1290static inline void get_pretty_name(int is_func, const char** name, const char** name_p)1225static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
1291{1226{
1292 switch (is_func) {1227 switch (is_func) {
@@ -1304,141 +1239,31 @@ static inline void get_pretty_name(int is_func, const char** name, const char** · 11 unmodified lines
1304static void report_sec_mismatch(const char *modname,1239static void report_sec_mismatch(const char *modname,
1305 const struct sectioncheck *mismatch,1240 const struct sectioncheck *mismatch,
1306 const char *fromsec,1241 const char *fromsec,
1307 unsigned long long fromaddr,
1308 const char *fromsym,1242 const char *fromsym,
1309 int from_is_func,1243 const char *tosec, const char *tosym)
1310 const char *tosec, const char *tosym,
1311 int to_is_func)
1312{1244{
1313 const char *from, *from_p;
1314 const char *to, *to_p;
1315 char *prl_from;
1316 char *prl_to;
1317
1318 sec_mismatch_count++;1245 sec_mismatch_count++;
1319 1246
1320 get_pretty_name(from_is_func, &from, &from_p);
1321 get_pretty_name(to_is_func, &to, &to_p);
1322
1323 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
1324 "to the %s %s:%s%s\n",
1325 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1326 tosym, to_p);
1327
1328 switch (mismatch->mismatch) {1247 switch (mismatch->mismatch) {
1329 case TEXT_TO_ANY_INIT:1248 case TEXT_TO_ANY_INIT:
1330 prl_from = sec2annotation(fromsec);1249 case DATA_TO_ANY_INIT:
1331 prl_to = sec2annotation(tosec);
1332 fprintf(stderr,
1333 "The function %s%s() references\n"
1334 "the %s %s%s%s.\n"
1335 "This is often because %s lacks a %s\n"
1336 "annotation or the annotation of %s is wrong.\n",
1337 prl_from, fromsym,
1338 to, prl_to, tosym, to_p,
1339 fromsym, prl_to, tosym);
1340 free(prl_from);
1341 free(prl_to);
1342 break;
1343 case DATA_TO_ANY_INIT: {
1344 prl_to = sec2annotation(tosec);
1345 fprintf(stderr,
1346 "The variable %s references\n"
1347 "the %s %s%s%s\n"
1348 "If the reference is valid then annotate the\n"
1349 "variable with __init* or __refdata (see linux/init.h) "
1350 "or name the variable:\n",
1351 fromsym, to, prl_to, tosym, to_p);
1352 print_section_list(mismatch->symbol_white_list);
1353 free(prl_to);
1354 break;
1355 }
1356 case TEXT_TO_ANY_EXIT:1250 case TEXT_TO_ANY_EXIT:
1357 prl_to = sec2annotation(tosec);1251 case DATA_TO_ANY_EXIT:
1358 fprintf(stderr,
1359 "The function %s() references a %s in an exit section.\n"
1360 "Often the %s %s%s has valid usage outside the exit section\n"
1361 "and the fix is to remove the %sannotation of %s.\n",
1362 fromsym, to, to, tosym, to_p, prl_to, tosym);
1363 free(prl_to);
1364 break;
1365 case DATA_TO_ANY_EXIT: {
1366 prl_to = sec2annotation(tosec);
1367 fprintf(stderr,
1368 "The variable %s references\n"
1369 "the %s %s%s%s\n"
1370 "If the reference is valid then annotate the\n"
1371 "variable with __exit* (see linux/init.h) or "
1372 "name the variable:\n",
1373 fromsym, to, prl_to, tosym, to_p);
1374 print_section_list(mismatch->symbol_white_list);
1375 free(prl_to);
1376 break;
1377 }
1378 case XXXINIT_TO_SOME_INIT:1252 case XXXINIT_TO_SOME_INIT:
1379 case XXXEXIT_TO_SOME_EXIT:1253 case XXXEXIT_TO_SOME_EXIT:
1380 prl_from = sec2annotation(fromsec);
1381 prl_to = sec2annotation(tosec);
1382 fprintf(stderr,
1383 "The %s %s%s%s references\n"
1384 "a %s %s%s%s.\n"
1385 "If %s is only used by %s then\n"
1386 "annotate %s with a matching annotation.\n",
1387 from, prl_from, fromsym, from_p,
1388 to, prl_to, tosym, to_p,
1389 tosym, fromsym, tosym);
1390 free(prl_from);
1391 free(prl_to);
1392 break;
1393 case ANY_INIT_TO_ANY_EXIT:1254 case ANY_INIT_TO_ANY_EXIT:
1394 prl_from = sec2annotation(fromsec);
1395 prl_to = sec2annotation(tosec);
1396 fprintf(stderr,
1397 "The %s %s%s%s references\n"
1398 "a %s %s%s%s.\n"
1399 "This is often seen when error handling "
1400 "in the init function\n"
1401 "uses functionality in the exit path.\n"
1402 "The fix is often to remove the %sannotation of\n"
1403 "%s%s so it may be used outside an exit section.\n",
1404 from, prl_from, fromsym, from_p,
1405 to, prl_to, tosym, to_p,
1406 prl_to, tosym, to_p);
1407 free(prl_from);
1408 free(prl_to);
1409 break;
1410 case ANY_EXIT_TO_ANY_INIT:1255 case ANY_EXIT_TO_ANY_INIT:
1411 prl_from = sec2annotation(fromsec);1256 warn("%s: section mismatch in reference: %s (section: %s) -> %s (section: %s)\n",
1412 prl_to = sec2annotation(tosec);1257 modname, fromsym, fromsec, tosym, tosec);
1413 fprintf(stderr,
1414 "The %s %s%s%s references\n"
1415 "a %s %s%s%s.\n"
1416 "This is often seen when error handling "
1417 "in the exit function\n"
1418 "uses functionality in the init path.\n"
1419 "The fix is often to remove the %sannotation of\n"
1420 "%s%s so it may be used outside an init section.\n",
1421 from, prl_from, fromsym, from_p,
1422 to, prl_to, tosym, to_p,
1423 prl_to, tosym, to_p);
1424 free(prl_from);
1425 free(prl_to);
1426 break;1258 break;
1427 case EXPORT_TO_INIT_EXIT:1259 case EXPORT_TO_INIT_EXIT:
1428 prl_to = sec2annotation(tosec);1260 warn("%s: EXPORT_SYMBOL used for init/exit symbol: %s (section: %s)\n",
1429 fprintf(stderr,1261 modname, tosym, tosec);
1430 "The symbol %s is exported and annotated %s\n"
1431 "Fix this by removing the %sannotation of %s "
1432 "or drop the export.\n",
1433 tosym, prl_to, prl_to, tosym);
1434 free(prl_to);
1435 break;1262 break;
1436 case EXTABLE_TO_NON_TEXT:1263 case EXTABLE_TO_NON_TEXT:
1437 fatal("There's a special handler for this mismatch type, "1264 fatal("There's a special handler for this mismatch type, we should never get here.\n");
1438 "we should never get here.");
1439 break;1265 break;
1440 }1266 }
1441 fprintf(stderr, "\n");
1442}1267}
1443 1268
1444static void default_mismatch_handler(const char *modname, struct elf_info *elf,1269static void default_mismatch_handler(const char *modname, struct elf_info *elf,
@@ -1454,9 +1279,6 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, · 9 unmodified lines
1454 from = find_elf_symbol2(elf, r->r_offset, fromsec);1279 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1455 fromsym = sym_name(elf, from);1280 fromsym = sym_name(elf, from);
1456 1281
1457 if (strstarts(fromsym, "reference___initcall"))
1458 return;
1459
1460 tosec = sec_name(elf, get_secindex(elf, sym));1282 tosec = sec_name(elf, get_secindex(elf, sym));
1461 to = find_elf_symbol(elf, r->r_addend, sym);1283 to = find_elf_symbol(elf, r->r_addend, sym);
1462 tosym = sym_name(elf, to);1284 tosym = sym_name(elf, to);
@@ -1465,9 +1287,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, · 2 unmodified lines
1465 if (secref_whitelist(mismatch,1287 if (secref_whitelist(mismatch,
1466 fromsec, fromsym, tosec, tosym)) {1288 fromsec, fromsym, tosec, tosym)) {
1467 report_sec_mismatch(modname, mismatch,1289 report_sec_mismatch(modname, mismatch,
1468 fromsec, r->r_offset, fromsym,1290 fromsec, fromsym, tosec, tosym);
1469 is_function(from), tosec, tosym,
1470 is_function(to));
1471 }1291 }
1472}1292}
1473 1293
@@ -1623,9 +1443,6 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) · 149 unmodified lines
1623 break;1443 break;
1624 case R_386_PC32:1444 case R_386_PC32:
1625 r->r_addend = TO_NATIVE(*location) + 4;1445 r->r_addend = TO_NATIVE(*location) + 4;
1626 /* For CONFIG_RELOCATABLE=y */
1627 if (elf->hdr->e_type == ET_EXEC)
1628 r->r_addend += r->r_offset;
1629 break;1446 break;
1630 }1447 }
1631 return 0;1448 return 0;
@@ -1718,8 +1535,7 @@ static void section_rela(const char *modname, struct elf_info *elf, · 86 unmodified lines
1718 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;1535 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
1719 Elf_Rela *stop = (void *)start + sechdr->sh_size;1536 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1720 1537
1721 fromsec = sech_name(elf, sechdr);1538 fromsec = sec_name(elf, sechdr->sh_info);
1722 fromsec += strlen(".rela");
1723 /* if from section (name) is know good then skip it */1539 /* if from section (name) is know good then skip it */
1724 if (match(fromsec, section_white_list))1540 if (match(fromsec, section_white_list))
1725 return;1541 return;
@@ -1771,8 +1587,7 @@ static void section_rel(const char *modname, struct elf_info *elf, · 45 unmodified lines
1771 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;1587 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
1772 Elf_Rel *stop = (void *)start + sechdr->sh_size;1588 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1773 1589
1774 fromsec = sech_name(elf, sechdr);1590 fromsec = sec_name(elf, sechdr->sh_info);
1775 fromsec += strlen(".rel");
1776 /* if from section (name) is know good then skip it */1591 /* if from section (name) is know good then skip it */
1777 if (match(fromsec, section_white_list))1592 if (match(fromsec, section_white_list))
1778 return;1593 return;
scripts/mod/modpost.h+19−14
@@ -26,7 +26,6 @@ · 25 unmodified lines
26#define Elf_Shdr Elf32_Shdr26#define Elf_Shdr Elf32_Shdr
27#define Elf_Sym Elf32_Sym27#define Elf_Sym Elf32_Sym
28#define Elf_Addr Elf32_Addr28#define Elf_Addr Elf32_Addr
29#define Elf_Sword Elf64_Sword
30#define Elf_Section Elf32_Half29#define Elf_Section Elf32_Half
31#define ELF_ST_BIND ELF32_ST_BIND30#define ELF_ST_BIND ELF32_ST_BIND
32#define ELF_ST_TYPE ELF32_ST_TYPE31#define ELF_ST_TYPE ELF32_ST_TYPE
@@ -41,7 +40,6 @@ · 8 unmodified lines
41#define Elf_Shdr Elf64_Shdr40#define Elf_Shdr Elf64_Shdr
42#define Elf_Sym Elf64_Sym41#define Elf_Sym Elf64_Sym
43#define Elf_Addr Elf64_Addr42#define Elf_Addr Elf64_Addr
44#define Elf_Sword Elf64_Sxword
45#define Elf_Section Elf64_Half43#define Elf_Section Elf64_Half
46#define ELF_ST_BIND ELF64_ST_BIND44#define ELF_ST_BIND ELF64_ST_BIND
47#define ELF_ST_TYPE ELF64_ST_TYPE45#define ELF_ST_TYPE ELF64_ST_TYPE
@@ -158,22 +156,28 @@ static inline int is_shndx_special(unsigned int i) · 110 unmodified lines
158 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;156 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
159}157}
160 158
161/*
162 * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
163 * the way to -256..-1, to avoid conflicting with real section
164 * indices.
165 */
166#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
167
168/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */159/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
169static inline unsigned int get_secindex(const struct elf_info *info,160static inline unsigned int get_secindex(const struct elf_info *info,
170 const Elf_Sym *sym)161 const Elf_Sym *sym)
171{162{
172 if (is_shndx_special(sym->st_shndx))163 unsigned int index = sym->st_shndx;
173 return SPECIAL(sym->st_shndx);164
174 if (sym->st_shndx != SHN_XINDEX)165 /*
175 return sym->st_shndx;166 * Elf{32,64}_Sym::st_shndx is 2 byte. Big section numbers are available
176 return info->symtab_shndx_start[sym - info->symtab_start];167 * in the .symtab_shndx section.
168 */
169 if (index == SHN_XINDEX)
170 return info->symtab_shndx_start[sym - info->symtab_start];
171
172 /*
173 * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
174 * the way to UINT_MAX-255..UINT_MAX, to avoid conflicting with real
175 * section indices.
176 */
177 if (index >= SHN_LORESERVE && index <= SHN_HIRESERVE)
178 return index - SHN_HIRESERVE - 1;
179
180 return index;
177}181}
178 182
179/* file2alias.c */183/* file2alias.c */
@@ -187,6 +191,7 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen); · 7 unmodified lines
187/* from modpost.c */191/* from modpost.c */
188char *read_text_file(const char *filename);192char *read_text_file(const char *filename);
189char *get_line(char **stringp);193char *get_line(char **stringp);
194void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
190 195
191enum loglevel {196enum loglevel {
192 LOG_WARN,197 LOG_WARN,
scripts/package/mkspec+3−0
@@ -49,6 +49,9 @@ sed -e '/^DEL/d' -e 's/^\t*//' <<EOF · 48 unmodified lines
49 URL: https://www.kernel.org49 URL: https://www.kernel.org
50$S Source: kernel-$__KERNELRELEASE.tar.gz50$S Source: kernel-$__KERNELRELEASE.tar.gz
51 Provides: $PROVIDES51 Provides: $PROVIDES
52 # $UTS_MACHINE as a fallback of _arch in case
53 # /usr/lib/rpm/platform/*/macros was not included.
54 %define _arch %{?_arch:$UTS_MACHINE}
52 %define __spec_install_post /usr/lib/rpm/brp-compress || :55 %define __spec_install_post /usr/lib/rpm/brp-compress || :
53 %define debug_package %{nil}56 %define debug_package %{nil}
54 57