| OLD | NEW | 
 | (Empty) | 
|    1 /* ==================================================================== |  | 
|    2  * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution |  | 
|    3  * and usage in source and binary forms are granted according to the |  | 
|    4  * OpenSSL license. |  | 
|    5  */ |  | 
|    6  |  | 
|    7 #include <stdio.h> |  | 
|    8 #if defined(__DECC) |  | 
|    9 # include <c_asm.h> |  | 
|   10 # pragma __nostandard |  | 
|   11 #endif |  | 
|   12  |  | 
|   13 #include "e_os.h" |  | 
|   14  |  | 
|   15 #if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION) |  | 
|   16 # if    (defined(__sun) && (defined(__sparc) || defined(__sparcv9)))    || \ |  | 
|   17         (defined(__sgi) && (defined(__mips) || defined(mips)))          || \ |  | 
|   18         (defined(__osf__) && defined(__alpha))                          || \ |  | 
|   19         (defined(__linux) && (defined(__arm) || defined(__arm__)))      || \ |  | 
|   20         (defined(__i386) || defined(__i386__))                          || \ |  | 
|   21         (defined(__x86_64) || defined(__x86_64__))                      || \ |  | 
|   22         (defined(vax) || defined(__vax__)) |  | 
|   23 #  define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION |  | 
|   24 # endif |  | 
|   25 #endif |  | 
|   26  |  | 
|   27 #if defined(__xlC__) && __xlC__>=0x600 && (defined(_POWER) || defined(_ARCH_PPC)
     ) |  | 
