The GNU Toolchain is a collection of  programming tools produced by the GNU Project. The tools are often packaged together due to their common use for developing software applications, operating systems, and low level software for embedded systems.

This blog is part of a regular series covering the latest changes and improvements in the components that make up this Toolchain.  Apart from the announcement of new releases however, the features described here are at the very bleeding edge of software development in the tools.  This does mean that it may be a while before they make it into production releases, although interested parties can always build their own copies of the toolchain in order to try them out.

GCC

The 6.2 release is now out.  It is an incremental release on 6.1 with several bugs fixed but no new features added.  The GCC development sources are about to be frozen prior to the creation of a GCC 7 release branch, and here is a list of the new features that you can expect to find in it:

  •  LRA is now the default register allocator for new targets and most of the major targets now use it.
  • Suggestions for corrections to misspelt identifiers has been expanded to include function names, macro names, enum values, type names and preprocessor directives.
  • The output from -fverbose-asm has been extended to add comments showing the source lines that correspond to the assembly. For example:

# example.c:4: int total = 0;
xorl %eax, %eax                                       # <retval>
# example.c:6: for (i = 0; i < n; i++)
xorl %edx, %edx                                      # i
.L2:
# example.c:6: for (i = 0; i < n; i++)
cmpl %edi, %edx                                     # n, i
jge .L5                                                        #
# example.c:7: total += i * i;
movl %edx, %ecx                                   # i, tmp92
imull %edx, %ecx                                   # i, tmp92
# example.c:6: for (i = 0; i < n; i++)
incl %edx                                                 # i
# example.c:7: total += i * i;
addl %ecx, %eax                                    # tmp92, <retval>
jmp .L2                                                    #

  • Attributes can now be set on null statements. For example:

    case 1:
    bar (1);
    __attribute__((fallthrough));
    case 2:

  • Experimental support for C++17 has been added. This includes:* Built-in functions have been added to allow access to the PowerPC ISA 3.0 instructions.

    * A command line option -faligned-new enables support for allocating memory for types that require more alignment than void*::operator new(std::size_t) provides. A numeric argument such as -faligned-new=32 can be used to specify how much alignment (in bytes) is provided by that function, but few users will need to override the default of alignof(std::max_align_t).

    * The option -fnew-inheriting-ctors which enables the P0136 adjustment to the semantics of C++11 constructor inheritance.

  • Some new warnings have been added as well:* -Wregister which warns when the register keyword is used as a storage class specifier, (except when it is part of the GNU Explicit Register Variables extension).  The use of the register keyword as storage class specifier has been deprecated in C++11 and removed in C++17.

    * -Wformat-length (or -Wformat-length=<level>) warns about calls to formatted input/output functions such as sprintf that might overflow the destination buffer, or about bounded functions such as snprintf that might result in output truncation.

    When the exact number of bytes written by a format directive cannot be determined at compile-time it is estimated based on heuristics that depend on the <level> argument and on the optimization level in use.

    -Wformat-length=1 employs a conservative approach that warns only about calls that most likely overflow the buffer or result in output truncation. For example, this call to sprintf below would be diagnosed:

    extern int a, b;
    char buf [12];
    sprintf (buf, "a = %i, b = %i\n", a, b);

    Increasing the buffer size by 1 however would stop the warning from being generated as it is possible that overflow will not occur if both a and b are small.

    -Wformat-length=2 also warns about calls where numeric arguments with maximal values would overflow. So in the example above the warning will be generated unless the buffer is at least 34 bytes long in order to allow for both a and b having a value of INT_MAX.

    * -Wimplicit-fallthrough (or -Wimplicit-fallthrough=<level>) warns when a switch case falls through. For example:

    switch (cond)
    {
    case 1: a = 1; break;
    case 2: a = 2;
    case 3: a = 3; break;
    }

    This warning does not warn when the last statement of a case cannot fall through, e.g. when there is a return statement or a call to function declared with the noreturn attribute.

    Since there are occasions where a switch case fall through is desirable, GCC provides an attribute, __attribute__((fallthrough)), that is to be used along with a null statement to suppress this warning that would normally occur. C++17 also provides a standard way to suppress the -Wimplicit-fallthrough warning using [[fallthrough]]; instead of the GNU attribute.

    Instead of the these attributes, it is also possible to add a fallthrough comment to silence the warning. The whole body of the C or C++ style comment should match the given regular expressions listed below. The optional argument <level> specifies what kind of comments are accepted:

    -Wimplicit-fallthrough=0 disables the warning altogether.

    -Wimplicit-fallthrough=1 matches .* regular expression. i.e. any comment is used as fallthrough comment.

    -Wimplicit-fallthrough=2 case insensitively matches the .*falls?[ \t-]*thr(ough|u).* regular expression.

    -Wimplicit-fallthrough=3 case sensitively matches one of the following regular expressions:

     -fallthrough
    @fallthrough@
    lint -fallthrough[ \t]*
    [ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?@*FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?
    [ \t.!]*(Else,? |Intentional(ly)? )?@*Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?
    [ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?@*fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?

    -Wimplicit-fallthrough=4 case sensitively matches one of the following regular expressions:

    -fallthrough
    @fallthrough@
    lint -fallthrough[ \t]*
    [ \t]*FALLTHR(OUGH|U)[ \t]*

    -Wimplicit-fallthrough=5 doesn't recognize any comments as fallthrough comments, only attributes disable the warning.

    * -Walloca warns when alloca is used anywhere in the source.

    * -Walloca-larger-than=<N> warns when a call to alloca is unbounded or greater than <N>. Note that even seemingly correct code involving signed integers can cause a warning.  For example:

    extern signed int n;
    if (n < 500) p = alloca (n);

    This option also warns when alloca is used in a loop.

    * -Wvla-larger-than=<N> warns on uses of variable-length arrays where the size is either unbounded, or bounded by an argument that can be larger than <N> bytes. Note that GCC may optimize small variable-length arrays of a known value into plain arrays, so this warning may not get triggered for such arrays.

    These last two warnings are not enabled by -Wall, and are only active when the -ftree-vrp optimization is active (which by default is when -O2 or higher is in use).

    * -Wbool-operation warns about suspicious operations on expressions of a boolean type. For instance, bitwise negation of a boolean is very likely a bug in the program. For C, this warning also warns about incrementing or decrementing a boolean, which rarely makes sense.

    * -Waligned-new warns about a new-expression of a type that requires greater alignment than the alignof(std::max_align_t) but which uses an allocation function without an explicit alignment parameter.

    * -Wint-in-bool-context warns about suspicious use of integer values where boolean values are expected, such as conditional expressions (?:) using non-boolean integer constants in boolean context:

    if (a <= b ? 2 : 3)

    Or left shifting of signed integers in a boolean context;

    for (a = 0; 1 << a; a++)

  • Some new optimizations have been added as well:* -fstore-merging combines narrow stores to consecutive memory addresses into larger, word sized stores.

    * -fsplit-loops splits a loop into two if it contains a condition that is always true for one side of the iteration space and false for the other.

    * -fprintf-return-value substitutes constants for known return values of formatted output functions such as sprintf etc. This transformation allows GCC to optimize or even eliminate branches based on the known return value of these functions. For example, both the branch and the body of the if statement (but not the call to snprintf) can be optimized away in this snippet, provided that the variable "i" is a 32-bit or smaller integer.

    char buf[9];
    if (snprintf (buf, "%08x", i) >= sizeof buf)

  • Lastly, but certainly not least, the ARM backend has added the option -mpure-code which stops constant data from being placed in code sections. Additionally, when compiling for ELF object format it gives all code sections the ELF processor-specific section attribute SHF_ARM_PURECODE.

GLIBC

A new release of GLIBC is unlikely to happen before the new year, but in the meantime lots of new features have been added to the development sources:

  • Support for the ISO/IEC TS 18661-1:2014 has been added including:* Adding the fesetexcept function to libm.

    * New <math.h> features:
    . Signalling NaN macros: SNANF, SNAN, SNANL.
    . Comparison macros: iseqsig.
    . Classification macros: iscanonical, issubnormal, iszero.
    . Total order functions: totalorder, totalorderf, totalorderl, totalordermag, totalordermagf, totalordermagl.
    . Canonicalize functions: canonicalize, canonicalizef, canonicalizel.
    . NaN functions: getpayload, getpayloadf, getpayloadl.

    * New libc functions: strfromd, strfromf, and strfroml.

  • The <sys/quota.h> header now includes the <linux/quota.h> header. Support for the Linux quota interface which pre-dates kernel version 2.4.22 has been removed.
  • The malloc_get_state and malloc_set_state functions have been removed.  Already existing binaries that dynamically link to these functions will get a hidden implementation in which malloc_get_state is a stub.
  • The ip6-dotint and no-ip6-dotint resolver options, and the corresponding RES_NOIP6DOTINT flag from <resolv.h> have been removed.
  • The ip6-bytestring resolver option and the corresponding RES_NOIP6DOTINT flag from <resolv.h> have been removed.
  • DNSSEC-related declarations and definitions have been removed from the <arpa/nameser.h> header file, and libresolv will no longer attempt to decode the data part of DNSSEC record types.
  • The resource record type classification macros ns_t_qt_p, ns_t_mrr_p, ns_t_rr_p, ns_t_udp_p, ns_t_xfr_p have been removed from the <arpa/nameser.h> header file because the distinction between RR types and meta-RR types is not officially standardized, subject to revision, and thus not suitable for encoding in a macro.
  • The types res_sendhookact, res_send_qhook, re_send_rhook, and the qhook and rhook members of the res_state type in <resolv.h> have been removed.

GDB

GDB 7.12 is now out. In addition the development sources have a nice new feature for MS-Windows developers:

  • Native debugging on MS-Windows supports command-line redirection.Command-line arguments used for starting programs on MS-Windows can now include redirection symbols supported by native Windows shells, such as <, >, >>, 2>&1, etc. This affects GDB commands such as run, start, and set args, as well as the corresponding MI features.

BINUTILS

And lastly the binutils development sources have a couple of new tricks to show off:

  • Support has been added for the RISC-V architecture.
  • The nm program has a new command line option (--with-version-strings) which will display a symbol's version information, if any, after the symbol's name.
  • The EXCLUDE_FILE linker script construct can now be applied outside of the section list in order for the exclusions to apply over all input sections in the list.
  • The command line option --no-eh-frame-hdr can now be used in ELF based linkers to disable the automatic generation of .eh_frame_hdr sections.
  • The ARM linker now supports --in-implib=<infile> to enable specifying a set of Secure Gateway veneers that must exist in the output import library specified by --out-implib=<outfile> and the address they must have.

That’s all for now.  I’ll post again in another couple of months.

Last updated: April 3, 2023