Skip to content

Commit

Permalink
fix win32 with Ming.org GCC 3.4.5 build
Browse files Browse the repository at this point in the history
dlltool 2.20.51.20100123 from Strawberry 5.12 and
dlltool 2.17.50 20060824 from Strawberry 5.8.9 were making a libperl527.a
that caused perl.exe and all XS DLLs to import "perl527.exp.dll" while
the disk file is called perl527.dll.

This bug was eventually fixed, since in my testing dlltool 2.25 no date
code, Copyright 2014 from Strawberry 5.22.1 doesn't have this problem. I
suspect the bug was fixed in binutils commit 04276a0cf5
"2010-12-01 Kai Tietz <kai.tietz@onevision.com>"
https://sourceware.org/bugzilla/show_bug.cgi?id=11065
in version "AM_INIT_AUTOMAKE(bfd, 2.21.51)" or 1 ver bump higher. Just
always pass an explicit DLL name to dlltool instead of any kind of
dlltool version checking at build time and then optional arg.

The breakage for Mingw.org 3.4.5 was introduced in
commit bf543ea "add parallelness to win32/GNUmakefile" where I added
parallelness by making the import lib .a file from just perldll.def,
rather than the import lib being a build product coming out of g++
linking perl527.dll. The old serial build recipie passed --dllname
to dlltool, my newer code didn't.

Passing $(PERLDLL) to dlltool's -D causes this harmless but scary warning

"dlltool: Path components stripped from dllname, '..\perl527.dll'."

So create PERLDLLBASE to silence the warning.

win32.h: In old GCCs,
https://sourceforge.net/p/mingw/mailman/message/22184185/ a function marked
declspec(dllimport) is not a constant. VC from day 1, and newer GCCs use
the address of a 1 instruction jump stub function if a constant function
pointer is needed to a function from a DLL that wont be known till runtime.
This can be worked around in older GCCs by deoptimizing them to always
use the jump stub for all references, and not the newer GCC and VC way
where x86 call instructions directly read the import table in the caller,
while constant functions ptrs in data or vars always refer to the jump
stubs. Since these are old GCCs, performance isn't the highest priority
and building at all is a more important goal. I suspect gcc 3.4.5 has
been broken since 5.13.6 when the declspec(dllimport) code was added.
  • Loading branch information
bulk88 authored and rurban committed Jun 16, 2018
1 parent 7d27dea commit e0ac454
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .git-rr-cache
Submodule .git-rr-cache updated 39 files
+22,988 −0 11deaff2ee7a8a61acdca24d811104384cf68312/postimage
+22,993 −0 11deaff2ee7a8a61acdca24d811104384cf68312/preimage
+2,283 −0 17b17197f27c6466077de394e1b8be32843d3ca7/preimage
+2,283 −0 17b17197f27c6466077de394e1b8be32843d3ca7/preimage.1
+2,283 −0 17b17197f27c6466077de394e1b8be32843d3ca7/preimage.2
+5,566 −0 2825a8162fef6b65d7942b1240871528dd0ae7df/postimage
+5,570 −0 2825a8162fef6b65d7942b1240871528dd0ae7df/preimage
+4,808 −0 3a55b917f7561d0a96073dc79948ad8086ecb458/postimage
+4,999 −0 3a55b917f7561d0a96073dc79948ad8086ecb458/preimage
+4,999 −0 3a55b917f7561d0a96073dc79948ad8086ecb458/thisimage
+954 −0 4173bda6ed3e61d26480f028d0508c330d39b29d/postimage
+959 −0 4173bda6ed3e61d26480f028d0508c330d39b29d/preimage
+3,042 −0 6f7c57ef9a27e898d3e6d2967a6b9342719165bc/postimage
+3,048 −0 6f7c57ef9a27e898d3e6d2967a6b9342719165bc/preimage
+357 −0 701800e0ddbf1dacfd56e003bc6abd4dd4dd9ff1/postimage
+361 −0 701800e0ddbf1dacfd56e003bc6abd4dd4dd9ff1/preimage
+361 −0 701800e0ddbf1dacfd56e003bc6abd4dd4dd9ff1/thisimage
+7,439 −0 7577839d7de5bf50994a375cb3ddb22f2cdcf1f2/postimage
+7,508 −0 7577839d7de5bf50994a375cb3ddb22f2cdcf1f2/preimage
+2,236 −0 b5258c121827e03e82c379470de520f43d59b6ce/postimage
+2,332 −0 b5258c121827e03e82c379470de520f43d59b6ce/preimage
+2,332 −0 b5258c121827e03e82c379470de520f43d59b6ce/thisimage
+7,541 −0 bdfeef6b2b4f571dde935d458d6c7c4d0dde30d5/postimage
+7,565 −0 bdfeef6b2b4f571dde935d458d6c7c4d0dde30d5/preimage
+7,173 −0 ca4654228e62511ff9c0140c2678c219d1d98d14/postimage
+7,179 −0 ca4654228e62511ff9c0140c2678c219d1d98d14/preimage
+547 −0 ca5ef9799cae9fc3f738d94308a87d9d8867df4a/postimage
+553 −0 ca5ef9799cae9fc3f738d94308a87d9d8867df4a/preimage
+849 −0 ef50d793b5ce55f5c02dafb6f5939e535bd3759e/postimage
+852 −0 ef50d793b5ce55f5c02dafb6f5939e535bd3759e/preimage
+852 −0 ef50d793b5ce55f5c02dafb6f5939e535bd3759e/thisimage
+21,555 −0 f607ba91133214db0470b4ff73e2cd220ef5023f/postimage
+21,558 −0 f607ba91133214db0470b4ff73e2cd220ef5023f/preimage
+10,308 −0 f771add1e2b316add508c02f1ed60b38d97cf434/postimage
+10,321 −0 f771add1e2b316add508c02f1ed60b38d97cf434/preimage
+23,756 −0 fd631a264b5552ee7cadc9167784895685f9a9e5/postimage
+23,762 −0 fd631a264b5552ee7cadc9167784895685f9a9e5/preimage
+5,409 −0 ffc3d075be2115381c8f507fa1a09c98cdf25735/postimage
+5,414 −0 ffc3d075be2115381c8f507fa1a09c98cdf25735/preimage
3 changes: 2 additions & 1 deletion win32/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ PERLIMPLIBBASE ?= cperl$(a)
PERLEXPLIB ?= $(COREDIR)\cperl$(PV).exp
PERLSTATICLIB ?= ..\cperl$(PV)s$(a)
PERLDLL = ..\cperl$(PV).dll
PERLDLLBASE = cperl$(PV).dll

