diff options
Diffstat (limited to 'src/lib/libssl/src/ms/uplink.pl')
-rwxr-xr-x | src/lib/libssl/src/ms/uplink.pl | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/lib/libssl/src/ms/uplink.pl b/src/lib/libssl/src/ms/uplink.pl new file mode 100755 index 0000000000..102400e880 --- /dev/null +++ b/src/lib/libssl/src/ms/uplink.pl | |||
@@ -0,0 +1,204 @@ | |||
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 | |||