summaryrefslogtreecommitdiffstats
path: root/crypto/perlasm
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2016-12-09 15:26:19 +0100
committerAndy Polyakov <appro@openssl.org>2016-12-12 11:00:50 +0100
commit82e089308bd9a7794a45f0fa3973d7659420fbd8 (patch)
tree7bde726223f081b763f81bdc01ee49941fc2e0bb /crypto/perlasm
parentabb8c44fbaf6b88f4f4879b89b32e423aa75617b (diff)
perlasm/x86_64-xlate.pl: refine sign extension in ea package.
$1<<32>>32 worked fine with either 32- or 64-bit perl for a good while, relying on quirk that [pure] 32-bit perl performed it as $1<<0>>0. But this apparently changed in some version past minimally required 5.10, and operation result became 0. Yet, it went unnoticed for another while, because most perl package providers configure their packages with -Duse64bitint option. Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/perlasm')
-rwxr-xr-xcrypto/perlasm/x86_64-xlate.pl11
1 files changed, 9 insertions, 2 deletions
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index f615fffbcd..4298b3f418 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -262,11 +262,18 @@ my %globals;
$self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
# Solaris /usr/ccs/bin/as can't handle multiplications
- # in $self->{label}, new gas requires sign extension...
+ # in $self->{label}...
use integer;
$self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
$self->{label} =~ s/\b([0-9]+\s*[\*\/\%]\s*[0-9]+)\b/eval($1)/eg;
- $self->{label} =~ s/\b([0-9]+)\b/$1<<32>>32/eg;
+
+ # Some assemblers insist on signed presentation of 32-bit
+ # offsets, but sign extension is a tricky business in perl...
+ if ((1<<31)<<1) {
+ $self->{label} =~ s/\b([0-9]+)\b/$1<<32>>32/eg;
+ } else {
+ $self->{label} =~ s/\b([0-9]+)\b/$1>>0/eg;
+ }
if (!$self->{label} && $self->{index} && $self->{scale}==1 &&
$self->{base} =~ /(rbp|r13)/) {