summaryrefslogtreecommitdiff
path: root/makedef.pl
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2015-01-19 17:30:04 -0500
committerSteve Hay <steve.m.hay@googlemail.com>2015-01-25 14:00:19 +0000
commit196f7c461ba850055201ff924cdf91c397a77bc7 (patch)
tree576c2412edfd22bcd93b75fe5159937f33f0c915 /makedef.pl
parent47b62f63607d1af76ce720886fdaffbf5aab33c5 (diff)
downloadperl-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.pl64
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";