Commit 09369f63 authored by Kai Germaschewski's avatar Kai Germaschewski

kbuild: Generate versions for exported symbols

Up to now, we had a way to store the checksums associated with the
exported symbols, but they were not filled in yet. This is done
with this patch, using the linker to actually do that for us.
  
The comment added with this patch explains what magic exactly is going
on.
parent a6b99776
...@@ -140,6 +140,13 @@ void *__symbol_get(const char *symbol); ...@@ -140,6 +140,13 @@ void *__symbol_get(const char *symbol);
void *__symbol_get_gpl(const char *symbol); void *__symbol_get_gpl(const char *symbol);
#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
#ifdef __GENKSYMS__
/* genksyms doesn't handle GPL-only symbols yet */
#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
#else
#ifdef CONFIG_MODVERSIONING #ifdef CONFIG_MODVERSIONING
/* Mark the CRC weak since genksyms apparently decides not to /* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */ * generate a checksums for some symbols */
...@@ -162,8 +169,13 @@ void *__symbol_get_gpl(const char *symbol); ...@@ -162,8 +169,13 @@ void *__symbol_get_gpl(const char *symbol);
__attribute__((section("__ksymtab" sec))) \ __attribute__((section("__ksymtab" sec))) \
= { (unsigned long)&sym, __kstrtab_##sym } = { (unsigned long)&sym, __kstrtab_##sym }
#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") #define EXPORT_SYMBOL(sym) \
#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") __EXPORT_SYMBOL(sym, "")
#define EXPORT_SYMBOL_GPL(sym) \
__EXPORT_SYMBOL(sym, "_gpl")
#endif
/* We don't mangle the actual symbol anymore, so no need for /* We don't mangle the actual symbol anymore, so no need for
* special casing EXPORT_SYMBOL_NOVERS */ * special casing EXPORT_SYMBOL_NOVERS */
......
...@@ -50,6 +50,55 @@ __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \ ...@@ -50,6 +50,55 @@ __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(subdir-ym) $(build-targets) $(subdir-ym) $(build-targets)
@: @:
# Module versioning
# ---------------------------------------------------------------------------
ifdef CONFIG_MODVERSIONING
# $(call if_changed_rule,vcc_o_c) does essentially the same as the
# normal $(call if_changed_dep,cc_o_c), i.e. compile an object file
# from a C file, keeping track of the command line and dependencies.
#
# However, actually it does:
# o compile a .tmp_<file>.o from <file>.c
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
# not export symbols, we just rename .tmp_<file>.o to <file>.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 <file>.o from .tmp_<file>.o using the linker to
# replace the unresolved symbols __crc_exported_symbol with
# the actual value of the checksum generated by genksyms
quiet_cmd_vcc_o_c = CC $(quiet_modtag) $@
cmd_vcc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
define rule_vcc_o_c
$(if $($(quiet)cmd_vcc_o_c),echo ' $($(quiet)cmd_vcc_o_c)';) \
$(cmd_vcc_o_c); \
\
if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
mv $(@D)/.tmp_$(@F) $@; \
else \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \
| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \
| grep __ver \
| sed 's/\#define __ver_\([^ ]*\)[ ]*\([^ ]*\)/__crc_\1 = 0x\2 ;/g' \
> $(@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); \
fi;
\
scripts/fixdep $(depfile) $@ '$(cmd_vcc_o_c)' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
endef
endif
# Compile C sources (.c) # Compile C sources (.c)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
...@@ -97,7 +146,11 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ ...@@ -97,7 +146,11 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
%.o: %.c FORCE %.o: %.c FORCE
ifdef CONFIG_MODVERSIONING
$(call if_changed_rule,vcc_o_c)
else
$(call if_changed_dep,cc_o_c) $(call if_changed_dep,cc_o_c)
endif
quiet_cmd_cc_lst_c = MKLST $@ quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment