diff options
author | Daniel Dragan <bulk88@hotmail.com> | 2015-01-19 17:30:04 -0500 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2015-01-25 14:00:19 +0000 |
commit | 196f7c461ba850055201ff924cdf91c397a77bc7 (patch) | |
tree | 576c2412edfd22bcd93b75fe5159937f33f0c915 /makedef.pl | |
parent | 47b62f63607d1af76ce720886fdaffbf5aab33c5 (diff) | |
download | perl-196f7c461ba850055201ff924cdf91c397a77bc7.tar.gz |
export data symbols as data on Win32
Previously on Win32 Perl, all the PL_* data symbols were treated as
function symbols with expectation of machine code at their targets when
generating the linking library perl5**.lib or perl5**.a. In VC Perl, if an
DLL XS module accidentally (by manipulating the defines before #including
perls headers) turned "extern __declspec(dllimport) I32 *PL_markstack_ptr;"
into "extern I32 *PL_markstack_ptr;", a SEGV would result as if the XS
module executed "I32 ax = (*(I32*)Perl_sv_2mortal)--;". By marking the
symbols as data in the linking lib, the VC linker will error out while
creating a XS DLL where this mistake of dropping out __declspec(dllimport)
happened, instead of a runtime crash. Mingw GCC linker does the correct
behavior, and does not treat the data symbol as machine code even if
"__declspec(dllimport)" is removed. Still add DATA to the GCC perldll.def
to be sure. There is no reason for "jmp" machine codestubs/thunks to
exist in the perl.lib/perl.a to a data export.
Also add constant folding to the loop in makedef.pl, since every other
platform check executes exactly once, there is no point of executing the
ops in the perl compile time constant folder vs runtime executing them.
If a data symbol name exceeds the 32 limit, then "DATA" will be catted onto
the symbol name and linking lib generation will fail since the symbol wont
exist. The 32 limit will then be increased at that point in the future.
See details about this patch in [perl #123626]
Diffstat (limited to 'makedef.pl')
-rw-r--r-- | makedef.pl | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/makedef.pl b/makedef.pl index 0bc3862f67..2b5ca80c53 100644 --- a/makedef.pl +++ b/makedef.pl @@ -32,36 +32,33 @@ # perl.imp NetWare # makedef.lis VMS -BEGIN { unshift @INC, "lib" } -use Config; -use strict; - -my %ARGS = (CCTYPE => 'MSVC', TARG_DIR => ''); - +my $fold; +my %ARGS; my %define; -my $fold; +BEGIN { + BEGIN { unshift @INC, "lib" } + use Config; + use strict; -sub process_cc_flags { - foreach (map {split /\s+/, $_} @_) { - $define{$1} = $2 // 1 if /^-D(\w+)(?:=(.+))?/; - } -} + %ARGS = (CCTYPE => 'MSVC', TARG_DIR => ''); -while (@ARGV) { - my $flag = shift; - if ($flag =~ /^(?:CC_FLAGS=)?(-D\w.*)/) { - process_cc_flags($1); - } elsif ($flag =~ /^(CCTYPE|FILETYPE|PLATFORM|TARG_DIR)=(.+)$/) { - $ARGS{$1} = $2; - } elsif ($flag eq '--sort-fold') { - ++$fold; + sub process_cc_flags { + foreach (map {split /\s+/, $_} @_) { + $define{$1} = $2 // 1 if /^-D(\w+)(?:=(.+))?/; + } } -} -require "$ARGS{TARG_DIR}regen/embed_lib.pl"; - -{ + while (@ARGV) { + my $flag = shift; + if ($flag =~ /^(?:CC_FLAGS=)?(-D\w.*)/) { + process_cc_flags($1); + } elsif ($flag =~ /^(CCTYPE|FILETYPE|PLATFORM|TARG_DIR)=(.+)$/) { + $ARGS{$1} = $2; + } elsif ($flag eq '--sort-fold') { + ++$fold; + } + } my @PLATFORM = qw(aix win32 wince os2 netware vms test); my %PLATFORM; @PLATFORM{@PLATFORM} = (); @@ -71,6 +68,9 @@ require "$ARGS{TARG_DIR}regen/embed_lib.pl"; die "PLATFORM must be one of: @PLATFORM\n" unless exists $PLATFORM{$ARGS{PLATFORM}}; } +use constant PLATFORM => $ARGS{PLATFORM}; + +require "$ARGS{TARG_DIR}regen/embed_lib.pl"; # Is the following guard strictly necessary? Added during refactoring # to keep the same behaviour when merging other code into here. @@ -1301,10 +1301,18 @@ elsif ($ARGS{PLATFORM} eq 'netware') { my @symbols = $fold ? sort {lc $a cmp lc $b} keys %export : sort keys %export; foreach my $symbol (@symbols) { - if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) { - print "\t$symbol\n"; + if (PLATFORM eq 'win32' || PLATFORM eq 'wince') { + #remembering the origin file of each symbol is an alternative to PL_ matching + if(substr($symbol, 0, 3) eq 'PL_') { + #PL_utf8_charname_continue @ 25 seems to be the longest symbol + #pick 32 for visual alignment, plus 32 is 8/tab aligned + print "\t$symbol".' 'x(32 - length $symbol )."DATA\n"; + } + else { + print "\t$symbol\n"; + } } - elsif ($ARGS{PLATFORM} eq 'os2') { + elsif (PLATFORM eq 'os2') { printf qq( %-31s \@%s\n), qq("$symbol"), $ordinal{$symbol} || ++$sym_ord; printf qq( %-31s \@%s\n), @@ -1312,7 +1320,7 @@ foreach my $symbol (@symbols) { $ordinal{$exportperlmalloc{$symbol}} || ++$sym_ord if $exportperlmalloc and exists $exportperlmalloc{$symbol}; } - elsif ($ARGS{PLATFORM} eq 'netware') { + elsif (PLATFORM eq 'netware') { print "\t$symbol,\n"; } else { print "$symbol\n"; |