On Thu, 2 Aug 2018, Liu Hao wrote:

在 2018-08-02 19:02, Martin Storsjö 写道:
Signed-off-by: Martin Storsjö <mar...@martin.st>
---
  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.99999"), __used__ , aligned(sizeof(void *)))) const void * __CTOR_END__ = (void *) 0; __attribute__ (( __section__ (".dtors.99999"), __used__ , aligned(sizeof(void *)))) const void * __DTOR_END__ = (void *) 0;
-#endif

Does GNU LD recognize the `.99999` suffix?

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

   .ctors$aaaa
   .ctors$foo
   .ctors$zzzz

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.00001,"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 00000-65535, the sentinel at 99999 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

Reply via email to