[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gcl-devel] Sparc mprotect bug
From: |
Camm Maguire |
Subject: |
[Gcl-devel] Sparc mprotect bug |
Date: |
Fri, 20 Feb 2009 14:17:41 -0500 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) |
Greetings! GCL has a runtime check for SGC functionality. This is
because it can vary from kernel to kernel and machine to machine,
though it is not supposed to. For example, hppa routinely disables
the SGC garbage collecting routine when building applications that use
it, notably ACL2.
I've just confirmed that current Debian sid sparc has an unreliable
mprotect at high addresses only, crashing the acl2 build. Apart from
filing a bug, is the best approach to expand the runtime check as
follows:
=============================================================================
static int
memprotect_test_int(char *b1,unsigned long n) {
char b2[PAGESIZE];
struct sigaction sa,sao,saob;
if (memprotect_result!=memprotect_none)
return memprotect_result!=memprotect_success;
if (atexit(memprotect_print)) {
fprintf(stderr,"Cannot setup memprotect_print on exit\n");
exit(-1);
}
memset(b1,32,n);
memset(b2,0,sizeof(b2));
memprotect_test_address=(void *)(((unsigned long)b1+PAGESIZE-1) &
~(PAGESIZE-1));
if (mprotect(memprotect_test_address,PAGESIZE,PROT_READ_EXEC)) {
memprotect_result=memprotect_cannot_protect;
return -1;
}
sa.sa_sigaction=(void *)memprotect_handler_test;
sa.sa_flags=MPROTECT_ACTION_FLAGS;
if (sigaction(SIGSEGV,&sa,&sao)) {
memprotect_result=memprotect_sigaction;
return -1;
}
if (sigaction(SIGBUS,&sa,&saob)) {
sigaction(SIGSEGV,&sao,NULL);
memprotect_result=memprotect_sigaction;
return -1;
}
memprotect_result=memprotect_bad_return;
memset(memprotect_test_address,0,PAGESIZE);
if (memprotect_result==memprotect_bad_return)
memprotect_result=memprotect_no_signal;
if (memprotect_result!=memprotect_none) {
sigaction(SIGSEGV,&sao,NULL);
sigaction(SIGBUS,&saob,NULL);
return -1;
}
if (memcmp(memprotect_test_address,b2,PAGESIZE)) {
memprotect_result=memprotect_no_restart;
sigaction(SIGSEGV,&sao,NULL);
sigaction(SIGBUS,&saob,NULL);
return -1;
}
memprotect_result=memprotect_success;
sigaction(SIGSEGV,&sao,NULL);
sigaction(SIGBUS,&saob,NULL);
return 0;
}
static int
memprotect_test(void) {
char b1[2*PAGESIZE],j;
if ((j=memprotect_test_int(b1,sizeof(b1))))
return j;
if ((unsigned long)(rb_start-heap_end)<2*PAGESIZE)
fprintf(stderr,"Warning: not checking SGC at heap end\n");
else {
memprotect_result=memprotect_none;
memprotect_handler_invocations=0;
if ((j=memprotect_test_int(heap_end,2*PAGESIZE)))
return j;
}
/*SPARC has trouble with mprotect at high addresses*/
if ((unsigned long)(core_end-rb_pointer)<2*PAGESIZE) {
fprintf(stderr,"Warning: not checking SGC at rb_pointer\n");
return 0;
}
memprotect_result=memprotect_none;
memprotect_handler_invocations=0;
return memprotect_test_int(rb_pointer,2*PAGESIZE);
}
=============================================================================
The alternative of course is to remove the ability in the
sparc-linux.h file, which then needs reupdating once the problem is
fixed.
Take care,
--
Camm Maguire address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah
- [Gcl-devel] Sparc mprotect bug,
Camm Maguire <=