mprotect
Greetings! In porting gcl, I'm trying to read the fault address on
writing to an array mprotect'ed to PROT_READ. This gives a SIGSEGV on
all Debian arches except s390. Anyone know why? Is there an
equivalent mechanism here?
Take care,
=============================================================================
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
/* #ifndef PAGESIZE */
/* #define PAGESIZE 4096 */
/* #endif */
#define NP 1024
long i,j,k,ps;
char *b1,*b;
#if defined(__i386__) || defined(__alpha__)
#include <asm/sigcontext.h>
void
s1(int sig,int code) {
struct sigaction sa={0};
i++;
#if defined(__i386__)
if (((struct sigcontext *)(&code))->cr2!=(long)(b+j)) {
printf("Mismatch: %p %p\n",((struct sigcontext *)(&sig+1))->cr2,(long)(b+j));
exit(1);
#elif defined (__alpha__)
if (((struct sigcontext *)(&code))->sc_sbase!=(char *)(b+j)) {
printf("Mismatch: %p %p\n",((struct sigcontext *)(&sig+1))->sc_sbase,(long)(b+j));
exit(1);
#endif
k=1;
}
if (mprotect(b+(j&~(ps-1)),1+(j&(ps-1)),PROT_READ|PROT_WRITE)) {
perror("cannot mprotect");
exit(errno);
}
}
#endif
void
segvh(int s,siginfo_t *si,void *p) {
struct sigaction sa={0};
i++;
if (si->si_addr!=(b+j)) {
printf("Mismatch: %p %p\n",si->si_addr,(long)(b+j));
exit(1);
k=1;
}
if (mprotect(b+(j&~(ps-1)),1+(j&(ps-1)),PROT_READ|PROT_WRITE)) {
perror("cannot mprotect");
exit(errno);
}
}
int
main(int argc,char * argv[]) {
struct sigaction sa={0};
time_t tt;
int ii;
if (!(ps=getpagesize())) {
perror("Cannot get pagesize");
return errno;
}
if (!(b1=malloc(ps*NP+ps-1))) {
perror("Cannot malloc");
return errno;
}
b=(char *)(((long)b1+ps-1) & ~(ps-1));
if (mprotect(b,ps*NP,PROT_READ)) {
perror("cannot mprotect");
exit(errno);
}
srand(time(&tt));
k=0;
#if defined(__i386__) || defined(__alpha__)
if (argc>1) {
#endif
sa.sa_sigaction=segvh;
sa.sa_flags=SA_RESTART|SA_SIGINFO;
sigaction(SIGSEGV,&sa,NULL);
#if defined(__i386__) || defined(__alpha__)
} else {
sa.sa_handler=s1;
sa.sa_flags=SA_RESTART;
sigaction(SIGSEGV,&sa,NULL);
}
#endif
for (ii=i=0;i<100 && ii<1000;ii++) {
j=ps*NP*(float)rand()/RAND_MAX;
b[j]=0;
if (mprotect(b,ps*NP,PROT_READ)) {
perror("cannot mprotect");
exit(errno);
}
}
return i==100 ? k : 1;
}
=============================================================================
--
Camm Maguire camm@enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah
--
To UNSUBSCRIBE, email to debian-s390-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Reply to: