]> git.ipfire.org Git - thirdparty/openssl.git/blob - ms/uplink.pl
Fix from stable branch.
[thirdparty/openssl.git] / ms / uplink.pl
1 #!/usr/bin/env perl
2 #
3 # For Microsoft CL this is implemented as inline assembler. So that
4 # even though this script can generate even Win32 code, we'll be
5 # using it primarily to generate Win64 modules. Both IA-64 and AMD64
6 # are supported...
7
8 # pull APPLINK_MAX value from applink.c...
9 $applink_c=$0;
10 $applink_c=~s|[^/\\]+$||g;
11 $applink_c.="applink.c";
12 open(INPUT,$applink_c) || die "can't open $applink_c: $!";
13 @max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
14 close(INPUT);
15 ($#max==0) or die "can't find APPLINK_MAX in $applink_c";
16
17 $max[0]=~/APPLINK_MAX\s+(\d+)/;
18 $N=$1; # number of entries in OPENSSL_UplinkTable not including
19 # OPENSSL_UplinkTable[0], which contains this value...
20
21 # Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
22 # which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
23 # and then dereference themselves. Latter shall result in endless
24 # loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
25 # something else, e.g. as 'table[index]=unimplemented;'...
26
27 $arg = shift;
28 #( defined shift || open STDOUT,">$arg" ) || die "can't open $arg: $!";
29
30 if ($arg =~ /win32n/) { ia32nasm(); }
31 elsif ($arg =~ /win32/) { ia32masm(); }
32 elsif ($arg =~ /coff/) { ia32gas(); }
33 elsif ($arg =~ /win64i/ or $arg =~ /ia64/) { ia64ias(); }
34 elsif ($arg =~ /win64a/ or $arg =~ /amd64/) { amd64masm(); }
35 else { die "nonsense $arg"; }
36
37 sub ia32gas() {
38 print <<___;
39 .text
40 ___
41 for ($i=1;$i<=$N;$i++) {
42 print <<___;
43 .def .Lazy$i; .scl 3; .type 32; .endef
44 .align 4
45 .Lazy$i:
46 pushl \$$i
47 pushl \$_OPENSSL_UplinkTable
48 call _OPENSSL_Uplink
49 addl \$8,%esp
50 jmp *(_OPENSSL_UplinkTable+4*$i)
51 ___
52 }
53 print <<___;
54 .data
55 .align 4
56 .globl _OPENSSL_UplinkTable
57 _OPENSSL_UplinkTable:
58 .long $N
59 ___
60 for ($i=1;$i<=$N;$i++) { print " .long .Lazy$i\n"; }
61 }
62
63 sub ia32masm() {
64 print <<___;
65 .386P
66 .model FLAT
67
68 _DATA SEGMENT
69 PUBLIC _OPENSSL_UplinkTable
70 _OPENSSL_UplinkTable DD $N ; amount of following entries
71 ___
72 for ($i=1;$i<=$N;$i++) { print " DD FLAT:\$lazy$i\n"; }
73 print <<___;
74 _DATA ENDS
75
76 _TEXT SEGMENT
77 EXTRN _OPENSSL_Uplink:NEAR
78 ___
79 for ($i=1;$i<=$N;$i++) {
80 print <<___;
81 ALIGN 4
82 \$lazy$i PROC NEAR
83 push $i
84 push OFFSET FLAT:_OPENSSL_UplinkTable
85 call _OPENSSL_Uplink
86 add esp,8
87 jmp DWORD PTR _OPENSSL_UplinkTable+4*$i
88 \$lazy$i ENDP
89 ___
90 }
91 print <<___;
92 ALIGN 4
93 _TEXT ENDS
94 END
95 ___
96 }
97
98 sub ia32nasm() {
99 print <<___;
100 SEGMENT .data
101 GLOBAL _OPENSSL_UplinkTable
102 _OPENSSL_UplinkTable DD $N ; amount of following entries
103 ___
104 for ($i=1;$i<=$N;$i++) { print " DD \$lazy$i\n"; }
105 print <<___;
106
107 SEGMENT .text
108 EXTERN _OPENSSL_Uplink
109 ___
110 for ($i=1;$i<=$N;$i++) {
111 print <<___;
112 ALIGN 4
113 \$lazy$i:
114 push $i
115 push _OPENSSL_UplinkTable
116 call _OPENSSL_Uplink
117 add esp,8
118 jmp [_OPENSSL_UplinkTable+4*$i]
119 ___
120 }
121 print <<___;
122 ALIGN 4
123 END
124 ___
125 }
126
127 sub ia64ias () {
128 local $V=8; # max number of args uplink functions may accept...
129 print <<___;
130 .data
131 .global OPENSSL_UplinkTable#
132 OPENSSL_UplinkTable: data8 $N // amount of following entries
133 ___
134 for ($i=1;$i<=$N;$i++) { print " data8 \@fptr(lazy$i#)\n"; }
135 print <<___;
136 .size OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
137
138 .text
139 .global OPENSSL_Uplink#
140 .type OPENSSL_Uplink#,\@function
141 ___
142 for ($i=1;$i<=$N;$i++) {
143 print <<___;
144 .proc lazy$i
145 lazy$i:
146 { .mii; alloc loc0=ar.pfs,$V,3,2,0
147 mov loc1=b0
148 addl loc2=\@ltoff(OPENSSL_UplinkTable#),gp };;
149 { .mmi; ld8 out0=[loc2]
150 mov out1=$i };;
151 { .mib; adds loc2=8*$i,out0
152 br.call.sptk.many b0=OPENSSL_Uplink# };;
153 { .mmi; ld8 r31=[loc2];;
154 ld8 r30=[r31],8 };;
155 { .mii; ld8 gp=[r31]
156 mov b6=r30
157 mov b0=loc1 };;
158 { .mib; mov ar.pfs=loc0
159 br.many b6 };;
160 .endp lazy$i#
161 ___
162 }
163 }
164
165 sub amd64masm() {
166 print <<___;
167 _DATA SEGMENT
168 PUBLIC OPENSSL_UplinkTable
169 OPENSSL_UplinkTable DQ $N
170 ___
171 for ($i=1;$i<=$N;$i++) { print " DQ \$lazy$i\n"; }
172 print <<___;
173 _DATA ENDS
174
175 _TEXT SEGMENT
176 EXTERN OPENSSL_Uplink:PROC
177 ___
178 for ($i=1;$i<=$N;$i++) {
179 print <<___;
180 ALIGN 4
181 \$lazy$i PROC
182 push r9
183 push r8
184 push rdx
185 push rcx
186 sub rsp,40
187 lea rcx,OFFSET OPENSSL_UplinkTable
188 mov rdx,$i
189 call OPENSSL_Uplink
190 add rsp,40
191 pop rcx
192 pop rdx
193 pop r8
194 pop r9
195 jmp QWORD PTR OPENSSL_UplinkTable+8*$i
196 \$lazy$i ENDP
197 ___
198 }
199 print <<___;
200 _TEXT ENDS
201 END
202 ___
203 }
204