123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #!/usr/bin/env perl
- #
- # For Microsoft CL this is implemented as inline assembler. So that
- # even though this script can generate even Win32 code, we'll be
- # using it primarily to generate Win64 modules. Both IA-64 and AMD64
- # are supported...
- # pull APPLINK_MAX value from applink.c...
- $applink_c=$0;
- $applink_c=~s|[^/\\]+$||g;
- $applink_c.="applink.c";
- open(INPUT,$applink_c) || die "can't open $applink_c: $!";
- @max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
- close(INPUT);
- ($#max==0) or die "can't find APPLINK_MAX in $applink_c";
- $max[0]=~/APPLINK_MAX\s+(\d+)/;
- $N=$1; # number of entries in OPENSSL_UplinkTable not including
- # OPENSSL_UplinkTable[0], which contains this value...
- # Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
- # which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
- # and then dereference themselves. Latter shall result in endless
- # loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
- # something else, e.g. as 'table[index]=unimplemented;'...
- $arg = shift;
- #( defined shift || open STDOUT,">$arg" ) || die "can't open $arg: $!";
- if ($arg =~ /win32n/) { ia32nasm(); }
- elsif ($arg =~ /win32/) { ia32masm(); }
- elsif ($arg =~ /coff/) { ia32gas(); }
- elsif ($arg =~ /win64i/ or $arg =~ /ia64/) { ia64ias(); }
- elsif ($arg =~ /win64a/ or $arg =~ /amd64/) { amd64masm(); }
- else { die "nonsense $arg"; }
- sub ia32gas() {
- print <<___;
- .text
- ___
- for ($i=1;$i<=$N;$i++) {
- print <<___;
- .def .Lazy$i; .scl 3; .type 32; .endef
- .align 4
- .Lazy$i:
- pushl \$$i
- pushl \$_OPENSSL_UplinkTable
- call _OPENSSL_Uplink
- addl \$8,%esp
- jmp *(_OPENSSL_UplinkTable+4*$i)
- ___
- }
- print <<___;
- .data
- .align 4
- .globl _OPENSSL_UplinkTable
- _OPENSSL_UplinkTable:
- .long $N
- ___
- for ($i=1;$i<=$N;$i++) { print " .long .Lazy$i\n"; }
- }
- sub ia32masm() {
- print <<___;
- .386P
- .model FLAT
- _DATA SEGMENT
- PUBLIC _OPENSSL_UplinkTable
- _OPENSSL_UplinkTable DD $N ; amount of following entries
- ___
- for ($i=1;$i<=$N;$i++) { print " DD FLAT:\$lazy$i\n"; }
- print <<___;
- _DATA ENDS
- _TEXT SEGMENT
- EXTRN _OPENSSL_Uplink:NEAR
- ___
- for ($i=1;$i<=$N;$i++) {
- print <<___;
- ALIGN 4
- \$lazy$i PROC NEAR
- push $i
- push OFFSET FLAT:_OPENSSL_UplinkTable
- call _OPENSSL_Uplink
- add esp,8
- jmp DWORD PTR _OPENSSL_UplinkTable+4*$i
- \$lazy$i ENDP
- ___
- }
- print <<___;
- ALIGN 4
- _TEXT ENDS
- END
- ___
- }
- sub ia32nasm() {
- print <<___;
- SEGMENT .data
- GLOBAL _OPENSSL_UplinkTable
- _OPENSSL_UplinkTable DD $N ; amount of following entries
- ___
- for ($i=1;$i<=$N;$i++) { print " DD \$lazy$i\n"; }
- print <<___;
- SEGMENT .text
- EXTERN _OPENSSL_Uplink
- ___
- for ($i=1;$i<=$N;$i++) {
- print <<___;
- ALIGN 4
- \$lazy$i:
- push $i
- push _OPENSSL_UplinkTable
- call _OPENSSL_Uplink
- add esp,8
- jmp [_OPENSSL_UplinkTable+4*$i]
- ___
- }
- print <<___;
- ALIGN 4
- END
- ___
- }
- sub ia64ias () {
- local $V=8; # max number of args uplink functions may accept...
- print <<___;
- .data
- .global OPENSSL_UplinkTable#
- OPENSSL_UplinkTable: data8 $N // amount of following entries
- ___
- for ($i=1;$i<=$N;$i++) { print " data8 \@fptr(lazy$i#)\n"; }
- print <<___;
- .size OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
- .text
- .global OPENSSL_Uplink#
- .type OPENSSL_Uplink#,\@function
- ___
- for ($i=1;$i<=$N;$i++) {
- print <<___;
- .proc lazy$i
- lazy$i:
- { .mii; alloc loc0=ar.pfs,$V,3,2,0
- mov loc1=b0
- addl loc2=\@ltoff(OPENSSL_UplinkTable#),gp };;
- { .mmi; ld8 out0=[loc2]
- mov out1=$i };;
- { .mib; adds loc2=8*$i,out0
- br.call.sptk.many b0=OPENSSL_Uplink# };;
- { .mmi; ld8 r31=[loc2];;
- ld8 r30=[r31],8 };;
- { .mii; ld8 gp=[r31]
- mov b6=r30
- mov b0=loc1 };;
- { .mib; mov ar.pfs=loc0
- br.many b6 };;
- .endp lazy$i#
- ___
- }
- }
- sub amd64masm() {
- print <<___;
- _DATA SEGMENT
- PUBLIC OPENSSL_UplinkTable
- OPENSSL_UplinkTable DQ $N
- ___
- for ($i=1;$i<=$N;$i++) { print " DQ \$lazy$i\n"; }
- print <<___;
- _DATA ENDS
- _TEXT SEGMENT
- EXTERN OPENSSL_Uplink:PROC
- ___
- for ($i=1;$i<=$N;$i++) {
- print <<___;
- ALIGN 4
- \$lazy$i PROC
- push r9
- push r8
- push rdx
- push rcx
- sub rsp,40
- lea rcx,OFFSET OPENSSL_UplinkTable
- mov rdx,$i
- call OPENSSL_Uplink
- add rsp,40
- pop rcx
- pop rdx
- pop r8
- pop r9
- jmp QWORD PTR OPENSSL_UplinkTable+8*$i
- \$lazy$i ENDP
- ___
- }
- print <<___;
- _TEXT ENDS
- END
- ___
- }
|