[RFC,v4,01/32] objtool: Prepare to merge recordmcount
diff mbox series

Message ID 4a71852d8ca0a245588159a6bbdc064619de91d9.1591125127.git.mhelsley@vmware.com
State New
Headers show
Series
  • objtool: Make recordmcount a subcommand
Related show

Commit Message

Matt Helsley June 2, 2020, 7:49 p.m. UTC
Move recordmcount into the objtool directory. We keep this step separate
so changes which turn recordmcount into a subcommand of objtool don't
get obscured.

Signed-off-by: Matt Helsley <mhelsley@vmware.com>
---
 Documentation/trace/ftrace-design.rst      |  4 ++--
 Documentation/trace/ftrace.rst             |  2 +-
 Makefile                                   | 15 +++++++++------
 scripts/.gitignore                         |  1 -
 scripts/Makefile                           |  1 -
 scripts/Makefile.build                     | 11 ++++++-----
 tools/objtool/.gitignore                   |  1 +
 tools/objtool/Build                        |  2 ++
 tools/objtool/Makefile                     | 13 ++++++++++++-
 {scripts => tools/objtool}/recordmcount.c  |  0
 {scripts => tools/objtool}/recordmcount.h  |  0
 {scripts => tools/objtool}/recordmcount.pl |  0
 12 files changed, 33 insertions(+), 17 deletions(-)
 rename {scripts => tools/objtool}/recordmcount.c (100%)
 rename {scripts => tools/objtool}/recordmcount.h (100%)
 rename {scripts => tools/objtool}/recordmcount.pl (100%)

Comments

Julien Thierry June 9, 2020, 8:54 a.m. UTC | #1
Hi Matt,

