Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Martin Storsjö

On Fri, 3 Aug 2018, Liu Hao wrote:


在 2018-08-03 03:16, Martin Storsjö 写道:

GNU binutils ld traditionally provides __CTOR_LIST__ and __DTOR_LIST__
symbols via a linker script, while lld doesn't.
 (... ...)
-#else
-// old method that iterates the list twice because old linker scripts do 
not have __CTOR_END__


This drops the compatibility with those 'old linker scripts', doesn't it?


No, it's still compatible - we provide our own __CTOR_END__ anyway, which 
is sorted in the right place by the linker due to the section name.


In practice this comment seemed to be a bit misleading, because not even 
the latest binutils provide __CTOR_END__. It does store the terminating 
null pointer here, but it doesn't provide any symbol pointing to it.


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] Error Codes Patch

2018-08-02 Thread Liu Hao
在 2018/8/3 1:10, Tom Ritter 写道:
> Hit an error compiling Firefox because 1471 wasn't defined.
> 
> -tom
> 

Thanks for the patch. Pushed to master.

LRN:
He was talking about the value of `ERROR_NOT_GUI_PROCESS` in the patch 
attached.


-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Liu Hao
在 2018-08-03 03:16, Martin Storsjö 写道:
> GNU binutils ld traditionally provides __CTOR_LIST__ and __DTOR_LIST__
> symbols via a linker script, while lld doesn't.
>  (... ...)
> -#else
> -// old method that iterates the list twice because old linker scripts do not 
> have __CTOR_END__

This drops the compatibility with those 'old linker scripts', doesn't it?

This patch looks good otherwise.

