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

--- Comment #19 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jan Beulich <jbeul...@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3cad19db4e6b72195b22be1f93c81a2b229e4c07

commit 3cad19db4e6b72195b22be1f93c81a2b229e4c07
Author: LIU Hao <lh_mo...@126.com>
Date:   Fri Jun 13 07:52:29 2025 +0200

    bfd,ld,dlltool: Emit delay-load import data into its own section

    A delay-import symbol (of a function) is resolved when a call to it is
made.
    The delay loader may overwrite the `__imp_` pointer to the actual function
    after it has been resolved, which requires the pointer itself be in a
    writeable section.

    Previously it was placed in the ordinary Import Address Table (IAT), which
    is emitted into the `.idata` section, which had been changed to read-only
    in db00f6c3aceabbf03acdb69e74b59b2d2b043cd7, which caused segmentation
    faults when functions from delay-import library were called.  This is
    PR 32675.

    This commit makes DLLTOOL emit delay-import IAT into `.didat`, as specified
    by Microsoft. Most of the code is copied from `.idata`, except that this
    section is writeable.  As a side-effect of this, PR 14339 is also fixed.

    Using this DEF:

       ```
       ; ws2_32.def
       LIBRARY "WS2_32.DLL"
       EXPORTS
         WSAGetLastError
       ```

    and this C program:

       ```
       // delay.c
       #define WIN32_LEAN_AND_MEAN 1
       #include <windows.h>
       #include <stdio.h>

       /////////////////////////////////////////////////////////
       // User code
       /////////////////////////////////////////////////////////

       DWORD WINAPI WSAGetLastError(void);
       extern PVOID __imp_WSAGetLastError;

       int
       main(void)
         {
           fprintf(stderr, "before delay load, __imp_WSAGetLastError = %p\n",
__imp_WSAGetLastError);
           SetLastError(123);
           fprintf(stderr, "WSAGetLastError() = %d\n", WSAGetLastError());
           fprintf(stderr, "after delay load, __imp_WSAGetLastError = %p\n",
__imp_WSAGetLastError);
           __imp_WSAGetLastError = (PVOID) 1234567;
           fprintf(stderr, "after plain write, __imp_WSAGetLastError = %p\n",
__imp_WSAGetLastError);
         }

       /////////////////////////////////////////////////////////
       // Overridden `__delayLoadHelper2` facility
       /////////////////////////////////////////////////////////

       extern char __ImageBase[];
       PVOID WINAPI ResolveDelayLoadedAPI(PVOID ParentModuleBase, LPCVOID
DelayloadDescriptor,
                                          PVOID FailureDllHook, PVOID
FailureSystemHook,
                                          FARPROC* ThunkAddress, ULONG Flags);
       FARPROC WINAPI DelayLoadFailureHook(LPCSTR name, LPCSTR function);

       FARPROC WINAPI __delayLoadHelper2(LPCVOID pidd, FARPROC* ppfnIATEntry)
       {
         return ResolveDelayLoadedAPI(&__ImageBase, pidd, NULL, (PVOID)
DelayLoadFailureHook,
                                      ppfnIATEntry, 0);
       }
       ```

    This program used to crash:

       ```
       $ dlltool -nn -d ws2_32.def -y delay_ws2_32.a
       $ gcc -g delay.c delay_ws2_32.a -o delay.exe
       $ ./delay.exe
       before delay load, __imp_WSAGetLastError = 00007FF6937215C6
       Segmentation fault
       ```

    After this commit, it loads and calls `WSAGetLastError()` properly, and
    `__imp_WSAGetLastError` is writeable:

       ```
       $ dlltool -nn -d ws2_32.def -y delay_ws2_32.a
       $ gcc -g delay.c delay_ws2_32.a -o delay.exe
       $ ./delay.exe
       before delay load, __imp_WSAGetLastError = 00007FF76E2215C6
       WSAGetLastError() = 123
       after delay load, __imp_WSAGetLastError = 00007FFF191FA720
       after plain write, __imp_WSAGetLastError = 000000000012D687
       ```

    Reference:
https://learn.microsoft.com/en-us/windows/win32/secbp/pe-metadata#import-handling
    Co-authored-by: Jeremy Drake <sourceware-bugzi...@jdrake.com>
    Signed-off-by: LIU Hao <lh_mo...@126.com>
    Signed-off-by: Jeremy Drake <sourceware-bugzi...@jdrake.com>

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

Reply via email to