A local copy of OpenSSL from GitHub
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.

175 lines
4.0 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. my $flavour = shift;
  9. my $output = shift;
  10. open STDOUT,">$output" || die "can't open $output: $!";
  11. $flavour = "linux32" if (!$flavour or $flavour eq "void");
  12. my %GLOBALS;
  13. my $dotinlocallabels=($flavour=~/linux/)?1:0;
  14. ################################################################
  15. # directives which need special treatment on different platforms
  16. ################################################################
  17. my $arch = sub {
  18. if ($flavour =~ /linux/) { ".arch\t".join(',',@_); }
  19. else { ""; }
  20. };
  21. my $fpu = sub {
  22. if ($flavour =~ /linux/) { ".fpu\t".join(',',@_); }
  23. else { ""; }
  24. };
  25. my $hidden = sub {
  26. if ($flavour =~ /ios/) { ".private_extern\t".join(',',@_); }
  27. else { ".hidden\t".join(',',@_); }
  28. };
  29. my $comm = sub {
  30. my @args = split(/,\s*/,shift);
  31. my $name = @args[0];
  32. my $global = \$GLOBALS{$name};
  33. my $ret;
  34. if ($flavour =~ /ios32/) {
  35. $ret = ".comm\t_$name,@args[1]\n";
  36. $ret .= ".non_lazy_symbol_pointer\n";
  37. $ret .= "$name:\n";
  38. $ret .= ".indirect_symbol\t_$name\n";
  39. $ret .= ".long\t0";
  40. $name = "_$name";
  41. } else { $ret = ".comm\t".join(',',@args); }
  42. $$global = $name;
  43. $ret;
  44. };
  45. my $globl = sub {
  46. my $name = shift;
  47. my $global = \$GLOBALS{$name};
  48. my $ret;
  49. SWITCH: for ($flavour) {
  50. /ios/ && do { $name = "_$name";
  51. last;
  52. };
  53. }
  54. $ret = ".globl $name" if (!$ret);
  55. $$global = $name;
  56. $ret;
  57. };
  58. my $global = $globl;
  59. my $extern = sub {
  60. &$globl(@_);
  61. return; # return nothing
  62. };
  63. my $type = sub {
  64. if ($flavour =~ /linux/) { ".type\t".join(',',@_); }
  65. elsif ($flavour =~ /ios32/) { if (join(',',@_) =~ /(\w+),%function/) {
  66. "#ifdef __thumb2__\n".
  67. ".thumb_func $1\n".
  68. "#endif";
  69. }
  70. }
  71. else { ""; }
  72. };
  73. my $size = sub {
  74. if ($flavour =~ /linux/) { ".size\t".join(',',@_); }
  75. else { ""; }
  76. };
  77. my $inst = sub {
  78. if ($flavour =~ /linux/) { ".inst\t".join(',',@_); }
  79. else { ".long\t".join(',',@_); }
  80. };
  81. my $asciz = sub {
  82. my $line = join(",",@_);
  83. if ($line =~ /^"(.*)"$/)
  84. { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; }
  85. else
  86. { ""; }
  87. };
  88. sub range {
  89. my ($r,$sfx,$start,$end) = @_;
  90. join(",",map("$r$_$sfx",($start..$end)));
  91. }
  92. sub expand_line {
  93. my $line = shift;
  94. my @ret = ();
  95. pos($line)=0;
  96. while ($line =~ m/\G[^@\/\{\"]*/g) {
  97. if ($line =~ m/\G(@|\/\/|$)/gc) {
  98. last;
  99. }
  100. elsif ($line =~ m/\G\{/gc) {
  101. my $saved_pos = pos($line);
  102. $line =~ s/\G([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/e;
  103. pos($line) = $saved_pos;
  104. $line =~ m/\G[^\}]*\}/g;
  105. }
  106. elsif ($line =~ m/\G\"/gc) {
  107. $line =~ m/\G[^\"]*\"/g;
  108. }
  109. }
  110. $line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
  111. return $line;
  112. }
  113. while($line=<>) {
  114. if ($line =~ m/^\s*(#|@|\/\/)/) { print $line; next; }
  115. $line =~ s|/\*.*\*/||; # get rid of C-style comments...
  116. $line =~ s|^\s+||; # ... and skip white spaces in beginning...
  117. $line =~ s|\s+$||; # ... and at the end
  118. {
  119. $line =~ s|[\b\.]L(\w{2,})|L$1|g; # common denominator for Locallabel
  120. $line =~ s|\bL(\w{2,})|\.L$1|g if ($dotinlocallabels);
  121. }
  122. {
  123. $line =~ s|(^[\.\w]+)\:\s*||;
  124. my $label = $1;
  125. if ($label) {
  126. printf "%s:",($GLOBALS{$label} or $label);
  127. }
  128. }
  129. if ($line !~ m/^[#@]/) {
  130. $line =~ s|^\s*(\.?)(\S+)\s*||;
  131. my $c = $1; $c = "\t" if ($c eq "");
  132. my $mnemonic = $2;
  133. my $opcode;
  134. if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/) {
  135. $opcode = eval("\$$1_$2");
  136. } else {
  137. $opcode = eval("\$$mnemonic");
  138. }
  139. my $arg=expand_line($line);
  140. if (ref($opcode) eq 'CODE') {
  141. $line = &$opcode($arg);
  142. } elsif ($mnemonic) {
  143. $line = $c.$mnemonic;
  144. $line.= "\t$arg" if ($arg ne "");
  145. }
  146. }
  147. print $line if ($line);
  148. print "\n";
  149. }
  150. close STDOUT;