[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <b527c9d1-4a20-4b2b-b7d1-d78b37713d33@roeck-us.net>
Date: Wed, 10 Dec 2025 10:42:36 -0800
From: Guenter Roeck <linux@...ck-us.net>
To: Alexandre Chartre <alexandre.chartre@...cle.com>,
"Maciej W. Rozycki" <macro@...am.me.uk>
Cc: linux-kernel@...r.kernel.org, Ingo Molnar <mingo@...nel.org>,
jpoimboe@...nel.org, peterz@...radead.org, david.laight.linux@...il.com
Subject: Re: [PATCH v6 03/30] objtool: Disassemble code with libopcodes
instead of running objdump
On 12/10/25 08:36, Alexandre Chartre wrote:
>
>
> On 12/10/25 16:26, Guenter Roeck wrote:
>> On 12/9/25 23:53, Alexandre Chartre wrote:
>>>
>>>
>>> On 12/10/25 06:08, Guenter Roeck wrote:
>>>> On 12/9/25 14:25, Maciej W. Rozycki wrote:
>>>>> On Tue, 9 Dec 2025, Alexandre Chartre wrote:
>>>>>
>>>>>>> Bisect log is attached. I see the problem with gcc 11.4.0, 13.3.0, and
>>>>>>> 14.3.0. I tried with both Ubuntu 22.04 and 24.04.
>>>>>>
>>>>>> This sounds like a configuration issue depending on the binutils version; in
>>>>>> particular the setting of DISASM_INIT_STYLED (although that's supposed to be
>>>>>> automatically configured by tools/objtool/Makefile).
>>>>>
>>>>> I only came across these patches now.
>>>>>
>>>>> As attractive as it may seem how is this stuff supposed to fly given that
>>>>> binutils internal libraries promise no stable API to out-of-tree software.
>>>>> The interfaces can change anytime, just as it is with our internals.
>>>>>
>>>>> Wouldn't it make sense to improve objdump instead so as to provide the
>>>>> features required?
>>>>>
>>>>> Also is it actually legal to link objtool and libopcodes together, given
>>>>> that they are GPLv2 and GPLv3 respectively?
>>>>>
>>>>> FWIW asking as one of the binutils contributors and port maintainers.
>>>>>
>>>>
>>>> After some more digging I found that the version of binutils installed in
>>>> the system determines if the build error is seen or not. So I can have
>>>> a toolchain with the latest binutils version, but the build still fails if
>>>> the binutils version installed in the system is too old. 2.38 (as in
>>>> Ubuntu 22.04) is too old since it does not define 'enum disassembler_style'
>>>> in dis-asm.h. As far as I can see that enum was only introduced with
>>>> binutils 2.39.
>>>>
>>>> Now the problem is that DISASM_INIT_STYLED is evaluated with
>>>> tools/build/feature/test-disassembler-init-styled.c, which checks for
>>>> the existence of struct disassemble_info (not the enum). AFAICS that
>>>> structure was introduced with binutils-2_18.
>>>>
>>>> Unless my analysis is wrong that means that Linux will now fail to build
>>>> on systems with binutils 2.18 ... 2.38 installed.
>>>
>>>
>>> test-disassembler-init-styled.c tests that init_disassemble_info() has four
>>> arguments. If this fails then this means that it has only three args and in
>>> that case enum disassembler_style is not defined, and the build should be done
>>> without defining DISASM_INIT_STYLED.
>>>
>>> init_disassemble_info() was changed from 3 args to 4 args by the following
>>> binutils change, and enum disassembler_style was introduced at the same time:
>>>
>>> https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=60a3da00bd5407f07
>>>
>>> This change has caused the Linux build to fail, and this was fixed by commit
>>> a45b3d6926231 ("tools include: add dis-asm-compat.h to handle version differences")
>>> which introduced dis-asm-compat.h
>>>
>>> Can you check that init_disassemble_info() is declared with only 3 arguments
>>> in your dis-asm.h file? (/usr/include/dis-asm.h).
>>>
>>> dis-asm.h should either:
>>>
>>> - declare init_disassemble_info() with 3 args and not define enum disassembler_style
>>>
>>> or
>>>
>>> - declare init_disassemble_info() with 4 args and define enum disassembler_style
>>>
>>
>> Thanks for the clarification.
>>
>> Here is the declaration:
>>
>> /* Method to initialize a disassemble_info struct. This should be
>> called by all applications creating such a struct. */
>> extern void init_disassemble_info (struct disassemble_info *dinfo, void *stream,
>> fprintf_ftype fprintf_func);
>>
>> So it has three arguments, but DISASM_INIT_STYLED is defined anyway.
>>
>> I think I found the problem: not even "make mrproper" or "make distclean" deletes
>> ./tools/objtool/feature/test-disassembler-init-styled.bin, and the file existed
>> in my tree. So DISASM_INIT_STYLED just ended up being defined until I deleted
>> the file manually.
>>
>> This condition also happens in my build system. I have not been able to re-create
>> the situation where the .bin file exists but shouldn't, but it somehow does happen.
>>
>
> 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.
Guenter
Powered by blists - more mailing lists