mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 11:16:11 +00:00
kbuild: strip generated symbols from *.ko
This patch changes the way __crc_ symbols are being resolved from using ld to do so to using the assembler, thus allowing these symbols to be marked local (the linker creates then as global ones) and hence allow stripping (for modules) or ignoring (for vmlinux) them. While at this, also strip other generated symbols during module installation. One potentially debatable point is the handling of the flags passeed to gcc when translating the intermediate assembly file into an object: passing $(c_flags) unchanged doesn't work as gcc passes --gdwarf2 to gas whenever is sees any -g* option, even for -g0, and despite the fact that the compiler would have already produced all necessary debug info in the C->assembly translation phase. I took the approach of just filtering out all -g* options, but an alternative to such negative filtering might be to have a positive filter which might, in the ideal case allow just all the -Wa,* options to pass through. Signed-off-by: Jan Beulich <jbeulich@novell.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
This commit is contained in:
parent
37a8d9f67f
commit
ad7a953c52
6 changed files with 84 additions and 40 deletions
16
Makefile
16
Makefile
|
@ -605,19 +605,19 @@ MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
|
||||||
export MODLIB
|
export MODLIB
|
||||||
|
|
||||||
#
|
#
|
||||||
# INSTALL_MOD_STRIP, if defined, will cause modules to be
|
# INSTALL_MOD_STRIP, if defined, will cause modules to be stripped while
|
||||||
# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
|
# they get installed. If INSTALL_MOD_STRIP is '1', then the default
|
||||||
# the default option --strip-debug will be used. Otherwise,
|
# options (see below) will be used. Otherwise, INSTALL_MOD_STRIP will
|
||||||
# INSTALL_MOD_STRIP will used as the options to the strip command.
|
# be used as the option(s) to the objcopy command.
|
||||||
|
|
||||||
ifdef INSTALL_MOD_STRIP
|
ifdef INSTALL_MOD_STRIP
|
||||||
ifeq ($(INSTALL_MOD_STRIP),1)
|
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
|
else
|
||||||
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
|
mod_strip_cmd = $(OBJCOPY) $(INSTALL_MOD_STRIP)
|
||||||
endif # INSTALL_MOD_STRIP=1
|
endif # INSTALL_MOD_STRIP=1
|
||||||
else
|
else
|
||||||
mod_strip_cmd = true
|
mod_strip_cmd = false
|
||||||
endif # INSTALL_MOD_STRIP
|
endif # INSTALL_MOD_STRIP
|
||||||
export mod_strip_cmd
|
export mod_strip_cmd
|
||||||
|
|
||||||
|
|
|
@ -151,16 +151,16 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
|
||||||
$(obj)/%.i: $(src)/%.c FORCE
|
$(obj)/%.i: $(src)/%.c FORCE
|
||||||
$(call if_changed_dep,cc_i_c)
|
$(call if_changed_dep,cc_i_c)
|
||||||
|
|
||||||
cmd_gensymtypes = \
|
cmd_genksyms = \
|
||||||
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
||||||
$(GENKSYMS) -T $@ -a $(ARCH) \
|
$(GENKSYMS) -T $@ -A -a $(ARCH) \
|
||||||
$(if $(KBUILD_PRESERVE),-p) \
|
$(if $(KBUILD_PRESERVE),-p) \
|
||||||
$(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
|
$(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
|
||||||
|
|
||||||
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
|
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
|
||||||
cmd_cc_symtypes_c = \
|
cmd_cc_symtypes_c = \
|
||||||
set -e; \
|
set -e; \
|
||||||
$(call cmd_gensymtypes, true) >/dev/null; \
|
$(call cmd_genksyms, true) >/dev/null; \
|
||||||
test -s $@ || rm -f $@
|
test -s $@ || rm -f $@
|
||||||
|
|
||||||
$(obj)/%.symtypes : $(src)/%.c FORCE
|
$(obj)/%.symtypes : $(src)/%.c FORCE
|
||||||
|
@ -177,28 +177,38 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
|
||||||
|
|
||||||
else
|
else
|
||||||
# When module versioning is enabled the following steps are executed:
|
# When module versioning is enabled the following steps are executed:
|
||||||
# o compile a .tmp_<file>.o from <file>.c
|
# o compile a .tmp_<file>.s from <file>.c
|
||||||
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
|
# o if .tmp_<file>.s doesn't contain a __ksymtab version, i.e. does
|
||||||
# not export symbols, we just rename .tmp_<file>.o to <file>.o and
|
# not export symbols, we just assemble .tmp_<file>.s to <file>.o and
|
||||||
# are done.
|
# are done.
|
||||||
# o otherwise, we calculate symbol versions using the good old
|
# o otherwise, we calculate symbol versions using the good old
|
||||||
# genksyms on the preprocessed source and postprocess them in a way
|
# genksyms on the preprocessed source and postprocess them in a way
|
||||||
# that they are usable as a linker script
|
# that they are usable as assembly source
|
||||||
# o generate <file>.o from .tmp_<file>.o using the linker to
|
# o assemble <file>.o from .tmp_<file>.s forcing inclusion of directives
|
||||||
# replace the unresolved symbols __crc_exported_symbol with
|
# defining the actual values of __crc_*, followed by objcopy-ing them
|
||||||
# the actual value of the checksum generated by genksyms
|
# 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 = \
|
cmd_modversions = \
|
||||||
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
|
if grep -q __ksymtab $(s_file); then \
|
||||||
$(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \
|
if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \
|
||||||
> $(@D)/.tmp_$(@F:.o=.ver); \
|
&& $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \
|
||||||
\
|
-o $(tmp_o_file) $(s_file) \
|
||||||
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
|
&& $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \
|
||||||
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
$(tmp_o_file) $@; \
|
||||||
rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
|
then \
|
||||||
|
: ; \
|
||||||
|
else \
|
||||||
|
rm -f $@; exit 1; \
|
||||||
|
fi; \
|
||||||
else \
|
else \
|
||||||
mv -f $(@D)/.tmp_$(@F) $@; \
|
rm -f $(v_file); \
|
||||||
|
$(CC) $(no_g_c_flags) -c -o $@ $(s_file); \
|
||||||
fi;
|
fi;
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -221,7 +231,12 @@ define rule_cc_o_c
|
||||||
$(cmd_record_mcount) \
|
$(cmd_record_mcount) \
|
||||||
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
|
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
|
||||||
$(dot-target).tmp; \
|
$(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
|
mv -f $(dot-target).tmp $(dot-target).cmd
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ __modinst: $(modules)
|
||||||
@:
|
@:
|
||||||
|
|
||||||
quiet_cmd_modules_install = INSTALL $@
|
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
|
# Modules built outside the kernel source tree go into extra by default
|
||||||
INSTALL_MOD_DIR ?= extra
|
INSTALL_MOD_DIR ?= extra
|
||||||
|
|
|
@ -43,7 +43,7 @@ int cur_line = 1;
|
||||||
char *cur_filename;
|
char *cur_filename;
|
||||||
|
|
||||||
static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
|
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 *arch = "";
|
||||||
static const char *mod_prefix = "";
|
static const char *mod_prefix = "";
|
||||||
|
|
||||||
|
@ -610,8 +610,11 @@ void export_symbol(const char *name)
|
||||||
if (flag_dump_defs)
|
if (flag_dump_defs)
|
||||||
fputs(">\n", debugfile);
|
fputs(">\n", debugfile);
|
||||||
|
|
||||||
/* Used as a linker script. */
|
/* Used as assembly source or a linker script. */
|
||||||
printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc);
|
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)
|
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__
|
#ifdef __GNU_LIBRARY__
|
||||||
" -a, --arch Select architecture\n"
|
" -a, --arch Select architecture\n"
|
||||||
|
" -A, --asm Generate assembly rather than linker script\n"
|
||||||
" -d, --debug Increment the debug level (repeatable)\n"
|
" -d, --debug Increment the debug level (repeatable)\n"
|
||||||
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
|
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
|
||||||
" -r, --reference file Read reference symbols from a file\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"
|
" -V, --version Print the release version\n"
|
||||||
#else /* __GNU_LIBRARY__ */
|
#else /* __GNU_LIBRARY__ */
|
||||||
" -a Select architecture\n"
|
" -a Select architecture\n"
|
||||||
|
" -A Generate assembly rather than linker script\n"
|
||||||
" -d Increment the debug level (repeatable)\n"
|
" -d Increment the debug level (repeatable)\n"
|
||||||
" -D Dump expanded symbol defs (for debugging only)\n"
|
" -D Dump expanded symbol defs (for debugging only)\n"
|
||||||
" -r file Read reference symbols from a file\n"
|
" -r file Read reference symbols from a file\n"
|
||||||
|
@ -683,6 +688,7 @@ int main(int argc, char **argv)
|
||||||
#ifdef __GNU_LIBRARY__
|
#ifdef __GNU_LIBRARY__
|
||||||
struct option long_opts[] = {
|
struct option long_opts[] = {
|
||||||
{"arch", 1, 0, 'a'},
|
{"arch", 1, 0, 'a'},
|
||||||
|
{"asm", 0, 0, 'A'},
|
||||||
{"debug", 0, 0, 'd'},
|
{"debug", 0, 0, 'd'},
|
||||||
{"warnings", 0, 0, 'w'},
|
{"warnings", 0, 0, 'w'},
|
||||||
{"quiet", 0, 0, 'q'},
|
{"quiet", 0, 0, 'q'},
|
||||||
|
@ -695,10 +701,10 @@ int main(int argc, char **argv)
|
||||||
{0, 0, 0, 0}
|
{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)
|
&long_opts[0], NULL)) != EOF)
|
||||||
#else /* __GNU_LIBRARY__ */
|
#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__ */
|
#endif /* __GNU_LIBRARY__ */
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -716,6 +722,9 @@ int main(int argc, char **argv)
|
||||||
case 'V':
|
case 'V':
|
||||||
fputs("genksyms version 2.5.60\n", stderr);
|
fputs("genksyms version 2.5.60\n", stderr);
|
||||||
break;
|
break;
|
||||||
|
case 'A':
|
||||||
|
flag_asm = 1;
|
||||||
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
flag_dump_defs = 1;
|
flag_dump_defs = 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -37,9 +37,6 @@
|
||||||
|
|
||||||
# readprofile starts reading symbols when _stext is found, and
|
# readprofile starts reading symbols when _stext is found, and
|
||||||
# continue until it finds a symbol which is not either of 'T', 't',
|
# continue until it finds a symbol which is not either of 'T', 't',
|
||||||
# 'W' or 'w'. __crc_ are 'A' and placed in the middle
|
# 'W' or 'w'.
|
||||||
# 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
|
|
||||||
|
|
||||||
|
$NM -n $1 | grep -v '\( [aNUw] \)\|\( \$[adt]\)' > $2
|
||||||
|
|
22
scripts/strip-symbols
Normal file
22
scripts/strip-symbols
Normal file
|
@ -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
|
Loading…
Reference in a new issue