Well, I've done what I can to diagnose this. It's up to the mingw devs from here.

dw

On 8/19/2014 1:04 PM, Vadim Chugunov wrote:
No, sorry, I don't have the setup to build mingw. Not likely that I will have time to do it any time soon either. I meant this as a bug report. I hope the problem has been investigated sufficiently for mingw devs to act on it.

Vadim



On Mon, Aug 18, 2014 at 9:34 PM, dw <limegreenso...@yahoo.com <mailto:limegreenso...@yahoo.com>> wrote:

    Did you ever get this sorted out?

    dw


    On 8/15/2014 10:53 PM, dw wrote:
    So, it looks like what has happened is that newer OSs (ie >=
    Vista) set the page protect to PAGE_EXECUTE_WRITECOPY when doing
    a LoadLibrary.  This is a (relatively) new flag and apparently
    Mingw still assumes the old values are always in use.

    There are 3 places in pseudo-reloc.c that do comparisons of
    b.Protect to PAGE_EXECUTE_READWRITE.  I believe all three should
    also check for PAGE_EXECUTE_WRITECOPY.

    It also looks like a minor perf improvement in __write_memory is
    possible by adding an #else for that VirtualQuery /
    VirtualProtect stuff:

    static void
    __write_memory (void *addr, const void *src, size_t len)
    {
      if (!len)
        return;

    #ifdef __MINGW64_VERSION_MAJOR

      /* Mark the section writable once, and unset it in
       * restore_modified_sections. */
      mark_section_writable ((LPVOID) addr);

    #else/* __MINGW64_VERSION_MAJOR */

      MEMORY_BASIC_INFORMATION b;
      DWORD oldprot = 0;
      int call_unprotect = 0;

      if (!VirtualQuery (addr, &b, sizeof(b)))
        {
          __report_error (" VirtualQuery failed for %d bytes at
    address %p",
                  (int) sizeof(b), addr);
        }

      /* Temporarily allow write access to read-only protected memory. */
      if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect !=
    PAGE_READWRITE && b.Protect != PAGE_EXECUTE_WRITECOPY)
        {
          call_unprotect = 1;
          VirtualProtect (b.BaseAddress, b.RegionSize,
    PAGE_EXECUTE_READWRITE,
                  &oldprot);
        }

    #endif /* __MINGW64_VERSION_MAJOR */

      /* write the data. */
      memcpy (addr, src, len);

    #ifndef __MINGW64_VERSION_MAJOR

      /* Restore original protection. */
      if (call_unprotect && b.Protect != PAGE_EXECUTE_READWRITE &&
    b.Protect != PAGE_READWRITE && b.Protect != PAGE_EXECUTE_WRITECOPY)
        VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot);

    #endif /* __MINGW64_VERSION_MAJOR */
    }

    If setting the protection in mark_section_writable was
    unsuccessful (unlikely as that is), trying to set it again here
    is not likely to help.

    NB: I haven't tried this, but you have the setup to test it
    anyway.  Also, this code snippet only fixes 2 of the 3 places
    that use PAGE_EXECUTE_WRITECOPY.  Remember to change the
    comparison in mark_section_writable() as well.

    FWIW,
    dw

    On 8/15/2014 8:17 PM, Vadim Chugunov wrote:
    Okay, I was wrong about __MINGW64_VERSION_MAJOR: it *was* defined.

    What apparently happens is that the VirtualQuery() call that
    follows mark_section_writable(), returns page protection status
    of 0x80 (PAGE_EXECUTE_WRITECOPY), which is unexpected by the
    relocator code, so it falls back to calling VirtualProtect() per
    relocation entry.

    I am not entirely sure how this situation comes about, but here
    you go...

    On Fri, Aug 15, 2014 at 1:01 AM, Vadim Chugunov
    <vadi...@gmail.com <mailto:vadi...@gmail.com>> wrote:

        Hi,
        I am trying to figure out the cause of a slow application
        startup, and the evidence I have so far, points to mingw's
        _pei386_runtime_relocator() routine as the culprit.   When I
        start my app under debugger, I see this function calling
        VirtualProtect() about a zillion times in a row.

        Looking at the source, I see that
        __pei386_runtime_relocator() is supposed to change memory
        protection just once per executable section, but only if
        __MINGW64_VERSION_MAJOR is defined at compilation time.
        Otherwise,  it reverts to changing protection once per
        relocation entry, for compatibility (?).
        Unfortunately, I don't see any headers included by
        pseudo-reloc.c that would define this symbol.  And, indeed,
        the behavior I am seeing at runtime indicates that if was
        not defined...

        Am I reading this right?

        Thanks!
        Vadim






------------------------------------------------------------------------------


_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to