On 6/2/20 8:49 PM, Matt Helsley wrote:
> Move recordmcount into the objtool directory. We keep this step separate
> so changes which turn recordmcount into a subcommand of objtool don't
> get obscured.
> 
> Signed-off-by: Matt Helsley <mhelsley@vmware.com>
> ---
>   Documentation/trace/ftrace-design.rst      |  4 ++--
>   Documentation/trace/ftrace.rst             |  2 +-
>   Makefile                                   | 15 +++++++++------
>   scripts/.gitignore                         |  1 -
>   scripts/Makefile                           |  1 -
>   scripts/Makefile.build                     | 11 ++++++-----
>   tools/objtool/.gitignore                   |  1 +
>   tools/objtool/Build                        |  2 ++
>   tools/objtool/Makefile                     | 13 ++++++++++++-
>   {scripts => tools/objtool}/recordmcount.c  |  0
>   {scripts => tools/objtool}/recordmcount.h  |  0
>   {scripts => tools/objtool}/recordmcount.pl |  0
>   12 files changed, 33 insertions(+), 17 deletions(-)
>   rename {scripts => tools/objtool}/recordmcount.c (100%)
>   rename {scripts => tools/objtool}/recordmcount.h (100%)
>   rename {scripts => tools/objtool}/recordmcount.pl (100%)
> 
> diff --git a/Documentation/trace/ftrace-design.rst b/Documentation/trace/ftrace-design.rst
> index a8e22e0db63c..dea8db5e79d0 100644
> --- a/Documentation/trace/ftrace-design.rst
> +++ b/Documentation/trace/ftrace-design.rst
> @@ -261,7 +261,7 @@ You need very few things to get the syscalls tracing in an arch.
>   HAVE_FTRACE_MCOUNT_RECORD
>   -------------------------
>   
> -See scripts/recordmcount.pl for more info.  Just fill in the arch-specific
> +See tools/objtool/recordmcount.pl for more info.  Just fill in the arch-specific
>   details for how to locate the addresses of mcount call sites via objdump.
>   This option doesn't make much sense without also implementing dynamic ftrace.
>   
> @@ -379,7 +379,7 @@ linux/ftrace.h for the functions::
>   	ftrace_make_call()
>   
>   The rec->ip value is the address of the mcount call site that was collected
> -by the scripts/recordmcount.pl during build time.
> +by the tools/objtool/recordmcount.pl during build time.
>   
>   The last function is used to do runtime patching of the active tracer.  This
>   will be modifying the assembly code at the location of the ftrace_call symbol
> diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst
> index 3b5614b1d1a5..9adefcc3c7a8 100644
> --- a/Documentation/trace/ftrace.rst
> +++ b/Documentation/trace/ftrace.rst
> @@ -2685,7 +2685,7 @@ starts of pointing to a simple return. (Enabling FTRACE will
>   include the -pg switch in the compiling of the kernel.)
>   
>   At compile time every C file object is run through the
> -recordmcount program (located in the scripts directory). This
> +recordmcount program (located in the tools/objtool directory). This
>   program will parse the ELF headers in the C object to find all
>   the locations in the .text section that call mcount. Starting
>   with gcc version 4.6, the -mfentry has been added for x86, which
> diff --git a/Makefile b/Makefile
> index 04f5662ae61a..d353a0a65a71 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -844,6 +844,7 @@ ifdef CONFIG_DYNAMIC_FTRACE
>   	ifdef CONFIG_HAVE_C_RECORDMCOUNT
>   		BUILD_C_RECORDMCOUNT := y
>   		export BUILD_C_RECORDMCOUNT
> +		objtool_target := tools/objtool FORCE
>   	endif
>   endif
>   endif
> @@ -1023,10 +1024,10 @@ endif
>   export mod_sign_cmd
>   
>   HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf)
> +has_libelf := $(call try-run,\
> +		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
>   

Maybe there could be some build dependency, e.g. CONFIG_OBJTOOL_SUBCMDS 
that sets the "objtool_target" and "has_libelf" when selected.

Then the CONFIG_UNWINDER_ORC, RECORD_MCOUNT and STACK_VALIDATION would 
just had to select that config option.

>   ifdef CONFIG_STACK_VALIDATION
> -  has_libelf := $(call try-run,\
> -		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
>     ifeq ($(has_libelf),1)
>       objtool_target := tools/objtool FORCE
>     else
> @@ -1163,13 +1164,15 @@ uapi-asm-generic:
>   
>   PHONY += prepare-objtool
>   prepare-objtool: $(objtool_target)
> -ifeq ($(SKIP_STACK_VALIDATION),1)
> -ifdef CONFIG_UNWINDER_ORC
> +ifneq ($(has_libelf),1)
> +  ifdef CONFIG_UNWINDER_ORC
>   	@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
>   	@false
> -else
> +  else
> +    ifeq ($(SKIP_STACK_VALIDATION),1)
>   	@echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2


I think this would be more readable without the else branch:

	ifneq ($(has_libelf),1)
		ifdef <some objtool command config>
			<warn about unavailability>
		endif
		ifdef <another objtool command config>
			<warn ...>
		endif
		<...>
	endif


Cheers,
Matt Helsley June 9, 2020, 3:42 p.m. UTC | #2
On Tue, Jun 09, 2020 at 09:54:33AM +0100, Julien Thierry wrote:
> Hi Matt,
> 
> On 6/2/20 8:49 PM, Matt Helsley wrote:
> > Move recordmcount into the objtool directory. We keep this step separate
> > so changes which turn recordmcount into a subcommand of objtool don't
> > get obscured.
> > 
> > Signed-off-by: Matt Helsley <mhelsley@vmware.com>

<snip>

> > diff --git a/Makefile b/Makefile
> > index 04f5662ae61a..d353a0a65a71 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -844,6 +844,7 @@ ifdef CONFIG_DYNAMIC_FTRACE
> >   	ifdef CONFIG_HAVE_C_RECORDMCOUNT
> >   		BUILD_C_RECORDMCOUNT := y
> >   		export BUILD_C_RECORDMCOUNT
> > +		objtool_target := tools/objtool FORCE
> >   	endif
> >   endif
> >   endif
> > @@ -1023,10 +1024,10 @@ endif
> >   export mod_sign_cmd
> >   HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf)
> > +has_libelf := $(call try-run,\
> > +		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
> 
> Maybe there could be some build dependency, e.g. CONFIG_OBJTOOL_SUBCMDS that
> sets the "objtool_target" and "has_libelf" when selected.
> 
> Then the CONFIG_UNWINDER_ORC, RECORD_MCOUNT and STACK_VALIDATION would just
> had to select that config option.

That might save a good amount of control flow in the Makefiles.

We could take it one step further and have specific CONFIG_OBJTOOL_<subcmd>
which might help us remove the per-architecture control-flow in
the multi-arch subcmd support found in tools/objtool/Makefile.

What do folks think of that -- too far?

> 
> >   ifdef CONFIG_STACK_VALIDATION
> > -  has_libelf := $(call try-run,\
> > -		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
> >     ifeq ($(has_libelf),1)
> >       objtool_target := tools/objtool FORCE
> >     else
> > @@ -1163,13 +1164,15 @@ uapi-asm-generic:
> >   PHONY += prepare-objtool
> >   prepare-objtool: $(objtool_target)
> > -ifeq ($(SKIP_STACK_VALIDATION),1)
> > -ifdef CONFIG_UNWINDER_ORC
> > +ifneq ($(has_libelf),1)
> > +  ifdef CONFIG_UNWINDER_ORC
> >   	@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
> >   	@false
> > -else
> > +  else
> > +    ifeq ($(SKIP_STACK_VALIDATION),1)
> >   	@echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
> 
> 
> I think this would be more readable without the else branch:
> 
> 	ifneq ($(has_libelf),1)
> 		ifdef <some objtool command config>
> 			<warn about unavailability>

Note: error not warn

> 		endif
> 		ifdef <another objtool command config>
> 			<warn ...>
> 		endif
> 		<...>
> 	endif

I think the next patch, which makes recordmcount a subcmd, makes it a
little clearer what the pattern is because it adds another ifdef block
in the way you suggest.

As for the else around the SKIP_STACK_VALIDATION check -- it is special
in a couple ways -- at least as best I can tell.

It's not a CONFIG_* -- it actually breaks the normal pattern with
CONFIG_* in that..

It's about a judgement call that it's OK to merely warn and skip the
stack validation rather than produce an error. The other, CONFIG_*
blocks produce errors.

These two reasons are why I think it makes sense to keep the logic
distinct with the "else".

Cheers,
	-Matt Helsley
Julien Thierry June 9, 2020, 7:31 p.m. UTC | #3
On 6/9/20 4:42 PM, Matt Helsley wrote:
> On Tue, Jun 09, 2020 at 09:54:33AM +0100, Julien Thierry wrote:
>> Hi Matt,
>>
>> On 6/2/20 8:49 PM, Matt Helsley wrote:
>>> Move recordmcount into the objtool directory. We keep this step separate
>>> so changes which turn recordmcount into a subcommand of objtool don't
>>> get obscured.
>>>
>>> Signed-off-by: Matt Helsley <mhelsley@vmware.com>
> 
> <snip>
> 
>>> diff --git a/Makefile b/Makefile
>>> index 04f5662ae61a..d353a0a65a71 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -844,6 +844,7 @@ ifdef CONFIG_DYNAMIC_FTRACE
>>>    	ifdef CONFIG_HAVE_C_RECORDMCOUNT
>>>    		BUILD_C_RECORDMCOUNT := y
>>>    		export BUILD_C_RECORDMCOUNT
>>> +		objtool_target := tools/objtool FORCE
>>>    	endif
>>>    endif
>>>    endif
>>> @@ -1023,10 +1024,10 @@ endif
>>>    export mod_sign_cmd
>>>    HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf)
>>> +has_libelf := $(call try-run,\
>>> +		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
>>
>> Maybe there could be some build dependency, e.g. CONFIG_OBJTOOL_SUBCMDS that
>> sets the "objtool_target" and "has_libelf" when selected.
>>
>> Then the CONFIG_UNWINDER_ORC, RECORD_MCOUNT and STACK_VALIDATION would just
>> had to select that config option.
> 
> That might save a good amount of control flow in the Makefiles.
> 
> We could take it one step further and have specific CONFIG_OBJTOOL_<subcmd>
> which might help us remove the per-architecture control-flow in
> the multi-arch subcmd support found in tools/objtool/Makefile.
> > What do folks think of that -- too far?
> 

I wasn't completely sure I understood before I saw your reply on the 
next patch. I don't think it's too far, it's cleaner! The current way 
was good enough to deal with only two x86 specific objtool subcommands.

Since you're adding another one and it is likely that more will be added 
in the future, I think it's worth having something a bit more structured 
:) .

>>
>>>    ifdef CONFIG_STACK_VALIDATION
>>> -  has_libelf := $(call try-run,\
>>> -		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
>>>      ifeq ($(has_libelf),1)
>>>        objtool_target := tools/objtool FORCE
>>>      else
>>> @@ -1163,13 +1164,15 @@ uapi-asm-generic:
>>>    PHONY += prepare-objtool
>>>    prepare-objtool: $(objtool_target)
>>> -ifeq ($(SKIP_STACK_VALIDATION),1)
>>> -ifdef CONFIG_UNWINDER_ORC
>>> +ifneq ($(has_libelf),1)
>>> +  ifdef CONFIG_UNWINDER_ORC
>>>    	@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
>>>    	@false
>>> -else
>>> +  else
>>> +    ifeq ($(SKIP_STACK_VALIDATION),1)
>>>    	@echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
>>
>>
>> I think this would be more readable without the else branch:
>>
>> 	ifneq ($(has_libelf),1)
>> 		ifdef <some objtool command config>
>> 			<warn about unavailability>
> 
> Note: error not warn
> 

Good point. But since those are errors, you don't need the "else" :)

>> 		endif
>> 		ifdef <another objtool command config>
>> 			<warn ...>
>> 		endif
>> 		<...>
>> 	endif
> 
> I think the next patch, which makes recordmcount a subcmd, makes it a
> little clearer what the pattern is because it adds another ifdef block
> in the way you suggest.
> 
> As for the else around the SKIP_STACK_VALIDATION check -- it is special
> in a couple ways -- at least as best I can tell.
> 
> It's not a CONFIG_* -- it actually breaks the normal pattern with
> CONFIG_* in that..
> 

Yes but $(SKIP_STACK_VALIDATION) == 1 is actually just 
CONFIG_STACK_VALIDATION && ($(has_libelf) != 1). And since you are 
already in the ifneq ($(has_libelf),1) branch, checking 
$(SKIP_STACK_VALIDATION) == 1 is the same as CONFIG_STACK_VALIDATION 
being defined.

> It's about a judgement call that it's OK to merely warn and skip the
> stack validation rather than produce an error. The other, CONFIG_*
> blocks produce errors.
> 

To me this is minor, we could also imagine another command CONFIG_ 
performing another action than warning or error when libelf is not 
available.

Anyway, this was just a suggestion, I don't want to insist to much on this.

Cheers,

Patch
diff mbox series

diff --git a/Documentation/trace/ftrace-design.rst b/Documentation/trace/ftrace-design.rst
index a8e22e0db63c..dea8db5e79d0 100644
--- a/Documentation/trace/ftrace-design.rst
+++ b/Documentation/trace/ftrace-design.rst
@@ -261,7 +261,7 @@  You need very few things to get the syscalls tracing in an arch.
 HAVE_FTRACE_MCOUNT_RECORD
 -------------------------
 
-See scripts/recordmcount.pl for more info.  Just fill in the arch-specific
+See tools/objtool/recordmcount.pl for more info.  Just fill in the arch-specific
 details for how to locate the addresses of mcount call sites via objdump.
 This option doesn't make much sense without also implementing dynamic ftrace.
 
@@ -379,7 +379,7 @@  linux/ftrace.h for the functions::
 	ftrace_make_call()
 
 The rec->ip value is the address of the mcount call site that was collected
-by the scripts/recordmcount.pl during build time.
+by the tools/objtool/recordmcount.pl during build time.
 
 The last function is used to do runtime patching of the active tracer.  This
 will be modifying the assembly code at the location of the ftrace_call symbol
diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst
index 3b5614b1d1a5..9adefcc3c7a8 100644
--- a/Documentation/trace/ftrace.rst
+++ b/Documentation/trace/ftrace.rst
@@ -2685,7 +2685,7 @@  starts of pointing to a simple return. (Enabling FTRACE will
 include the -pg switch in the compiling of the kernel.)
 
 At compile time every C file object is run through the
-recordmcount program (located in the scripts directory). This
+recordmcount program (located in the tools/objtool directory). This
 program will parse the ELF headers in the C object to find all
 the locations in the .text section that call mcount. Starting
 with gcc version 4.6, the -mfentry has been added for x86, which
diff --git a/Makefile b/Makefile
index 04f5662ae61a..d353a0a65a71 100644
--- a/Makefile
+++ b/Makefile
@@ -844,6 +844,7 @@  ifdef CONFIG_DYNAMIC_FTRACE
 	ifdef CONFIG_HAVE_C_RECORDMCOUNT
 		BUILD_C_RECORDMCOUNT := y
 		export BUILD_C_RECORDMCOUNT
+		objtool_target := tools/objtool FORCE
 	endif
 endif
 endif
@@ -1023,10 +1024,10 @@  endif
 export mod_sign_cmd
 
 HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf)
+has_libelf := $(call try-run,\
+		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
 
 ifdef CONFIG_STACK_VALIDATION
-  has_libelf := $(call try-run,\
-		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
   ifeq ($(has_libelf),1)
     objtool_target := tools/objtool FORCE
   else
@@ -1163,13 +1164,15 @@  uapi-asm-generic:
 
 PHONY += prepare-objtool
 prepare-objtool: $(objtool_target)
-ifeq ($(SKIP_STACK_VALIDATION),1)
-ifdef CONFIG_UNWINDER_ORC
+ifneq ($(has_libelf),1)
+  ifdef CONFIG_UNWINDER_ORC
 	@echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
 	@false
-else
+  else
+    ifeq ($(SKIP_STACK_VALIDATION),1)
 	@echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2
-endif
+    endif
+  endif
 endif
 
 # Generate some files
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 0d1c8e217cd7..dafda6d2c306 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -2,7 +2,6 @@ 
 bin2c
 kallsyms
 unifdef
-recordmcount
 sorttable
 asn1_compiler
 extract-cert
diff --git a/scripts/Makefile b/scripts/Makefile
index 95ecf970c74c..d8d81de4f1cb 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -5,7 +5,6 @@ 
 
 always-$(CONFIG_BUILD_BIN2C)			+= bin2c
 always-$(CONFIG_KALLSYMS)			+= kallsyms
-always-$(BUILD_C_RECORDMCOUNT)			+= recordmcount
 always-$(CONFIG_BUILDTIME_TABLE_SORT)		+= sorttable
 always-$(CONFIG_ASN1)				+= asn1_compiler
 always-$(CONFIG_MODULE_SIG_FORMAT)		+= sign-file
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 9fcbfac15d1d..d753facdb943 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -174,18 +174,19 @@  endif
 # files, including recordmcount.
 sub_cmd_record_mcount =					\
 	if [ $(@) != "scripts/mod/empty.o" ]; then	\
-		$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)";	\
+		$(objtree)/tools/objtool/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)";	\
 	fi;
-recordmcount_source := $(srctree)/scripts/recordmcount.c \
-		    $(srctree)/scripts/recordmcount.h
+
+recordmcount_source := $(srctree)/tools/objtool/recordmcount.c \
+		    $(srctree)/tools/objtool/recordmcount.h
 else
-sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
+sub_cmd_record_mcount = perl $(srctree)/tools/objtool/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
+recordmcount_source := $(srctree)/tools/objtool/recordmcount.pl
 endif # BUILD_C_RECORDMCOUNT
 cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),	\
 	$(sub_cmd_record_mcount))
diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore
index 45cefda24c7b..ea441abcd1d3 100644
--- a/tools/objtool/.gitignore
+++ b/tools/objtool/.gitignore
@@ -1,4 +1,5 @@ 
 # SPDX-License-Identifier: GPL-2.0-only
 arch/x86/lib/inat-tables.c
 objtool
+recordmcount
 fixdep
diff --git a/tools/objtool/Build b/tools/objtool/Build
index b7222d5cc7bc..4d399aff76de 100644
--- a/tools/objtool/Build
+++ b/tools/objtool/Build
@@ -35,3 +35,5 @@  $(OUTPUT)str_error_r.o: ../lib/str_error_r.c FORCE
 $(OUTPUT)librbtree.o: ../lib/rbtree.c FORCE
 	$(call rule_mkdir)
 	$(call if_changed_dep,cc_o_c)
+
+recordmcount-y += recordmcount.o
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 7770edcda3a0..285474a77fe9 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -31,6 +31,12 @@  OBJTOOL_IN := $(OBJTOOL)-in.o
 LIBELF_FLAGS := $(shell pkg-config libelf --cflags 2>/dev/null)
 LIBELF_LIBS  := $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf)
 
