Work around gcc-4.9 bug
Alan Modra
amodra@gmail.com
Fri Feb 27 00:12:32 GMT 2026
On Thu, Feb 26, 2026 at 02:32:06PM +0000, Matthieu Longo wrote:
> On 26/02/2026 07:47, Alan Modra wrote:
> > Commit 893eb49c9b12 exposed a gcc-4.9 build error, with gcc-4.9
> > erroneously complaining that F_MIN_SUBSECTION_DATA_LEN has a
> > non-constant initialisation.
> >
> > * readelf.c (F_MIN_SUBSECTION_DATA_LEN): Use #define to work
> > around gcc-4.9 bug.
> > (F_SUBSECTION_LEN, F_SUBSECTION_COMPREHENSION),
> > (F_SUBSECTION_ENCODING): Use #define here too.
> > (elf_parse_attrs_subsection_v2): Adjust format string.
> >
> > diff --git a/binutils/readelf.c b/binutils/readelf.c
> > index c9ec085adc4..0c3e24e8bf7 100644
> > --- a/binutils/readelf.c
> > +++ b/binutils/readelf.c
> > @@ -20098,14 +20098,14 @@ typedef struct {
> > uint64_t read;
> > } BufferReadOp_t;
> > -const uint32_t F_SUBSECTION_LEN = sizeof (uint32_t);
> > -const uint32_t F_SUBSECTION_COMPREHENSION = sizeof(uint8_t);
> > -const uint32_t F_SUBSECTION_ENCODING = sizeof(uint8_t);
> > /* The minimum subsection length is 7: 4 bytes for the length itself, and 1
> > byte for an empty NUL-terminated string, 1 byte for the comprehension,
> > 1 byte for the encoding, and no vendor-data. */
> > -const uint32_t F_MIN_SUBSECTION_DATA_LEN = F_SUBSECTION_LEN + 1 /* for '\0' */
> > - + F_SUBSECTION_COMPREHENSION + F_SUBSECTION_ENCODING;
> > +#define F_SUBSECTION_LEN 4
> > +#define F_SUBSECTION_COMPREHENSION 1
> > +#define F_SUBSECTION_ENCODING 1
> > +#define F_MIN_SUBSECTION_DATA_LEN \
> > + (F_SUBSECTION_LEN + 1 + F_SUBSECTION_COMPREHENSION + F_SUBSECTION_ENCODING)
> > static BufferReadOp_t
> > elf_parse_attrs_subsection_v2 (const unsigned char *cursor,
> > @@ -20128,7 +20128,7 @@ elf_parse_attrs_subsection_v2 (const unsigned char *cursor,
> > }
> > else if (subsection_len < F_MIN_SUBSECTION_DATA_LEN)
> > {
> > - error (_("Bad subsection length: too small (%u < min=%"PRIu32")\n"),
> > + error (_("Bad subsection length: too small (%u < min=%u)\n"),
> > subsection_len, F_MIN_SUBSECTION_DATA_LEN);
> > /* Error, but still try to display the content until meeting a more
> > serious error. */
> >
>
> Hi Alan,
>
> Would it make sense to add a check on the compiler version around the original code instead of replacing it ?
>
> #if defined (__GNUC__) && (__GNUC__ > 4)
> /* Keep the new code */
> #else
> /* Fix for 4.9 which is easy to detect with a grep, and drop when support for GCC 4.9 goes away. */
> #endif
No, that would *not* be a good idea in this particular instance. You
would basically be using ifdefs to select between two different styles
of programming. That isn't to say I'm against the newer c++ style
here of using const int in place of #define, in fact I prefer it.
(Yes I should have made them static const int when moving them out of
the function body..)
Which isn't to say I like every c++ style either. For instance, your
use of a struct return in elf_parse_attrs_subsection_v2. I'm an old
dinosaur and know enough about machine ABIs to expect poor code to be
generated for that, except that in this case the function will be
inlined by modern compilers, avoiding function struct return
inefficiency. Does that mean I want you to change that? No, it's
fine as is. Incidentally, I understand and appreciate someone who
pushes back at me trampling over their code!
> This would help to modernize the code as soon as the support for an
> old compiler is dropped.
I did seriously consider dropping my gcc-4.9 builds when I saw this
"error". (I was only doing them because I know other people were
still using gcc-4.9, at least a couple of years ago.) We have to
remember that people still use old tools, particularly in the embedded
space.
> As a drawback, it makes some pieces of code more difficult to read,
> and there are risks of differences in behavior depending on the
> implementation that was selected at compile time (tests were helping
> to detect issues in this regard).
Right, which is why it would be a bad idea here. Ironic too, to use
#ifdef because you'd prefer not to use #define.
--
Alan Modra
More information about the Binutils
mailing list