2016-06-26 14:30:32 -04:00
|
|
|
#! /usr/bin/env perl
|
2020-12-11 11:36:54 -05:00
|
|
|
# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
2016-06-26 14:30:32 -04:00
|
|
|
#
|
|
|
|
# Licensed under the OpenSSL license (the "License"). You may not use
|
|
|
|
# this file except in compliance with the License. You can obtain a copy
|
|
|
|
# in the file LICENSE in the source distribution or at
|
|
|
|
# https://www.openssl.org/source/license.html
|
|
|
|
|
2014-06-20 12:00:00 -07:00
|
|
|
|
|
|
|
# require 'x86asm.pl';
|
2017-05-11 18:19:53 -04:00
|
|
|
# &asm_init(<flavor>[,$i386only]);
|
2014-06-20 12:00:00 -07:00
|
|
|
# &function_begin("foo");
|
|
|
|
# ...
|
|
|
|
# &function_end("foo");
|
|
|
|
# &asm_finish
|
|
|
|
|
|
|
|
$out=();
|
|
|
|
$i386=0;
|
|
|
|
|
|
|
|
# AUTOLOAD is this context has quite unpleasant side effect, namely
|
|
|
|
# that typos in function calls effectively go to assembler output,
|
|
|
|
# but on the pros side we don't have to implement one subroutine per
|
|
|
|
# each opcode...
|
|
|
|
sub ::AUTOLOAD
|
|
|
|
{ my $opcode = $AUTOLOAD;
|
|
|
|
|
|
|
|
die "more than 4 arguments passed to $opcode" if ($#_>3);
|
|
|
|
|
|
|
|
$opcode =~ s/.*:://;
|
|
|
|
if ($opcode =~ /^push/) { $stack+=4; }
|
|
|
|
elsif ($opcode =~ /^pop/) { $stack-=4; }
|
|
|
|
|
|
|
|
&generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
|
|
|
|
}
|
|
|
|
|
2021-05-11 16:25:57 -07:00
|
|
|
# record_function_hit(int) writes a byte with value one to the given offset of
|
|
|
|
# |BORINGSSL_function_hit|, but only if BORINGSSL_DISPATCH_TEST is defined.
|
|
|
|
# This is used in impl_dispatch_test.cc to test whether the expected assembly
|
|
|
|
# functions are triggered by high-level API calls.
|
|
|
|
sub ::record_function_hit
|
|
|
|
{ my($index)=@_;
|
|
|
|
&preprocessor_ifdef("BORINGSSL_DISPATCH_TEST");
|
|
|
|
&push("ebx");
|
|
|
|
&push("edx");
|
|
|
|
&call(&label("pic"));
|
|
|
|
&set_label("pic");
|
|
|
|
&blindpop("ebx");
|
|
|
|
&lea("ebx",&DWP("BORINGSSL_function_hit+$index"."-".&label("pic"),"ebx"));
|
|
|
|
&mov("edx", 1);
|
|
|
|
&movb(&BP(0, "ebx"), "dl");
|
|
|
|
&pop("edx");
|
|
|
|
&pop("ebx");
|
|
|
|
&preprocessor_endif();
|
|
|
|
}
|
|
|
|
|
2014-06-20 12:00:00 -07:00
|
|
|
sub ::emit
|
|
|
|
{ my $opcode=shift;
|
|
|
|
|
|
|
|
if ($#_==-1) { push(@out,"\t$opcode\n"); }
|
|
|
|
else { push(@out,"\t$opcode\t".join(',',@_)."\n"); }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::LB
|
|
|
|
{ $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
|
|
|
|
$1."l";
|
|
|
|
}
|
|
|
|
sub ::HB
|
|
|
|
{ $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
|
|
|
|
$1."h";
|
|
|
|
}
|
|
|
|
sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num); }
|
|
|
|
sub ::stack_pop { my $num=$_[0]*4; $stack-=$num; &add("esp",$num); }
|
|
|
|
sub ::blindpop { &pop($_[0]); $stack+=4; }
|
|
|
|
sub ::wparam { &DWP($stack+4*$_[0],"esp"); }
|
|
|
|
sub ::swtmp { &DWP(4*$_[0],"esp"); }
|
|
|
|
|
|
|
|
sub ::bswap
|
|
|
|
{ if ($i386) # emulate bswap for i386
|
|
|
|
{ &comment("bswap @_");
|
|
|
|
&xchg(&HB(@_),&LB(@_));
|
|
|
|
&ror (@_,16);
|
|
|
|
&xchg(&HB(@_),&LB(@_));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ &generic("bswap",@_); }
|
|
|
|
}
|
|
|
|
# These are made-up opcodes introduced over the years essentially
|
|
|
|
# by ignorance, just alias them to real ones...
|
|
|
|
sub ::movb { &mov(@_); }
|
|
|
|
sub ::xorb { &xor(@_); }
|
|
|
|
sub ::rotl { &rol(@_); }
|
|
|
|
sub ::rotr { &ror(@_); }
|
|
|
|
sub ::exch { &xchg(@_); }
|
|
|
|
sub ::halt { &hlt; }
|
|
|
|
sub ::movz { &movzx(@_); }
|
|
|
|
sub ::pushf { &pushfd; }
|
|
|
|
sub ::popf { &popfd; }
|
|
|
|
|
|
|
|
# 3 argument instructions
|
|
|
|
sub ::movq
|
|
|
|
{ my($p1,$p2,$optimize)=@_;
|
|
|
|
|
|
|
|
if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
|
|
|
|
# movq between mmx registers can sink Intel CPUs
|
|
|
|
{ &::pshufw($p1,$p2,0xe4); }
|
|
|
|
else
|
|
|
|
{ &::generic("movq",@_); }
|
|
|
|
}
|
|
|
|
|
|
|
|
# SSE>2 instructions
|
|
|
|
my %regrm = ( "eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3,
|
|
|
|
"esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7 );
|
|
|
|
sub ::pextrd
|
|
|
|
{ my($dst,$src,$imm)=@_;
|
|
|
|
if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/)
|
|
|
|
{ &::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm); }
|
|
|
|
else
|
|
|
|
{ &::generic("pextrd",@_); }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::pinsrd
|
|
|
|
{ my($dst,$src,$imm)=@_;
|
|
|
|
if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/)
|
|
|
|
{ &::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm); }
|
|
|
|
else
|
|
|
|
{ &::generic("pinsrd",@_); }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::pshufb
|
|
|
|
{ my($dst,$src)=@_;
|
|
|
|
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
|
|
|
{ &data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2); }
|
|
|
|
else
|
|
|
|
{ &::generic("pshufb",@_); }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::palignr
|
|
|
|
{ my($dst,$src,$imm)=@_;
|
|
|
|
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
|
|
|
{ &::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm); }
|
|
|
|
else
|
|
|
|
{ &::generic("palignr",@_); }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::pclmulqdq
|
|
|
|
{ my($dst,$src,$imm)=@_;
|
|
|
|
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
|
|
|
{ &::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm); }
|
|
|
|
else
|
|
|
|
{ &::generic("pclmulqdq",@_); }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::rdrand
|
|
|
|
{ my ($dst)=@_;
|
|
|
|
if ($dst =~ /(e[a-dsd][ixp])/)
|
|
|
|
{ &::data_byte(0x0f,0xc7,0xf0|$regrm{$dst}); }
|
|
|
|
else
|
|
|
|
{ &::generic("rdrand",@_); }
|
|
|
|
}
|
|
|
|
|
2016-06-26 14:30:32 -04:00
|
|
|
sub ::rdseed
|
|
|
|
{ my ($dst)=@_;
|
|
|
|
if ($dst =~ /(e[a-dsd][ixp])/)
|
|
|
|
{ &::data_byte(0x0f,0xc7,0xf8|$regrm{$dst}); }
|
|
|
|
else
|
|
|
|
{ &::generic("rdrand",@_); }
|
|
|
|
}
|
|
|
|
|
2014-06-20 12:00:00 -07:00
|
|
|
sub rxb {
|
|
|
|
local *opcode=shift;
|
|
|
|
my ($dst,$src1,$src2,$rxb)=@_;
|
|
|
|
|
|
|
|
$rxb|=0x7<<5;
|
|
|
|
$rxb&=~(0x04<<5) if($dst>=8);
|
|
|
|
$rxb&=~(0x01<<5) if($src1>=8);
|
|
|
|
$rxb&=~(0x02<<5) if($src2>=8);
|
|
|
|
push @opcode,$rxb;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::vprotd
|
|
|
|
{ my $args=join(',',@_);
|
|
|
|
if ($args =~ /xmm([0-7]),xmm([0-7]),([x0-9a-f]+)/)
|
|
|
|
{ my @opcode=(0x8f);
|
|
|
|
rxb(\@opcode,$1,$2,-1,0x08);
|
|
|
|
push @opcode,0x78,0xc2;
|
|
|
|
push @opcode,0xc0|($2&7)|(($1&7)<<3); # ModR/M
|
|
|
|
my $c=$3;
|
|
|
|
push @opcode,$c=~/^0/?oct($c):$c;
|
|
|
|
&::data_byte(@opcode);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ &::generic("vprotd",@_); }
|
|
|
|
}
|
|
|
|
|
2016-06-26 14:30:32 -04:00
|
|
|
sub ::endbranch
|
|
|
|
{
|
|
|
|
&::data_byte(0xf3,0x0f,0x1e,0xfb);
|
|
|
|
}
|
|
|
|
|
2014-06-20 12:00:00 -07:00
|
|
|
# label management
|
|
|
|
$lbdecor="L"; # local label decoration, set by package
|
|
|
|
$label="000";
|
|
|
|
|
|
|
|
sub ::islabel # see is argument is a known label
|
|
|
|
{ my $i;
|
|
|
|
foreach $i (values %label) { return $i if ($i eq $_[0]); }
|
|
|
|
$label{$_[0]}; # can be undef
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::label # instantiate a function-scope label
|
|
|
|
{ if (!defined($label{$_[0]}))
|
|
|
|
{ $label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++; }
|
|
|
|
$label{$_[0]};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::LABEL # instantiate a file-scope label
|
|
|
|
{ $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
|
|
|
|
$label{$_[0]};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::static_label { &::LABEL($_[0],$lbdecor.$_[0]); }
|
|
|
|
|
|
|
|
sub ::set_label_B { push(@out,"@_:\n"); }
|
|
|
|
sub ::set_label
|
|
|
|
{ my $label=&::label($_[0]);
|
|
|
|
&::align($_[1]) if ($_[1]>1);
|
|
|
|
&::set_label_B($label);
|
|
|
|
$label;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::wipe_labels # wipes function-scope labels
|
|
|
|
{ foreach $i (keys %label)
|
|
|
|
{ delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/); }
|
|
|
|
}
|
|
|
|
|
|
|
|
# subroutine management
|
|
|
|
sub ::function_begin
|
|
|
|
{ &function_begin_B(@_);
|
|
|
|
$stack=4;
|
|
|
|
&push("ebp");
|
|
|
|
&push("ebx");
|
|
|
|
&push("esi");
|
|
|
|
&push("edi");
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::function_end
|
|
|
|
{ &pop("edi");
|
|
|
|
&pop("esi");
|
|
|
|
&pop("ebx");
|
|
|
|
&pop("ebp");
|
|
|
|
&ret();
|
|
|
|
&function_end_B(@_);
|
|
|
|
$stack=0;
|
|
|
|
&wipe_labels();
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::function_end_A
|
|
|
|
{ &pop("edi");
|
|
|
|
&pop("esi");
|
|
|
|
&pop("ebx");
|
|
|
|
&pop("ebp");
|
|
|
|
&ret();
|
|
|
|
$stack+=16; # readjust esp as if we didn't pop anything
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::asciz
|
|
|
|
{ my @str=unpack("C*",shift);
|
|
|
|
push @str,0;
|
|
|
|
while ($#str>15) {
|
|
|
|
&data_byte(@str[0..15]);
|
|
|
|
foreach (0..15) { shift @str; }
|
|
|
|
}
|
|
|
|
&data_byte(@str) if (@str);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub ::asm_finish
|
|
|
|
{ &file_end();
|
2021-10-19 15:42:05 -04:00
|
|
|
my $comment = "//";
|
2020-12-11 11:36:54 -05:00
|
|
|
$comment = ";" if ($win32);
|
2018-11-21 13:02:52 -06:00
|
|
|
print <<___;
|
|
|
|
$comment This file is generated from a similarly-named Perl script in the BoringSSL
|
|
|
|
$comment source tree. Do not edit by hand.
|
|
|
|
|
|
|
|
___
|
2020-12-11 11:36:54 -05:00
|
|
|
if ($win32) {
|
2018-11-25 20:21:38 -06:00
|
|
|
print <<___ unless $masm;
|
2023-09-27 21:15:24 -07:00
|
|
|
\%include "ring_core_generated/prefix_symbols_nasm.inc"
|
Fully condition all assembly files.
For the C files, rather than force the caller to juggle
crypto_linux_sources, etc., we just wrap the whole file in ifdefs and
ask the callers to link everything together.
Assembly is typically built by a different tool, so we have less room
here. However, there are really only two families of tools we care
about: gas (which runs the C preprocessor) and nasm (which has its own
preprocessor). Callers should be able to limit themselves to
special-casing Windows x86(_64) for NASM and then pass all the remaining
assembly files to their gas-like tool. File-wide ifdefs can take care of
the rest.
We're almost set up to allow this, except the files condition on
architecture, but not OS. Add __ELF__, __APPLE__, and _WIN32 conditions
as appropriate.
One subtlety: the semantics of .note.GNU-stack are that *any* unmarked
object file makes the stack executable. (In current GNU ld. lld doesn't
have this issue, and GNU ld claims they'll remove it in a later
release.) Empirically, this doesn't seem to apply to empty object files
but, to be safe, we should ensure all object files have the marking.
That leads to a second subtlety: on targets where @ is a comment,
@progbits is spelled %progbits, per [0]. If we want all .S files to work
in all targets, that includes these markers. Fortunately, %progbits
appears to work universally (see [1], [2], [3], [4]), so I've just
switched us to that spelling.
I've also tightened up the __arm__ and __aarch64__ checks to __ARMEL__
and __AARCH64EL__. We don't support big-endian Arm (or any other
platform) and, even if we did, the conditions in the assembly files
should match the conditions in the C files that pull them in.
This CL doesn't change our build to take advantage of this (though I'll
give it a go later), just makes it possible for builds to do it.
[0] https://sourceware.org/binutils/docs/as/Section.html
[1] https://patchwork.kernel.org/project/linux-crypto/patch/20170119212805.18049-1-dvlasenk@redhat.com/#20050285
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92820#c11
[3] https://sourceware.org/legacy-ml/gdb-patches/2016-01/msg00319.html
[4] https://github.com/llvm/llvm-project/commit/de990b270d73632a834cb37e6ea50db093321aad
Bug: 542
Change-Id: I0a8ded24423087c0da13bd0335cbd757d4eee65a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55626
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2022-11-19 10:15:55 -05:00
|
|
|
\%ifidn __OUTPUT_FORMAT__, win32
|
2018-11-25 20:21:38 -06:00
|
|
|
___
|
Fully condition all assembly files.
For the C files, rather than force the caller to juggle
crypto_linux_sources, etc., we just wrap the whole file in ifdefs and
ask the callers to link everything together.
Assembly is typically built by a different tool, so we have less room
here. However, there are really only two families of tools we care
about: gas (which runs the C preprocessor) and nasm (which has its own
preprocessor). Callers should be able to limit themselves to
special-casing Windows x86(_64) for NASM and then pass all the remaining
assembly files to their gas-like tool. File-wide ifdefs can take care of
the rest.
We're almost set up to allow this, except the files condition on
architecture, but not OS. Add __ELF__, __APPLE__, and _WIN32 conditions
as appropriate.
One subtlety: the semantics of .note.GNU-stack are that *any* unmarked
object file makes the stack executable. (In current GNU ld. lld doesn't
have this issue, and GNU ld claims they'll remove it in a later
release.) Empirically, this doesn't seem to apply to empty object files
but, to be safe, we should ensure all object files have the marking.
That leads to a second subtlety: on targets where @ is a comment,
@progbits is spelled %progbits, per [0]. If we want all .S files to work
in all targets, that includes these markers. Fortunately, %progbits
appears to work universally (see [1], [2], [3], [4]), so I've just
switched us to that spelling.
I've also tightened up the __arm__ and __aarch64__ checks to __ARMEL__
and __AARCH64EL__. We don't support big-endian Arm (or any other
platform) and, even if we did, the conditions in the assembly files
should match the conditions in the C files that pull them in.
This CL doesn't change our build to take advantage of this (though I'll
give it a go later), just makes it possible for builds to do it.
[0] https://sourceware.org/binutils/docs/as/Section.html
[1] https://patchwork.kernel.org/project/linux-crypto/patch/20170119212805.18049-1-dvlasenk@redhat.com/#20050285
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92820#c11
[3] https://sourceware.org/legacy-ml/gdb-patches/2016-01/msg00319.html
[4] https://github.com/llvm/llvm-project/commit/de990b270d73632a834cb37e6ea50db093321aad
Bug: 542
Change-Id: I0a8ded24423087c0da13bd0335cbd757d4eee65a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55626
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2022-11-19 10:15:55 -05:00
|
|
|
print @out;
|
2023-01-25 17:40:42 -05:00
|
|
|
print <<___ unless $masm;
|
|
|
|
\%else
|
|
|
|
; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738
|
|
|
|
ret
|
|
|
|
\%endif
|
|
|
|
___
|
2018-11-25 20:21:38 -06:00
|
|
|
} else {
|
Fully condition all assembly files.
For the C files, rather than force the caller to juggle
crypto_linux_sources, etc., we just wrap the whole file in ifdefs and
ask the callers to link everything together.
Assembly is typically built by a different tool, so we have less room
here. However, there are really only two families of tools we care
about: gas (which runs the C preprocessor) and nasm (which has its own
preprocessor). Callers should be able to limit themselves to
special-casing Windows x86(_64) for NASM and then pass all the remaining
assembly files to their gas-like tool. File-wide ifdefs can take care of
the rest.
We're almost set up to allow this, except the files condition on
architecture, but not OS. Add __ELF__, __APPLE__, and _WIN32 conditions
as appropriate.
One subtlety: the semantics of .note.GNU-stack are that *any* unmarked
object file makes the stack executable. (In current GNU ld. lld doesn't
have this issue, and GNU ld claims they'll remove it in a later
release.) Empirically, this doesn't seem to apply to empty object files
but, to be safe, we should ensure all object files have the marking.
That leads to a second subtlety: on targets where @ is a comment,
@progbits is spelled %progbits, per [0]. If we want all .S files to work
in all targets, that includes these markers. Fortunately, %progbits
appears to work universally (see [1], [2], [3], [4]), so I've just
switched us to that spelling.
I've also tightened up the __arm__ and __aarch64__ checks to __ARMEL__
and __AARCH64EL__. We don't support big-endian Arm (or any other
platform) and, even if we did, the conditions in the assembly files
should match the conditions in the C files that pull them in.
This CL doesn't change our build to take advantage of this (though I'll
give it a go later), just makes it possible for builds to do it.
[0] https://sourceware.org/binutils/docs/as/Section.html
[1] https://patchwork.kernel.org/project/linux-crypto/patch/20170119212805.18049-1-dvlasenk@redhat.com/#20050285
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92820#c11
[3] https://sourceware.org/legacy-ml/gdb-patches/2016-01/msg00319.html
[4] https://github.com/llvm/llvm-project/commit/de990b270d73632a834cb37e6ea50db093321aad
Bug: 542
Change-Id: I0a8ded24423087c0da13bd0335cbd757d4eee65a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55626
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2022-11-19 10:15:55 -05:00
|
|
|
my $target;
|
|
|
|
if ($elf) {
|
|
|
|
$target = "defined(__ELF__)";
|
|
|
|
} elsif ($macosx) {
|
|
|
|
$target = "defined(__APPLE__)";
|
|
|
|
} else {
|
|
|
|
die "unknown target";
|
|
|
|
}
|
|
|
|
|
2018-11-25 20:21:38 -06:00
|
|
|
print <<___;
|
2023-09-29 12:52:11 -07:00
|
|
|
#include <ring-core/asm_base.h>
|
Consistently include BTI markers in every assembly file
Trying to migrate Chromium to the "link all the asm files together"
strategy broke the aarch64 Android build because some of the ifdef'd out
assembly files were missing the .note.gnu.property section for BTI. If
we add support for IBT, that'll be another one.
To fix this, introduce <openssl/asm_base.h>, which must be included at
the start of every assembly file (before the target ifdefs). This does a
couple things:
- It emits BTI and noexecstack markers into every assembly file, even
those that ifdef themselves out.
- It resolves the MSan -> OPENSSL_NO_ASM logic, so we only need to do it
once.
- It defines the same OPENSSL_X86_64, etc., defines we set elsewhere, so
we can ensure they're consistent.
This required carving files up a bit. <openssl/base.h> has a lot of
things, such that trying to guard everything in it on __ASSEMBLER__
would be tedious. Instead, I moved the target defines to a new
<openssl/target.h>. Then <openssl/asm_base.h> is the new header that
pulls in all those things.
Bug: 542
Change-Id: I1682b4d929adea72908655fa1bb15765a6b3473b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60765
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2023-06-12 18:11:13 -04:00
|
|
|
|
|
|
|
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && $target
|
Fully condition all assembly files.
For the C files, rather than force the caller to juggle
crypto_linux_sources, etc., we just wrap the whole file in ifdefs and
ask the callers to link everything together.
Assembly is typically built by a different tool, so we have less room
here. However, there are really only two families of tools we care
about: gas (which runs the C preprocessor) and nasm (which has its own
preprocessor). Callers should be able to limit themselves to
special-casing Windows x86(_64) for NASM and then pass all the remaining
assembly files to their gas-like tool. File-wide ifdefs can take care of
the rest.
We're almost set up to allow this, except the files condition on
architecture, but not OS. Add __ELF__, __APPLE__, and _WIN32 conditions
as appropriate.
One subtlety: the semantics of .note.GNU-stack are that *any* unmarked
object file makes the stack executable. (In current GNU ld. lld doesn't
have this issue, and GNU ld claims they'll remove it in a later
release.) Empirically, this doesn't seem to apply to empty object files
but, to be safe, we should ensure all object files have the marking.
That leads to a second subtlety: on targets where @ is a comment,
@progbits is spelled %progbits, per [0]. If we want all .S files to work
in all targets, that includes these markers. Fortunately, %progbits
appears to work universally (see [1], [2], [3], [4]), so I've just
switched us to that spelling.
I've also tightened up the __arm__ and __aarch64__ checks to __ARMEL__
and __AARCH64EL__. We don't support big-endian Arm (or any other
platform) and, even if we did, the conditions in the assembly files
should match the conditions in the C files that pull them in.
This CL doesn't change our build to take advantage of this (though I'll
give it a go later), just makes it possible for builds to do it.
[0] https://sourceware.org/binutils/docs/as/Section.html
[1] https://patchwork.kernel.org/project/linux-crypto/patch/20170119212805.18049-1-dvlasenk@redhat.com/#20050285
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92820#c11
[3] https://sourceware.org/legacy-ml/gdb-patches/2016-01/msg00319.html
[4] https://github.com/llvm/llvm-project/commit/de990b270d73632a834cb37e6ea50db093321aad
Bug: 542
Change-Id: I0a8ded24423087c0da13bd0335cbd757d4eee65a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55626
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2022-11-19 10:15:55 -05:00
|
|
|
___
|
|
|
|
print @out;
|
|
|
|
print <<___;
|
Consistently include BTI markers in every assembly file
Trying to migrate Chromium to the "link all the asm files together"
strategy broke the aarch64 Android build because some of the ifdef'd out
assembly files were missing the .note.gnu.property section for BTI. If
we add support for IBT, that'll be another one.
To fix this, introduce <openssl/asm_base.h>, which must be included at
the start of every assembly file (before the target ifdefs). This does a
couple things:
- It emits BTI and noexecstack markers into every assembly file, even
those that ifdef themselves out.
- It resolves the MSan -> OPENSSL_NO_ASM logic, so we only need to do it
once.
- It defines the same OPENSSL_X86_64, etc., defines we set elsewhere, so
we can ensure they're consistent.
This required carving files up a bit. <openssl/base.h> has a lot of
things, such that trying to guard everything in it on __ASSEMBLER__
would be tedious. Instead, I moved the target defines to a new
<openssl/target.h>. Then <openssl/asm_base.h> is the new header that
pulls in all those things.
Bug: 542
Change-Id: I1682b4d929adea72908655fa1bb15765a6b3473b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60765
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
2023-06-12 18:11:13 -04:00
|
|
|
#endif // !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && $target
|
2018-11-25 20:21:38 -06:00
|
|
|
___
|
|
|
|
}
|
2014-06-20 12:00:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
sub ::asm_init
|
2017-05-11 18:19:53 -04:00
|
|
|
{ my ($type,$cpu)=@_;
|
2014-06-20 12:00:00 -07:00
|
|
|
|
|
|
|
$i386=$cpu;
|
|
|
|
|
2020-12-11 11:36:54 -05:00
|
|
|
$elf=$cpp=$coff=$aout=$macosx=$win32=$mwerks=$android=0;
|
2014-06-20 12:00:00 -07:00
|
|
|
if (($type eq "elf"))
|
|
|
|
{ $elf=1; require "x86gas.pl"; }
|
2014-06-20 12:00:00 -07:00
|
|
|
elsif (($type eq "elf-1"))
|
|
|
|
{ $elf=-1; require "x86gas.pl"; }
|
2014-06-20 12:00:00 -07:00
|
|
|
elsif (($type eq "a\.out"))
|
|
|
|
{ $aout=1; require "x86gas.pl"; }
|
|
|
|
elsif (($type eq "coff" or $type eq "gaswin"))
|
|
|
|
{ $coff=1; require "x86gas.pl"; }
|
|
|
|
elsif (($type eq "win32n"))
|
|
|
|
{ $win32=1; require "x86nasm.pl"; }
|
|
|
|
elsif (($type eq "win32"))
|
2018-11-25 20:21:38 -06:00
|
|
|
{ $win32=1; $masm=1; require "x86masm.pl"; }
|
2014-06-20 12:00:00 -07:00
|
|
|
elsif (($type eq "macosx"))
|
|
|
|
{ $aout=1; $macosx=1; require "x86gas.pl"; }
|
|
|
|
elsif (($type eq "android"))
|
|
|
|
{ $elf=1; $android=1; require "x86gas.pl"; }
|
|
|
|
else
|
|
|
|
{ print STDERR <<"EOF";
|
|
|
|
Pick one target type from
|
|
|
|
elf - Linux, FreeBSD, Solaris x86, etc.
|
|
|
|
a.out - DJGPP, elder OpenBSD, etc.
|
|
|
|
coff - GAS/COFF such as Win32 targets
|
|
|
|
win32n - Windows 95/Windows NT NASM format
|
|
|
|
macosx - Mac OS X
|
|
|
|
EOF
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
$pic=0;
|
|
|
|
for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
|
|
|
|
|
2017-05-11 18:19:53 -04:00
|
|
|
&file();
|
2014-06-20 12:00:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
sub ::hidden {}
|
|
|
|
|
|
|
|
1;
|