#include <stdio.h>
#if defined(__DECC)
# include <c_asm.h>
# pragma __nostandard
#endif
#include "e_os.h"
#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
# if (defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
(defined(__sgi) && (defined(__mips) || defined(mips))) || \
(defined(__osf__) && defined(__alpha)) || \
(defined(__linux) && (defined(__arm) || defined(__arm__))) || \
(defined(__i386) || defined(__i386__)) || \
(defined(__x86_64) || defined(__x86_64__)) || \
(defined(vax) || defined(__vax__))
# define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
# endif
#endif
#ifdef FIPS_START
#define FIPS_ref_point FIPS_text_start
const unsigned int FIPS_rodata_start[]=
{ 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
#else
#define FIPS_ref_point FIPS_text_end
const unsigned int FIPS_rodata_end[]=
{ 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b };
#endif
static void *instruction_pointer(void)
{ void *ret=NULL;
#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
INSTRUCTION_POINTER_IMPLEMENTED(ret);
#elif defined(__GNUC__) && __GNUC__>=2
# if defined(__alpha) || defined(__alpha__)
# define INSTRUCTION_POINTER_IMPLEMENTED
__asm __volatile ( "br %0,1f\n1:" : "=r"(ret) );
# elif defined(__i386) || defined(__i386__)
# define INSTRUCTION_POINTER_IMPLEMENTED
__asm __volatile ( "call 1f\n1: popl %0" : "=r"(ret) );
ret = (void *)((size_t)ret&~3UL);
# elif defined(__ia64) || defined(__ia64__)
# define INSTRUCTION_POINTER_IMPLEMENTED
__asm __volatile ( "mov %0=ip" : "=r"(ret) );
# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
# define INSTRUCTION_POINTER_IMPLEMENTED
__asm __volatile ( "blr %%r0,%0\n\tnop" : "=r"(ret) );
ret = (void *)((size_t)ret&~3UL);
# elif defined(__mips) || defined(__mips__)
# define INSTRUCTION_POINTER_IMPLEMENTED
void *scratch;
__asm __volatile ( "move %1,$31\n\t"
"bal .+8; nop\n\t"
"move %0,$31\n\t"
"move $31,%1"
: "=r"(ret),"=r"(scratch) );
# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
defined(__PPC64__) || defined(__powerpc64__)
# define INSTRUCTION_POINTER_IMPLEMENTED
void *scratch;
__asm __volatile ( "mfspr %1,8\n\t"
"bl .+4\n\t"
"mfspr %0,8\n\t"
"mtspr 8,%1"
: "=r"(ret),"=r"(scratch) );
# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
# define INSTRUCTION_POINTER_IMPLEMENTED
void *scratch;
__asm __volatile ( "mov %%o7,%1\n\t"
"call .+8; nop\n\t"
"mov %%o7,%0\n\t"
"mov %1,%%o7"
: "=r"(ret),"=r"(scratch) );
# elif defined(__x86_64) || defined(__x86_64__)
# define INSTRUCTION_POINTER_IMPLEMENTED
__asm __volatile ( "leaq 0(%%rip),%0" : "=r"(ret) );
ret = (void *)((size_t)ret&~3UL);
# endif
#elif defined(__DECC) && defined(__alpha)
# define INSTRUCTION_POINTER_IMPLEMENTED
ret = (void *)(size_t)asm("br %v0,1f\n1:");
#elif defined(_MSC_VER) && defined(_M_IX86)
# undef INSTRUCTION_POINTER_IMPLEMENTED
void *scratch;
_asm {
call self
self: pop eax
mov scratch,eax
}
ret = (void *)((size_t)scratch&~3UL);
#endif
return ret;
}
void *FIPS_ref_point()
{
#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
return instruction_pointer();
#elif defined(_AIX)
struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
return p->ip;
#elif defined(_HPUX_SOURCE)
# if defined(__hppa) || defined(__hppa__)
struct { void *i[4]; } *p = (void *)FIPS_ref_point;
if (sizeof(p) == 8)
return p->i[2];
else if ((size_t)p & 2)
{ p = (void *)((size_t)p&~3UL);
return p->i[0];
}
else
return (void *)p;
# elif defined(__ia64) || defined(__ia64__)
struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
return (void *)(size_t)p->ip;
# endif
#elif (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
return (void *)(size_t)p->ip;
#elif defined(__VOS__)
struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
return p->ip;
#elif defined(_WIN32)
# if defined(_WIN64) && defined(_M_IA64)
struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
return p->ip;
# else
return (void *)FIPS_ref_point;
# endif
#elif defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
return (void *)instruction_pointer;
#else
return NULL;
#endif
}