From: Debian OpenSSL Team Date: Sun, 5 Nov 2017 15:09:09 +0100 Subject: pic --- crypto/des/asm/desboth.pl | 17 ++++++++++++++--- crypto/perlasm/cbc.pl | 24 ++++++++++++++++++++---- crypto/perlasm/x86gas.pl | 16 ++++++++++++++++ crypto/x86cpuid.pl | 10 +++++----- 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/crypto/des/asm/desboth.pl b/crypto/des/asm/desboth.pl index afffd20d84cd..b50e85ce24f8 100644 --- a/crypto/des/asm/desboth.pl +++ b/crypto/des/asm/desboth.pl @@ -23,6 +23,11 @@ sub DES_encrypt3 &push("edi"); + &call (&label("pic_point0")); + &set_label("pic_point0"); + &blindpop("ebp"); + &add ("ebp", "\$_GLOBAL_OFFSET_TABLE_+[.-" . &label("pic_point0") . "]"); + &comment(""); &comment("Load the data words"); &mov($L,&DWP(0,"ebx","",0)); @@ -54,15 +59,21 @@ sub DES_encrypt3 &mov(&swtmp(2), (DWC(($enc)?"1":"0"))); &mov(&swtmp(1), "eax"); &mov(&swtmp(0), "ebx"); - &call("DES_encrypt2"); + &exch("ebx", "ebp"); + &call("DES_encrypt2\@PLT"); + &exch("ebx", "ebp"); &mov(&swtmp(2), (DWC(($enc)?"0":"1"))); &mov(&swtmp(1), "edi"); &mov(&swtmp(0), "ebx"); - &call("DES_encrypt2"); + &exch("ebx", "ebp"); + &call("DES_encrypt2\@PLT"); + &exch("ebx", "ebp"); &mov(&swtmp(2), (DWC(($enc)?"1":"0"))); &mov(&swtmp(1), "esi"); &mov(&swtmp(0), "ebx"); - &call("DES_encrypt2"); + &exch("ebx", "ebp"); + &call("DES_encrypt2\@PLT"); + &exch("ebx", "ebp"); &stack_pop(3); &mov($L,&DWP(0,"ebx","",0)); diff --git a/crypto/perlasm/cbc.pl b/crypto/perlasm/cbc.pl index ef09e0fd297a..fe6ff45d1804 100644 --- a/crypto/perlasm/cbc.pl +++ b/crypto/perlasm/cbc.pl @@ -129,7 +129,11 @@ sub cbc &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call &mov(&DWP($data_off+4,"esp","",0), "ebx"); # - &call($enc_func); + &call (&label("pic_point0")); + &set_label("pic_point0"); + &blindpop("ebx"); + &add ("ebx", "\$_GLOBAL_OFFSET_TABLE_+[.-" . &label("pic_point0") . "]"); + &call("$enc_func\@PLT"); &mov("eax", &DWP($data_off,"esp","",0)); &mov("ebx", &DWP($data_off+4,"esp","",0)); @@ -199,7 +203,11 @@ sub cbc &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call &mov(&DWP($data_off+4,"esp","",0), "ebx"); # - &call($enc_func); + &call (&label("pic_point1")); + &set_label("pic_point1"); + &blindpop("ebx"); + &add ("ebx", "\$_GLOBAL_OFFSET_TABLE_+[.-" . &label("pic_point1") . "]"); + &call("$enc_func\@PLT"); &mov("eax", &DWP($data_off,"esp","",0)); &mov("ebx", &DWP($data_off+4,"esp","",0)); @@ -232,7 +240,11 @@ sub cbc &mov(&DWP($data_off,"esp","",0), "eax"); # put back &mov(&DWP($data_off+4,"esp","",0), "ebx"); # - &call($dec_func); + &call (&label("pic_point2")); + &set_label("pic_point2"); + &blindpop("ebx"); + &add ("ebx", "\$_GLOBAL_OFFSET_TABLE_+[.-" . &label("pic_point2") . "]"); + &call("$dec_func\@PLT"); &mov("eax", &DWP($data_off,"esp","",0)); # get return &mov("ebx", &DWP($data_off+4,"esp","",0)); # @@ -275,7 +287,11 @@ sub cbc &mov(&DWP($data_off,"esp","",0), "eax"); # put back &mov(&DWP($data_off+4,"esp","",0), "ebx"); # - &call($dec_func); + &call (&label("pic_point3")); + &set_label("pic_point3"); + &blindpop("ebx"); + &add ("ebx", "\$_GLOBAL_OFFSET_TABLE_+[.-" . &label("pic_point3") . "]"); + &call("$dec_func\@PLT"); &mov("eax", &DWP($data_off,"esp","",0)); # get return &mov("ebx", &DWP($data_off+4,"esp","",0)); # diff --git a/crypto/perlasm/x86gas.pl b/crypto/perlasm/x86gas.pl index 1b2b27c02286..a62c01b175a2 100644 --- a/crypto/perlasm/x86gas.pl +++ b/crypto/perlasm/x86gas.pl @@ -171,6 +171,7 @@ sub ::file_end if ($::macosx) { push (@out,"$tmp,2\n"); } elsif ($::elf) { push (@out,"$tmp,4\n"); } else { push (@out,"$tmp\n"); } + if ($::elf) { push (@out,".hidden\tOPENSSL_ia32cap_P\n"); } } push(@out,$initseg) if ($initseg); if ($::elf) { @@ -249,8 +250,23 @@ ___ elsif ($::elf) { $initseg.=<<___; .section .init +___ + if ($::pic) + { $initseg.=<<___; + pushl %ebx + call .pic_point0 +.pic_point0: + popl %ebx + addl \$_GLOBAL_OFFSET_TABLE_+[.-.pic_point0],%ebx + call $f\@PLT + popl %ebx +___ + } + else + { $initseg.=<<___; call $f ___ + } } elsif ($::coff) { $initseg.=<<___; # applies to both Cygwin and Mingw diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index a7bcb27e262d..6688a1fc4464 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -16,6 +16,8 @@ $output = pop and open STDOUT,">$output"; for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } +push(@out, ".hidden OPENSSL_ia32cap_P\n"); + &function_begin("OPENSSL_ia32_cpuid"); &xor ("edx","edx"); &pushf (); @@ -161,9 +163,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &set_label("nocpuid"); &function_end("OPENSSL_ia32_cpuid"); -&external_label("OPENSSL_ia32cap_P"); - -&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); +&function_begin_B("OPENSSL_rdtsc"); &xor ("eax","eax"); &xor ("edx","edx"); &picmeup("ecx","OPENSSL_ia32cap_P"); @@ -177,7 +177,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } # This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host], # but it's safe to call it on any [supported] 32-bit platform... # Just check for [non-]zero return value... -&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); +&function_begin_B("OPENSSL_instrument_halt"); &picmeup("ecx","OPENSSL_ia32cap_P"); &bt (&DWP(0,"ecx"),4); &jnc (&label("nohalt")); # no TSC @@ -244,7 +244,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &ret (); &function_end_B("OPENSSL_far_spin"); -&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); +&function_begin_B("OPENSSL_wipe_cpu"); &xor ("eax","eax"); &xor ("edx","edx"); &picmeup("ecx","OPENSSL_ia32cap_P");