diff --git a/Makefile b/Makefile index e1c5ae8a8162845b1e76c7d80542d8cf5b1a0652..5dd0ed3b12c60a437e74c681b6f6d144c0cfeaa1 100644 --- a/Makefile +++ b/Makefile @@ -605,19 +605,19 @@ MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB # -# INSTALL_MOD_STRIP, if defined, will cause modules to be -# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then -# the default option --strip-debug will be used. Otherwise, -# INSTALL_MOD_STRIP will used as the options to the strip command. - +# INSTALL_MOD_STRIP, if defined, will cause modules to be stripped while +# they get installed. If INSTALL_MOD_STRIP is '1', then the default +# options (see below) will be used. Otherwise, INSTALL_MOD_STRIP will +# be used as the option(s) to the objcopy command. ifdef INSTALL_MOD_STRIP ifeq ($(INSTALL_MOD_STRIP),1) -mod_strip_cmd = $(STRIP) --strip-debug +mod_strip_cmd = $(OBJCOPY) --strip-debug --strip-symbols \ + $(srctree)/scripts/strip-symbols --wildcard else -mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) +mod_strip_cmd = $(OBJCOPY) $(INSTALL_MOD_STRIP) endif # INSTALL_MOD_STRIP=1 else -mod_strip_cmd = true +mod_strip_cmd = false endif # INSTALL_MOD_STRIP export mod_strip_cmd diff --git a/scripts/Makefile.build b/scripts/Makefile.build index c1da14b9f59de00d20da8dfae8b36a392ddf6f80..6a2153891592738b309d421b3ef9915e6ed57030 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -151,16 +151,16 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(src)/%.c FORCE $(call if_changed_dep,cc_i_c) -cmd_gensymtypes = \ +cmd_genksyms = \ $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ - $(GENKSYMS) -T $@ -a $(ARCH) \ + $(GENKSYMS) -T $@ -A -a $(ARCH) \ $(if $(KBUILD_PRESERVE),-p) \ $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null))) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = \ set -e; \ - $(call cmd_gensymtypes, true) >/dev/null; \ + $(call cmd_genksyms, true) >/dev/null; \ test -s $@ || rm -f $@ $(obj)/%.symtypes : $(src)/%.c FORCE @@ -177,28 +177,38 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< else # When module versioning is enabled the following steps are executed: -# o compile a .tmp_.o from .c -# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does -# not export symbols, we just rename .tmp_.o to .o and +# o compile a .tmp_.s from .c +# o if .tmp_.s doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just assemble .tmp_.s to .o and # are done. # o otherwise, we calculate symbol versions using the good old # genksyms on the preprocessed source and postprocess them in a way -# that they are usable as a linker script -# o generate .o from .tmp_.o using the linker to -# replace the unresolved symbols __crc_exported_symbol with -# the actual value of the checksum generated by genksyms +# that they are usable as assembly source +# o assemble .o from .tmp_.s forcing inclusion of directives +# defining the actual values of __crc_*, followed by objcopy-ing them +# to force these symbols to be local to permit stripping them later. +s_file = $(@D)/.tmp_$(@F:.o=.s) +v_file = $(@D)/.tmp_$(@F:.o=.v) +tmp_o_file = $(@D)/.tmp_$(@F) +no_g_c_flags = $(filter-out -g%,$(c_flags)) + +cmd_cc_o_c = $(CC) $(c_flags) -S -o $(s_file) $< -cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< cmd_modversions = \ - if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ - $(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \ - > $(@D)/.tmp_$(@F:.o=.ver); \ - \ - $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ - -T $(@D)/.tmp_$(@F:.o=.ver); \ - rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + if grep -q __ksymtab $(s_file); then \ + if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \ + && $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \ + -o $(tmp_o_file) $(s_file) \ + && $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \ + $(tmp_o_file) $@; \ + then \ + : ; \ + else \ + rm -f $@; exit 1; \ + fi; \ else \ - mv -f $(@D)/.tmp_$(@F) $@; \ + rm -f $(v_file); \ + $(CC) $(no_g_c_flags) -c -o $@ $(s_file); \ fi; endif @@ -221,7 +231,12 @@ define rule_cc_o_c $(cmd_record_mcount) \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ $(dot-target).tmp; \ - rm -f $(depfile); \ + if [ -r $(@D)/.tmp_$(@F:.o=.v) ]; then \ + echo >> $(dot-target).tmp; \ + echo '$@: $(GENKSYMS)' >> $(dot-target).tmp; \ + echo '$(GENKSYMS):: ;' >> $(dot-target).tmp; \ + fi; \ + rm -f $(depfile) $(@D)/.tmp_$(@F:.o=.?); \ mv -f $(dot-target).tmp $(dot-target).cmd endef diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index efa5d940e6324caa0aa120343043b89475502e74..a5122dce126421803f5b19c1729261fb819aa182 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -17,7 +17,8 @@ __modinst: $(modules) @: quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) + cmd_modules_install = mkdir -p $(2); \ + $(mod_strip_cmd) $@ $(2)/$(notdir $@) || cp $@ $(2) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 3a8297b5184cb1e1443c659905fdc41d9346902b..f8bb4cabd62d30b7b3d762cd8b8f2cde0b7b72be 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -43,7 +43,7 @@ int cur_line = 1; char *cur_filename; static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, - flag_preserve, flag_warnings; + flag_preserve, flag_warnings, flag_asm; static const char *arch = ""; static const char *mod_prefix = ""; @@ -610,8 +610,11 @@ void export_symbol(const char *name) if (flag_dump_defs) fputs(">\n", debugfile); - /* Used as a linker script. */ - printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); + /* Used as assembly source or a linker script. */ + printf(flag_asm + ? ".equiv %s__crc_%s, %#08lx\n" + : "%s__crc_%s = %#08lx ;\n", + mod_prefix, name, crc); } } @@ -648,9 +651,10 @@ void error_with_pos(const char *fmt, ...) static void genksyms_usage(void) { - fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" + fputs("Usage:\n" "genksyms [-aAdDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" #ifdef __GNU_LIBRARY__ " -a, --arch Select architecture\n" + " -A, --asm Generate assembly rather than linker script\n" " -d, --debug Increment the debug level (repeatable)\n" " -D, --dump Dump expanded symbol defs (for debugging only)\n" " -r, --reference file Read reference symbols from a file\n" @@ -662,6 +666,7 @@ static void genksyms_usage(void) " -V, --version Print the release version\n" #else /* __GNU_LIBRARY__ */ " -a Select architecture\n" + " -A Generate assembly rather than linker script\n" " -d Increment the debug level (repeatable)\n" " -D Dump expanded symbol defs (for debugging only)\n" " -r file Read reference symbols from a file\n" @@ -683,6 +688,7 @@ int main(int argc, char **argv) #ifdef __GNU_LIBRARY__ struct option long_opts[] = { {"arch", 1, 0, 'a'}, + {"asm", 0, 0, 'A'}, {"debug", 0, 0, 'd'}, {"warnings", 0, 0, 'w'}, {"quiet", 0, 0, 'q'}, @@ -695,10 +701,10 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; - while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph", + while ((o = getopt_long(argc, argv, "a:dwqVADr:T:ph", &long_opts[0], NULL)) != EOF) #else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF) + while ((o = getopt(argc, argv, "a:dwqVADr:T:ph")) != EOF) #endif /* __GNU_LIBRARY__ */ switch (o) { case 'a': @@ -716,6 +722,9 @@ int main(int argc, char **argv) case 'V': fputs("genksyms version 2.5.60\n", stderr); break; + case 'A': + flag_asm = 1; + break; case 'D': flag_dump_defs = 1; break; diff --git a/scripts/mksysmap b/scripts/mksysmap index 6e133a0bae7a8db162a5233fbf4af319f5ede35f..1db316a3712b640f38541d65c8e1d2ff5ebb4c7e 100644 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -37,9 +37,6 @@ # readprofile starts reading symbols when _stext is found, and # continue until it finds a symbol which is not either of 'T', 't', -# 'W' or 'w'. __crc_ are 'A' and placed in the middle -# so we just ignore them to let readprofile continue to work. -# (At least sparc64 has __crc_ in the middle). - -$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2 +# 'W' or 'w'. +$NM -n $1 | grep -v '\( [aNUw] \)\|\( \$[adt]\)' > $2 diff --git a/scripts/strip-symbols b/scripts/strip-symbols new file mode 100644 index 0000000000000000000000000000000000000000..29ee8c1a014b3cd9792438570cf6661af925183f --- /dev/null +++ b/scripts/strip-symbols @@ -0,0 +1,22 @@ +<*> +*.h +__compound_literal[$.][0-9]* +__crc_[a-zA-Z_]* +__exitcall_[a-zA-Z_]* +__func__[$.][0-9]* +__FUNCTION__[$.][0-9]* +gcc[0-9]_compiled[$.] +__initcall_[a-zA-Z_]* +__kcrctab_[a-zA-Z_]* +__kstrtab_[a-zA-Z_]* +__ksymtab_[a-zA-Z_]* +__mod_[a-zA-Z_]*[0-9] +__module_depends +__param_[a-zA-Z_]* +__pci_fixup_*PCI_ANY_IDPCI_ANY_ID* +__pci_fixup_*PCI_ANY_IDPCI_DEVICE_ID_* +__pci_fixup_*PCI_VENDOR_ID_*PCI_ANY_ID* +__pci_fixup_*PCI_VENDOR_ID_*PCI_DEVICE_ID_* +__PRETTY_FUNCTION__[$.][0-9]* +__setup_[a-zA-Z_]* +____versions