(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/ms/uplink.pl

    1: #!/usr/bin/env perl
    2: #
    3: # For Microsoft CL this is implemented as inline assembler. So that
    4: # even though this script can generate even Win32 code, we'll be
    5: # using it primarily to generate Win64 modules. Both IA-64 and AMD64
    6: # are supported...
    7: 
    8: # pull APPLINK_MAX value from applink.c...
    9: $applink_c=$0;
   10: $applink_c=~s|[^/\\]+$||g;
   11: $applink_c.="applink.c";
   12: open(INPUT,$applink_c) || die "can't open $applink_c: $!";
   13: @max=grep {/APPLINK_MAX\s+(\d+)/} <INPUT>;
   14: close(INPUT);
   15: ($#max==0) or die "can't find APPLINK_MAX in $applink_c";
   16: 
   17: $max[0]=~/APPLINK_MAX\s+(\d+)/;
   18: $N=$1;  # number of entries in OPENSSL_UplinkTable not including
   19:         # OPENSSL_UplinkTable[0], which contains this value...
   20: 
   21: # Idea is to fill the OPENSSL_UplinkTable with pointers to stubs
   22: # which invoke 'void OPENSSL_Uplink (ULONG_PTR *table,int index)';
   23: # and then dereference themselves. Latter shall result in endless
   24: # loop *unless* OPENSSL_Uplink does not replace 'table[index]' with
   25: # something else, e.g. as 'table[index]=unimplemented;'...
   26: 
   27: $arg = shift;
   28: #( defined shift || open STDOUT,">$arg" ) || die "can't open $arg: $!";
   29: 
   30: if ($arg =~ /win32n/)   { ia32nasm();  }
   31: elsif ($arg =~ /win32/) { ia32masm();  }
   32: elsif ($arg =~ /coff/)  { ia32gas();   }
   33: elsif ($arg =~ /win64i/ or $arg =~ /ia64/)      { ia64ias();   }
   34: elsif ($arg =~ /win64a/ or $arg =~ /amd64/)     { amd64masm(); }
   35: else    { die "nonsense $arg"; }
   36: 
   37: sub ia32gas() {
   38: print <<___;
   39: .text
   40: ___
   41: for ($i=1;$i<=$N;$i++) {
   42: print <<___;
   43: .def    .Lazy$i;   .scl      3;   .type     32; .endef
   44: .align  4
   45: .Lazy$i:
   46:         pushl  \$$i
   47:         pushl  \$_OPENSSL_UplinkTable
   48:         call   _OPENSSL_Uplink
   49:         addl   \$8,%esp
   50:         jmp    *(_OPENSSL_UplinkTable+4*$i)
   51: ___
   52: }
   53: print <<___;
   54: .data
   55: .align  4
   56: .globl  _OPENSSL_UplinkTable
   57: _OPENSSL_UplinkTable:
   58:         .long  $N
   59: ___
   60: for ($i=1;$i<=$N;$i++) {   print "      .long        .Lazy$i\n";   }
   61: }
   62: 
   63: sub ia32masm() {
   64: print <<___;
   65: .386P
   66: .model  FLAT
   67: 
   68: _DATA   SEGMENT
   69: PUBLIC  _OPENSSL_UplinkTable
   70: _OPENSSL_UplinkTable    DD $N      ; amount of following entries
   71: ___
   72: for ($i=1;$i<=$N;$i++) {   print "      DD   FLAT:\$lazy$i\n";   }
   73: print <<___;
   74: _DATA   ENDS
   75: 
   76: _TEXT   SEGMENT
   77: EXTRN   _OPENSSL_Uplink:NEAR
   78: ___
   79: for ($i=1;$i<=$N;$i++) {
   80: print <<___;
   81: ALIGN   4
   82: \$lazy$i        PROC NEAR
   83:         push   $i
   84:         push   OFFSET FLAT:_OPENSSL_UplinkTable
   85:         call   _OPENSSL_Uplink
   86:         add    esp,8
   87:         jmp    DWORD PTR _OPENSSL_UplinkTable+4*$i
   88: \$lazy$i        ENDP
   89: ___
   90: }
   91: print <<___;
   92: ALIGN   4
   93: _TEXT   ENDS
   94: END
   95: ___
   96: }
   97: 
   98: sub ia32nasm() {
   99: print <<___;
  100: SEGMENT .data
  101: GLOBAL  _OPENSSL_UplinkTable
  102: _OPENSSL_UplinkTable    DD $N      ; amount of following entries
  103: ___
  104: for ($i=1;$i<=$N;$i++) {   print "      DD   \$lazy$i\n";   }
  105: print <<___;
  106: 
  107: SEGMENT .text
  108: EXTERN  _OPENSSL_Uplink
  109: ___
  110: for ($i=1;$i<=$N;$i++) {
  111: print <<___;
  112: ALIGN   4
  113: \$lazy$i:
  114:         push   $i
  115:         push   _OPENSSL_UplinkTable
  116:         call   _OPENSSL_Uplink
  117:         add    esp,8
  118:         jmp    [_OPENSSL_UplinkTable+4*$i]
  119: ___
  120: }
  121: print <<___;
  122: ALIGN   4
  123: END
  124: ___
  125: }
  126: 
  127: sub ia64ias () {
  128: local $V=8;     # max number of args uplink functions may accept...
  129: print <<___;
  130: .data
  131: .global OPENSSL_UplinkTable#
  132: OPENSSL_UplinkTable:    data8      $N   // amount of following entries
  133: ___
  134: for ($i=1;$i<=$N;$i++) {   print "      data8        \@fptr(lazy$i#)\n";   }
  135: print <<___;
  136: .size   OPENSSL_UplinkTable,.-OPENSSL_UplinkTable#
  137: 
  138: .text
  139: .global OPENSSL_Uplink#
  140: .type   OPENSSL_Uplink#,\@function
  141: ___
  142: for ($i=1;$i<=$N;$i++) {
  143: print <<___;
  144: .proc   lazy$i
  145: lazy$i:
  146: { .mii; alloc   loc0=ar.pfs,$V,3,2,0
  147:         mov    loc1=b0
  148:         addl   loc2=\@ltoff(OPENSSL_UplinkTable#),gp     };;
  149: { .mmi; ld8     out0=[loc2]
  150:         mov    out1=$i                                    };;
  151: { .mib; adds    loc2=8*$i,out0
  152:         br.call.sptk.many      b0=OPENSSL_Uplink#   };;
  153: { .mmi; ld8     r31=[loc2];;
  154:         ld8    r30=[r31],8                                };;
  155: { .mii; ld8     gp=[r31]
  156:         mov    b6=r30
  157:         mov    b0=loc1                                    };;
  158: { .mib; mov     ar.pfs=loc0
  159:         br.many        b6                                     };;
  160: .endp   lazy$i#
  161: ___
  162: }
  163: }
  164: 
  165: sub amd64masm() {
  166: print <<___;
  167: _DATA   SEGMENT
  168: PUBLIC  OPENSSL_UplinkTable
  169: OPENSSL_UplinkTable     DQ  $N
  170: ___
  171: for ($i=1;$i<=$N;$i++) {   print "      DQ   \$lazy$i\n";   }
  172: print <<___;
  173: _DATA   ENDS
  174: 
  175: _TEXT   SEGMENT
  176: EXTERN  OPENSSL_Uplink:PROC
  177: ___
  178: for ($i=1;$i<=$N;$i++) {
  179: print <<___;
  180: ALIGN   4
  181: \$lazy$i        PROC
  182:         push   r9
  183:         push   r8
  184:         push   rdx
  185:         push   rcx
  186:         sub    rsp,40
  187:         lea    rcx,OFFSET OPENSSL_UplinkTable
  188:         mov    rdx,$i
  189:         call   OPENSSL_Uplink
  190:         add    rsp,40
  191:         pop    rcx
  192:         pop    rdx
  193:         pop    r8
  194:         pop    r9
  195:         jmp    QWORD PTR OPENSSL_UplinkTable+8*$i
  196: \$lazy$i        ENDP
  197: ___
  198: }
  199: print <<___;
  200: _TEXT   ENDS
  201: END
  202: ___
  203: }
  204: 
Syntax (Markdown)