xref: /openbsd/gnu/usr.bin/perl/vms/gen_shrfls.pl (revision e0680481)
1# Create global symbol declarations, transfer vector, and
2# linker options files for PerlShr.
3#
4# Processes the output of makedef.pl.
5#
6# Input:
7#    $cc_cmd - compiler command
8#    $objsuffix - file type (including '.') used for object files.
9#    $libperl - Perl object library.
10#    $extnames - package names for static extensions (used to generate
11#        linker options file entries for boot functions)
12#    $rtlopt - name of options file specifying RTLs to which PerlShr.Exe
13#        must be linked
14#
15# Output:
16#    PerlShr_Attr.Opt - linker options file which specifies that global vars
17#        be placed in NOSHR,WRT psects.  Use when linking any object files
18#        against PerlShr.Exe, since cc places global vars in SHR,WRT psects
19#        by default.
20#    PerlShr_Bld.Opt - declares universal symbols for PerlShr.Exe
21#
22# To do:
23#   - figure out a good way to collect global vars in one psect, given that
24#     we can't use globaldef because of gcc.
25#   - then, check for existing files and preserve symbol and transfer vector
26#     order for upward compatibility
27#   - then, add GSMATCH to options file - but how do we insure that new
28#     library has everything old one did
29#     (i.e. /Define=DEBUGGING,EMBED,MULTIPLICITY)?
30#
31# Author: Charles Bailey  bailey@newman.upenn.edu
32
33use strict;
34require 5.000;
35
36my $debug = $ENV{'GEN_SHRFLS_DEBUG'};
37
38print "gen_shrfls.pl Rev. 8-Jul-2011\n" if $debug;
39
40if ($ARGV[0] eq '-f') {
41  open(INP,'<',$ARGV[1]) or die "Can't read input file $ARGV[1]: $!\n";
42  print "Input taken from file $ARGV[1]\n" if $debug;
43  @ARGV = ();
44  while (<INP>) {
45    chomp;
46    push(@ARGV,split(/\|/,$_));
47  }
48  close INP;
49  print "Read input data | ",join(' | ',@ARGV)," |\n" if $debug > 1;
50}
51
52my $cc_cmd = shift @ARGV; # no longer used to run the preprocessor
53
54print "Input \$cc_cmd: \\$cc_cmd\\\n" if $debug;
55my $docc = ($cc_cmd !~ /^~~/);
56print "\$docc = $docc\n" if $debug;
57
58my ( $use_threads, $use_mymalloc, $care_about_case, $shorten_symbols,
59     $debugging_enabled, $hide_mymalloc, $use_perlio, $dir )
60   = ( 0, 0, 0, 0, 0, 0, 0 );
61
62if (-f 'perl.h') { $dir = '[]'; }
63elsif (-f '[-]perl.h') { $dir = '[-]'; }
64else { die "$0: Can't find perl.h\n"; }
65
66# Go see what is enabled in config.sh
67my $config = $dir . "config.sh";
68open CONFIG, '<', $config;
69while(<CONFIG>) {
70    $use_threads++ if /usethreads='(define|yes|true|t|y|1)'/i;
71    $use_mymalloc++ if /usemymalloc='(define|yes|true|t|y|1)'/i;
72    $care_about_case++ if /d_vms_case_sensitive_symbols='(define|yes|true|t|y|1)'/i;
73    $shorten_symbols++ if /d_vms_shorten_long_symbols='(define|yes|true|t|y|1)'/i;
74    $debugging_enabled++ if /usedebugging_perl='(define|yes|true|t|y|1)'/i;
75    $hide_mymalloc++ if /embedmymalloc='(define|yes|true|t|y|1)'/i;
76    $use_perlio++ if /useperlio='(define|yes|true|t|y|1)'/i;
77}
78close CONFIG;
79
80# put quotes back onto defines - they were removed by DCL on the way in
81if (my ($prefix,$defines,$suffix) =
82         ($cc_cmd =~ m#(.*)/Define=(.*?)([/\s].*)#i)) {
83  $defines =~ s/^\((.*)\)$/$1/;
84  $debugging_enabled ||= $defines =~ /\bDEBUGGING\b/;
85  my @defines = split(/,/,$defines);
86  $cc_cmd = "$prefix/Define=(" . join(',',grep($_ = "\"$_\"",@defines))
87              . ')' . $suffix;
88}
89print "Filtered \$cc_cmd: \\$cc_cmd\\\n" if $debug;
90
91print "\$debugging_enabled: $debugging_enabled\n" if $debug;
92
93my $objsuffix = shift @ARGV;
94print "\$objsuffix: \\$objsuffix\\\n" if $debug;
95my $dbgprefix = shift @ARGV;
96print "\$dbgprefix: \\$dbgprefix\\\n" if $debug;
97my $olbsuffix = shift @ARGV;
98print "\$olbsuffix: \\$olbsuffix\\\n" if $debug;
99my $libperl = "${dbgprefix}libperl$olbsuffix";
100my $extnames = shift @ARGV;
101print "\$extnames: \\$extnames\\\n" if $debug;
102my $rtlopt = shift @ARGV;
103print "\$rtlopt: \\$rtlopt\\\n" if $debug;
104
105my (%vars, %fcns);
106
107open my $makedefs, '<', $dir . 'makedef.lis' or die "Unable to open makedef.lis: $!";
108
109while (my $line = <$makedefs>) {
110  chomp $line;
111  $line = shorten_symbol($line, $care_about_case) if $shorten_symbols;
112  # makedef.pl loses distinction between vars and funcs, so
113  # use the start of the name to guess and add specific
114  # exceptions when we know about them.
115  if ($line =~ m/^(PL_|MallocCfg)/
116      || $line eq 'PerlIO_perlio'
117      || $line eq 'PerlIO_pending') {
118    $vars{$line}++;
119  }
120  else {
121    $fcns{$line}++;
122  }
123}
124
125foreach (split /\s+/, $extnames) {
126  my($pkgname) = $_;
127  $pkgname =~ s/::/__/g;
128  $fcns{"boot_$pkgname"}++;
129  print "Adding boot_$pkgname to \%fcns (for extension $_)\n" if $debug;
130}
131
132# Eventually, we'll check against existing copies here, so we can add new
133# symbols to an existing options file in an upwardly-compatible manner.
134
135my $marord = 1;
136open(OPTBLD,'>', "${dir}${dbgprefix}perlshr_bld.opt")
137  or die "$0: Can't write to ${dir}${dbgprefix}perlshr_bld.opt: $!\n";
138
139
140print OPTBLD "PSECT_ATTR=LIB\$INITIALIZE,GBL,NOEXE,NOWRT,NOSHR,LONG\n";
141print OPTBLD "case_sensitive=yes\n" if $care_about_case;
142my $count = 0;
143foreach my $var (sort (keys %vars)) {
144  print OPTBLD "SYMBOL_VECTOR=($var=DATA)\n";
145}
146
147foreach my $func (sort keys %fcns) {
148  print OPTBLD "SYMBOL_VECTOR=($func=PROCEDURE)\n";
149}
150
151open(OPTATTR, '>', "${dir}perlshr_attr.opt")
152  or die "$0: Can't write to ${dir}perlshr_attr.opt: $!\n";
153
154print OPTATTR "! No additional linker directives are needed when using DECC\n";
155close OPTATTR;
156
157my $incstr = 'perl,globals';
158my (@symfiles, $drvrname);
159
160# Initial hack to permit building of compatible shareable images for a
161# given version of Perl.
162if ($ENV{PERLSHR_USE_GSMATCH}) {
163  if ($ENV{PERLSHR_USE_GSMATCH} eq 'INCLUDE_COMPILE_OPTIONS') {
164    # Build up a major ID. Since on Alpha it can only be 8 bits, we encode
165    # the version number in the top 6 bits and use the bottom 2 for build
166    # options most likely to cause incompatibilities.  Breaks at Perl 5.64.
167    my ($ver, $sub) = $] =~ /\.(\d\d\d)(\d\d\d)/;
168    $ver += 0; $sub += 0;
169    my $gsmatch = ($ver % 2 == 1) ? "EQUAL" : "LEQUAL"; # Force an equal match for
170						  # dev, but be more forgiving
171						  # for releases
172
173    $ver <<= 2;
174    $ver += 1 if $debugging_enabled;	# If DEBUGGING is set
175    $ver += 2 if $use_threads;		# if we're threaded
176    print OPTBLD "GSMATCH=$gsmatch,$ver,$sub\n";
177  }
178  else {
179    my $major = int($] * 1000)                        & 0xFF;  # range 0..255
180    my $minor = int(($] * 1000 - $major) * 100 + 0.5) & 0xFF;  # range 0..255
181    print OPTBLD "GSMATCH=LEQUAL,$major,$minor\n";
182  }
183}
184elsif (@symfiles) { $incstr .= ',' . join(',',@symfiles); }
185# Include object modules and RTLs in options file
186# Linker wants /Include and /Library on different lines
187print OPTBLD "$libperl/Include=($incstr)\n";
188print OPTBLD "$libperl/Library\n";
189open(RTLOPT,'<',$rtlopt) or die "$0: Can't read options file $rtlopt: $!\n";
190while (<RTLOPT>) { print OPTBLD; }
191close RTLOPT;
192close OPTBLD;
193
194
195# Symbol shortening Copyright (c) 2012 Craig A. Berry
196#
197# Released under the same terms as Perl itself.
198#
199# This code provides shortening of long symbols (> 31 characters) using the
200# same mechanism as the OpenVMS C compiler.  The basic procedure is to compute
201# an AUTODIN II checksum of the entire symbol, encode the checksum in base32,
202# and glue together a shortened symbol from the first 23 characters of the
203# original symbol plus the encoded checksum appended.  The output format is
204# the same used in the name mangler database, stored by default in
205# [.CXX_REPOSITORY]CXX$DEMANGLER_DB.
206
207sub crc32 {
208    use constant autodin_ii_table => [
209        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
210        0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
211        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
212        0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
213        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
214        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
215        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
216        0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
217        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
218        0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
219        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
220        0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
221        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
222        0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
223        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
224        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
225        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
226        0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
227        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
228        0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
229        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
230        0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
231        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
232        0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
233        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
234        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
235        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
236        0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
237        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
238        0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
239        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
240        0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
241        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
242        0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
243        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
244        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
245        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
246        0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
247        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
248        0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
249        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
250        0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
251        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
252    ];
253
254    my $input_string = shift;
255    my $crc = 0xFFFFFFFF;
256
257    for my $byte (unpack 'C*', $input_string) {
258        $crc = ($crc >> 8) ^ autodin_ii_table->[($crc ^ $byte) & 0xff];
259    }
260    return ~$crc;
261}
262
263sub base32 {
264    my $input = shift;
265    my $output = '';
266    use constant base32hex_table => [
267        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
268        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
269        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
270        'u', 'v'
271    ];
272
273    # Grab lowest 5 bits and look up conversion in table.  Lather, rinse,
274    # repeat for a total of 7, 5-bit chunks to accommodate 32 bits of input.
275
276    for (0..6) {
277        $output  = base32hex_table->[$input & 0x1f] . $output;
278        $input >>= 5;     # position to look at next 5
279    }
280    $output .= '$';       #  It's DEC, so use '$' not '=' to pad.
281
282    return $output;
283}
284
285sub shorten_symbol {
286    my $input_symbol = shift;
287    my $as_is_flag = shift;
288    my $symbol = $input_symbol;
289
290    return $symbol unless length($input_symbol) > 31;
291
292    $symbol = uc($symbol) unless $as_is_flag;
293    my $crc = crc32($symbol);
294    $crc = ~$crc;  # Compiler uses non-inverted form.
295    my $b32 = base32($crc);
296    $b32 = uc($b32) unless $as_is_flag;
297
298    return substr($symbol, 0, 23) . $b32;
299}
300
301__END__
302
303