diff options
Diffstat (limited to 'src/lib/libcrypto/perlasm/x86gas.pl')
-rw-r--r-- | src/lib/libcrypto/perlasm/x86gas.pl | 92 |
1 files changed, 70 insertions, 22 deletions
diff --git a/src/lib/libcrypto/perlasm/x86gas.pl b/src/lib/libcrypto/perlasm/x86gas.pl index ca644ba553..f28a590549 100644 --- a/src/lib/libcrypto/perlasm/x86gas.pl +++ b/src/lib/libcrypto/perlasm/x86gas.pl | |||
@@ -177,34 +177,52 @@ sub ::align | |||
177 | push(@out,".align\t$val\n"); | 177 | push(@out,".align\t$val\n"); |
178 | } | 178 | } |
179 | 179 | ||
180 | sub ::picmeup | 180 | # |
181 | { my($dst,$sym,$base,$reflabel)=@_; | 181 | # PIC data access wrappers |
182 | 182 | # | |
183 | if ($::openbsd) | 183 | # Usage: |
184 | { &::emitraw("#if defined(PIC) || defined(__PIC__)"); | 184 | # picsetup($base) |
185 | &::emitraw("PIC_PROLOGUE"); | 185 | # - only allowed once per function (because of hardcoded label name), |
186 | &::mov($dst, &::DWP("PIC_GOT($sym)")); | 186 | # sets up pic access, uses $base register as temporary |
187 | &::emitraw("PIC_EPILOGUE"); | 187 | # picsymbol($dst, $sym, $base) |
188 | &::emitraw("#else /* PIC */"); | 188 | # - loads the address of symbol $sym into $dst with the help of $base |
189 | &::lea($dst,&::DWP($sym)); | 189 | # initialized by picsetup |
190 | &::emitraw("#endif /* PIC */"); | 190 | # picadjust($sym, $base) |
191 | } | 191 | # - adjusts a code pointer read from a code_sym table with the help of |
192 | elsif (($::pic && ($::elf || $::aout)) || $::macosx) | 192 | # $base initialized by picsetup |
193 | { if (!defined($base)) | 193 | # code_sym($sym) |
194 | { &::call(&::label("PIC_me_up")); | 194 | # - emits a pointer to the given code symbol, relative to the GOT if |
195 | &::set_label("PIC_me_up"); | 195 | # PIC. This pointer will need to be adjusted with picadjust above |
196 | &::blindpop($dst); | 196 | # before use. |
197 | $base=$dst; | 197 | |
198 | $reflabel=&::label("PIC_me_up"); | 198 | sub ::picsetup |
199 | } | 199 | { my($base)=@_; |
200 | |||
201 | if (($::pic && ($::openbsd || $::elf || $::aout)) || $::macosx) | ||
202 | { | ||
203 | &::call(&::label("PIC_setup")); | ||
204 | &::set_label("PIC_setup"); | ||
205 | &::blindpop($base); | ||
200 | if ($::macosx) | 206 | if ($::macosx) |
201 | { my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr"); | 207 | { my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr"); |
202 | &::mov($dst,&::DWP("$indirect-$reflabel",$base)); | ||
203 | $non_lazy_ptr{"$nmdecor$sym"}=$indirect; | 208 | $non_lazy_ptr{"$nmdecor$sym"}=$indirect; |
204 | } | 209 | } |
210 | } | ||
211 | } | ||
212 | |||
213 | sub ::picsymbol | ||
214 | { my($dst,$sym,$base)=@_; | ||
215 | |||
216 | if (($::pic && ($::openbsd || $::elf || $::aout)) || $::macosx) | ||
217 | { | ||
218 | my $reflabel=&::label("PIC_setup"); | ||
219 | if ($::macosx) | ||
220 | { my $indirect=$non_lazy_ptr{"$nmdecor$sym"}; | ||
221 | &::mov($dst,&::DWP("$indirect-$reflabel",$base)); | ||
222 | } | ||
205 | else | 223 | else |
206 | { &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", | 224 | { &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", |
207 | $base)); | 225 | $base)); |
208 | &::mov($dst,&::DWP("$sym\@GOT",$dst)); | 226 | &::mov($dst,&::DWP("$sym\@GOT",$dst)); |
209 | } | 227 | } |
210 | } | 228 | } |
@@ -212,6 +230,30 @@ sub ::picmeup | |||
212 | { &::lea($dst,&::DWP($sym)); } | 230 | { &::lea($dst,&::DWP($sym)); } |
213 | } | 231 | } |
214 | 232 | ||
233 | sub ::picadjust | ||
234 | { my($sym,$base)=@_; | ||
235 | |||
236 | if (($::pic && ($::openbsd || $::elf || $::aout)) || $::macosx) | ||
237 | { | ||
238 | my $reflabel=&::label("PIC_setup"); | ||
239 | &::lea($sym,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", | ||
240 | $base,$sym)); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | sub ::code_sym | ||
245 | { my($sym)=@_; | ||
246 | |||
247 | if (($::pic && ($::openbsd || $::elf || $::aout)) || $::macosx) | ||
248 | { | ||
249 | $sym."\@GOTOFF"; | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | $sym; | ||
254 | } | ||
255 | } | ||
256 | |||
215 | sub ::initseg | 257 | sub ::initseg |
216 | { my $f=$nmdecor.shift; | 258 | { my $f=$nmdecor.shift; |
217 | 259 | ||
@@ -264,4 +306,10 @@ ___ | |||
264 | sub ::dataseg | 306 | sub ::dataseg |
265 | { push(@out,".data\n"); } | 307 | { push(@out,".data\n"); } |
266 | 308 | ||
309 | sub ::rodataseg | ||
310 | { push(@out,".rodata\n"); } | ||
311 | |||
312 | sub ::previous | ||
313 | { push(@out,".previous\n"); } | ||
314 | |||
267 | 1; | 315 | 1; |