[PATCH] objtool: fix libopcodes linking with static libraries

Sasha Levin posted 1 patch 2 weeks, 3 days ago
tools/objtool/Makefile | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
[PATCH] objtool: fix libopcodes linking with static libraries
Posted by Sasha Levin 2 weeks, 3 days ago
Commit 436326bc525d ("objtool: fix build failure due to missing libopcodes
check") tests for libopcodes using an empty main(), which passes even when
static libraries lack their dependencies. This causes undefined reference
errors (xmalloc, bfd_get_bits, etc.) when linking against static libopcodes
without its required libbfd and libiberty.

Fix by testing with an actual libopcodes symbol and trying increasingly
complete library combinations until one succeeds.

Fixes: 436326bc525d ("objtool: fix build failure due to missing libopcodes check")
Reported-by: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

Rafael, I'd appreciate if you could test this patch without the .so symlink
workaround. Thanks :)

 tools/objtool/Makefile | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 9b4503113ce5f..a40f302329291 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -77,8 +77,21 @@ HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)"
 # We check using HOSTCC directly rather than the shared feature framework
 # because objtool is a host tool that links against host libraries.
 #
-HAVE_LIBOPCODES := $(shell echo 'int main(void) { return 0; }' | \
-			$(HOSTCC) -xc - -o /dev/null -lopcodes 2>/dev/null && echo y)
+# When using shared libraries, -lopcodes is sufficient as dependencies are
+# resolved automatically. With static libraries, we must explicitly link
+# against libopcodes' dependencies: libbfd, libiberty, and sometimes libz.
+# Try each combination and use the first one that succeeds.
+#
+LIBOPCODES_LIBS := $(shell \
+	for libs in "-lopcodes" \
+		    "-lopcodes -lbfd" \
+		    "-lopcodes -lbfd -liberty" \
+		    "-lopcodes -lbfd -liberty -lz"; do \
+		echo 'extern void disassemble_init_for_target(void *);' \
+		     'int main(void) { disassemble_init_for_target(0); return 0; }' | \
+			$(HOSTCC) -xc - -o /dev/null $$libs 2>/dev/null && \
+			echo "$$libs" && break; \
+	done)
 
 # Styled disassembler support requires binutils >= 2.39
 HAVE_DISASM_STYLED := $(shell echo '$(pound)include <dis-asm.h>' | \
@@ -86,10 +99,10 @@ HAVE_DISASM_STYLED := $(shell echo '$(pound)include <dis-asm.h>' | \
 
 BUILD_DISAS := n
 
-ifeq ($(HAVE_LIBOPCODES),y)
+ifneq ($(LIBOPCODES_LIBS),)
 	BUILD_DISAS := y
 	OBJTOOL_CFLAGS += -DDISAS -DPACKAGE='"objtool"'
-	OBJTOOL_LDFLAGS += -lopcodes
+	OBJTOOL_LDFLAGS += $(LIBOPCODES_LIBS)
 ifeq ($(HAVE_DISASM_STYLED),y)
 	OBJTOOL_CFLAGS += -DDISASM_INIT_STYLED
 endif
-- 
2.51.0
Re: [PATCH] objtool: fix libopcodes linking with static libraries
Posted by Rafael J. Wysocki 2 weeks, 3 days ago
On Wed, Jan 21, 2026 at 5:25 PM Sasha Levin <sashal@kernel.org> wrote:
>
> Commit 436326bc525d ("objtool: fix build failure due to missing libopcodes
> check") tests for libopcodes using an empty main(), which passes even when
> static libraries lack their dependencies. This causes undefined reference
> errors (xmalloc, bfd_get_bits, etc.) when linking against static libopcodes
> without its required libbfd and libiberty.
>
> Fix by testing with an actual libopcodes symbol and trying increasingly
> complete library combinations until one succeeds.
>
> Fixes: 436326bc525d ("objtool: fix build failure due to missing libopcodes check")
> Reported-by: Rafael J. Wysocki <rafael@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>
> Rafael, I'd appreciate if you could test this patch without the .so symlink
> workaround. Thanks :)

Works here, so

Tested-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>

>  tools/objtool/Makefile | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
> index 9b4503113ce5f..a40f302329291 100644
> --- a/tools/objtool/Makefile
> +++ b/tools/objtool/Makefile
> @@ -77,8 +77,21 @@ HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)"
>  # We check using HOSTCC directly rather than the shared feature framework
>  # because objtool is a host tool that links against host libraries.
>  #
> -HAVE_LIBOPCODES := $(shell echo 'int main(void) { return 0; }' | \
> -                       $(HOSTCC) -xc - -o /dev/null -lopcodes 2>/dev/null && echo y)
> +# When using shared libraries, -lopcodes is sufficient as dependencies are
> +# resolved automatically. With static libraries, we must explicitly link
> +# against libopcodes' dependencies: libbfd, libiberty, and sometimes libz.
> +# Try each combination and use the first one that succeeds.
> +#
> +LIBOPCODES_LIBS := $(shell \
> +       for libs in "-lopcodes" \
> +                   "-lopcodes -lbfd" \
> +                   "-lopcodes -lbfd -liberty" \
> +                   "-lopcodes -lbfd -liberty -lz"; do \
> +               echo 'extern void disassemble_init_for_target(void *);' \
> +                    'int main(void) { disassemble_init_for_target(0); return 0; }' | \
> +                       $(HOSTCC) -xc - -o /dev/null $$libs 2>/dev/null && \
> +                       echo "$$libs" && break; \
> +       done)
>
>  # Styled disassembler support requires binutils >= 2.39
>  HAVE_DISASM_STYLED := $(shell echo '$(pound)include <dis-asm.h>' | \
> @@ -86,10 +99,10 @@ HAVE_DISASM_STYLED := $(shell echo '$(pound)include <dis-asm.h>' | \
>
>  BUILD_DISAS := n
>
> -ifeq ($(HAVE_LIBOPCODES),y)
> +ifneq ($(LIBOPCODES_LIBS),)
>         BUILD_DISAS := y
>         OBJTOOL_CFLAGS += -DDISAS -DPACKAGE='"objtool"'
> -       OBJTOOL_LDFLAGS += -lopcodes
> +       OBJTOOL_LDFLAGS += $(LIBOPCODES_LIBS)
>  ifeq ($(HAVE_DISASM_STYLED),y)
>         OBJTOOL_CFLAGS += -DDISASM_INIT_STYLED
>  endif
> --
> 2.51.0
>
Re: [PATCH] objtool: fix libopcodes linking with static libraries
Posted by Peter Zijlstra 2 weeks, 3 days ago
On Wed, Jan 21, 2026 at 08:08:51PM +0100, Rafael J. Wysocki wrote:
> On Wed, Jan 21, 2026 at 5:25 PM Sasha Levin <sashal@kernel.org> wrote:
> >
> > Commit 436326bc525d ("objtool: fix build failure due to missing libopcodes
> > check") tests for libopcodes using an empty main(), which passes even when
> > static libraries lack their dependencies. This causes undefined reference
> > errors (xmalloc, bfd_get_bits, etc.) when linking against static libopcodes
> > without its required libbfd and libiberty.
> >
> > Fix by testing with an actual libopcodes symbol and trying increasingly
> > complete library combinations until one succeeds.
> >
> > Fixes: 436326bc525d ("objtool: fix build failure due to missing libopcodes check")
> > Reported-by: Rafael J. Wysocki <rafael@kernel.org>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> > ---
> >
> > Rafael, I'd appreciate if you could test this patch without the .so symlink
> > workaround. Thanks :)
> 
> Works here, so
> 
> Tested-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>

Excellent, thanks all!
[tip: objtool/urgent] objtool: Fix libopcodes linking with static libraries
Posted by tip-bot2 for Sasha Levin 2 weeks, 3 days ago
The following commit has been merged into the objtool/urgent branch of tip:

Commit-ID:     3f2de814c0597c97d5abe09a1635d8c4e2fddaf2
Gitweb:        https://git.kernel.org/tip/3f2de814c0597c97d5abe09a1635d8c4e2fddaf2
Author:        Sasha Levin <sashal@kernel.org>
AuthorDate:    Wed, 21 Jan 2026 11:25:32 -05:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 21 Jan 2026 20:25:14 +01:00

objtool: Fix libopcodes linking with static libraries

Commit 436326bc525d ("objtool: fix build failure due to missing libopcodes
check") tests for libopcodes using an empty main(), which passes even when
static libraries lack their dependencies. This causes undefined reference
errors (xmalloc, bfd_get_bits, etc.) when linking against static libopcodes
without its required libbfd and libiberty.

Fix by testing with an actual libopcodes symbol and trying increasingly
complete library combinations until one succeeds.

Fixes: 436326bc525d ("objtool: fix build failure due to missing libopcodes check")
Reported-by: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Link: https://patch.msgid.link/20260121162532.1596238-1-sashal@kernel.org
---
 tools/objtool/Makefile | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 9b45031..a40f302 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -77,8 +77,21 @@ HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)"
 # We check using HOSTCC directly rather than the shared feature framework
 # because objtool is a host tool that links against host libraries.
 #
-HAVE_LIBOPCODES := $(shell echo 'int main(void) { return 0; }' | \
-			$(HOSTCC) -xc - -o /dev/null -lopcodes 2>/dev/null && echo y)
+# When using shared libraries, -lopcodes is sufficient as dependencies are
+# resolved automatically. With static libraries, we must explicitly link
+# against libopcodes' dependencies: libbfd, libiberty, and sometimes libz.
+# Try each combination and use the first one that succeeds.
+#
+LIBOPCODES_LIBS := $(shell \
+	for libs in "-lopcodes" \
+		    "-lopcodes -lbfd" \
+		    "-lopcodes -lbfd -liberty" \
+		    "-lopcodes -lbfd -liberty -lz"; do \
+		echo 'extern void disassemble_init_for_target(void *);' \
+		     'int main(void) { disassemble_init_for_target(0); return 0; }' | \
+			$(HOSTCC) -xc - -o /dev/null $$libs 2>/dev/null && \
+			echo "$$libs" && break; \
+	done)
 
 # Styled disassembler support requires binutils >= 2.39
 HAVE_DISASM_STYLED := $(shell echo '$(pound)include <dis-asm.h>' | \
@@ -86,10 +99,10 @@ HAVE_DISASM_STYLED := $(shell echo '$(pound)include <dis-asm.h>' | \
 
 BUILD_DISAS := n
 
-ifeq ($(HAVE_LIBOPCODES),y)
+ifneq ($(LIBOPCODES_LIBS),)
 	BUILD_DISAS := y
 	OBJTOOL_CFLAGS += -DDISAS -DPACKAGE='"objtool"'
-	OBJTOOL_LDFLAGS += -lopcodes
+	OBJTOOL_LDFLAGS += $(LIBOPCODES_LIBS)
 ifeq ($(HAVE_DISASM_STYLED),y)
 	OBJTOOL_CFLAGS += -DDISASM_INIT_STYLED
 endif