Bug 32429 - annobin gcc plugin fails with GCC 15 due to out-of-date prototype of "warning" in annobin_active_check
Summary: annobin gcc plugin fails with GCC 15 due to out-of-date prototype of "warning...
Status: RESOLVED FIXED
Alias: None
Product: annobin
Classification: Unclassified
Component: annobin (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Nick Clifton
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-12-08 16:25 UTC by Dave Malcolm
Modified: 2024-12-10 11:16 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Proposed patch (352 bytes, patch)
2024-12-09 09:38 UTC, Nick Clifton
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Malcolm 2024-12-08 16:25:48 UTC
I'm attempting to do a mass prebuild of Fedora with GCC 15.

Unfortunately, my builds, such as in:

https://download.copr.fedorainfracloud.org/results/dmalcolm/gcc-15-smoketest/fedora-rawhide-aarch64/08352334-AllegroOGG/builder-live.log.gz

are failing with:

cc1: error: cannot load plugin /usr/lib/gcc/aarch64-redhat-linux/15/plugin/gcc-annobin.so: /usr/lib/gcc/aarch64-redhat-linux/15/plugin/gcc-annobin.so: undefined symbol: _Z7warningiPKcz

which is:
  warning(int, char const*, ...)

and is declared in gcc diagnostic-core.h for gcc <= 15

whereas gcc 15's diagnostic-core.h now has:
  warning (diagnostic_option_id, const char *, ...)

which is:
  _Z7warning20diagnostic_option_idPKcz

I changed this in GCC in 89991f31c5ded21179b12a9f4063c2b8fabc2e3b:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=89991f31c5ded21179b12a9f4063c2b8fabc2e3b

Logs show that my builds are using gcc-plugin-annobin.15.0.0-0.2.fc42.aarch64 as expected from the copr (i.e. a gcc-plugin-annobin built as part of the new gcc).

Looking at annobin sources in 
  https://sourceware.org/cgit/annobin/tree/gcc-plugin/annobin.cc#n2446

I see:

static void
annobin_active_check (const char * message)
{
  // FIXME - for some reason the prototype of warning() in diagnostic-core.h
  // does not match the implementation.  So we use our own prototype here.
  extern bool warning (int, const char *, ...);

where that prototype of "warning" was added in:
https://sourceware.org/cgit/annobin/commit/gcc-plugin/annobin.cc?id=9c7cf16054207046c45139b5589c8b04b51c5f96

Looks like that local prototype of "warning" is fouling up the gcc annobin plugin, since that's no longer the correct signature for GCC 15.
Comment 1 Dave Malcolm 2024-12-08 16:29:50 UTC
should have been:

> and is declared in gcc diagnostic-core.h for gcc <= 15
                                               ~~~~~~~~~
                                               gcc < 15
Comment 2 Nick Clifton 2024-12-09 09:38:42 UTC
Created attachment 15827 [details]
Proposed patch

Hi David,

  Is this patch sufficient ?

  (I am struggling to create a gcc-15 test environment of my own, so I thought that I could ask you for help :-).

Cheers
  Nick
Comment 3 Dave Malcolm 2024-12-09 18:10:00 UTC
Hi Nick.

I tried building
https://sourceware.org/cgit/annobin/commit/?id=9e8c540616c7074adab53eccc7c0999471b207ec
against gcc 15.

I confirmed via "make V=1" that it was indeed building against my "dogfood" install of gcc 15:

/bin/sh ../libtool  --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../gcc-plugin  -I'..' -I'../..' -I/home/david/coding/gcc-newgit-clean/install-dogfood/lib/gcc/x86_64-pc-linux-gnu/15.0.0/plugin/include  -g -O2 -c -o annobin.lo ../../gcc-plugin/annobin.cc
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I../../gcc-plugin -I.. -I../.. -I/home/david/coding/gcc-newgit-clean/install-dogfood/lib/gcc/x86_64-pc-linux-gnu/15.0.0/plugin/include -g -O2 -c ../../gcc-plugin/annobin.cc  -fPIC -DPIC -o .libs/annobin.o
/bin/sh ../libtool --tag=CXX   --mode=link g++  -g -O2 -module  -o annobin.la -rpath /usr/local/libexec/annobin-plugin annobin.lo annobin-common.lo x86_64.annobin.lo 



Looking at the result of
  eu-readelf -s gcc-plugin/.libs/annobin.so.0.0.0 | grep warning
I see:
   37: 0000000000000000      0 NOTYPE  GLOBAL DEFAULT    UNDEF _Z7warningPKcz
  190: 0000000000000000      0 NOTYPE  GLOBAL DEFAULT    UNDEF _Z7warningPKcz

which is:

  warning(char const*, ...)

which looks wrong.  Adding -Wall to the build flags I see:

g++ -DHAVE_CONFIG_H -I. -I../../gcc-plugin -I.. -I../.. -I/home/david/coding/gcc-newgit-clean/install-dogfood/lib/gcc/x86_64-pc-linux-gnu/15.0.0/plugin/include -g -O2 -c ../../gcc-plugin/annobin.cc  -fPIC -DPIC -o .libs/annobin.o -Wall
../../gcc-plugin/annobin.cc: In function ‘void annobin_active_check(const char*)’:
../../gcc-plugin/annobin.cc:2473:13: warning: argument 1 null where non-null expected [-Wnonnull]
 2473 |     warning (0, "%s", message);
      |     ~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from ../../gcc-plugin/annobin.h:48,
                 from ../../gcc-plugin/annobin.cc:21:
/home/david/coding/gcc-newgit-clean/install-dogfood/lib/gcc/x86_64-pc-linux-gnu/15.0.0/plugin/include/errors.h:31:13: note: in a call to function ‘void warning(const char*, ...)’ declared ‘nonnull’
   31 | extern void warning (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_COLD;
      |             ^~~~~~~
../../gcc-plugin/annobin.cc:2473:17: warning: too many arguments for format [-Wformat-extra-args]
 2473 |     warning (0, "%s", message);
      |                 ^~~~
Comment 4 Dave Malcolm 2024-12-09 18:15:28 UTC
Not sure gcc installs errors.h for plugins; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117972

Those decls are for use when building tools that are used as part of gcc's own build; I don't think plugins should be using errors.h 

That might explain why you needed that workaround.
Comment 5 Dave Malcolm 2024-12-09 18:16:16 UTC
(In reply to Dave Malcolm from comment #4)
> Not sure gcc installs errors.h for plugins; see

"Not sure why", I meant to say
Comment 6 Dave Malcolm 2024-12-09 18:23:23 UTC
FWIW with this patch:

diff --git a/gcc-plugin/annobin.h b/gcc-plugin/annobin.h
index 130e967..688d374 100644
--- a/gcc-plugin/annobin.h
+++ b/gcc-plugin/annobin.h
@@ -45,8 +45,6 @@ extern struct plugin_gcc_version gcc_version ATTRIBUTE_UNUSED;
 #include "cgraph.h"
 #include "target.h"
 #if GCCPLUGIN_VERSION_MAJOR >= 5
-#include "errors.h"
-#else
 #include "diagnostic-core.h"
 #endif
 #if GCCPLUGIN_VERSION_MAJOR >= 12

I get:

$ eu-readelf -s .libs/annobin.so.0.0.0|grep warning
    6: 0000000000000000      0 NOTYPE  GLOBAL DEFAULT    UNDEF _Z7warning20diagnostic_option_idPKcz
  141: 0000000000000000      0 NOTYPE  GLOBAL DEFAULT    UNDEF _Z7warning20diagnostic_option_idPKcz

i.e.

  warning(diagnostic_option_id, char const*, ...)

which looks correct.

Only tested by building against GCC 15 though; do you have any automatic testing against multiple GCC versions?

Caveat: I haven't tried actually running the plugin yet
Comment 7 Dave Malcolm 2024-12-09 18:32:25 UTC
Use of errors.h seems to have originated in "plugin/annobin.cc" in https://sourceware.org/cgit/annobin/commit/?id=863ee07a50192e335d388b4754ee5d752c0a6538 :

commit 863ee07a50192e335d388b4754ee5d752c0a6538
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Oct 10 11:18:42 2018 +0100

    annobin: Add active-checks option to enable compile time tests.  Add test and documentation.
    annobin: Fix bug generating group name for hot and cold groups.
    annocheck: Improve wording for skipped tests.

Use of diagnostic-core.h seems to have originated in https://sourceware.org/cgit/annobin/commit/?id=cb4d174afe83ddcbcbce6fbbc77b0e3d54a69f8a :

commit cb4d174afe83ddcbcbce6fbbc77b0e3d54a69f8a
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Nov 26 10:56:34 2018 +0000

    annocheck: Add test for an ENDBR instruction at the entry point for x86/x86_64 executables.



Plugins shouldn't be using errors.h

For recent GCCs, plugins should be using diagnostic-core.h; it was split from diagnostic.h in SVN r159947 aka r0-100277-g1da2ed5f19bc58:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=1da2ed5f19bc5844735b9f5719e5717d744ad54c
which was in 2010.  I'm not sure which GCC version that is, but it predates 5; probably one of the many 4.*s
Comment 8 Dave Malcolm 2024-12-09 18:35:13 UTC
I believe that since diagnostic-core.h was split out, diagnostic.h has always included it, so if you want to support gcc 4.* it may work to
  #include "diagnostic.h"

But 
  #include "diagnostic-core.h"

should work on all GCC >= 5 (and some earlier)
Comment 9 Nick Clifton 2024-12-10 10:49:18 UTC
Hi David,

> FWIW with this patch:
[snip]
> -#include "errors.h"
> -#else

Thanks - that works for me too.  I have also tested that the build plugin does then work, although it turns out that there was a bug in the annobin testsuite: despite the fact that the build can be configured with CC="<path-to-gcc>" the testsuite was ignoring this and always using the system gcc to run its tests.  Naturally enough this meant that none of them worked as a gcc-15 targeted plugin will not load when run by gcc-14.   Anyway, I have now fixed that problem as well.

I am currently building and testing annobin 12.79 which should contain these fixes.  I will update this PR when it is done.
  

> Not sure gcc installs errors.h for plugins; 
> see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117972

It does.  Well at least for gcc 15 in my local build.


> Those decls are for use when building tools that are used 
> as part of gcc's own build; I don't think plugins should 
> be using errors.h 

You are correct, but I am confused as to why errors.h is exported if it should not be used.  I am also confused as to why it contains a different prototype for the warning() and error() functions.

 
> Only tested by building against GCC 15 though; do you 
> have any automatic testing against multiple GCC versions?

Sadly no.  What I tend to do in situations like this is to first build against rawhide (or in this case my own home built gcc, since rawhide is still using gcc 14 I think) and once that works, make a scratch build using RHEL-9 (which contains the earliest version of gcc for which I want to be sure annobin will still work).

Cheers
  Nick
Comment 10 Nick Clifton 2024-12-10 11:16:28 UTC
Right, annobin-12.79 is now in rawhide (well it has been built, it will take a little while to make it through gating).