This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix VC perlglob.exe segv with wrong default libc
authorDaniel Dragan <bulk88@hotmail.com>
Mon, 17 Feb 2020 01:57:46 +0000 (20:57 -0500)
committerTony Cook <tony@develop-help.com>
Mon, 24 Feb 2020 05:05:02 +0000 (16:05 +1100)
commit34667d08d3bf4da83ed39a692fb83467dc30a4a6
treeb3335b67a1534711f61b7e8c976e9e76e755d8ba
parent7b2e3959a40934433b74c1f3c6e7882a538e508b
fix VC perlglob.exe segv with wrong default libc

commit "win32: separate $Config{ccflags} and $Config{optimize}"
4be1bfd74 removed -Md and -MDd from $(OPTIMIZE), so perlglob.exe whose
build recipe is special in that it is compiled and linked in 1 step lost
the -Md flag, this causes "stdout" global var that is linked in from MSVC
libc to resolve to a broken symbol and segv since the FILE * is a pointer
to machine code instead to a FILE struct in the CRT DLL. This is with MSVC
2003 32b CC.

Disassembly shows that after that commit perlglob.exe is
push    8000h
mov     edi, offset __imp____getmainargs
push    edi             ; File
call    _fileno_0

which is a pointer to machine code instead of

mov     eax, ds:__imp___iob
add     eax, 20h
push    8000h           ; int
push    eax             ; File
call    ds:__imp___fileno

where _iob is a pointer to start of static global array of FH structs in
MS CRT.

-Md controls ".drectve" section in .obj file that contains
"/DEFAULTLIB:"MSVCRT"" (proper) or "/DEFAULTLIB:"LIBC"" (SEGV)

crash stack
ntdll.dll!_RtlpWaitForCriticalSection@4
ntdll.dll!_RtlEnterCriticalSection@4
msvcr71.dll!_lock_file
msvcr71.dll!fwrite
perlglob.exe!main
perlglob.exe!mainCRTStartup
kernel32.dll!_BaseProcessStart@4

The CS struct is gibberish because the FILE * is gibberish.
win32/GNUmakefile
win32/makefile.mk
win32/perlglob.c