/* First determine if getauxval() is available (OSSL_IMPLEMENT_GETAUXVAL) */
+#if defined(__GNUC__) && __GNUC__ >= 2
+void OPENSSL_cpuid_setup(void) __attribute__((constructor));
+#endif
+
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
#if __GLIBC_PREREQ(2, 16)
#include <sys/auxv.h>
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
+ OPENSSL_cpuid_setup();
break;
case DLL_THREAD_ATTACH:
break;
$::lbdecor=$::aout?"L":".L"; # local label decoration
$nmdecor=($::aout or $::coff)?"_":""; # external name decoration
+$initseg="";
+
$align=16;
$align=log($align)/log(2) if ($::aout);
$com_start="#" if ($::aout or $::coff);
elsif ($::elf) { push (@out,"$tmp,4\n"); }
else { push (@out,"$tmp\n"); }
}
+ push(@out,$initseg) if ($initseg);
if ($::elf) {
push(@out,"
.section \".note.gnu.property\", \"a\"
{ &::lea($dst,&::DWP($sym)); }
}
+sub ::initseg
+{ my $f=$nmdecor.shift;
+
+ if ($::android)
+ { $initseg.=<<___;
+.section .init_array
+.align 4
+.long $f
+___
+ }
+ elsif ($::elf)
+ { $initseg.=<<___;
+.section .init
+ call $f
+___
+ }
+ elsif ($::coff)
+ { $initseg.=<<___; # applies to both Cygwin and Mingw
+.section .ctors
+.long $f
+___
+ }
+ elsif ($::macosx)
+ { $initseg.=<<___;
+.mod_init_func
+.align 2
+.long $f
+___
+ }
+ elsif ($::aout)
+ { my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
+ $initseg.=".text\n";
+ $initseg.=".type $ctor,\@function\n" if ($::pic);
+ $initseg.=<<___; # OpenBSD way...
+.globl $ctor
+.align 2
+$ctor:
+ jmp $f
+___
+ }
+}
+
sub ::dataseg
{ push(@out,".data\n"); }
$::lbdecor="\$L"; # local label decoration
$nmdecor="_"; # external name decoration
+$initseg="";
$segment="";
sub ::generic
grep {s/(^EXTERN\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
push (@out,$comm);
}
+ push (@out,$initseg) if ($initseg);
push (@out,"END\n");
}
&::lea($dst,&::DWP($sym));
}
+sub ::initseg
+{ my $f=$nmdecor.shift;
+
+ $initseg.=<<___;
+.CRT\$XCU SEGMENT DWORD PUBLIC 'DATA'
+EXTERN $f:NEAR
+DD $f
+.CRT\$XCU ENDS
+___
+}
+
sub ::dataseg
{ push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA"; }
$nmdecor="_"; # external name decoration
$drdecor=$::mwerks?".":""; # directive decoration
+$initseg="";
+
sub ::generic
{ my $opcode=shift;
my $tmp;
grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
push (@out,$comm)
}
+ push (@out,$initseg) if ($initseg);
}
sub ::comment { foreach (@_) { push(@out,"\t; $_\n"); } }
&::lea($dst,&::DWP($sym));
}
+sub ::initseg
+{ my $f=$nmdecor.shift;
+ if ($::win32)
+ { $initseg=<<___;
+segment .CRT\$XCU data align=4
+extern $f
+dd $f
+___
+ }
+}
+
sub ::dataseg
{ if ($mwerks) { push(@out,".section\t.data,4\n"); }
else { push(@out,"section\t.data align=4\n"); }
#define HWCAP_ARCH_3_00 (1U << 23)
#define HWCAP_ARCH_3_1 (1U << 18)
+#if defined(__GNUC__) && __GNUC__ >= 2
+__attribute__((constructor))
+#endif
void OPENSSL_cpuid_setup(void)
{
char *e;
return vlen;
}
+#if defined(__GNUC__) && __GNUC__ >= 2
+__attribute__((constructor))
+#endif
void OPENSSL_cpuid_setup(void)
{
char *e;
___
}
+$code.=<<___;
+.section .init
+ brasl $ra,OPENSSL_cpuid_setup
+___
+
$code =~ s/\`([^\`]*)\`/eval $1/gem;
print $code;
close STDOUT or die "error closing STDOUT: $!"; # force flush
sub %o3,%o1,%o0
.type _sparcv9_vis1_instrument_bus2,#function
.size _sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
+
+.section ".init",#alloc,#execinstr
+ call OPENSSL_cpuid_setup
+ nop
#include crypto/cryptlib.h
.extern OPENSSL_cpuid_setup
.hidden OPENSSL_cpuid_setup
+.section .init
+ call OPENSSL_cpuid_setup
+
.hidden OPENSSL_ia32cap_P
.comm OPENSSL_ia32cap_P,40,4 # <--Should match with internal/cryptlib.h OPENSSL_IA32CAP_P_MAX_INDEXES
.text
&gen_random("rdrand");
&gen_random("rdseed");
+&initseg("OPENSSL_cpuid_setup");
+
&hidden("OPENSSL_cpuid_setup");
&hidden("OPENSSL_ia32cap_P");