Working on some integration of some PPC-jit code to one project, and while all compiles fine, it happyly crashes (of course) on amigaos4.
Checked with author, he say
Quote:
an ISI i have would likely be caused by stale data in the instruction cache (the code in cache_block_closing is meant to prevent this), or trying to run code from memory that isn't marked as executable. Most PPC32 platforms don't implement this, but if yours does it needs to support mprotect() to change the memory permissions (see the "#if (C_HAVE_MPROTECT)" section around line 604 in cache.h).
So i check, and sure, we don't have mprotect() or any sys/mman.h things which will cover it. And so author say that:
Quote:
It definitely sounds like the memory allocated for the dynamic code is not being marked as executable.
It also sounds like AmigaOS has its own functions for specialised memory allocation: https://wiki.amigaos.net/wiki/Exec_Memory_Allocation
You'd need to use this instead of malloc to allocate the memory for cache_code_start_ptr.
That the relevant part of code:
static void cache_init(bool enable) {
Bits i;
if (enable) {
// see if cache is already initialized
if (cache_initialized) return;
cache_initialized = true;
if (cache_blocks == NULL) {
// allocate the cache blocks memory
cache_blocks=(CacheBlockDynRec*)malloc(CACHE_BLOCKS*sizeof(CacheBlockDynRec));
if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS);
cache.block.free=&cache_blocks[0];
// initialize the cache blocks
for (i=0;i<CACHE_BLOCKS-1;i++) {
cache_blocks[i].link[0].to=(CacheBlockDynRec *)1;
cache_blocks[i].link[1].to=(CacheBlockDynRec *)1;
cache_blocks[i].cache.next=&cache_blocks[i+1];
}
}
if (cache_code_start_ptr==NULL) {
// allocate the code cache memory
#if defined (WIN32)
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (!cache_code_start_ptr)
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#else
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#endif
if(!cache_code_start_ptr) E_Exit("Allocating dynamic cache failed");
// align the cache at a page boundary
cache_code=(Bit8u*)(((Bitu)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1));//Bitu is same size as a pointer.
cache_code_link_blocks=cache_code;
cache_code=cache_code+PAGESIZE_TEMP;
#if (C_HAVE_MPROTECT)
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
LOG_MSG("Setting execute permission on the code cache has failed");
#endif
CacheBlockDynRec * block=cache_getblock();
cache.block.first=block;
cache.block.active=block;
block->cache.start=&cache_code[0];
block->cache.size=CACHE_TOTAL;
block->cache.next=0; // last block in the list
}
// setup the default blocks for block linkage returns
cache.pos=&cache_code_link_blocks[0];
core_dynrec.runcode=(BlockReturn (*)(Bit8u*))cache.pos;
// can use op to PAGESIZE_TEMP-64 bytes
dyn_run_code();
cache_block_before_close();
cache_block_closing(cache_code_link_blocks, cache.pos-cache_code_link_blocks);
cache.pos=&cache_code_link_blocks[PAGESIZE_TEMP-64];
link_blocks[0].cache.start=cache.pos;
// link code that returns with a special return code
// must be less than 32 bytes
dyn_return(BR_Link1,false);
cache_block_before_close();
cache_block_closing(link_blocks[0].cache.start, cache.pos-link_blocks[0].cache.start);
cache.pos=&cache_code_link_blocks[PAGESIZE_TEMP-32];
link_blocks[1].cache.start=cache.pos;
// link code that returns with a special return code
// must be less than 32 bytes
dyn_return(BR_Link2,false);
cache_block_before_close();
cache_block_closing(link_blocks[1].cache.start, cache.pos-link_blocks[1].cache.start);
cache.free_pages=0;
cache.last_page=0;
cache.used_pages=0;
// setup the code pages
for (i=0;i<CACHE_PAGES;i++) {
CodePageHandlerDynRec * newpage=new CodePageHandlerDynRec();
newpage->next=cache.free_pages;
cache.free_pages=newpage;
}
}
}
Question now is:
1). Are we have indeed crash because we can't execute memory which we "malloc()" , because it marked in amigaos4 as for "Data" and not as something from which we can execute instructions => ISI crash
2). Are all what need to be done, it's in that code add amigaos4 ifdef, in which, instead of malloc() do some specific for amigaos4 memory allocation, which will mean that this part can be executed ?
What i mean is that line:
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
Should be changed on something meaning "allocate the memory not with malloc() for data, but via amigaos4 allocate functions and mark allocated memory be executable".
Is that possible at all?
Thanks !