• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /usr/bin/env perl
2# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the OpenSSL license (the "License").  You may not use
5# this file except in compliance with the License.  You can obtain a copy
6# in the file LICENSE in the source distribution or at
7# https://www.openssl.org/source/license.html
8
9use strict;
10
11my $flavour = shift;
12my $output = shift;
13open STDOUT,">$output" || die "can't open $output: $!";
14
15$flavour = "linux32" if (!$flavour or $flavour eq "void");
16
17my %GLOBALS;
18my $dotinlocallabels=($flavour=~/linux/)?1:0;
19
20################################################################
21# directives which need special treatment on different platforms
22################################################################
23my $arch = sub {
24    if ($flavour =~ /linux/)	{ ".arch\t".join(',',@_); }
25    else			{ ""; }
26};
27my $fpu = sub {
28    if ($flavour =~ /linux/)	{ ".fpu\t".join(',',@_); }
29    else			{ ""; }
30};
31my $hidden = sub {
32    if ($flavour =~ /ios/)	{ ".private_extern\t".join(',',@_); }
33    else			{ ".hidden\t".join(',',@_); }
34};
35my $comm = sub {
36    my @args = split(/,\s*/,shift);
37    my $name = @args[0];
38    my $global = \$GLOBALS{$name};
39    my $ret;
40
41    if ($flavour =~ /ios32/)	{
42	$ret = ".comm\t_$name,@args[1]\n";
43	$ret .= ".non_lazy_symbol_pointer\n";
44	$ret .= "$name:\n";
45	$ret .= ".indirect_symbol\t_$name\n";
46	$ret .= ".long\t0";
47	$name = "_$name";
48    } else			{ $ret = ".comm\t".join(',',@args); }
49
50    $$global = $name;
51    $ret;
52};
53my $globl = sub {
54    my $name = shift;
55    my $global = \$GLOBALS{$name};
56    my $ret;
57
58    SWITCH: for ($flavour) {
59	/ios/		&& do { $name = "_$name";
60				last;
61			      };
62    }
63
64    $ret = ".globl	$name\n";
65    # All symbols in assembly files are hidden.
66    $ret .= &$hidden($name);
67    $$global = $name;
68    $ret;
69};
70my $global = $globl;
71my $extern = sub {
72    &$globl(@_);
73    return;	# return nothing
74};
75my $type = sub {
76    if ($flavour =~ /linux/)	{ ".type\t".join(',',@_); }
77    elsif ($flavour =~ /ios32/)	{ if (join(',',@_) =~ /(\w+),%function/) {
78					"#ifdef __thumb2__\n".
79					".thumb_func	$1\n".
80					"#endif";
81				  }
82			        }
83    else			{ ""; }
84};
85my $size = sub {
86    if ($flavour =~ /linux/)	{ ".size\t".join(',',@_); }
87    else			{ ""; }
88};
89my $inst = sub {
90    if ($flavour =~ /linux/)    { ".inst\t".join(',',@_); }
91    else                        { ".long\t".join(',',@_); }
92};
93my $asciz = sub {
94    my $line = join(",",@_);
95    if ($line =~ /^"(.*)"$/)
96    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
97    else
98    {	"";	}
99};
100my $section = sub {
101    if ($flavour =~ /ios/) {
102        if ($_[0] eq ".rodata") {
103            return ".section\t__TEXT,__const";
104        }
105        die "Unknown section name $_[0]";
106    } else {
107        return ".section\t" . join(",", @_);
108    }
109};
110
111sub range {
112  my ($r,$sfx,$start,$end) = @_;
113
114    join(",",map("$r$_$sfx",($start..$end)));
115}
116
117sub expand_line {
118  my $line = shift;
119  my @ret = ();
120
121    pos($line)=0;
122
123    while ($line =~ m/\G[^@\/\{\"]*/g) {
124	if ($line =~ m/\G(@|\/\/|$)/gc) {
125	    last;
126	}
127	elsif ($line =~ m/\G\{/gc) {
128	    my $saved_pos = pos($line);
129	    $line =~ s/\G([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/e;
130	    pos($line) = $saved_pos;
131	    $line =~ m/\G[^\}]*\}/g;
132	}
133	elsif ($line =~ m/\G\"/gc) {
134	    $line =~ m/\G[^\"]*\"/g;
135	}
136    }
137
138    $line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
139
140    return $line;
141}
142
143print <<___;
144// This file is generated from a similarly-named Perl script in the BoringSSL
145// source tree. Do not edit by hand.
146
147#if defined(__has_feature)
148#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM)
149#define OPENSSL_NO_ASM
150#endif
151#endif
152
153#if !defined(OPENSSL_NO_ASM)
154___
155
156print "#if defined(__arm__)\n" if ($flavour eq "linux32");
157print "#if defined(__aarch64__)\n" if ($flavour eq "linux64");
158
159print "#if defined(BORINGSSL_PREFIX)\n";
160print "#include <boringssl_prefix_symbols_asm.h>\n";
161print "#endif\n";
162
163while(my $line=<>) {
164
165    if ($line =~ m/^\s*(#|@|\/\/)/)	{ print $line; next; }
166
167    $line =~ s|/\*.*\*/||;	# get rid of C-style comments...
168    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
169    $line =~ s|\s+$||;		# ... and at the end
170
171    {
172	$line =~ s|[\b\.]L(\w{2,})|L$1|g;	# common denominator for Locallabel
173	$line =~ s|\bL(\w{2,})|\.L$1|g	if ($dotinlocallabels);
174    }
175
176    {
177	$line =~ s|(^[\.\w]+)\:\s*||;
178	my $label = $1;
179	if ($label) {
180	    printf "%s:",($GLOBALS{$label} or $label);
181	}
182    }
183
184    if ($line !~ m/^[#@]/) {
185	$line =~ s|^\s*(\.?)(\S+)\s*||;
186	my $c = $1; $c = "\t" if ($c eq "");
187	my $mnemonic = $2;
188	my $opcode;
189	if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/) {
190	    $opcode = eval("\$$1_$2");
191	} else {
192	    $opcode = eval("\$$mnemonic");
193	}
194
195	if ($flavour =~ /ios/) {
196	    # Mach-O and ELF use different syntax for these relocations. Note
197	    # that we require :pg_hi21: to be explicitly listed. It is normally
198	    # optional with adrp instructions.
199	    $line =~ s|:pg_hi21:(\w+)|\1\@PAGE|;
200	    $line =~ s|:lo12:(\w+)|\1\@PAGEOFF|;
201	} else {
202	    # Clang's integrated assembly does not support the optional
203	    # :pg_hi21: markers, so erase them.
204	    $line =~ s|:pg_hi21:||;
205	}
206
207	my $arg=expand_line($line);
208
209	if (ref($opcode) eq 'CODE') {
210		$line = &$opcode($arg);
211	} elsif ($mnemonic)         {
212		$line = $c.$mnemonic;
213		$line.= "\t$arg" if ($arg ne "");
214	}
215    }
216
217    print $line if ($line);
218    print "\n";
219}
220
221print "#endif\n" if ($flavour eq "linux32" || $flavour eq "linux64");
222print "#endif  // !OPENSSL_NO_ASM\n";
223
224close STDOUT;
225