You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

225 regels
5.4 KiB

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