Commit: PR 22823: Fix gcc 8 compile time warnings

Maciej W. Rozycki
Wed Feb 14 03:06:00 GMT 2018

Hi Nick,

>   I am applying the attached patch to fix the compile time warnings that
>   are generated when compiling the binutils with gcc v8.0.1.  Almost all
>   of them were about conflicts in the casts of function pointers to
>   dummy functions.  To solve this I chose to create a set of extra dummy
>   functions which accept a variable number of arguments.  Thus
>   satisfying the compiler and allowing the build to finish.

 Unfortunately this has broken LD severely, in a host rather than target 
dependent manner I believe.  I can see it with the `x86_64-linux' host and 
the `mips-linux' target as numerous segfaults throughout the LD test 

 The thing is the new `bfd_false_any' function is a variable-argument one 
and expects the argument count in $rax, as per the x86-64 psABI[1].  This 
is how compiled code looks like:

Dump of assembler code for function bfd_false_any:
0x0000000000455119 <bfd_false_any+0>:	push   %rbp
0x000000000045511a <bfd_false_any+1>:	mov    %rsp,%rbp
0x000000000045511d <bfd_false_any+4>:	sub    $0xc0,%rsp
0x0000000000455124 <bfd_false_any+11>:	mov    %rsi,-0xa8(%rbp)
0x000000000045512b <bfd_false_any+18>:	mov    %rdx,-0xa0(%rbp)
0x0000000000455132 <bfd_false_any+25>:	mov    %rcx,-0x98(%rbp)
0x0000000000455139 <bfd_false_any+32>:	mov    %r8,-0x90(%rbp)
0x0000000000455140 <bfd_false_any+39>:	mov    %r9,-0x88(%rbp)
0x0000000000455147 <bfd_false_any+46>:	movzbl %al,%eax
0x000000000045514a <bfd_false_any+49>:	mov    %rax,-0xc0(%rbp)
0x0000000000455151 <bfd_false_any+56>:	mov    -0xc0(%rbp),%rdx
0x0000000000455158 <bfd_false_any+63>:	lea    0x0(,%rdx,4),%rax
0x0000000000455160 <bfd_false_any+71>:	movq   $0x45519f,-0xc0(%rbp)
0x000000000045516b <bfd_false_any+82>:	sub    %rax,-0xc0(%rbp)
0x0000000000455172 <bfd_false_any+89>:	lea    -0x1(%rbp),%rax
0x0000000000455176 <bfd_false_any+93>:	mov    -0xc0(%rbp),%rdx
0x000000000045517d <bfd_false_any+100>:	jmpq   *%rdx
0x000000000045517f <bfd_false_any+102>:	movaps %xmm7,-0xf(%rax)
0x0000000000455183 <bfd_false_any+106>:	movaps %xmm6,-0x1f(%rax)
0x0000000000455187 <bfd_false_any+110>:	movaps %xmm5,-0x2f(%rax)
0x000000000045518b <bfd_false_any+114>:	movaps %xmm4,-0x3f(%rax)
0x000000000045518f <bfd_false_any+118>:	movaps %xmm3,-0x4f(%rax)
0x0000000000455193 <bfd_false_any+122>:	movaps %xmm2,-0x5f(%rax)
0x0000000000455197 <bfd_false_any+126>:	movaps %xmm1,-0x6f(%rax)
0x000000000045519b <bfd_false_any+130>:	movaps %xmm0,-0x7f(%rax)
0x000000000045519f <bfd_false_any+134>:	mov    %rdi,-0xb8(%rbp)
0x00000000004551a6 <bfd_false_any+141>:	mov    $0x5,%edi
0x00000000004551ab <bfd_false_any+146>:	callq  0x44eda4 <bfd_set_error>
0x00000000004551b0 <bfd_false_any+151>:	mov    $0x0,%eax
0x00000000004551b5 <bfd_false_any+156>:	leaveq 
0x00000000004551b6 <bfd_false_any+157>:	retq   
End of assembler dump.

This code breaks when called as the handler for 
`bed->elf_backend_allow_non_load_phdr' from elf.c:6141 in 

 The incoming value of $rax is 0x91d920, an outcome from earlier 
operations and not set up for the call to `bfd_false_any'.  This gets 
truncated to 0x20 at 0x455147, multiplied by 4 at 0x455158 and subtracted 
from 0x45519f at 0x45516b, to calculate which of the 8 MOVAPS instructions 
ending at 0x45519f to jump to at 0x45517d.  As 0x20 is above 8, this 
calculation causes an overrun and as a result the jump is made to 0x45511f 
to what is now interpreted as this instruction:

0x45511f <bfd_false_any+6>:	in     (%dx),%al

which then segfaults.  This happens at `-O0'; perhaps the optimiser hides 
the problem with optimisation enabled.

 For some host psABIs I suppose initialising a fixed-argument function 
pointer with a variable-argument function reference and then using the 
pointer to make a call is going to work, but this is UB AFAIK as per the C 
language standard, so I suggest that you revert your change and look for a 
better alternative, as the cure seems worse than the disease.

 NB I don't know where the idea of complaining about extraneous function 
arguments has come from for GCC 8 (except maybe for `-pedantic'), as this 
property of the C vs Pascal function calling convention has been relied on 
since forever.


[1] "System V Application Binary Interface AMD64 Architecture Processor 
    Supplement", Draft Version 0.99.6, July 2, 2012, Section 3.5.7 
    "Variable Argument Lists", p. 50


More information about the Binutils mailing list