From 8cc7a29750983ccae7ec85aa11eb7e5c5d69c1a3 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Sat, 5 Oct 2002 06:57:05 -0500 Subject: [PATCH] kbuild: Generalize adding of additional sections to vmlinux kallsyms needs to actually have a final vmlinux to extract the symbols, and then add this information as a new section to the final vmlinux. Currently, we basically just do the vmlinux link twice, adding .tmp_kallsyms.o the second time. However, it's actually possible to just link together the temporary vmlinux generated the first time and the new object file directly without going back to all the single parts that the temporary vmlinux was linked from. This mechanism should be useful for sparc as well, where the btfix mechanism needs an already linked vmlinux, too. IMPORTANT: This does only work as desired if the link script can be used recursively, i.e. ld -T arch/$(ARCH)/vmlinux.lds.s -o vmlinux.test vmlinux generates a vmlinux.test which is identical to vmlinux. arch/i386/vmlinux.lds.S needed a little tweaking, so probably the other archs do as well. --- Makefile | 62 ++++++++++++++++++++++++++--------------- arch/i386/vmlinux.lds.S | 3 +- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index d9fcbfd7aadd..b2550568e5c6 100644 --- a/Makefile +++ b/Makefile @@ -285,8 +285,8 @@ export MODLIB vmlinux-objs := $(HEAD) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) -quiet_cmd_link_vmlinux = LD $@ -define cmd_link_vmlinux +quiet_cmd_ld_tmp_vmlinux = LD $@ +define cmd_ld_tmp_vmlinux $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(HEAD) $(init-y) \ --start-group \ $(core-y) \ @@ -294,21 +294,19 @@ define cmd_link_vmlinux $(drivers-y) \ $(net-y) \ --end-group \ - $(filter $(kallsyms.o),$^) \ -o $@ endef # set -e makes the rule exit immediately on error -define rule_vmlinux +define rule_ld_tmp_vmlinux set -e echo ' Generating build number' . scripts/mkversion > .tmp_version mv -f .tmp_version .version +$(call descend,init,) - $(call cmd,link_vmlinux) - echo 'cmd_$@ := $(cmd_link_vmlinux)' > $(@D)/.$(@F).cmd - $(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map + $(call cmd,ld_tmp_vmlinux) + echo 'cmd_$@ := $(cmd_ld_tmp_vmlinux)' > $(@D)/.$(@F).cmd endef LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s @@ -317,33 +315,42 @@ LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s ifdef CONFIG_KALLSYMS -kallsyms.o := .tmp_kallsyms.o +final-objs += .tmp_kallsyms.o quiet_cmd_kallsyms = KSYM $@ -cmd_kallsyms = $(KALLSYMS) $< > $@ +define cmd_kallsyms + $(KALLSYMS) $< > $@ +endef .tmp_kallsyms.o: .tmp_vmlinux $(call cmd,kallsyms) -# After generating .tmp_vmlinux just like vmlinux, decrement the version -# number again, so the final vmlinux gets the same one. -# Ignore return value of 'expr'. +endif -define rule_.tmp_vmlinux - $(rule_vmlinux) - if expr 0`cat .version` - 1 > .tmp_version; then true; fi - mv -f .tmp_version .version -endef +# Link a temporary vmlinux for postprocessing +# (e.g. kallsyms) .tmp_vmlinux: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE - $(call if_changed_rule,.tmp_vmlinux) - -endif + $(call if_changed_rule,ld_tmp_vmlinux) # Finally the vmlinux rule -vmlinux: $(vmlinux-objs) $(kallsyms.o) arch/$(ARCH)/vmlinux.lds.s FORCE - $(call if_changed_rule,vmlinux) +quiet_cmd_ld_vmlinux = LD $(echo_target) +cmd_ld_vmlinux = $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \ + $(filter-out FORCE,$^) -o $@ + +define rule_ld_vmlinux + set -e + $(call cmd,ld_vmlinux) + echo 'cmd_$@ := $(cmd_ld_vmlinux)' > $(@D)/.$(@F).cmd + $(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map +endef + +# Link the actual vmlinux, which is temporary one from above, +# and possibly additional sections given in $(final-objs) + +vmlinux: .tmp_vmlinux $(final-objs) arch/$(ARCH)/vmlinux.lds.s FORCE + $(call if_changed_rule,ld_vmlinux) # The actual objects are generated when descending, # make sure no implicit rule kicks in @@ -861,6 +868,17 @@ ifneq ($(cmd_files),) include $(cmd_files) endif +# function to only execute the passed command if necessary + +if_changed = $(if $(strip $? \ + $(filter-out $(cmd_$(1)),$(cmd_$@))\ + $(filter-out $(cmd_$@),$(cmd_$(1)))),\ + @set -e; \ + $(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \ + $(cmd_$(1)); \ + echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd) + + # execute the command and also postprocess generated .d dependencies # file diff --git a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S index f5d7554096ef..3afaad74bf2f 100644 --- a/arch/i386/vmlinux.lds.S +++ b/arch/i386/vmlinux.lds.S @@ -49,6 +49,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { + *(.initcall.init) *(.initcall1.init) *(.initcall2.init) *(.initcall3.init) @@ -72,7 +73,7 @@ SECTIONS __nosave_end = .; . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } + .data.page_aligned : { *(.data.page_aligned) *(.data.idt) } . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } -- 2.39.5