[Bug c++/64697] C++11 thread_local: relocation truncated to fit: R_X86_64_PC32 against undefined symbol `TLS init function for N::ptd'

2020-01-08 Thread jon.turney at dronecode dot org.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64697

jon.turney at dronecode dot org.uk changed:

   What|Removed |Added

 CC||jon.turney at dronecode dot 
org.uk

--- Comment #21 from jon.turney at dronecode dot org.uk ---
I looked into this a bit, as gdb 9.0 now uses thread_local in a way which trips
over this.

I came up with a slightly simpler reproduction:

$ cat def.h

extern thread_local int tlv;

$ cat def.cc

#include "def.h"

thread_local int tlv;

$ cat use.cc

#include "def.h"

int main()
{
  tlv = 1;
}

$ x86_64-pc-cygwin-gcc def.cc use.cc --save-temps
/tmp/ccMAKHhL.o:use.cc:(.text$_ZTW3tlv[_ZTW3tlv]+0x15): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `TLS init function for tlv'
collect2: error: ld returned 1 exit status

This compiles without error with x86_64-w64-mingw32-gcc.

Looking at use.s:

.file   "use.cc"
.text
.section.text$_ZTW3tlv,"x"
.linkonce discard
.globl  _ZTW3tlv
.def_ZTW3tlv;   .scl2;  .type   32; .endef
.seh_proc   _ZTW3tlv
_ZTW3tlv:
.LFB1:
pushq   %rbp
.seh_pushreg%rbp
movq%rsp, %rbp
.seh_setframe   %rbp, 0
subq$32, %rsp
.seh_stackalloc 32
.seh_endprologue
movq.refptr._ZTH3tlv(%rip), %rax
testq   %rax, %rax
je  .L2
call_ZTH3tlv
.L2:
movq.refptr.__emutls_v.tlv(%rip), %rcx
call__emutls_get_address
addq$32, %rsp
popq%rbp
ret
.seh_endproc
.def__main; .scl2;  .type   32; .endef
.text
.globl  main
.defmain;   .scl2;  .type   32; .endef
.seh_proc   main
main:
.LFB0:
pushq   %rbp
.seh_pushreg%rbp
movq%rsp, %rbp
.seh_setframe   %rbp, 0
subq$32, %rsp
.seh_stackalloc 32
.seh_endprologue
call__main
call_ZTW3tlv
movl$1, (%rax)
movl$0, %eax
addq$32, %rsp
popq%rbp
ret
.seh_endproc
.weak   _ZTH3tlv
.ident  "GCC: (GNU) 7.4.0"
.def_ZTH3tlv;   .scl2;  .type   32; .endef
.def__emutls_get_address;   .scl2;  .type   32; .endef
.section.rdata$.refptr.__emutls_v.tlv, "dr"
.globl  .refptr.__emutls_v.tlv
.linkonce   discard
.refptr.__emutls_v.tlv:
.quad   __emutls_v.tlv
.section.rdata$.refptr._ZTH3tlv, "dr"
.globl  .refptr._ZTH3tlv
.linkonce   discard
.refptr._ZTH3tlv:
.quad   _ZTH3tlv

The problem seems to be in the TLS wrapper function (_ZTW3tlv):

[...]
movq.refptr._ZTH3tlv(%rip), %rax
testq   %rax, %rax
je  .L2
call_ZTH3tlv
[...]
.weak   _ZTH3tlv
[...]
.refptr._ZTH3tlv:
.quad   _ZTH3tlv

The call here is to absolute address 0 (since the weak symbol has no other
defintion), which is encoded relative to %rip.  This requires a relocation, and
the relative offset can't be contained in 32 signed bits, if the ImageBase is
>2GB.

As some confirmation of this analysis, this problem can be shown with
x86_64-w64-mingw32-gcc, if the ImageBase is altered from 0x40  (the default
for that) to 0x1 0040 0 (the default for x86_64 Cygwin)

