|
From: <sv...@va...> - 2006-01-19 17:44:53
|
Author: sewardj
Date: 2006-01-19 17:44:38 +0000 (Thu, 19 Jan 2006)
New Revision: 5567
Log:
- Make this work on systems where the stack is non executable:
put the to-be-modified insns in an mmap'd page
- Clarify init_function a bit (does not change what it does)
Modified:
trunk/none/tests/ppc32/jm-insns.c
Modified: trunk/none/tests/ppc32/jm-insns.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/ppc32/jm-insns.c 2006-01-19 05:01:28 UTC (rev 5566)
+++ trunk/none/tests/ppc32/jm-insns.c 2006-01-19 17:44:38 UTC (rev 5567)
@@ -166,8 +166,8 @@
=20
=20
#include <stdint.h>
+#include <sys/mman.h>
=20
-
/* Something of the same size as void*, so can be safely be coerced
to/from a pointer type. Also same size as the host's gp registers. */
#ifndef __powerpc64__
@@ -233,7 +233,26 @@
#endif // #ifndef __powerpc64__
=20
=20
+/* Return a pointer to a 1-page area where is is safe to both write
+ and execute instructions. Area is filled with 'trap' insns. */
+static
+uint32_t* get_rwx_area ( void )
+{
+ int i;
+ static uint32_t* p =3D NULL;
+ if (p =3D=3D NULL) {
+ p =3D mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ assert(p !=3D MAP_FAILED);
+ }
=20
+ for (i =3D 0; i < 4096/sizeof(uint32_t); i++)
+ p[i] =3D 0x7fe00008; /* trap */
+
+ return p;
+}
+
+
/* -------------- BEGIN #include "test-ppc.h" -------------- */
/*
* test-ppc.h:
@@ -4716,29 +4735,37 @@
}
=20
=20
+/* Copy the 2 insn function starting at p_func_F to func_buf[], and
+ return a possibly different pointer, which, when called, runs the
+ copy in func_buf[]. */
static inline
-void init_function( test_func_t *p_func, uint32_t func_buf[] )
+test_func_t init_function( test_func_t p_func_F, uint32_t func_buf[] )
{
- uint32_t *p;
+ uint32_t* p_func =3D (uint32_t*)p_func_F;
#ifndef __powerpc64__
- p =3D (uint32_t *)*p_func;
- func_buf[0] =3D p[0];
- func_buf[1] =3D p[1];
- *p_func =3D (void *)func_buf;
+ func_buf[0] =3D p_func[0];
+ func_buf[1] =3D p_func[1];
+ return (test_func_t)&func_buf[0];
#else
- p =3D (uint32_t *)((uint64_t *)*p_func)[0];
- func_buf[0] =3D p[0];
- func_buf[1] =3D p[1];
- ((uint64_t *)*p_func)[0] =3D (uint64_t)&func_buf[0];
+ /* p_func points to a function descriptor, the first word of which
+ points to the real code. Copy the code itself but not the
+ descriptor, and just swizzle the descriptor's entry pointer. */
+ uint64_t* descr =3D (uint64_t*)p_func;
+ uint32_t* entry =3D (uint32_t*)(descr[0]);
+ func_buf[0] =3D entry[0];
+ func_buf[1] =3D entry[1];
+ descr[0] =3D (uint64_t)&func_buf[0];
+ return (test_func_t)descr;
#endif // #ifndef __powerpc64__
}
=20
=20
static void test_int_one_reg_imm16 (const char* name,
- test_func_t func,
+ test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j;
@@ -4746,7 +4773,7 @@
for (i=3D0; i<nb_iargs; i++) {
for (j=3D0; j<nb_ii16; j++) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm16(&func_buf[0], ii16[j]);
=20
r14 =3D iargs[i];
@@ -4809,10 +4836,11 @@
* sradi rA,rS,SH
*/
=20
-static void rlwi_cb (const char* name, test_func_t func,
+static void rlwi_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, k, l, arg_step;
@@ -4826,7 +4854,7 @@
for (k=3D0; k<32; k+=3Darg_step) {
for (l=3D0; l<32; l+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
_patch_op_imm(&func_buf[0], j, 11, 5);
_patch_op_imm(&func_buf[0], k, 6, 5);
patch_op_imm(&func_buf[0], l, 1, 5);
@@ -4869,10 +4897,11 @@
}
}
=20
-static void rlwnm_cb (const char* name, test_func_t func,
+static void rlwnm_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, k, l, arg_step;
@@ -4884,7 +4913,7 @@
for (k=3D0; k<32; k+=3Darg_step) {
for (l=3D0; l<32; l+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
_patch_op_imm(&func_buf[0], k, 6, 5);
patch_op_imm(&func_buf[0], l, 1, 5);
=20
@@ -4927,10 +4956,11 @@
}
}
=20
-static void srawi_cb (const char* name, test_func_t func,
+static void srawi_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, arg_step;
@@ -4940,7 +4970,7 @@
for (i=3D0; i<nb_iargs; i++) {
for (j=3D0; j<32; j+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], j, 11, 5);
=20
r14 =3D iargs[i];
@@ -4979,10 +5009,11 @@
}
}
=20
-static void mcrf_cb (const char* name, test_func_t func,
+static void mcrf_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, k, arg_step;
=20
@@ -4992,7 +5023,7 @@
for (j=3D0; j<8; j+=3Darg_step) {
for (k=3D0; k<8; k+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
_patch_op_imm(&func_buf[0], j, 23, 3);
patch_op_imm(&func_buf[0], k, 18, 3);
=20
@@ -5039,10 +5070,11 @@
#endif
=20
=20
-static void mcrxr_cb (const char* name, test_func_t func,
+static void mcrxr_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, k, arg_step;
=20
@@ -5052,7 +5084,7 @@
j =3D i << 28;
for (k=3D0; k<8; k+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], k, 23, 3);
=20
r14 =3D j;
@@ -5396,10 +5428,11 @@
}
#endif
=20
-static void mtcrf_cb (const char* name, test_func_t func,
+static void mtcrf_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, arg_step;
=20
@@ -5408,7 +5441,7 @@
for (i=3D0; i<nb_iargs; i++) {
for (j=3D0; j<256; j+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], j, 12, 8);
=20
r14 =3D iargs[i];
@@ -5597,10 +5630,11 @@
}
=20
#ifdef __powerpc64__
-static void rldc_cb (const char* name, test_func_t func,
+static void rldc_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, k, arg_step;
@@ -5611,7 +5645,7 @@
for (j=3D0; j<nb_iargs; j++) {
for (k=3D0; k<64; k+=3Darg_step) {
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5=
, 6);
=20
r14 =3D iargs[i];
@@ -5648,10 +5682,11 @@
}
}
=20
-static void rldi_cb (const char* name, test_func_t func,
+static void rldi_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, k, arg_step;
@@ -5662,7 +5697,7 @@
for (j=3D0; j<64; j+=3Darg_step) { // SH
for (k=3D0; k<64; k+=3Darg_step) { // MB|ME
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
_patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5);
_patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1);
patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5=
, 6);
@@ -5700,10 +5735,11 @@
}
}
=20
-static void sradi_cb (const char* name, test_func_t func,
+static void sradi_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, j, arg_step;
@@ -5713,7 +5749,7 @@
for (i=3D0; i<nb_iargs; i++) {
for (j=3D0; j<64; j+=3Darg_step) { // SH
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
_patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5);
patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1);
=20
@@ -5922,10 +5958,11 @@
=20
=20
static void test_int_ld_one_reg_imm16 (const char* name,
- test_func_t func,
+ test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile HWord_t res, base;
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, offs, is_lwa=3D0;
@@ -5940,7 +5977,7 @@
offs =3D i * sizeof(HWord_t);
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
if (is_lwa)
patch_op_imm(&func_buf[0], offs>>2, 2, 14);
else
@@ -5986,7 +6023,7 @@
offs =3D i * sizeof(HWord_t);
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func, func_buf );
patch_op_imm16(&func_buf[0], offs);
=20
r14 =3D base;
@@ -6071,10 +6108,11 @@
}
=20
static void test_int_st_two_regs_imm16 (const char* name,
- test_func_t func,
+ test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, xer, tmpcr, tmpxer;
int i, offs, k;
HWord_t *iargs_priv, base;
@@ -6091,7 +6129,7 @@
offs =3D i * sizeof(HWord_t);
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm16(&func_buf[0], offs);
=20
r14 =3D iargs[i]; // read from iargs
@@ -6137,7 +6175,7 @@
offs =3D i * sizeof(HWord_t);
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func, func_buf );
patch_op_imm16(&func_buf[0], offs);
=20
r14 =3D iargs[nb_iargs-1+i]; // read from iargs
@@ -6486,10 +6524,12 @@
=20
=20
static void test_float_ld_one_reg_imm16 (const char* name,
- test_func_t func,
+ test_func_t func_IN,
unused uint32_t test_flags)
{
- uint32_t base, func_buf[2];
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
+ uint32_t base;
volatile uint32_t flags, xer, tmpcr, tmpxer;
volatile double src, res;
int i, offs;
@@ -6506,7 +6546,7 @@
}
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm16(&func_buf[0], offs);
=20
// load from fargs[idx] =3D> r14 + offs
@@ -6611,11 +6651,12 @@
}
=20
static void test_float_st_two_regs_imm16 (const char* name,
- test_func_t func,
+ test_func_t func_IN,
unused uint32_t test_flags)
{
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
HWord_t base;
- uint32_t func_buf[2];
volatile uint32_t flags, xer, tmpcr, tmpxer;
double src, *p_dst;
int i, offs;
@@ -6651,7 +6692,7 @@
*p_dst =3D 0; // clear dst
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm16(&func_buf[0], offs);
=20
// read from fargs[idx] =3D> f14
@@ -7105,13 +7146,14 @@
}
}
=20
-static void vsplt_cb (const char* name, test_func_t func,
+static void vsplt_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, tmpcr;
volatile vector unsigned int tmpvscr;
volatile vector unsigned int vec_in1, vec_out, vscr;
- uint32_t func_buf[2];
unsigned int *src1, *dst;
int i,j;
#if defined TEST_VSCR_SAT
@@ -7125,7 +7167,7 @@
vec_out =3D (vector unsigned int){ 0,0,0,0 };
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], j, 16, 5);
=20
/* Save flags */
@@ -7174,13 +7216,14 @@
}
}
=20
-static void vspltis_cb (const char* name, test_func_t func,
+static void vspltis_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, tmpcr;
volatile vector unsigned int tmpvscr;
volatile vector unsigned int vec_out, vscr;
- uint32_t func_buf[2];
unsigned int *dst;
int i;
#if defined TEST_VSCR_SAT
@@ -7191,7 +7234,7 @@
vec_out =3D (vector unsigned int){ 0,0,0,0 };
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], i, 16, 5);
=20
/* Save flags */
@@ -7231,13 +7274,14 @@
}
}
=20
-static void vsldoi_cb (const char* name, test_func_t func,
+static void vsldoi_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, tmpcr;
volatile vector unsigned int tmpvscr;
volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr;
- uint32_t func_buf[2];
unsigned int *src1, *src2, *dst;
int i,j,k;
#if defined TEST_VSCR_SAT
@@ -7252,7 +7296,7 @@
vec_out =3D (vector unsigned int){ 0,0,0,0 };
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], k, 6, 4);
=20
/* Save flags */
@@ -7789,13 +7833,14 @@
}
}
=20
-static void vcvt_cb (const char* name, test_func_t func,
+static void vcvt_cb (const char* name, test_func_t func_IN,
unused uint32_t test_flags)
{
+ volatile test_func_t func;
+ uint32_t* func_buf =3D get_rwx_area();
volatile uint32_t flags, tmpcr;
volatile vector unsigned int tmpvscr;
volatile vector unsigned int vec_in, vec_out, vscr;
- uint32_t func_buf[2];
unsigned int *src, *dst;
int i,j;
#if defined TEST_VSCR_SAT
@@ -7809,7 +7854,7 @@
vec_out =3D (vector unsigned int){ 0,0,0,0 };
=20
/* Patch up the instruction */
- init_function( &func, func_buf );
+ func =3D init_function( func_IN, func_buf );
patch_op_imm(&func_buf[0], j, 16, 5);
=20
/* Save flags */
|