summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/perlasm/x86gas.pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/perlasm/x86gas.pl')
-rw-r--r--src/lib/libcrypto/perlasm/x86gas.pl92
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
180sub ::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"); 198sub ::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
213sub ::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
233sub ::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
244sub ::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
215sub ::initseg 257sub ::initseg
216{ my $f=$nmdecor.shift; 258{ my $f=$nmdecor.shift;
217 259
@@ -264,4 +306,10 @@ ___
264sub ::dataseg 306sub ::dataseg
265{ push(@out,".data\n"); } 307{ push(@out,".data\n"); }
266 308
309sub ::rodataseg
310{ push(@out,".rodata\n"); }
311
312sub ::previous
313{ push(@out,".previous\n"); }
314
2671; 3151;