have startup code ensure that code resource is locked.

This commit is contained in:
Wolfgang Thaller 2015-07-20 02:02:28 +02:00
parent 334f06ed83
commit f549ead8ac
4 changed files with 57 additions and 19 deletions

View File

@ -147,9 +147,9 @@ int main(int argc, char *argv[])
longword(code1, 0x61000002); // bsr *+2
word(code1, 0x0697); // addi.l #_, (a7)
longword(code1, entrypoint + 8);
longword(code1, entrypoint + 12);
word(code1, 0x4e75); // rts
longword(code1, code1.tellp() + 4);
code1 << flt;
rsrc.addResource(Resource("CODE", 1, code1.str()));

View File

@ -1,13 +1,15 @@
type 'INIT' (0) {
type 'INIT' {
hex string dontBreakAtEntry = $"", breakAtEntry = $"A9FF";
longint = 0x61000002; // bsr *+2
relativeTo:
integer = 0x0697; // addi.l #_, (a7)
longint = $$long(fltfile + 8*8) + 8;
longint = $$long(fltfile + 8*8) + (fltfile-relativeTo)/8;
integer = 0x4e75; // rts
longint = fltfile/8;
fltfile:
hex string;
};
resource 'INIT' (0) {
resource 'INIT' (128) {
dontBreakAtEntry, $$read("SystemExtension.flt");
};

View File

@ -23,16 +23,22 @@
<http://www.gnu.org/licenses/>.
*/
#define RETRO68_GET_DISPLACEMENT(DISPLACEMENT) \
#define _RETRO68_GET_DISPLACEMENT(DISPLACEMENT, STRIP) \
do { \
long virtualstart, realstart; \
char *virtualstart, *realstart; \
__asm__( "1:\n" \
"\tmove.l #1b, %0\n" \
"\tlea (1b:w,%%pc), %1" \
: "=r"(virtualstart) , "=a"(realstart) ); \
DISPLACEMENT = realstart - virtualstart; \
DISPLACEMENT = STRIP(realstart) - virtualstart; \
} while(0)
#define RETRO68_GET_DISPLACEMENT(DISPLACEMENT) \
_RETRO68_GET_DISPLACEMENT(DISPLACEMENT, )
#define RETRO68_GET_DISPLACEMENT_STRIP(DISPLACEMENT) \
_RETRO68_GET_DISPLACEMENT(DISPLACEMENT, StripAddress)
#define RETRO68_CALL_UNRELOCATED(FUN,ARGS) \
do { \
long displacement; \

View File

@ -65,8 +65,9 @@ extern void __fini_section_end(void);
static long headerVirtualAddress = -0x40;
static long headerVirtualAddress = -sizeof(struct flat_hdr);
static Ptr bssPtr = (Ptr) -1;
static Handle codeHandle = NULL;
#define ACCESS_DISPLACED(VAR) \
( * (typeof(&VAR)) ((char*)(&VAR) + displacement) )
@ -74,9 +75,35 @@ static Ptr bssPtr = (Ptr) -1;
void Retro68Relocate()
{
long displacement;
RETRO68_GET_DISPLACEMENT(displacement);
RETRO68_GET_DISPLACEMENT_STRIP(displacement);
struct flat_hdr *header = (struct flat_hdr*) (ACCESS_DISPLACED(headerVirtualAddress) + displacement);
if(displacement == 0)
{
if(bssPtr != (Ptr) -1)
{
// this is not the first time, no relocations needed.
// should only happen for code resources.
HLock(codeHandle);
return;
}
}
long headerOldVirtualAddress = ACCESS_DISPLACED(headerVirtualAddress);
struct flat_hdr *header = (struct flat_hdr*) (headerOldVirtualAddress + displacement);
uint8_t *base = (uint8_t*) (header+1);
uint32_t headerOffsetInResource = ((uint32_t*)header)[-1];
if(headerOffsetInResource < 4096)
// Arbitrary magic number. We expect the offset to be small, just a few header bytes before it.
{
Handle h = RecoverHandle((Ptr) header - headerOffsetInResource);
if(MemError() == noErr && h)
{
HLock(h);
ACCESS_DISPLACED(codeHandle) = h;
}
}
SysEnvRec env;
long bss_size;
@ -89,7 +116,8 @@ void Retro68Relocate()
long n = header->reloc_count;
long *relocs = (long*)( (char*)header + header->reloc_start );
long i;
long data_end = header->data_end - 0x40;
long data_end = header->data_end + headerOldVirtualAddress;
uint32_t flt_size = (uint32_t) header->data_end;
long bss_displacement = 0;
Ptr bss = ACCESS_DISPLACED(bssPtr);
@ -105,17 +133,19 @@ void Retro68Relocate()
for(i = 0; i < n; i++)
{
uint8_t *addrPtr = (uint8_t*)(relocs[i] + displacement);
long addr;
uint8_t *addrPtr = base + relocs[i];
uint32_t addr;
addr = (addrPtr[0] << 24) | (addrPtr[1] << 16) | (addrPtr[2] << 8) | addrPtr[3];
//addr = *(uint32_t*)addrPtr;
addr = (((((addrPtr[0] << 8) | addrPtr[1]) << 8) | addrPtr[2]) << 8) | addrPtr[3];
addr += addr >= data_end ? bss_displacement : displacement;
addr += (uint32_t)(addr - headerOldVirtualAddress) >= flt_size ? bss_displacement : displacement;
addrPtr[0] = addr >> 24;
addrPtr[1] = addr >> 16;
addrPtr[2] = addr >> 8;
addrPtr[3] = addr;
addrPtr[2] = (addr >>= 8);
addrPtr[1] = (addr >>= 8);
addrPtr[0] = (addr >>= 8);
//*(uint32_t*)addrPtr = addr;
}
if(env.processor >= env68040)