$ x86_64-w64-mingw32-gcc def.cc use.cc -Wl,--image-base,0x10040
/tmp/cc3XRN6L.o:use.cc:(.text$_ZTW3tlv[_ZTW3tlv]+0x15): relocation truncated to
fit: R_X86_64_PC32 against undefined symbol `TLS init function for tlv'
collect2: error: ld returned 1 exit status

Naively, I think this could be fixed by generating code which indirects the
call through the pseudo-reloc, but I'm not sure that makes sense.

[Bug libgcc/61752] on cygwin, aborts during exit() with a dynamically loaded C++ library

2020-01-12 Thread jon.turney at dronecode dot org.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61752

Jon Turney  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #3 from Jon Turney  ---
(In reply to Jon Turney from comment #2)
> Better patch: https://cygwin.com/ml/cygwin/2014-07/msg00180.html

That patch was applied as svn commit 213009.

[Bug other/62279] Demangler crash

2015-04-19 Thread jon.turney at dronecode dot org.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62279

jon.turney at dronecode dot org.uk changed:

   What|Removed |Added

 CC||jon.turney at dronecode dot 
org.uk

--- Comment #2 from jon.turney at dronecode dot org.uk ---
See also the corresponding GDB bug
https://sourceware.org/bugzilla/show_bug.cgi?id=17066


[Bug libgcc/61752] New: on cygwin, aborts during exit() with a dynamically loaded C++ library

2014-07-08 Thread jon.turney at dronecode dot org.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61752

Bug ID: 61752
   Summary: on cygwin, aborts during exit() with a dynamically
loaded C++ library
   Product: gcc
   Version: 4.8.3
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libgcc
  Assignee: unassigned at gcc dot gnu.org
  Reporter: jon.turney at dronecode dot org.uk
Target: i686-pc-cygwin

There seems to be a problem somehow related to having a C++ library which does
depend on libgcc dynamically loaded by a C program which doesn't depend on
libgcc, where abort is being called during exit()

This seems to be specific to x86 cygwin/mingw targets with dw2 eh

test.c:

#include 
#include 

int main()
{
   void *h = dlopen("dllib.dll", 0);
   assert(h);
   dlclose(h);
}

dllib.c:

#include 

std::fstream instance;

Makefile:

all:
g++ -g -O0 -c dllib.cc
g++ -g -O0 -shared -o dllib.dll dllib.o
gcc -g -O0 -o test.exe test.c
./test


Running under gdb shows gcc_abort() in __deregister_frame_info_bases() is being
hit

$ gdb test
[...]
Program received signal SIGABRT, Aborted.
0x0028da18 in ?? ()
(gdb) bt
#0  0x0028da18 in ?? ()
#1  0x74f912cc in WriteFile () from /cygdrive/c/Windows/syswow64/kernel32.dll
#2  0x610da70c in sig_send(_pinfo*, siginfo_t&, _cygtls*)@12
(p=p@entry=0x60fd, si=..., tls=tls@entry=0x0)
at /usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/sigproc.cc:638
#3  0x610d7dbc in _pinfo::kill(siginfo_t&)@8 (this=0x60fd, si=...)
at /usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/signal.cc:248
#4  0x610d8286 in kill0 (pid=pid@entry=5044, si=...) at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/signal.cc:299
#5  0x610d8452 in kill (sig=sig@entry=6, pid=5044) at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/signal.cc:308
#6  raise (sig=sig@entry=6) at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/signal.cc:284
#7  0x610d86f3 in abort () at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/signal.cc:371
#8  0x699134d1 in __deregister_frame_info_bases (begin=0x404038
<__EH_FRAME_BEGIN__>)
at /usr/src/debug/gcc-4.8.3-1/libgcc/unwind-dw2-fde.c:216
#9  0x00401182 in __gcc_deregister_frame ()
#10 0x61006466 in do_global_dtors () at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/dcrt0.cc:62
#11 0x61159aba in __call_exitprocs (code=code@entry=0, d=d@entry=0x0)
at /usr/src/debug/cygwin-1.7.30-1/newlib/libc/stdlib/__call_atexit.c:118
#12 0x611305d8 in exit (code=0) at
/usr/src/debug/cygwin-1.7.30-1/newlib/libc/stdlib/exit.c:66
#13 0x61006b39 in cygwin_exit (n=0) at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/dcrt0.cc:1248
#14 0x61008041 in cygwin_exit_return () at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/dcrt0.cc:1041
#15 0x61005e84 in _cygtls::call2(unsigned long (*)(void*, void*), void*,
void*)@16 (this=,
func=func@entry=0x610071d0 , arg=arg@entry=0x0,
buf=buf@entry=0x28cd84)
at /usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/cygtls.cc:100
#16 0x61005ff6 in _cygtls::call (func=func@entry=0x610071d0
, arg=arg@entry=0x0)
at /usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/cygtls.cc:30
#17 0x61006f54 in _dll_crt0@0 () at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/dcrt0.cc:1098
#18 0x00401222 in cygwin_crt0 (f=0x4011a0 ) at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/lib/cygwin_crt0.c:22
#19 0x00401015 in mainCRTStartup () at
/usr/src/debug/cygwin-1.7.30-1/winsup/cygwin/crt0.c:29


[Bug libgcc/61752] on cygwin, aborts during exit() with a dynamically loaded C++ library

2014-07-08 Thread jon.turney at dronecode dot org.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61752

--- Comment #1 from jon.turney at dronecode dot org.uk ---
Created attachment 33092
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33092&action=edit
Patch to cygming-crtbegin.c to prevent libgcc pinning itself in memory

This seems to be caused by the fix for pr 57982, to fix a different abort
during __gcc_deregister_frame()

Since that change is baked into libgcc itself, that patch has the side-effect
of making libgcc pin itself in memory.

I can't really tell from what's written there if that was deliberate or not,
but it seems that it introduces a different problem when the executable doesn't
have a dependency on libgcc.

Attached is a patch which modifies __gcc_register_frame() to avoid it pinning
itself in memory.

Alternatively, as [1] says, the assert in __deregister_frame_info_bases()
itself could be removed. 

[1] http://www.mail-archive.com/gcc@gcc.gnu.org/msg68286.html


[Bug libgcc/61752] on cygwin, aborts during exit() with a dynamically loaded C++ library

2014-07-22 Thread jon.turney at dronecode dot org.uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61752

--- Comment #2 from jon.turney at dronecode dot org.uk ---
Better patch: https://cygwin.com/ml/cygwin/2014-07/msg00180.html