diff options
Diffstat (limited to 'crypto/openssl/crypto/perlasm/x86unix.pl')
-rw-r--r-- | crypto/openssl/crypto/perlasm/x86unix.pl | 108 |
1 files changed, 105 insertions, 3 deletions
diff --git a/crypto/openssl/crypto/perlasm/x86unix.pl b/crypto/openssl/crypto/perlasm/x86unix.pl index 10a7af8..3ad889f 100644 --- a/crypto/openssl/crypto/perlasm/x86unix.pl +++ b/crypto/openssl/crypto/perlasm/x86unix.pl @@ -3,6 +3,8 @@ package x86unix; $label="L000"; +$const=""; +$constl=0; $align=($main'aout)?"4":"16"; $under=($main'aout)?"_":""; @@ -85,12 +87,12 @@ sub main'DWP $ret.=$addr if ($addr ne "") && ($addr ne 0); if ($reg2 ne "") { - if($idx ne "") + if($idx ne "" && $idx != 0) { $ret.="($reg1,$reg2,$idx)"; } else { $ret.="($reg1,$reg2)"; } } - else + elsif ($reg1 ne "") { $ret.="($reg1)" } return($ret); } @@ -162,8 +164,10 @@ sub main'dec { &out1("decl",@_); } sub main'inc { &out1("incl",@_); } sub main'push { &out1("pushl",@_); $stack+=4; } sub main'pop { &out1("popl",@_); $stack-=4; } +sub main'pushf { &out0("pushf"); $stack+=4; } +sub main'popf { &out0("popf"); $stack-=4; } sub main'not { &out1("notl",@_); } -sub main'call { &out1("call",$under.$_[0]); } +sub main'call { &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); } sub main'ret { &out0("ret"); } sub main'nop { &out0("nop"); } @@ -344,6 +348,7 @@ sub main'function_end .${func}_end: EOF push(@out,$tmp); + if ($main'cpp) { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } elsif ($main'gaswin) @@ -453,9 +458,106 @@ sub main'set_label sub main'file_end { + if ($const ne "") + { + push(@out,".section .rodata\n"); + push(@out,$const); + $const=""; + } } sub main'data_word { push(@out,"\t.long $_[0]\n"); } + +# debug output functions: puts, putx, printf + +sub main'puts + { + &pushvars(); + &main'push('$Lstring' . ++$constl); + &main'call('puts'); + $stack-=4; + &main'add("esp",4); + &popvars(); + + $const .= "Lstring$constl:\n\t.string \"@_[0]\"\n"; + } + +sub main'putx + { + &pushvars(); + &main'push($_[0]); + &main'push('$Lstring' . ++$constl); + &main'call('printf'); + &main'add("esp",8); + $stack-=8; + &popvars(); + + $const .= "Lstring$constl:\n\t.string \"\%X\"\n"; + } + +sub main'printf + { + $ostack = $stack; + &pushvars(); + for ($i = @_ - 1; $i >= 0; $i--) + { + if ($i == 0) # change this to support %s format strings + { + &main'push('$Lstring' . ++$constl); + $const .= "Lstring$constl:\n\t.string \"@_[$i]\"\n"; + } + else + { + if ($_[$i] =~ /([0-9]*)\(%esp\)/) + { + &main'push(($1 + $stack - $ostack) . '(%esp)'); + } + else + { + &main'push($_[$i]); + } + } + } + &main'call('printf'); + $stack-=4*@_; + &main'add("esp",4*@_); + &popvars(); + } + +sub pushvars + { + &main'pushf(); + &main'push("edx"); + &main'push("ecx"); + &main'push("eax"); + } + +sub popvars + { + &main'pop("eax"); + &main'pop("ecx"); + &main'pop("edx"); + &main'popf(); + } + +sub main'picmeup + { + local($dst,$sym)=@_; + local($tmp)=<<___; +#if (defined(ELF) || defined(SOL)) && defined(PIC) + .align 8 + call 1f +1: popl $regs{$dst} + addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst} + movl $sym\@GOT($regs{$dst}),$regs{$dst} +#else + leal $sym,$regs{$dst} +#endif +___ + push(@out,$tmp); + } + +sub main'blindpop { &out1("popl",@_); } |