-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread JonY via Mingw-w64-public
On 08/02/2018 08:25 PM, Martin Storsjö wrote:
> On Thu, 2 Aug 2018, Liu Hao wrote:
> 
>>> index 54cbf02..44ff653 100644
>>> --- a/mingw-w64-crt/crt/gccmain.c
>>> +++ b/mingw-w64-crt/crt/gccmain.c
>>> @@ -23,18 +23,24 @@ __do_global_dtors (void)
>>>   while (*p)
>>>   {
>>> -  (*(p)) ();
>>> +  // If the linker provided its own __DTOR_LIST__ in addition to
>>> the
>>> +  // one we provide, we'd end up with the first pointer here being
>>> +  // a (func_ptr)-1 sentinel.
>>
>> jon_y used to require all comments be C89-ish. I am not totally clear
>> about the reason. May he elaborate a little.
> 
> I forgot to change this for this patch when I posted the updated
> version, but I changed it for the cxa_atexit patchset before pushing.
> 
> // Martin
> 
>


It's a preference, but not a hard one, seeing though C89 style comments
are supported by all C compliant compilers.


signature.asc
Description: OpenPGP digital signature
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Liu Hao wrote:


index 54cbf02..44ff653 100644
--- a/mingw-w64-crt/crt/gccmain.c
+++ b/mingw-w64-crt/crt/gccmain.c
@@ -23,18 +23,24 @@ __do_global_dtors (void)
  while (*p)
  {
-  (*(p)) ();
+  // If the linker provided its own __DTOR_LIST__ in addition to the
+  // one we provide, we'd end up with the first pointer here being
+  // a (func_ptr)-1 sentinel.


jon_y used to require all comments be C89-ish. I am not totally clear about 
the reason. May he elaborate a little.


I forgot to change this for this patch when I posted the updated version, 
but I changed it for the cxa_atexit patchset before pushing.


// Martin


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018/8/2 19:22, Martin Storsjö 写道:

+
+typedef void (__thiscall * dtor)(void*);
+int __cxa_atexit(dtor dtor, void *obj, void *dso);
+int __cxa_thread_atexit(dtor dtor, void *obj, void *dso);
+
+typedef struct dtor_obj dtor_obj;
+struct dtor_obj {
+  dtor dtor;


It is a bit strange to see the same identifier be repeated here. I 
suggest you rename the typedef to `dtor_fn` or `dtor_proc`.


Renamed the typedef to dtor_fn


These 4 patches look good to me.


Thanks for the thorough review! Pushed.

// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Martin Storsjö wrote:


On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018/8/2 19:02, Martin Storsjö 写道:

-#ifdef __clang__
  extern func_ptr __CTOR_END__[];
  extern func_ptr __DTOR_END__[];

  void __do_global_ctors (void)
  {
static func_ptr *p = __CTOR_END__ - 1;
+  // If the linker provided its own __CTOR_LIST__ in addition to the one
+  // we provide, we'd actually stop at __CTOR_LIST__+1, but that's no 

problem

+  // for this function.
while (*p != (func_ptr) -1) {
  (*(p))();


At the very firsts iteration, isn't `*p` null if there are two null 
termini in the list?


(i.e. the list looks like `-1, -1, ... some `func_ptr`s ... , 0, 0`)


I thought the same; that's why I did the extra check with "if (*p)", as I 
mentioned in the other mail.


However, in practice, __CTOR_END__ points to the first 0-terminator. Not 
sure why that is, but you can check with -Wl,-Map,map.txt.


But yes, it's safer with that extra check added, then both iterations 
should be fine, regardless which one the symbol points to, in both ends.


This is because it seems like GNU LD actually never provides any 
__CTOR_END__ symbol. But we can have the extra check in any case, for 
safety and symmetry.


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] Error Codes Patch

2018-08-02 Thread LRN
On 02.08.2018 20:10, Tom Ritter wrote:
> Hit an error compiling Firefox because 1471 wasn't defined.

Add more context here because 1471 doesn't ring a bell.



signature.asc
Description: OpenPGP digital signature
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] Error Codes Patch

2018-08-02 Thread Tom Ritter
Hit an error compiling Firefox because 1471 wasn't defined.

-tom
From 71ee4edf14d76ddacb8154620024c7a8b60be18b Mon Sep 17 00:00:00 2001
From: Tom Ritter 
Date: Thu, 2 Aug 2018 09:50:56 -0500
Subject: [PATCH] Add Error Codes between 1460 and 1471

---
 mingw-w64-headers/include/winerror.h| 9 +
 mingw-w64-tools/widl/include/winerror.h | 1 +
 2 files changed, 10 insertions(+)
 mode change 100644 => 100755 mingw-w64-headers/include/winerror.h

diff --git a/mingw-w64-headers/include/winerror.h 
b/mingw-w64-headers/include/winerror.h
old mode 100644
new mode 100755
index e117b046..5eba03f6
--- a/mingw-w64-headers/include/winerror.h
+++ b/mingw-w64-headers/include/winerror.h
@@ -631,6 +631,15 @@
 #define ERROR_TIMEOUT __MSABI_LONG(1460)
 #define ERROR_INVALID_MONITOR_HANDLE __MSABI_LONG(1461)
 #define ERROR_INCORRECT_SIZE __MSABI_LONG(1462)
+#define ERROR_SYMLINK_CLASS_DISABLED __MSABI_LONG(1463)
+#define ERROR_SYMLINK_NOT_SUPPORTED __MSABI_LONG(1464)
+#define ERROR_XML_PARSE_ERROR __MSABI_LONG(1465)
+#define ERROR_XMLDSIG_ERROR __MSABI_LONG(1466)
+#define ERROR_RESTART_APPLICATION __MSABI_LONG(1467)
+#define ERROR_WRONG_COMPARTMENT __MSABI_LONG(1468)
+#define ERROR_AUTHIP_FAILURE __MSABI_LONG(1469)
+#define ERROR_NO_NVRAM_RESOURCES __MSABI_LONG(1470)
+#define ERROR_NOT_GUI_PROCESS __MSABI_LONG(1471)
 #define ERROR_EVENTLOG_FILE_CORRUPT __MSABI_LONG(1500)
 #define ERROR_EVENTLOG_CANT_START __MSABI_LONG(1501)
 #define ERROR_LOG_FILE_FULL __MSABI_LONG(1502)
diff --git a/mingw-w64-tools/widl/include/winerror.h 
b/mingw-w64-tools/widl/include/winerror.h
index 2c6ce20b..180e3efe 100644
--- a/mingw-w64-tools/widl/include/winerror.h
+++ b/mingw-w64-tools/widl/include/winerror.h
@@ -940,6 +940,7 @@ static inline HRESULT HRESULT_FROM_WIN32(unsigned int x)
 #define ERROR_WRONG_COMPARTMENT1468
 #define ERROR_AUTHIP_FAILURE   1469
 #define ERROR_NO_NVRAM_RESOURCES   1470
+#define ERROR_NOT_GUI_PROCESS  1471
 #define ERROR_EVENTLOG_FILE_CORRUPT1500
 #define ERROR_EVENTLOG_CANT_START  1501
 #define ERROR_LOG_FILE_FULL1502
-- 
2.17.1

--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018/8/2 19:02, Martin Storsjö 写道:

-#ifdef __clang__
  extern func_ptr __CTOR_END__[];
  extern func_ptr __DTOR_END__[];

  void __do_global_ctors (void)
  {
static func_ptr *p = __CTOR_END__ - 1;
+  // If the linker provided its own __CTOR_LIST__ in addition to the one
+  // we provide, we'd actually stop at __CTOR_LIST__+1, but that's no problem
+  // for this function.
while (*p != (func_ptr) -1) {
  (*(p))();


At the very firsts iteration, isn't `*p` null if there are two null 
termini in the list?


(i.e. the list looks like `-1, -1, ... some `func_ptr`s ... , 0, 0`)


I thought the same; that's why I did the extra check with "if (*p)", as I 
mentioned in the other mail.


However, in practice, __CTOR_END__ points to the first 0-terminator. Not 
sure why that is, but you can check with -Wl,-Map,map.txt.


But yes, it's safer with that extra check added, then both iterations 
should be fine, regardless which one the symbol points to, in both ends.


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Liu Hao
在 2018/8/2 19:22, Martin Storsjö 写道:
> +
> +typedef void (__thiscall * dtor)(void*);
> +int __cxa_atexit(dtor dtor, void *obj, void *dso);
> +int __cxa_thread_atexit(dtor dtor, void *obj, void *dso);
> +
> +typedef struct dtor_obj dtor_obj;
> +struct dtor_obj {
> +  dtor dtor;

It is a bit strange to see the same identifier be repeated here. I 
suggest you rename the typedef to `dtor_fn` or `dtor_proc`.

These 4 patches look good to me.

-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Liu Hao
在 2018/8/2 19:02, Martin Storsjö 写道:
> -#ifdef __clang__
>   extern func_ptr __CTOR_END__[];
>   extern func_ptr __DTOR_END__[];
>   
>   void __do_global_ctors (void)
>   {
> static func_ptr *p = __CTOR_END__ - 1;
> +  // If the linker provided its own __CTOR_LIST__ in addition to the one
> +  // we provide, we'd actually stop at __CTOR_LIST__+1, but that's no problem
> +  // for this function.
> while (*p != (func_ptr) -1) {
>   (*(p))();

At the very firsts iteration, isn't `*p` null if there are two null 
termini in the list?

(i.e. the list looks like `-1, -1, ... some `func_ptr`s ... , 0, 0`)

>   p--;
> @@ -42,30 +48,6 @@ void __do_global_ctors (void)
> atexit (__do_global_dtors);
>   }
>   



-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018-08-02 19:02, Martin Storsjö 写道:

Signed-off-by: Martin Storsjö 
---
  mingw-w64-crt/crt/crtdll.c  |  2 --
  mingw-w64-crt/crt/crtexe.c  |  2 --
  mingw-w64-crt/crt/gccmain.c | 34 --
  3 files changed, 8 insertions(+), 30 deletions(-)

diff --git a/mingw-w64-crt/crt/crtdll.c b/mingw-w64-crt/crt/crtdll.c
index 50a9eb4..af69573 100644
--- a/mingw-w64-crt/crt/crtdll.c
+++ b/mingw-w64-crt/crt/crtdll.c
@@ -40,12 +40,10 @@ extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];
  extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
  extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
  -#ifdef __clang__
  __attribute__ (( __section__ (".ctors"), __used__ , aligned(sizeof(void 
* const void * __CTOR_LIST__ = (void *) -1;
  __attribute__ (( __section__ (".dtors"), __used__ , aligned(sizeof(void 
* const void * __DTOR_LIST__ = (void *) -1;
  __attribute__ (( __section__ (".ctors.9"), __used__ , 
aligned(sizeof(void * const void * __CTOR_END__ = (void *) 0;
  __attribute__ (( __section__ (".dtors.9"), __used__ , 
aligned(sizeof(void * const void * __DTOR_END__ = (void *) 0;

-#endif


Does GNU LD recognize the `.9` suffix?

The known and working way to sort sections for GNU LD for Windows is

   .ctors$
   .ctors$foo
   .ctors$

and such sections are sorted in alphabet order rather than numeric order. 
This could explain why these symbols are not emitted for GCC.


Yes, GNU LD supports it - you get similar things emitted by GCC if you 
specify a constructor priority.


Case example:

$ cat test.cpp

void other(void);

class Foo {
public:
Foo() {
other();
}
};

Foo foo1 __attribute__((init_priority(101)));
Foo foo2 __attribute__((init_priority(65534)));

$ x86_64-w64-mingw32-g++ -S test.cpp -o - -O2 | grep ctors
.section.ctors.65434,"w"
.section.ctors.1,"w"

The number after .ctors is 65535 minus the value specified in 
init_priority. The values are padded to 5 digits with leading zeros, and 
GNU LD sorts them alphabetically when linking, which is equal to numeric 
order when it's zero padded.


Since the values are in the range 0-65535, the sentinel at 9 will 
always be sorted last.



diff --git a/mingw-w64-crt/crt/gccmain.c b/mingw-w64-crt/crt/gccmain.c
index 54cbf02..44ff653 100644
--- a/mingw-w64-crt/crt/gccmain.c
+++ b/mingw-w64-crt/crt/gccmain.c
@@ -23,18 +23,24 @@ __do_global_dtors (void)
  while (*p)
  {
-  (*(p)) ();
+  // If the linker provided its own __DTOR_LIST__ in addition to the
+  // one we provide, we'd end up with the first pointer here being
+  // a (func_ptr)-1 sentinel.


jon_y used to require all comments be C89-ish. I am not totally clear about 
the reason. May he elaborate a little.


I can change them to that style if there's a preference for that - I'll 
not repost any new version of the patch just for that though.


Just to be safe, I'm amending the patch locally like this as well:

@@ -42,7 +42,8 @@ void __do_global_ctors (void)
   // we provide, we'd actually stop at __CTOR_LIST__+1, but that's no problem
   // for this function.
   while (*p != (func_ptr) -1) {
-(*(p))();
+if (*p)
+  (*(p))();
 p--;
   }

That doesn't turn out to be necessary in my testing with GNU LD, but it's 
safer that way.


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] [PATCH] crt: Unify and simplify handling of constructor/destructor lists

2018-08-02 Thread Martin Storsjö
GNU binutils ld traditionally provides __CTOR_LIST__ and __DTOR_LIST__
symbols via a linker script, while lld doesn't.

Due to this, we previously provided our own copy of these symbols while
building with clang (assuming that means we'd be linking with lld), see
1e81200e88f.

In an attempt to unify things, binutils 2.30 changed the linker script
to conditionally provide these symbols, in case they were undefined,
but otherwise prefer the ones provided by object files linked in.

This attempt failed though (and was reverted for binutils 2.31), since
libgcc turned out to contain dummy fallback symbols named __CTOR_LIST__
and __DTOR_LIST__, without any section assignments, meaning they weren't
actually sorted by the linker along with any of the constructors to be
called.

In order to unify and simplify things, always provide our own version
of these symbols. When using a binutils version other than 2.30, that
always unconditionally provides its own __CTOR_LIST__/__DTOR_LIST__
symbols, this doesn't result in a conflict with multiply defined symbols,
but ld just silently uses the symbol it provided via the linker script,
but retains the data provided from the object files. (Tested with
binutils 2.22, 2.26 and 2.30.)

In such a case, the list between __CTOR_LIST__ and __CTOR_END__ will
contain one extra (func_ptr)-1 entry at the start, the one provided by
code (and one extra, for our purposes harmless, null terminator at the
end).

By always providing our own, and adapting the code for iterating the
lists to cope with a stray extra sentinel in the list, we can use the
same logic for all cases of both binutils ld and lld, including the
previously broken binutils 2.30.

Signed-off-by: Martin Storsjö 
---
 mingw-w64-crt/crt/crtdll.c  |  2 --
 mingw-w64-crt/crt/crtexe.c  |  2 --
 mingw-w64-crt/crt/gccmain.c | 34 --
 3 files changed, 8 insertions(+), 30 deletions(-)

diff --git a/mingw-w64-crt/crt/crtdll.c b/mingw-w64-crt/crt/crtdll.c
index 50a9eb4..af69573 100644
--- a/mingw-w64-crt/crt/crtdll.c
+++ b/mingw-w64-crt/crt/crtdll.c
@@ -40,12 +40,10 @@ extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];
 extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
 extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
 
-#ifdef __clang__
 __attribute__ (( __section__ (".ctors"), __used__ , aligned(sizeof(void * 
const void * __CTOR_LIST__ = (void *) -1;
 __attribute__ (( __section__ (".dtors"), __used__ , aligned(sizeof(void * 
const void * __DTOR_LIST__ = (void *) -1;
 __attribute__ (( __section__ (".ctors.9"), __used__ , aligned(sizeof(void 
* const void * __CTOR_END__ = (void *) 0;
 __attribute__ (( __section__ (".dtors.9"), __used__ , aligned(sizeof(void 
* const void * __DTOR_END__ = (void *) 0;
-#endif
 
 /* TLS initialization hook.  */
 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
diff --git a/mingw-w64-crt/crt/crtexe.c b/mingw-w64-crt/crt/crtexe.c
index e390074..5dcfefd 100644
--- a/mingw-w64-crt/crt/crtexe.c
+++ b/mingw-w64-crt/crt/crtexe.c
@@ -60,12 +60,10 @@ extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];
 extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
 extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
 
-#ifdef __clang__
 __attribute__ (( __section__ (".ctors"), __used__ , aligned(sizeof(void * 
const void * __CTOR_LIST__ = (void *) -1;
 __attribute__ (( __section__ (".dtors"), __used__ , aligned(sizeof(void * 
const void * __DTOR_LIST__ = (void *) -1;
 __attribute__ (( __section__ (".ctors.9"), __used__ , aligned(sizeof(void 
* const void * __CTOR_END__ = (void *) 0;
 __attribute__ (( __section__ (".dtors.9"), __used__ , aligned(sizeof(void 
* const void * __DTOR_END__ = (void *) 0;
-#endif
 
 /* TLS initialization hook.  */
 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
diff --git a/mingw-w64-crt/crt/gccmain.c b/mingw-w64-crt/crt/gccmain.c
index 54cbf02..44ff653 100644
--- a/mingw-w64-crt/crt/gccmain.c
+++ b/mingw-w64-crt/crt/gccmain.c
@@ -23,18 +23,24 @@ __do_global_dtors (void)
 
   while (*p)
 {
-  (*(p)) ();
+  // If the linker provided its own __DTOR_LIST__ in addition to the
+  // one we provide, we'd end up with the first pointer here being
+  // a (func_ptr)-1 sentinel.
+  if (*p != (func_ptr) -1)
+(*(p)) ();
   p++;
 }
 }
 
-#ifdef __clang__
 extern func_ptr __CTOR_END__[];
 extern func_ptr __DTOR_END__[];
 
 void __do_global_ctors (void)
 {
   static func_ptr *p = __CTOR_END__ - 1;
+  // If the linker provided its own __CTOR_LIST__ in addition to the one
+  // we provide, we'd actually stop at __CTOR_LIST__+1, but that's no problem
+  // for this function.
   while (*p != (func_ptr) -1) {
 (*(p))();
 p--;
@@ -42,30 +48,6 @@ void __do_global_ctors (void)
   atexit (__do_global_dtors);
 }
 
-#else
-// old method that iterates the list twice because old linker scripts do not 
have __CTOR_END__
-
-void
-__do_global_ctors (void)
-{
-  unsigned long nptrs = (unsigned long) (ptrdiff_t) 

[Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Martin Storsjö
In order to properly call destructors of a DLL when that DLL is
unloaded, we need to provide these as part of the static library
libmingw32.a, which gets linked into the module itself.

C++ libraries (both libstdc++ and libcxxabi) can also provide the
function __cxa_thread_atexit, and defer the actual handling to the
platform via a __cxa_thread_atexit_impl function. However, if linking
a C++ standard library dynamically, that would mean that all destructors
are registered in the C++ DLL and only invoked when that one is unloaded,
not when an individual DLL gets unloaded.

Therefore we need to provide these functions directly in a static library
that gets linked into each module (if referenced).

This probably doesn't end up used with GCC and libstdc++ (which still
probably provides its own __cxa_thread_atexit which will be linked before
libmingw32.a). But it does work with clang (if compiling with
-fuse-cxa-atexit) and libcxxabi (which doesn't provide any
__cxa_thread_atexit when targeting mingw).

Signed-off-by: Martin Storsjö 
---
Removed code for cleaning up other threads' pending destructors, added
a verbose comment about the matter.
---
 mingw-w64-crt/Makefile.am  |   2 +-
 mingw-w64-crt/crt/cxa_atexit.c | 113 +
 2 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 mingw-w64-crt/crt/cxa_atexit.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 8ca1072..d98fa3a 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -119,7 +119,7 @@ src_libmingw32=include/oscalls.h include/internal.h 
include/sect_attribs.h \
   crt/mingw_custom.c  crt/mingw_helpers.c  \
   crt/pseudo-reloc.c  crt/udll_argv.c  \
   crt/xtxtmode.c  crt/crt_handler.c\
-  crt/tlsthrd.c   crt/tlsmthread.c crt/tlsmcrt.c
+  crt/tlsthrd.c   crt/tlsmthread.c crt/tlsmcrt.c   crt/cxa_atexit.c
 
 src_libscrnsave=libsrc/scrnsave.c
 src_libscrnsavw=libsrc/scrnsave.c
diff --git a/mingw-w64-crt/crt/cxa_atexit.c b/mingw-w64-crt/crt/cxa_atexit.c
new file mode 100644
index 000..d74968d
--- /dev/null
+++ b/mingw-w64-crt/crt/cxa_atexit.c
@@ -0,0 +1,113 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include 
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include 
+
+#include 
+#include 
+#include 
+
+
+typedef void (__thiscall * dtor)(void*);
+int __cxa_atexit(dtor dtor, void *obj, void *dso);
+int __cxa_thread_atexit(dtor dtor, void *obj, void *dso);
+
+typedef struct dtor_obj dtor_obj;
+struct dtor_obj {
+  dtor dtor;
+  void *obj;
+  dtor_obj *next;
+};
+
+HANDLE __dso_handle;
+
+static CRITICAL_SECTION lock;
+static int inited = 0;
+static dtor_obj *global_dtors = NULL;
+static __thread dtor_obj *tls_dtors = NULL;
+
+int __cxa_atexit(dtor dtor, void *obj, void *dso) {
+  if (!inited)
+return 1;
+  assert(!dso || dso == &__dso_handle);
+  dtor_obj *handler = (dtor_obj *) calloc(1, sizeof(*handler));
+  if (!handler)
+return 1;
+  handler->dtor = dtor;
+  handler->obj = obj;
+  EnterCriticalSection();
+  handler->next = global_dtors;
+  global_dtors = handler;
+  LeaveCriticalSection();
+  return 0;
+}
+
+static void run_dtor_list(dtor_obj **ptr) {
+  dtor_obj *list = *ptr;
+  while (list) {
+list->dtor(list->obj);
+dtor_obj *next = list->next;
+free(list);
+list = next;
+  }
+  *ptr = NULL;
+}
+
+int __cxa_thread_atexit(dtor dtor, void *obj, void *dso) {
+  if (!inited)
+return 1;
+  assert(!dso || dso == &__dso_handle);
+  dtor_obj *handler = (dtor_obj *) calloc(1, sizeof(*handler));
+  if (!handler)
+return 1;
+  handler->dtor = dtor;
+  handler->obj = obj;
+  handler->next = tls_dtors;
+  tls_dtors = handler;
+  return 0;
+}
+
+static void WINAPI tls_callback(HANDLE hDllHandle, DWORD dwReason, LPVOID 
__UNUSED_PARAM(lpReserved)) {
+  switch (dwReason) {
+  case DLL_PROCESS_ATTACH:
+if (inited == 0) {
+  InitializeCriticalSection();
+  __dso_handle = hDllHandle;
+}
+inited = 1;
+break;
+  case DLL_PROCESS_DETACH:
+// If there are other threads still running that haven't been detached,
+// we don't attempt to run their destructors (MSVC doesn't either), but
+// simply leak the destructor list and whatever resources the destructors
+// would have released.
+// From Vista onwards, we could have used FlsAlloc to get a TLS key that
+// runs a destructor on each thread that has a value attached ot it, but
+// since MSVC doesn't run destructors on other threads in this case,
+// users shouldn't assume it and we don't attempt to do anything 
potentially
+// risky about it. TL;DR, threads with pending TLS destructors for a DLL
+// need to be joined before unloading the DLL.
+run_dtor_list(_dtors);
+run_dtor_list(_dtors);
+  

[Mingw-w64-public] [PATCHv2 4/4] crt: Use _register_thread_local_exe_atexit_callback for TLS dtors

2018-08-02 Thread Martin Storsjö
The standard says that destructors of thread local objects should be
invoked before any other destructors. Since the destructors are called
by the CRT via what has been registered via atexit (ordered so that the
function registered last will be executed first), we need to use this
API from UCRT to request a function to be executed before any other
atexit callback.

Signed-off-by: Martin Storsjö 
---
 mingw-w64-crt/crt/cxa_atexit.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/mingw-w64-crt/crt/cxa_atexit.c b/mingw-w64-crt/crt/cxa_atexit.c
index d74968d..560e93e 100644
--- a/mingw-w64-crt/crt/cxa_atexit.c
+++ b/mingw-w64-crt/crt/cxa_atexit.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 typedef void (__thiscall * dtor)(void*);
@@ -28,6 +29,7 @@ struct dtor_obj {
 };
 
 HANDLE __dso_handle;
+extern char __mingw_module_is_dll;
 
 static CRITICAL_SECTION lock;
 static int inited = 0;
@@ -81,6 +83,16 @@ static void WINAPI tls_callback(HANDLE hDllHandle, DWORD 
dwReason, LPVOID __UNUS
 if (inited == 0) {
   InitializeCriticalSection();
   __dso_handle = hDllHandle;
+  // We can only call _register_thread_local_exe_atexit_callback once
+  // in a thread; if we call it a second time the process terminates.
+  // When DLLs are unloaded, this callback is invoked before we run the
+  // _onexit tables, but for exes, we need to ask this to be called before
+  // all other registered atexit functions.
+  // Since we are registered as a normal TLS callback, we will be called
+  // another time later as well, but that doesn't matter, it's safe to
+  // invoke this with DLL_PROCESS_DETACH twice.
+  if (!__mingw_module_is_dll)
+_register_thread_local_exe_atexit_callback(tls_callback);
 }
 inited = 1;
 break;
-- 
2.7.4


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] [PATCHv2 3/4] crt: Expose a private variable that indicates whether the module is an exe or dll

2018-08-02 Thread Martin Storsjö
Signed-off-by: Martin Storsjö 
---
 mingw-w64-crt/crt/crtdll.c | 2 ++
 mingw-w64-crt/crt/crtexe.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/mingw-w64-crt/crt/crtdll.c b/mingw-w64-crt/crt/crtdll.c
index 50a9eb4..5f53602 100644
--- a/mingw-w64-crt/crt/crtdll.c
+++ b/mingw-w64-crt/crt/crtdll.c
@@ -210,3 +210,5 @@ int __cdecl atexit (_PVFV func)
 {
 return _register_onexit_function(_table, (_onexit_t)func);
 }
+
+char __mingw_module_is_dll = 1;
diff --git a/mingw-w64-crt/crt/crtexe.c b/mingw-w64-crt/crt/crtexe.c
index 7000a19..3f724e5 100644
--- a/mingw-w64-crt/crt/crtexe.c
+++ b/mingw-w64-crt/crt/crtexe.c
@@ -430,3 +430,5 @@ int __cdecl atexit (_PVFV func)
 {
 return _onexit((_onexit_t)func) ? 0 : -1;
 }
+
+char __mingw_module_is_dll = 0;
-- 
2.7.4


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] [PATCHv2 2/4] crt: Declare _register_thread_local_exe_atexit_callback in headers, provide fallback

2018-08-02 Thread Martin Storsjö
This function is available in the universal CRT.

Add a best effort fallback version of it for other CRTs.

Signed-off-by: Martin Storsjö 
---
 mingw-w64-crt/Makefile.am|  1 +
 mingw-w64-crt/misc/register_tls_atexit.c | 29 +
 mingw-w64-headers/crt/process.h  |  3 +++
 3 files changed, 33 insertions(+)
 create mode 100644 mingw-w64-crt/misc/register_tls_atexit.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index d98fa3a..3745a2f 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -157,6 +157,7 @@ src_libws2_32=libsrc/ws2_32.c \
 
 src_msvcrt_common=\
   misc/onexit_table.c \
+  misc/register_tls_atexit.c \
   stdio/acrt_iob_func.c
 
 src_msvcrt=\
diff --git a/mingw-w64-crt/misc/register_tls_atexit.c 
b/mingw-w64-crt/misc/register_tls_atexit.c
new file mode 100644
index 000..338cffd
--- /dev/null
+++ b/mingw-w64-crt/misc/register_tls_atexit.c
@@ -0,0 +1,29 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+static _tls_callback_type callback;
+
+static void run_callback(void)
+{
+  if (callback)
+callback(NULL, DLL_PROCESS_DETACH, 0);
+  callback = NULL;
+}
+
+int __cdecl _register_thread_local_exe_atexit_callback(_tls_callback_type cb)
+{
+  callback = cb;
+  // This should guarantee that the callback is called. It won't be run in the
+  // exact right spot as intended to, but it will be run.
+  atexit(run_callback);
+}
+
+typeof(_register_thread_local_exe_atexit_callback) 
*__MINGW_IMP_SYMBOL(_register_thread_local_exe_atexit_callback) = 
_register_thread_local_exe_atexit_callback;
diff --git a/mingw-w64-headers/crt/process.h b/mingw-w64-headers/crt/process.h
index b698685..5c38766 100644
--- a/mingw-w64-headers/crt/process.h
+++ b/mingw-w64-headers/crt/process.h
@@ -55,6 +55,9 @@ extern "C" {
 
 #endif /* _CRT_TERMINATE_DEFINED */
 
+  typedef void (__stdcall *_tls_callback_type)(void*,unsigned long,void*);
+  _CRTIMP int __cdecl 
_register_thread_local_exe_atexit_callback(_tls_callback_type callback);
+
   void __cdecl __MINGW_NOTHROW _cexit(void);
   void __cdecl __MINGW_NOTHROW _c_exit(void);
   _CRTIMP int __cdecl _getpid(void);
-- 
2.7.4


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Liu Hao
在 2018-08-02 14:58, Martin Storsjö 写道:
> Sorry for the double post, I accidentally dropped Liu from the CC of the 
> previous reply,
> 

It doesn't matter, as I have subscribed to this list, and my client 
(ThunderBird) filters out duplicate mails.

BTW, I have my name spelled in the surname-first order. People mistake 
my surname for given name so frequently, which I am quite accustomed to. :>


-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Martin Storsjö
Sorry for the double post, I accidentally dropped Liu from the CC of the 
previous reply,


On Thu, 2 Aug 2018, Martin Storsjö wrote:


On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018/8/2 13:56, Martin Storsjö 写道:
Yes, a responsible user would join all his threads before calling exit() 
or returning from main, there's no disagreement about that.


But the problematic case I'm thinking about is when you load and unload 
e.g. plugins, which may contain TLS objects. If more than one long 
running threads (which aren't stopped meanwhile) touch the plugin while 
it is loaded (with proper synchronization of course), you'll have leaks.


// Martin


I don't know how many people unload DLLs in practice. AFAIU once a DLL 
is loaded and a function from it is called, it is virtually impossible 
to eliminate the possibility of references of anything in that DLL, 
especially C++ RTTI, virtual functions, specialized function templates, 
etc. If people don't ever unload a DLL, thread local objects in that DLL 
will be considered reachable and therefore are not leaks.


VLC is the specific example I have in mind, which regularly loads and 
unloads DLL plugins. On unload, nothing in the remaining process should 
have any handle to anything sourced from this DLL. The plugins themselves 
only expose a C API although they internally can use C++.


VLC also has numerous threads running. I'm not sure if more than one 
thread actually will interact with each plugin though, and if that is the 
same as does the loading of the plugin, or if it might be a different one.


... which is the reason why I think this should be a reasonable behaviour.

But as MSVC's implementation of this doesn't call TLS destructors for 
other threads, I guess it's fine to just document this as the intended 
behaviour, and have VLC reconsider their use of TLS objects here (either 
it's all actually done on the same thread that unloads the DLL, or threads 
that touched it are joined before unloading it, or they shouldn't use it).


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Martin Storsjö wrote:


On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018/8/2 13:56, Martin Storsjö 写道:
Yes, a responsible user would join all his threads before calling exit() 
or returning from main, there's no disagreement about that.


But the problematic case I'm thinking about is when you load and unload 
e.g. plugins, which may contain TLS objects. If more than one long 
running threads (which aren't stopped meanwhile) touch the plugin while 
it is loaded (with proper synchronization of course), you'll have leaks.


// Martin


I don't know how many people unload DLLs in practice. AFAIU once a DLL 
is loaded and a function from it is called, it is virtually impossible 
to eliminate the possibility of references of anything in that DLL, 
especially C++ RTTI, virtual functions, specialized function templates, 
etc. If people don't ever unload a DLL, thread local objects in that DLL 
will be considered reachable and therefore are not leaks.


VLC is the specific example I have in mind, which regularly loads and 
unloads DLL plugins. On unload, nothing in the remaining process should 
have any handle to anything sourced from this DLL. The plugins themselves 
only expose a C API although they internally can use C++.


VLC also has numerous threads running. I'm not sure if more than one 
thread actually will interact with each plugin though, and if that is the 
same as does the loading of the plugin, or if it might be a different one.


... which is the reason why I think this should be a reasonable behaviour.

But as MSVC's implementation of this doesn't call TLS destructors for 
other threads, I guess it's fine to just document this as the intended 
behaviour, and have VLC reconsider their use of TLS objects here (either 
it's all actually done on the same thread that unloads the DLL, or threads 
that touched it are joined before unloading it, or they shouldn't use it).


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCH 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Liu Hao
在 2018/8/2 13:56, Martin Storsjö 写道:
> Yes, a responsible user would join all his threads before calling exit() 
> or returning from main, there's no disagreement about that.
> 
> But the problematic case I'm thinking about is when you load and unload 
> e.g. plugins, which may contain TLS objects. If more than one long 
> running threads (which aren't stopped meanwhile) touch the plugin while 
> it is loaded (with proper synchronization of course), you'll have leaks.
> 
> // Martin

I don't know how many people unload DLLs in practice. AFAIU once a DLL 
is loaded and a function from it is called, it is virtually impossible 
to eliminate the possibility of references of anything in that DLL, 
especially C++ RTTI, virtual functions, specialized function templates, 
etc. If people don't ever unload a DLL, thread local objects in that DLL 
will be considered reachable and therefore are not leaks.


-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public