bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/26678] construction vtable defined in a discarded section


From: ccoutant at gmail dot com
Subject: [Bug gold/26678] construction vtable defined in a discarded section
Date: Sat, 06 Feb 2021 01:09:42 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=26678

Cary Coutant <ccoutant at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |NOTABUG

--- Comment #1 from Cary Coutant <ccoutant at gmail dot com> ---
This appears to be a bug in GCC, but the inline asm, being outside the ABI,
could simply render this an unfortunate incompatibility between GCC and Clang.

The problem is that the inline asm is making GCC think that ~A::A() can
raise an exception, so it creates compensation code in D::D(), which
requires a construction vtable for B-in-C, which gets added to the COMDAT
group that also contains the vtable for C (_ZV1C).

Here's the code GCC generates for D::D(), from a.o:

0000000000000002 <_ZN1DC1E1C>:
   2:   48 83 ec 18             sub    $0x18,%rsp
   6:   48 8b 06                mov    (%rsi),%rax
   9:   48 8b 40 e8             mov    -0x18(%rax),%rax
   d:   8b 04 06                mov    (%rsi,%rax,1),%eax
  10:   89 44 24 08             mov    %eax,0x8(%rsp)
  14:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # 1b
<_ZN1DC1E1C+0x19>
                        17: R_X86_64_REX_GOTPCRELX      _ZTV1C-0x4
  1b:   48 8d 40 18             lea    0x18(%rax),%rax
  1f:   48 89 04 24             mov    %rax,(%rsp)
  23:   48 89 e7                mov    %rsp,%rdi
  26:   e8 00 00 00 00          callq  2b <_ZN1DC1E1C+0x29>
                        27: R_X86_64_PLT32      _Z1f1C-0x4
  2b:   eb 17                   jmp    44 <_ZN1DC1E1C+0x42>
  2d:   48 89 c7                mov    %rax,%rdi
  30:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # 37
<_ZN1DC1E1C+0x35>
                        33: R_X86_64_PC32       _ZTC1C0_1B+0x14
  37:   48 89 04 24             mov    %rax,(%rsp)
  3b:   89 44 24 08             mov    %eax,0x8(%rsp)
  3f:   e8 00 00 00 00          callq  44 <_ZN1DC1E1C+0x42>
                        40: R_X86_64_PLT32      _Unwind_Resume-0x4
  44:   48 83 c4 18             add    $0x18,%rsp
  48:   c3                      retq   

The code from offset 0x2d through the callq at 0x3f is the compensation code
generated if an exception happens during the call of f(c). Without that inline
asm, GCC would have generated the same code as clang, with no compensation code
and no construction vtable necessary.

Compile with --no-exceptions, and the problem also goes away.

I see the same problem whether compiling a.cpp at -O0, -O1, -O2, or -O3.

At least GCC is consistent when compiling a.cpp and main.cpp, so it could
be argued that this case simply isn't covered by the C++ ABI, and GCC and
Clang are free to treat it differently. I made some trivial attempts to
reproduce with something other than inline asm, but could not.

As for why you're getting an error from gold, but not from bfd or lld,
gold is reporting what could have been a real error, though in this
particular case, since an exception could never have been thrown,
the compensation code would never have executed. But when you link with
bfd ld or lld, the lea instruction at 0x2d is left unrelocated, with no
warning, and the program could conceivably crash in the case of an
exception being thrown during the call to f().

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]