# don't let "gmake -n all" try to run "miniperl.exe make_ext.pl"
PLMAKE = gmake
Expand Down Expand Up @@ -1500,7 +1501,7 @@ $(PERLEXPLIB) : $(PERLIMPLIB)

$(PERLIMPLIB) : perldll.def
ifeq ($(CCTYPE),GCC)
$(IMPLIB) -k -d perldll.def -l $(PERLIMPLIB) -e $(PERLEXPLIB)
$(IMPLIB) -k -d perldll.def -D $(PERLDLLBASE) -l $(PERLIMPLIB) -e $(PERLEXPLIB)
else
lib -def:perldll.def -machine:$(ARCHITECTURE) /OUT:$(PERLIMPLIB)
endif
Expand Down
3 changes: 2 additions & 1 deletion win32/makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,7 @@ PERLIMPLIB *= $(COREDIR)\cperl$(a)
PERLEXPLIB *= $(COREDIR)\cperl.exp
PERLSTATICLIB *= ..\cperl$(PV)s$(a)
PERLDLL = ..\cperl$(PV).dll
PERLDLLBASE = cperl$(PV).dll

#EUMM on Win32 isn't ready for parallel make, so only allow this file to be parallel
#$(MAKE) will contain the -P that this makefile was called with, which is bad for
Expand Down Expand Up @@ -1446,7 +1447,7 @@ perldll.def : $(HAVEMINIPERL) $(CONFIGPM) ..\embed.fnc ..\makedef.pl

$(PERLEXPLIB) $(PERLIMPLIB) .UPDATEALL : perldll.def
.IF "$(CCTYPE)" == "GCC"
$(IMPLIB) -k -d perldll.def -l $(PERLIMPLIB) -e $(PERLEXPLIB)
$(IMPLIB) -k -d perldll.def -D $(PERLDLLBASE) -l $(PERLIMPLIB) -e $(PERLEXPLIB)
.ELSE #VC family
lib -def:perldll.def -machine:$(ARCHITECTURE) /OUT:$(PERLIMPLIB)
.ENDIF
Expand Down
42 changes: 30 additions & 12 deletions win32/win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,41 @@
* The XS code in the re extension is special, in that it redefines
* core APIs locally, so don't mark them as "dllimport" because GCC
* cannot handle this situation.
* Certain old GCCs will not allow the function pointer of dllimport marked
* function to be "const". This was fixed later on. Since this is a
* deoptimization, target "gcc version 3.4.5 (mingw-vista special r3)" only,
* The GCC bug was fixed in GCC patch "varasm.c (initializer_constant_valid_p):
* Don't deny DECL_DLLIMPORT_P on functions", which probably was first released
* in GCC 4.3.0, this #if can be expanded upto but not including 4.3.0 if more
* deployed GCC are found that wont build with the follow error, initializer
* element is a PerlIO func exported from perl5xx.dll.
*
* encoding.xs:610: error: initializer element is not constant
* encoding.xs:610: error: (near initialization for `PerlIO_encode.Open')
*/
#if !defined(PERLDLL) && !defined(PERL_EXT_RE_BUILD)
# ifdef __cplusplus
# define PERL_CALLCONV extern "C" __declspec(dllimport)
# ifdef _MSC_VER
# define PERL_CALLCONV_NO_RET extern "C" __declspec(dllimport) __declspec(noreturn)

#if (defined(__GNUC__) && defined(__MINGW32__) && \
!defined(__MINGW64_VERSION_MAJOR) && !defined(__clang__) && \
((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 5))))
/* use default fallbacks from perl.h for this particular GCC */
#else
# if !defined(PERLDLL) && !defined(PERL_EXT_RE_BUILD)
# ifdef __cplusplus
# define PERL_CALLCONV extern "C" __declspec(dllimport)
# ifdef _MSC_VER
# define PERL_CALLCONV_NO_RET extern "C" __declspec(dllimport) __declspec(noreturn)
# endif
# else
# define PERL_CALLCONV __declspec(dllimport)
# ifdef _MSC_VER
# define PERL_CALLCONV_NO_RET __declspec(dllimport) __declspec(noreturn)
# endif
# endif
# else
# define PERL_CALLCONV __declspec(dllimport)
# else /* MSVC noreturn support inside the interp */
# ifdef _MSC_VER
# define PERL_CALLCONV_NO_RET __declspec(dllimport) __declspec(noreturn)
# define PERL_CALLCONV_NO_RET __declspec(noreturn)
# endif
# endif
#else /* MSVC noreturn support inside the interp */
# ifdef _MSC_VER
# define PERL_CALLCONV_NO_RET __declspec(noreturn)
# endif
#endif

#ifdef _MSC_VER
Expand Down

0 comments on commit e0ac454

Please sign in to comment.