Re: [PATCH v6 03/30] objtool: Disassemble code with libopcodes instead of running objdump

From: Alexandre Chartre

Date: Mon Dec 15 2025 - 11:01:23 EST



On 12/10/25 22:54, Guenter Roeck wrote:
On 12/10/25 10:42, Guenter Roeck wrote:
...
That's weird because the "clean" rule in tools/objtool/Makefile should remove the
entire tools/objtool/feature directory:

$ cat tools/objtool/Makefile
...
clean: $(LIBSUBCMD)-clean
     $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL)
     $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
     $(Q)$(RM) $(OUTPUT)arch/x86/lib/cpu-feature-names.c $(OUTPUT)fixdep
     $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep
     $(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.objtool
     $(Q)$(RM) -r -- $(OUTPUT)feature

see $(Q)$(RM) -r -- $(OUTPUT)feature


$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.c
./tools/objtool/feature/test-disassembler-init-styled.make.output
./tools/objtool/feature/test-disassembler-init-styled.d
$ make clean
   CLEAN   arch/x86/lib
   CLEAN   certs
   CLEAN   arch/x86/entry/vdso
   CLEAN   init
   CLEAN   lib/crc
   CLEAN   arch/x86/tools
   CLEAN   arch/x86/realmode/rm
   CLEAN   security/selinux
   CLEAN   usr
   CLEAN   .
$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.c
./tools/objtool/feature/test-disassembler-init-styled.make.output
./tools/objtool/feature/test-disassembler-init-styled.d
$

"make clean" does not execute the cleanup in tools/objtool. I have to run
"make -C tools/objtool clean". "make mrproper" doesn't clean tools either.

I guess that is on purpose ?

Anyway, even "make -C tools/objtool clean" doesn't solve my problem if I build with
an out-of-tree toolchain. Turns out that, in this case, test-disassembler-init-styled
is build with binutils from the toolchain (which succeeds because its binutils
version is more recent). Later on, the actual build of disas.c fails because it uses
the system toolchain.


This is actually even worse than I thought.

$ git clean -d -x -f -q
$ make defconfig
$ make -j40
$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.c
./tools/objtool/feature/test-disassembler-init-styled.make.output
./tools/objtool/feature/test-disassembler-init-styled.d
$ make -C tools/objtool/ clean
$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.make.output
./tools/build/feature/test-disassembler-init-styled.c
./tools/build/feature/test-disassembler-init-styled.d
$ rm -f ./tools/build/feature/test-disassembler-init-styled.make.output ./tools/build/feature/test-disassembler-init-styled.d
$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.c
$ make -C tools/objtool/ clean
$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.make.output
./tools/build/feature/test-disassembler-init-styled.c
./tools/build/feature/test-disassembler-init-styled.d

Repeated with local toolchain:
$ git clean -d -x -f -q
$ make-x86 defconfig
$ make-x86 -j40
  (fails)
$ make-x86 -C tools/objtool clean
$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.c
./tools/objtool/feature/test-disassembler-init-styled.make.output
./tools/objtool/feature/test-disassembler-init-styled.bin
./tools/objtool/feature/test-disassembler-init-styled.d

So the "make clean" command actually (re-)creates the .bin file. Worse,
if I now run

$ make -C tools/objtool clean

with the system toolchain, the .bin file is not removed.

$ find . -name test-disassembler-init-styled*
./tools/build/feature/test-disassembler-init-styled.make.output
./tools/build/feature/test-disassembler-init-styled.bin
./tools/build/feature/test-disassembler-init-styled.c
./tools/build/feature/test-disassembler-init-styled.d

The local toolchain used in this example is gcc 13.3.0 with binutils 2.42.


I think I've found the issue. The problem is that the feature check for objtool
is also run for the "clean" target, and this creates the
tools/build/feature/test-disassembler-init-styled.* files.

The change below should fix this problem. I will prepare a patch. Note that
you will still need to run "make -C tools/objtool clean" (I don't know the
reason for "make clean" not to cleanup tools/objtool).

Thanks,

alex.

-----

diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index ad6e1ec706ce0..0c9238cacdcea 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -77,7 +77,22 @@ HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)"
FEATURE_USER = .objtool
FEATURE_TESTS = libbfd disassembler-init-styled
FEATURE_DISPLAY =
+
+check_feat := 1
+NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
+ifdef MAKECMDGOALS
+ifeq ($(filter-out $(NON_CHECK_FEAT_TARGETS),$(MAKECMDGOALS)),)
+ check_feat := 0
+endif
+endif
+
+ifeq ($(check_feat),1)
+ifeq ($(FEATURES_DUMP),)
include $(srctree)/tools/build/Makefile.feature
+else
+include $(FEATURES_DUMP)
+endif
+endif
ifeq ($(feature-disassembler-init-styled), 1)
OBJTOOL_CFLAGS += -DDISASM_INIT_STYLED