|   28 static void *instruction_pointer_xlc(void); |  | 
|   29 # pragma mc_func instruction_pointer_xlc {\ |  | 
|   30         "7c0802a6"      /* mflr r0  */  \ |  | 
|   31         "48000005"      /* bl   $+4 */  \ |  | 
|   32         "7c6802a6"      /* mflr r3  */  \ |  | 
|   33         "7c0803a6"      /* mtlr r0  */  } |  | 
|   34 # pragma reg_killed_by instruction_pointer_xlc gr0 gr3 |  | 
|   35 # define INSTRUCTION_POINTER_IMPLEMENTED(ret) (ret=instruction_pointer_xlc()); |  | 
|   36 #endif |  | 
|   37  |  | 
|   38 #ifdef FIPS_START |  | 
|   39 #define FIPS_ref_point FIPS_text_start |  | 
|   40 /* Some compilers put string literals into a separate segment. As we |  | 
|   41  * are mostly interested to hash AES tables in .rodata, we declare |  | 
|   42  * reference points accordingly. In case you wonder, the values are |  | 
|   43  * big-endian encoded variable names, just to prevent these arrays |  | 
|   44  * from being merged by linker. */ |  | 
|   45 const unsigned int FIPS_rodata_start[]= |  | 
|   46         { 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 }; |  | 
|   47 #else |  | 
|   48 #define FIPS_ref_point FIPS_text_end |  | 
|   49 const unsigned int FIPS_rodata_end[]= |  | 
|   50         { 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b }; |  | 
|   51 #endif |  | 
|   52  |  | 
|   53 /* |  | 
|   54  * I declare reference function as static in order to avoid certain |  | 
|   55  * pitfalls in -dynamic linker behaviour... |  | 
|   56  */ |  | 
|   57 static void *instruction_pointer(void) |  | 
|   58 { void *ret=NULL; |  | 
|   59 /* These are ABI-neutral CPU-specific snippets. ABI-neutrality means |  | 
|   60  * that they are designed to work under any OS running on particular |  | 
|   61  * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in |  | 
|   62  * this function. */ |  | 
|   63 #if     defined(INSTRUCTION_POINTER_IMPLEMENTED) |  | 
|   64     INSTRUCTION_POINTER_IMPLEMENTED(ret); |  | 
|   65 #elif   defined(__GNUC__) && __GNUC__>=2 |  | 
|   66 # if    defined(__alpha) || defined(__alpha__) |  | 
|   67 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|   68     __asm __volatile (  "br     %0,1f\n1:" : "=r"(ret) ); |  | 
|   69 # elif  defined(__i386) || defined(__i386__) |  | 
|   70 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|   71     __asm __volatile (  "call 1f\n1:    popl %0" : "=r"(ret) ); |  | 
|   72     ret = (void *)((size_t)ret&~3UL); /* align for better performance */ |  | 
|   73 # elif  defined(__ia64) || defined(__ia64__) |  | 
|   74 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|   75     __asm __volatile (  "mov    %0=ip" : "=r"(ret) ); |  | 
|   76 # elif  defined(__hppa) || defined(__hppa__) || defined(__pa_risc) |  | 
|   77 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|   78     __asm __volatile (  "blr    %%r0,%0\n\tnop" : "=r"(ret) ); |  | 
|   79     ret = (void *)((size_t)ret&~3UL); /* mask privilege level */ |  | 
|   80 # elif  defined(__mips) || defined(__mips__) |  | 
|   81 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|   82     void *scratch; |  | 
|   83     __asm __volatile (  "move   %1,$31\n\t"     /* save ra */ |  | 
|   84                         "bal    .+8; nop\n\t" |  | 
|   85                         "move   %0,$31\n\t" |  | 
|   86                         "move   $31,%1"         /* restore ra */ |  | 
|   87                         : "=r"(ret),"=r"(scratch) ); |  | 
|   88 # elif  defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \ |  | 
|   89         defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \ |  | 
|   90         defined(__PPC64__) || defined(__powerpc64__) |  | 
|   91 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|   92     void *scratch; |  | 
|   93     __asm __volatile (  "mfspr  %1,8\n\t"       /* save lr */ |  | 
|   94                         "bl     $+4\n\t" |  | 
|   95                         "mfspr  %0,8\n\t"       /* mflr ret */ |  | 
|   96                         "mtspr  8,%1"           /* restore lr */ |  | 
|   97                         : "=r"(ret),"=r"(scratch) ); |  | 
|   98 # elif  defined(__s390__) || defined(__s390x__) |  | 
|   99 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|  100     __asm __volatile (  "bras   %0,1f\n1:" : "=r"(ret) ); |  | 
|  101     ret = (void *)((size_t)ret&~3UL); |  | 
|  102 # elif  defined(__sparc) || defined(__sparc__) || defined(__sparcv9) |  | 
|  103 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|  104     void *scratch; |  | 
|  105     __asm __volatile (  "mov    %%o7,%1\n\t" |  | 
|  106                         "call   .+8; nop\n\t" |  | 
|  107                         "mov    %%o7,%0\n\t" |  | 
|  108                         "mov    %1,%%o7" |  | 
|  109                         : "=r"(ret),"=r"(scratch) ); |  | 
|  110 # elif  defined(__x86_64) || defined(__x86_64__) |  | 
|  111 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|  112     __asm __volatile (  "leaq   0(%%rip),%0" : "=r"(ret) ); |  | 
|  113     ret = (void *)((size_t)ret&~3UL); /* align for better performance */ |  | 
|  114 # endif |  | 
|  115 #elif   defined(__DECC) && defined(__alpha) |  | 
|  116 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|  117     ret = (void *)(size_t)asm("br %v0,1f\n1:"); |  | 
|  118 #elif   defined(_MSC_VER) && defined(_M_IX86) |  | 
|  119 #   define INSTRUCTION_POINTER_IMPLEMENTED |  | 
|  120     void *scratch; |  | 
|  121     _asm { |  | 
|  122             call    self |  | 
|  123     self:   pop     eax |  | 
|  124             mov     scratch,eax |  | 
|  125          } |  | 
|  126     ret = (void *)((size_t)scratch&~3UL); |  | 
|  127 #endif |  | 
|  128   return ret; |  | 
|  129 } |  | 
|  130  |  | 
|  131 /* |  | 
|  132  * This function returns pointer to an instruction in the vicinity of |  | 
|  133  * its entry point, but not outside this object module. This guarantees |  | 
|  134  * that sequestered code is covered... |  | 
|  135  */ |  | 
|  136 void *FIPS_ref_point() |  | 
|  137 { |  | 
|  138 #if     defined(INSTRUCTION_POINTER_IMPLEMENTED) |  | 
|  139     return instruction_pointer(); |  | 
|  140 /* Below we essentially cover vendor compilers which do not support |  | 
|  141  * inline assembler... */ |  | 
|  142 #elif   defined(_AIX) |  | 
|  143     struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer; |  | 
|  144     return p->ip; |  | 
|  145 #elif   defined(_HPUX_SOURCE) |  | 
|  146 # if    defined(__hppa) || defined(__hppa__) |  | 
|  147     struct { void *i[4]; } *p = (void *)FIPS_ref_point; |  | 
|  148  |  | 
|  149     if (sizeof(p) == 8) /* 64-bit */ |  | 
|  150         return p->i[2]; |  | 
|  151     else if ((size_t)p & 2) |  | 
|  152     {   p = (void *)((size_t)p&~3UL); |  | 
|  153         return p->i[0]; |  | 
|  154     } |  | 
|  155     else |  | 
|  156         return (void *)p; |  | 
|  157 # elif  defined(__ia64) || defined(__ia64__) |  | 
|  158     struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer; |  | 
|  159     return (void *)(size_t)p->ip; |  | 
|  160 # endif |  | 
|  161 #elif   (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__)) |  | 
|  162     /* applies to both alpha and ia64 */ |  | 
|  163     struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer; |  | 
|  164     return (void *)(size_t)p->ip; |  | 
|  165 #elif   defined(__VOS__) |  | 
|  166     /* applies to both pa-risc and ia32 */ |  | 
|  167     struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer; |  | 
|  168     return p->ip; |  | 
|  169 #elif   defined(_WIN32) |  | 
|  170 # if    defined(_WIN64) && defined(_M_IA64) |  | 
|  171     struct { void *ip,*gp; } *p = (void *)FIPS_ref_point; |  | 
|  172     return p->ip; |  | 
|  173 # else |  | 
|  174     return (void *)FIPS_ref_point; |  | 
|  175 # endif |  | 
|  176 /* |  | 
|  177  * In case you wonder why there is no #ifdef __linux. All Linux targets |  | 
|  178  * are GCC-based and therefore are covered by instruction_pointer above |  | 
|  179  * [well, some are covered by by the one below]... |  | 
|  180  */  |  | 
|  181 #elif   defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION) |  | 
|  182     return (void *)instruction_pointer; |  | 
|  183 #else |  | 
|  184     return NULL; |  | 
|  185 #endif |  | 
|  186 } |  | 
| OLD | NEW |