]>
Commit | Line | Data |
---|---|---|
3fc378aa AP |
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 =~ /ia64/) { ia64ias(); } | |
33 | elsif ($arg =~ /amd64/) { amd64masm(); } | |
34 | else { die "nonsense $arg"; } | |
35 | ||
36 | sub ia32masm() { | |
37 | print <<___; | |
38 | .386P | |
39 | .model FLAT | |
40 | ||
41 | _DATA SEGMENT | |
42 | PUBLIC _OPENSSL_UplinkTable | |
43 | _OPENSSL_UplinkTable DD $N ; amount of following entries | |
44 | ___ | |
45 | for ($i=1;$i<=$N;$i++) { print " DD FLAT:\$lazy$i\n"; } | |
46 | print <<___; | |
47 | _DATA ENDS | |
48 | ||
49 | _TEXT SEGMENT | |
50 | EXTRN _OPENSSL_Uplink:NEAR | |
51 | ___ | |
52 | for ($i=1;$i<=$N;$i++) { | |
53 | print <<___; | |
54 | ALIGN 4 | |
55 | \$lazy$i PROC NEAR | |
56 | push $i | |
57 | push OFFSET FLAT:_OPENSSL_UplinkTable | |
58 | call _OPENSSL_Uplink | |
59 | add esp,8 | |
60 | jmp DWORD PTR _OPENSSL_UplinkTable+4*$i | |
61 | \$lazy$i ENDP | |
62 | ___ | |
63 | } | |
64 | print <<___; | |
65 | ALIGN 4 | |
66 | _TEXT ENDS | |
67 | END | |
68 | ___ | |
69 | } | |
70 | ||
71 | sub ia32nasm() { | |
72 | print <<___; | |
73 | SEGMENT .data | |
74 | GLOBAL _OPENSSL_UplinkTable | |
75 | _OPENSSL_UplinkTable DD $N ; amount of following entries | |
76 | ___ | |
77 | for ($i=1;$i<=$N;$i++) { print " DD \$lazy$i\n"; } | |
78 | print <<___; | |
79 | ||
80 | SEGMENT .text | |
81 | EXTERN _OPENSSL_Uplink | |
82 | ___ | |
83 | for ($i=1;$i<=$N;$i++) { | |
84 | print <<___; | |
85 | ALIGN 4 | |
86 | \$lazy$i: | |
87 | push $i | |
88 | push _OPENSSL_UplinkTable | |
89 | call _OPENSSL_Uplink | |
90 | add esp,8 | |
91 | jmp [_OPENSSL_UplinkTable+4*$i] | |
92 | ___ | |
93 | } | |
94 | print <<___; | |
95 | ALIGN 4 | |
96 | END | |
97 | ___ | |
98 | } | |
99 | ||
100 | sub ia64ias () { | |
101 | local $V=8; # max number of args uplink functions may accept... | |
102 | print <<___; | |
103 | .data | |
104 | .global OPENSSL_UplinkTable# | |
105 | OPENSSL_UplinkTable: data8 $N // amount of following entries | |
106 | ___ | |
107 | for ($i=1;$i<=$N;$i++) { print " data8 \@fptr(lazy$i#)\n"; } | |
108 | print <<___; | |
109 | .size OPENSSL_UplinkTable,.-OPENSSL_UplinkTable# | |
110 | ||
111 | .text | |
112 | .global OPENSSL_Uplink# | |
113 | .type OPENSSL_Uplink#,\@function | |
114 | ___ | |
115 | for ($i=1;$i<=$N;$i++) { | |
116 | print <<___; | |
117 | .proc lazy$i | |
118 | lazy$i: | |
119 | { .mii; alloc loc0=ar.pfs,$V,3,2,0 | |
120 | mov loc1=b0 | |
121 | addl loc2=\@ltoff(OPENSSL_UplinkTable#),gp };; | |
122 | { .mmi; ld8 out0=[loc2] | |
123 | mov out1=$i };; | |
124 | { .mib; adds loc2=8*$i,out0 | |
125 | br.call.sptk.many b0=OPENSSL_Uplink# };; | |
126 | { .mmi; ld8 r31=[loc2];; | |
127 | ld8 r30=[r31],8 };; | |
128 | { .mii; ld8 gp=[r31] | |
129 | mov b6=r30 | |
130 | mov b0=loc1 };; | |
131 | { .mib; mov ar.pfs=loc0 | |
132 | br.many b6 };; | |
133 | .endp lazy$i# | |
134 | ___ | |
135 | } | |
136 | } | |
137 | ||
138 | sub amd64masm() { | |
139 | print <<___; | |
140 | _DATA SEGMENT | |
141 | PUBLIC OPENSSL_UplinkTable | |
142 | OPENSSL_UplinkTable DQ $N | |
143 | ___ | |
144 | for ($i=1;$i<=$N;$i++) { print " DQ FLAT:\$lazy$i\n"; } | |
145 | print <<___; | |
146 | _DATA ENDS | |
147 | ||
148 | TEXT SEGMENT | |
149 | EXTERN OPENSSL_Uplink:NEAR | |
150 | ___ | |
151 | for ($i=1;$i<=$N;$i++) { | |
152 | print <<___; | |
153 | ALIGN 4 | |
154 | \$lazy$i PROC NEAR | |
155 | push r9 | |
156 | push r8 | |
157 | push rdx | |
158 | push rcx | |
159 | sub rsp,40 | |
160 | mov rcx,OFFSET FLAT:OPENSSL_UplinkTable | |
161 | mov rdx,$i | |
162 | call OPENSSL_Uplink | |
163 | add rsp,40 | |
164 | pop rcx | |
165 | pop rdx | |
166 | pop r8 | |
167 | pop r9 | |
168 | jmp QWORD PTR OPENSSL_UplinkTable+8*$i | |
169 | \$lazy$i ENDP | |
170 | ___ | |
171 | } | |
172 | print <<___; | |
173 | TEXT ENDS | |
174 | END | |
175 | ___ | |
176 | } | |
177 |