1#! /usr/bin/env perl -w 2use 5.10.0; 3use strict; 4use FindBin; 5use lib "$FindBin::Bin/../openssl/"; 6use lib "$FindBin::Bin/../openssl/util/perl"; 7use lib "$FindBin::Bin/../openssl/util/perl/OpenSSL"; 8use File::Basename; 9use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; 10use File::Copy; 11use File::Path qw/make_path/; 12#use with_fallback qw(Text::Template); 13use fallback qw(Text::Template); 14 15# Read configdata from ../openssl/configdata.pm that is generated 16# with ../openssl/Configure options arch 17use configdata; 18 19my $asm = shift @ARGV; 20 21unless ($asm eq "asm" or $asm eq "asm_avx2" or $asm eq "no-asm") { 22 die "Error: $asm is invalid argument"; 23} 24my $arch = shift @ARGV; 25 26# nasm version check 27my $nasm_banner = `nasm -v`; 28die "Error: nasm is not installed." if (!$nasm_banner); 29 30# gas version check 31my $gas_version_min = 2.30; 32my $gas_banner = `gcc -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`; 33my ($gas_version) = ($gas_banner =~/GNU assembler version ([2-9]\.[0-9]+)/); 34if ($gas_version < $gas_version_min) { 35 die "Error: gas version $gas_version is too old." . 36 "$gas_version_min or higher is required."; 37} 38 39our $src_dir = "../openssl"; 40our $arch_dir = "../config/archs/$arch"; 41our $base_dir = "$arch_dir/$asm"; 42 43my $is_win = ($arch =~/^VC-WIN/); 44# VC-WIN32 and VC-WIN64A generate makefile but it can be available 45# with only nmake. Use pre-created Makefile_VC_WIN32 46# Makefile_VC-WIN64A instead. 47my $makefile = $is_win ? "../config/Makefile_$arch": "Makefile"; 48# Generate arch dependent header files with Makefile 49my $buildinf = "crypto/buildinf.h"; 50my $progs = "apps/progs.h"; 51my $prov_headers = "providers/common/include/prov/der_dsa.h providers/common/include/prov/der_wrap.h providers/common/include/prov/der_rsa.h providers/common/include/prov/der_ecx.h providers/common/include/prov/der_sm2.h providers/common/include/prov/der_ec.h providers/common/include/prov/der_digests.h"; 52my $fips_ld = ($arch =~ m/linux/ ? "providers/fips.ld" : ""); 53my $cmd1 = "cd ../openssl; make -f $makefile clean build_generated $buildinf $progs $prov_headers $fips_ld;"; 54system($cmd1) == 0 or die "Error in system($cmd1)"; 55 56# Copy and move all arch dependent header files into config/archs 57make_path("$base_dir/crypto/include/internal", "$base_dir/include/openssl", 58 "$base_dir/include/crypto", "$base_dir/providers/common/include/prov", 59 "$base_dir/apps", 60 { 61 error => \my $make_path_err}); 62if (@$make_path_err) { 63 for my $diag (@$make_path_err) { 64 my ($file, $message) = %$diag; 65 die "make_path error: $file $message\n"; 66 } 67} 68copy("$src_dir/configdata.pm", "$base_dir/") or die "Copy failed: $!"; 69 70my @openssl_dir_headers = shift @ARGV; 71copy_headers(@openssl_dir_headers, 'openssl'); 72 73my @crypto_dir_headers = shift @ARGV; 74copy_headers(@crypto_dir_headers, 'crypto'); 75 76move("$src_dir/include/crypto/bn_conf.h", 77 "$base_dir/include/crypto/bn_conf.h") or die "Move failed: $!"; 78move("$src_dir/include/crypto/dso_conf.h", 79 "$base_dir/include/crypto/dso_conf.h") or die "Move failed: $!"; 80 81copy("$src_dir/$buildinf", 82 "$base_dir/crypto/") or die "Copy failed: $!"; 83move("$src_dir/$progs", 84 "$base_dir/include") or die "Copy failed: $!"; 85copy("$src_dir/apps/progs.c", 86 "$base_dir/apps") or die "Copy failed: $!"; 87 88copy("$src_dir/providers/common/include/prov/der_dsa.h", 89 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 90copy("$src_dir/providers/common/include/prov/der_wrap.h", 91 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 92copy("$src_dir/providers/common/include/prov/der_rsa.h", 93 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 94copy("$src_dir/providers/common/include/prov/der_ecx.h", 95 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 96copy("$src_dir/providers/common/include/prov/der_sm2.h", 97 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 98copy("$src_dir/providers/common/include/prov/der_ec.h", 99 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 100copy("$src_dir/providers/common/include/prov/der_digests.h", 101 "$base_dir/providers/common/include/prov/") or die "Copy failed: $!"; 102 103my $linker_script_dir = "<(PRODUCT_DIR)/../../deps/openssl/config/archs/$arch/$asm/providers"; 104my $fips_linker_script = ""; 105if ($fips_ld ne "" and not $is_win) { 106 $fips_linker_script = "$linker_script_dir/fips.ld"; 107 copy("$src_dir/providers/fips.ld", 108 "$base_dir/providers/fips.ld") or die "Copy failed: $!"; 109} 110 111 112# read openssl source lists from configdata.pm 113my @libapps_srcs = (); 114foreach my $obj (@{$unified_info{sources}->{'apps/libapps.a'}}) { 115 #print("libapps ${$unified_info{sources}->{$obj}}[0]\n"); 116 push(@libapps_srcs, ${$unified_info{sources}->{$obj}}[0]); 117} 118 119my @libssl_srcs = (); 120foreach my $obj (@{$unified_info{sources}->{libssl}}) { 121 push(@libssl_srcs, ${$unified_info{sources}->{$obj}}[0]); 122} 123 124my @libcrypto_srcs = (); 125my @generated_srcs = (); 126foreach my $obj (@{$unified_info{sources}->{'libcrypto'}}) { 127 my $src = ${$unified_info{sources}->{$obj}}[0]; 128 #print("libcrypto src: $src \n"); 129 # .S files should be preprocessed into .s 130 if ($unified_info{generate}->{$src}) { 131 # .S or .s files should be preprocessed into .asm for WIN 132 $src =~ s\.[sS]$\.asm\ if ($is_win); 133 push(@generated_srcs, $src); 134 } else { 135 if ($src =~ m/\.c$/) { 136 push(@libcrypto_srcs, $src); 137 } 138 } 139} 140 141if ($arch eq 'linux32-s390x' || $arch eq 'linux64-s390x') { 142 push(@libcrypto_srcs, 'crypto/bn/asm/s390x.S'); 143} 144 145my @lib_defines = (); 146foreach my $df (@{$unified_info{defines}->{libcrypto}}) { 147 #print("libcrypto defines: $df\n"); 148 push(@lib_defines, $df); 149} 150 151 152foreach my $obj (@{$unified_info{sources}->{'providers/libdefault.a'}}) { 153 my $src = ${$unified_info{sources}->{$obj}}[0]; 154 #print("libdefault src: $src \n"); 155 # .S files should be preprocessed into .s 156 if ($unified_info{generate}->{$src}) { 157 # .S or .s files should be preprocessed into .asm for WIN 158 $src =~ s\.[sS]$\.asm\ if ($is_win); 159 push(@generated_srcs, $src); 160 } else { 161 if ($src =~ m/\.c$/) { 162 push(@libcrypto_srcs, $src); 163 } 164 } 165} 166 167foreach my $obj (@{$unified_info{sources}->{'providers/libcommon.a'}}) { 168 my $src = ${$unified_info{sources}->{$obj}}[0]; 169 #print("libimplementations src: $src \n"); 170 # .S files should be preprocessed into .s 171 if ($unified_info{generate}->{$src}) { 172 # .S or .s files should be preprocessed into .asm for WIN 173 $src =~ s\.[sS]$\.asm\ if ($is_win); 174 push(@generated_srcs, $src); 175 } else { 176 if ($src =~ m/\.c$/) { 177 push(@libcrypto_srcs, $src); 178 } 179 } 180} 181 182foreach my $obj (@{$unified_info{sources}->{'providers/liblegacy.a'}}) { 183 my $src = ${$unified_info{sources}->{$obj}}[0]; 184 #print("liblegacy src: $src \n"); 185 # .S files should be preprocessed into .s 186 if ($unified_info{generate}->{$src}) { 187 # .S or .s files should be preprocessed into .asm for WIN 188 $src =~ s\.[sS]$\.asm\ if ($is_win); 189 push(@generated_srcs, $src); 190 } else { 191 if ($src =~ m/\.c$/) { 192 push(@libcrypto_srcs, $src); 193 } 194 } 195} 196 197foreach my $obj (@{$unified_info{sources}->{'providers/legacy'}}) { 198 if ($obj eq 'providers/legacy.ld' and not $is_win) { 199 push(@generated_srcs, $obj); 200 } else { 201 my $src = ${$unified_info{sources}->{$obj}}[0]; 202 #print("providers/fips obj: $obj, src: $src\n"); 203 if ($src =~ m/\.c$/) { 204 push(@libcrypto_srcs, $src); 205 } 206 } 207} 208 209my @libfips_srcs = (); 210foreach my $obj (@{$unified_info{sources}->{'providers/libfips.a'}}) { 211 my $src = ${$unified_info{sources}->{$obj}}[0]; 212 #print("providers/libfips.a obj: $obj src: $src \n"); 213 # .S files should be preprocessed into .s 214 if ($unified_info{generate}->{$src}) { 215 # .S or .s files should be preprocessed into .asm for WIN 216 #$src =~ s\.[sS]$\.asm\ if ($is_win); 217 #push(@generated_srcs, $src); 218 } else { 219 if ($src =~ m/\.c$/) { 220 push(@libfips_srcs, $src); 221 } 222 } 223} 224 225foreach my $obj (@{$unified_info{sources}->{'providers/libcommon.a'}}) { 226 my $src = ${$unified_info{sources}->{$obj}}[0]; 227 #print("providers/libfips.a obj: $obj src: $src \n"); 228 # .S files should be preprocessed into .s 229 if ($unified_info{generate}->{$src}) { 230 # .S or .s files should be preprocessed into .asm for WIN 231 #$src =~ s\.[sS]$\.asm\ if ($is_win); 232 #push(@generated_srcs, $src); 233 } else { 234 if ($src =~ m/\.c$/) { 235 push(@libfips_srcs, $src); 236 } 237 } 238} 239 240foreach my $obj (@{$unified_info{sources}->{'providers/fips'}}) { 241 if ($obj eq 'providers/fips.ld' and not $is_win) { 242 push(@generated_srcs, $obj); 243 } else { 244 my $src = ${$unified_info{sources}->{$obj}}[0]; 245 #print("providers/fips obj: $obj, src: $src\n"); 246 if ($src =~ m/\.c$/) { 247 push(@libfips_srcs, $src); 248 } 249 } 250} 251 252my @libfips_defines = (); 253foreach my $df (@{$unified_info{defines}->{'providers/libfips.a'}}) { 254 #print("libfips defines: $df\n"); 255 push(@libfips_defines, $df); 256} 257 258foreach my $df (@{$unified_info{defines}->{'providers/fips'}}) { 259 #print("libfips defines: $df\n"); 260 push(@libfips_defines, $df); 261} 262 263my @apps_openssl_srcs = (); 264foreach my $obj (@{$unified_info{sources}->{'apps/openssl'}}) { 265 push(@apps_openssl_srcs, ${$unified_info{sources}->{$obj}}[0]); 266} 267 268# Generate all asm files and copy into config/archs 269foreach my $src (@generated_srcs) { 270 my $cmd = "cd ../openssl; CC=gcc ASM=nasm make -f $makefile $src;" . 271 "cp --parents $src ../config/archs/$arch/$asm; cd ../config"; 272 system("$cmd") == 0 or die "Error in system($cmd)"; 273} 274 275$target{'lib_cppflags'} =~ s/-D//g; 276my @lib_cppflags = split(/ /, $target{'lib_cppflags'}); 277 278my @cflags = (); 279push(@cflags, @{$config{'cflags'}}); 280push(@cflags, @{$config{'CFLAGS'}}); 281push(@cflags, $target{'cflags'}); 282push(@cflags, $target{'CFLAGS'}); 283 284# AIX has own assembler not GNU as that does not support --noexecstack 285if ($arch =~ /aix/) { 286 @cflags = grep $_ ne '-Wa,--noexecstack', @cflags; 287} 288 289# Create openssl.gypi 290my $template = 291 Text::Template->new(TYPE => 'FILE', 292 SOURCE => 'openssl.gypi.tmpl', 293 DELIMITERS => [ "%%-", "-%%" ] 294 ); 295my $gypi = $template->fill_in( 296 HASH => { 297 libssl_srcs => \@libssl_srcs, 298 libcrypto_srcs => \@libcrypto_srcs, 299 lib_defines => \@lib_defines, 300 generated_srcs => \@generated_srcs, 301 config => \%config, 302 target => \%target, 303 cflags => \@cflags, 304 asm => \$asm, 305 arch => \$arch, 306 lib_cppflags => \@lib_cppflags, 307 is_win => \$is_win, 308 }); 309 310open(GYPI, "> ./archs/$arch/$asm/openssl.gypi"); 311print GYPI "$gypi"; 312close(GYPI); 313# 314# Create openssl-fips.gypi 315my $fipstemplate = 316 Text::Template->new(TYPE => 'FILE', 317 SOURCE => 'openssl-fips.gypi.tmpl', 318 DELIMITERS => [ "%%-", "-%%" ] 319 ); 320my $fipsgypi = $fipstemplate->fill_in( 321 HASH => { 322 libfips_srcs => \@libfips_srcs, 323 libfips_defines => \@libfips_defines, 324 generated_srcs => \@generated_srcs, 325 config => \%config, 326 target => \%target, 327 cflags => \@cflags, 328 asm => \$asm, 329 arch => \$arch, 330 lib_cppflags => \@lib_cppflags, 331 is_win => \$is_win, 332 linker_script => $fips_linker_script, 333 }); 334 335open(FIPSGYPI, "> ./archs/$arch/$asm/openssl-fips.gypi"); 336print FIPSGYPI "$fipsgypi"; 337close(FIPSGYPI); 338 339# Create openssl-cl.gypi 340my $cltemplate = 341 Text::Template->new(TYPE => 'FILE', 342 SOURCE => 'openssl-cl.gypi.tmpl', 343 DELIMITERS => [ "%%-", "-%%" ] 344 ); 345 346my $clgypi = $cltemplate->fill_in( 347 HASH => { 348 apps_openssl_srcs => \@apps_openssl_srcs, 349 lib_defines => \@lib_defines, 350 libapps_srcs => \@libapps_srcs, 351 config => \%config, 352 target => \%target, 353 cflags => \@cflags, 354 asm => \$asm, 355 arch => \$arch, 356 lib_cppflags => \@lib_cppflags, 357 is_win => \$is_win, 358 }); 359 360open(CLGYPI, "> ./archs/$arch/$asm/openssl-cl.gypi"); 361print CLGYPI "$clgypi"; 362close(CLGYPI); 363 364# Clean Up 365my $cmd2 ="cd $src_dir; make -f $makefile clean; make -f $makefile distclean;" . 366 "git clean -f $src_dir/crypto"; 367system($cmd2) == 0 or die "Error in system($cmd2)"; 368 369 370sub copy_headers { 371 my @headers = split / /, $_[0]; 372 my $inc_dir = $_[1]; 373 foreach my $header_name (@headers) { 374 # Copy the header from OpenSSL source directory to the arch specific dir. 375 #print("copy header $src_dir/include/$inc_dir/${header_name}.h to $base_dir/include/$inc_dir \n"); 376 copy("$src_dir/include/$inc_dir/${header_name}.h", 377 "$base_dir/include/$inc_dir/") or die "Copy failed: $!"; 378 } 379} 380