Loading crypto/perlasm/x86_64-xlate.pl +39 −9 Original line number Diff line number Diff line Loading @@ -57,7 +57,13 @@ # lea .Label-.Lpic_point(%rcx),%rbp my $output = shift; open STDOUT,">$output" || die "can't open $output: $!"; { my ($stddev,$stdino,@junk)=stat(STDOUT); my ($outdev,$outino,@junk)=stat($output); open STDOUT,">$output" || die "can't open $output: $!" if ($stddev!=$outdev || $stdino!=$outino); } my $masm=1 if ($output =~ /\.asm/); Loading @@ -70,7 +76,7 @@ my $current_function; local *line = shift; undef $ret; if ($line =~ /^([a-z]+)/i) { if ($line =~ /^([a-z][a-z0-9]*)/i) { $self->{op} = $1; $ret = $self; $line = substr($line,@+[0]); $line =~ s/^\s+//; Loading @@ -95,8 +101,10 @@ my $current_function; sub out { my $self = shift; if (!$masm) { if ($self->{op} eq "movz") { # movz in pain... if ($self->{op} eq "movz") { # movz is pain... sprintf "%s%s%s",$self->{op},$self->{sz},shift; } elsif ($self->{op} =~ /^set/) { "$self->{op}"; } elsif ($self->{op} eq "ret") { ".byte 0xf3,0xc3"; } else { Loading Loading @@ -133,6 +141,10 @@ my $current_function; my $self = shift; if (!$masm) { # Solaris /usr/ccs/bin/as can't handle multiplications # in $self->{value} $self->{value} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; sprintf "\$%s",$self->{value}; } else { $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig; Loading Loading @@ -163,14 +175,16 @@ my $current_function; my $self = shift; my $sz = shift; # Silently convert all EAs to 64-bit. This is required for # elder GNU assembler and results in more compact code, # *but* most importantly AES module depends on this feature! $self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; $self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; if (!$masm) { # elder GNU assembler insists on 64-bit EAs:-( # on pros side, this results in more compact code:-) $self->{index} =~ s/^[er](.?[0-9xp])[d]?$/r\1/; $self->{base} =~ s/^[er](.?[0-9xp])[d]?$/r\1/; # Solaris /usr/ccs/bin/as can't handle multiplications # in $self->{label} $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/eg; $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; if (defined($self->{index})) { Loading @@ -192,6 +206,8 @@ my $current_function; $self->{label}, $self->{index},$self->{scale}, $self->{base}; } elsif ($self->{base} eq "rip") { sprintf "%s PTR %s",$szmap{$sz},$self->{label}; } else { sprintf "%s PTR %s[%s]",$szmap{$sz}, $self->{label},$self->{base}; Loading Loading @@ -317,6 +333,10 @@ my $current_function; $line =~ s/\@function.*/\@function/; if ($line =~ /\.picmeup\s+(%r[\w]+)/i) { $self->{value} = sprintf "\t.long\t0x%x,0x90000000",$opcode{$1}; } elsif ($line =~ /\.asciz\s+"(.*)"$/) { $self->{value} = ".byte\t".join(",",unpack("C*",$1),0); } elsif ($line =~ /\.extern/) { $self->{value} = ""; # swallow extern } else { $self->{value} = $line; } Loading @@ -338,6 +358,7 @@ my $current_function; $self->{value} = $v; last; }; /\.extern/ && do { $self->{value} = "EXTRN\t".$line; last; }; /\.globl/ && do { $self->{value} = "PUBLIC\t".$line; last; }; /\.type/ && do { ($sym,$type,$narg) = split(',',$line); if ($type eq "\@function") { Loading Loading @@ -372,6 +393,12 @@ my $current_function; /\.picmeup/ && do { $self->{value} = sprintf"\tDD\t 0%Xh,090000000h",$opcode{$line}; last; }; /\.asciz/ && do { if ($line =~ /^"(.*)"$/) { $self->{value} = "DB\t" .join(",",unpack("C*",$1),0); } last; }; } $line = ""; } Loading Loading @@ -480,7 +507,10 @@ close STDOUT; # arguments passed to callee, *but* not less than 4! This means that # upon function entry point 5th argument resides at 40(%rsp), as well # as that 32 bytes from 8(%rsp) can always be used as temporal # storage [without allocating a frame]. # storage [without allocating a frame]. One can actually argue that # one can assume a "red zone" above stack pointer under Win64 as well. # Point is that at apparently no occasion Windows kernel would alter # the area above user stack pointer in true asynchronous manner... # # All the above means that if assembler programmer adheres to Unix # register and stack layout, but disregards the "red zone" existense, Loading Loading
crypto/perlasm/x86_64-xlate.pl +39 −9 Original line number Diff line number Diff line Loading @@ -57,7 +57,13 @@ # lea .Label-.Lpic_point(%rcx),%rbp my $output = shift; open STDOUT,">$output" || die "can't open $output: $!"; { my ($stddev,$stdino,@junk)=stat(STDOUT); my ($outdev,$outino,@junk)=stat($output); open STDOUT,">$output" || die "can't open $output: $!" if ($stddev!=$outdev || $stdino!=$outino); } my $masm=1 if ($output =~ /\.asm/); Loading @@ -70,7 +76,7 @@ my $current_function; local *line = shift; undef $ret; if ($line =~ /^([a-z]+)/i) { if ($line =~ /^([a-z][a-z0-9]*)/i) { $self->{op} = $1; $ret = $self; $line = substr($line,@+[0]); $line =~ s/^\s+//; Loading @@ -95,8 +101,10 @@ my $current_function; sub out { my $self = shift; if (!$masm) { if ($self->{op} eq "movz") { # movz in pain... if ($self->{op} eq "movz") { # movz is pain... sprintf "%s%s%s",$self->{op},$self->{sz},shift; } elsif ($self->{op} =~ /^set/) { "$self->{op}"; } elsif ($self->{op} eq "ret") { ".byte 0xf3,0xc3"; } else { Loading Loading @@ -133,6 +141,10 @@ my $current_function; my $self = shift; if (!$masm) { # Solaris /usr/ccs/bin/as can't handle multiplications # in $self->{value} $self->{value} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; sprintf "\$%s",$self->{value}; } else { $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig; Loading Loading @@ -163,14 +175,16 @@ my $current_function; my $self = shift; my $sz = shift; # Silently convert all EAs to 64-bit. This is required for # elder GNU assembler and results in more compact code, # *but* most importantly AES module depends on this feature! $self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; $self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; if (!$masm) { # elder GNU assembler insists on 64-bit EAs:-( # on pros side, this results in more compact code:-) $self->{index} =~ s/^[er](.?[0-9xp])[d]?$/r\1/; $self->{base} =~ s/^[er](.?[0-9xp])[d]?$/r\1/; # Solaris /usr/ccs/bin/as can't handle multiplications # in $self->{label} $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/eg; $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; if (defined($self->{index})) { Loading @@ -192,6 +206,8 @@ my $current_function; $self->{label}, $self->{index},$self->{scale}, $self->{base}; } elsif ($self->{base} eq "rip") { sprintf "%s PTR %s",$szmap{$sz},$self->{label}; } else { sprintf "%s PTR %s[%s]",$szmap{$sz}, $self->{label},$self->{base}; Loading Loading @@ -317,6 +333,10 @@ my $current_function; $line =~ s/\@function.*/\@function/; if ($line =~ /\.picmeup\s+(%r[\w]+)/i) { $self->{value} = sprintf "\t.long\t0x%x,0x90000000",$opcode{$1}; } elsif ($line =~ /\.asciz\s+"(.*)"$/) { $self->{value} = ".byte\t".join(",",unpack("C*",$1),0); } elsif ($line =~ /\.extern/) { $self->{value} = ""; # swallow extern } else { $self->{value} = $line; } Loading @@ -338,6 +358,7 @@ my $current_function; $self->{value} = $v; last; }; /\.extern/ && do { $self->{value} = "EXTRN\t".$line; last; }; /\.globl/ && do { $self->{value} = "PUBLIC\t".$line; last; }; /\.type/ && do { ($sym,$type,$narg) = split(',',$line); if ($type eq "\@function") { Loading Loading @@ -372,6 +393,12 @@ my $current_function; /\.picmeup/ && do { $self->{value} = sprintf"\tDD\t 0%Xh,090000000h",$opcode{$line}; last; }; /\.asciz/ && do { if ($line =~ /^"(.*)"$/) { $self->{value} = "DB\t" .join(",",unpack("C*",$1),0); } last; }; } $line = ""; } Loading Loading @@ -480,7 +507,10 @@ close STDOUT; # arguments passed to callee, *but* not less than 4! This means that # upon function entry point 5th argument resides at 40(%rsp), as well # as that 32 bytes from 8(%rsp) can always be used as temporal # storage [without allocating a frame]. # storage [without allocating a frame]. One can actually argue that # one can assume a "red zone" above stack pointer under Win64 as well. # Point is that at apparently no occasion Windows kernel would alter # the area above user stack pointer in true asynchronous manner... # # All the above means that if assembler programmer adheres to Unix # register and stack layout, but disregards the "red zone" existense, Loading