| 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 |