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