+RECORDMCOUNT := $(OUTPUT)recordmcount
+RECORDMCOUNT_IN := $(RECORDMCOUNT)-in.o
+ifeq ($(BUILD_C_RECORDMCOUNT),y)
+all:  $(RECORDMCOUNT)
+endif
+
 all: $(OBJTOOL)
 
 INCLUDES := -I$(srctree)/tools/include \
@@ -63,15 +69,20 @@  $(OBJTOOL_IN): fixdep FORCE
 	@$(CONFIG_SHELL) ./sync-check.sh
 	@$(MAKE) $(build)=objtool
 
+$(RECORDMCOUNT_IN): fixdep FORCE
+	@$(MAKE) $(build)=recordmcount
+
 $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
 	$(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
 
+$(RECORDMCOUNT): $(RECORDMCOUNT_IN)
+	$(QUIET_LINK)$(CC) $(RECORDMCOUNT_IN) $(KBUILD_HOSTLDFLAGS) -o $@
 
 $(LIBSUBCMD): fixdep FORCE
 	$(Q)$(MAKE) -C $(SUBCMD_SRCDIR) OUTPUT=$(LIBSUBCMD_OUTPUT)
 
 clean:
-	$(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL)
+	$(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL) $(RECORDMCOUNT)
 	$(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
 	$(Q)$(RM) $(OUTPUT)arch/x86/inat-tables.c $(OUTPUT)fixdep
 
diff --git a/scripts/recordmcount.c b/tools/objtool/recordmcount.c
similarity index 100%
rename from scripts/recordmcount.c
rename to tools/objtool/recordmcount.c
diff --git a/scripts/recordmcount.h b/tools/objtool/recordmcount.h
similarity index 100%
rename from scripts/recordmcount.h
rename to tools/objtool/recordmcount.h
diff --git a/scripts/recordmcount.pl b/tools/objtool/recordmcount.pl
similarity index 100%
rename from scripts/recordmcount.pl
rename to tools/objtool/recordmcount.pl