[FTRACE] vmlinux __mcount_loc section
kernel/scripts/Makefile.build
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl ifdef BUILD_C_RECORDMCOUNT ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") RECORDMCOUNT_FLAGS = -w endif # Due to recursion, we must skip empty.o. # The empty.o file is created in the make process in order to determine # the target endianness and word size. It is made before all other C # files, including recordmcount. sub_cmd_record_mcount = if [ $(@) != "scripts/mod/empty.o" ]; then $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; fi; recordmcount_source := $(srctree)/scripts/recordmcount.c $(srctree)/scripts/recordmcount.h else sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" "$(if $(CONFIG_64BIT),64,32)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" "$(if $(part-of-module),1,0)" "$(@)"; recordmcount_source := $(srctree)/scripts/recordmcount.pl endif # BUILD_C_RECORDMCOUNT cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), $(sub_cmd_record_mcount)) endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
s上面record mcount有两种类型,一个是c语言类型,另一个是perl类型
# Built-in and composite module parts $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)就会call rule_cc_o_c:
define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
$(call cmd,gen_ksymdeps)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,objtool)
$(call cmd,modversions_c)
$(call cmd,record_mcount)
endef
会对kernel里的每一个c文件对应的.o文件进行处理,处理完后形成__mcount_loc section:
kernel/include/asm-generic/vmlinux.lds.h
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
/*
* The ftrace call sites are logged to a section whose name depends on the
* compiler option used. A given kernel image will only use one, AKA
* FTRACE_CALLSITE_SECTION. We capture all of them here to avoid header
* dependencies for FTRACE_CALLSITE_SECTION's definition.
*
* Need to also make ftrace_stub_graph point to ftrace_stub
* so that the same stub location may have different protocols
* and not mess up with C verifiers.
*/
#define MCOUNT_REC() . = ALIGN(8);
__start_mcount_loc = .;
KEEP(*(__mcount_loc))
KEEP(*(__patchable_function_entries))
__stop_mcount_loc = .;
ftrace_stub_graph = ftrace_stub;
reference: https://www.cnblogs.com/openix/p/4163995.html