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