mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-26 22:51:01 +00:00
MultiSeg Apps: First working version (exceptions don't work)
This commit is contained in:
parent
a4716081c2
commit
d08331584e
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -42,11 +43,14 @@
|
|||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::unordered_map;
|
using std::unordered_map;
|
||||||
|
using std::map;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::ofstream;
|
using std::ofstream;
|
||||||
using std::shared_ptr;
|
using std::shared_ptr;
|
||||||
using std::make_shared;
|
using std::make_shared;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
|
using std::pair;
|
||||||
|
using std::make_pair;
|
||||||
|
|
||||||
size_t sectionHeaderStringTableIdx;
|
size_t sectionHeaderStringTableIdx;
|
||||||
size_t mainStringTableIdx = (size_t)-1;
|
size_t mainStringTableIdx = (size_t)-1;
|
||||||
@ -102,10 +106,12 @@ public:
|
|||||||
Elf_Scn *elfsec;
|
Elf_Scn *elfsec;
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
vector<Symbol> symbols;
|
vector<Symbol> symbols;
|
||||||
|
map<pair<int,uint32_t>, int> symbolsByAddress;
|
||||||
|
|
||||||
Symtab(Elf_Scn *elfsec);
|
Symtab(Elf_Scn *elfsec);
|
||||||
|
|
||||||
Symbol& GetSym(int idx);
|
Symbol& GetSym(int idx);
|
||||||
|
int FindSym(int secidx, uint32_t addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Reloc : public GElf_Rela
|
class Reloc : public GElf_Rela
|
||||||
@ -143,6 +149,7 @@ public:
|
|||||||
|
|
||||||
void ScanRelocs();
|
void ScanRelocs();
|
||||||
void FixRelocs();
|
void FixRelocs();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Symbol::Symbol()
|
Symbol::Symbol()
|
||||||
@ -177,21 +184,32 @@ Symtab::Symtab(Elf_Scn *elfsec)
|
|||||||
gelf_getshdr(elfsec, &shdr);
|
gelf_getshdr(elfsec, &shdr);
|
||||||
|
|
||||||
int count = shdr.sh_size / shdr.sh_entsize;
|
int count = shdr.sh_size / shdr.sh_entsize;
|
||||||
symbols.resize(count);
|
symbols.reserve(count);
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
GElf_Sym sym;
|
||||||
|
auto res = gelf_getsym(data, i, &sym);
|
||||||
|
assert(res != 0);
|
||||||
|
symbols.emplace_back(sym);
|
||||||
|
|
||||||
|
if(sym.st_shndx != SHN_UNDEF && sym.st_shndx < SHN_LORESERVE)
|
||||||
|
symbolsByAddress[make_pair((int)sym.st_shndx,sym.st_value)] = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol &Symtab::GetSym(int idx)
|
Symbol &Symtab::GetSym(int idx)
|
||||||
{
|
{
|
||||||
if(symbols[idx].valid)
|
|
||||||
return symbols[idx];
|
return symbols[idx];
|
||||||
else
|
}
|
||||||
{
|
|
||||||
GElf_Sym sym;
|
|
||||||
auto res = gelf_getsym(data, idx, &sym);
|
|
||||||
assert(res != 0);
|
|
||||||
|
|
||||||
return (symbols[idx] = Symbol(sym));
|
int Symtab::FindSym(int secidx, uint32_t addr)
|
||||||
}
|
{
|
||||||
|
auto p = symbolsByAddress.find(make_pair(secidx, addr));
|
||||||
|
if(p != symbolsByAddress.end())
|
||||||
|
return p->second;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -213,6 +231,7 @@ Section::Section(string name, int idx, SectionKind kind, Elf_Scn *elfsec)
|
|||||||
outputBase = shdr.sh_addr;
|
outputBase = shdr.sh_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Section::SetRela(Elf_Scn *scn)
|
void Section::SetRela(Elf_Scn *scn)
|
||||||
{
|
{
|
||||||
relasec = scn;
|
relasec = scn;
|
||||||
@ -269,7 +288,7 @@ string Section::GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry
|
|||||||
if(useOffsets)
|
if(useOffsets)
|
||||||
offset -= shdr.sh_addr;
|
offset -= shdr.sh_addr;
|
||||||
|
|
||||||
|
std::cout << "RELA: " << std::hex << offset << " " << (int)rela.relocBase << std::dec << std::endl;
|
||||||
longword(out, offset | ((int)rela.relocBase << 24));
|
longword(out, offset | ((int)rela.relocBase << 24));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,19 +299,31 @@ string Section::GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry
|
|||||||
|
|
||||||
void Section::ScanRelocs()
|
void Section::ScanRelocs()
|
||||||
{
|
{
|
||||||
for(auto& rela : relocs)
|
for(Reloc& rela : relocs)
|
||||||
{
|
{
|
||||||
int symidx = GELF_R_SYM(rela.r_info);
|
int symidx = GELF_R_SYM(rela.r_info);
|
||||||
if(symidx == 0)
|
if(symidx == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Symbol& sym = symtab->GetSym(symidx);
|
Symbol *sym = &symtab->GetSym(symidx);
|
||||||
|
|
||||||
if(sym.st_shndx == SHN_UNDEF)
|
if(sym->st_shndx == SHN_UNDEF)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(sym.st_shndx != idx)
|
if(rela.r_addend != 0)
|
||||||
sym.referencedExternally = true;
|
{
|
||||||
|
int symidx2 = symtab->FindSym(sym->st_shndx, sym->st_value + rela.r_addend);
|
||||||
|
if(symidx2 != -1)
|
||||||
|
{
|
||||||
|
sym = &symtab->GetSym(symidx2);
|
||||||
|
rela.r_addend = 0;
|
||||||
|
rela.r_info = GELF_R_INFO(symidx2, GELF_R_TYPE(rela.r_info));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sym->st_shndx != idx)
|
||||||
|
sym->referencedExternally = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +367,8 @@ void Section::FixRelocs()
|
|||||||
assert(sym.section.get() == this);
|
assert(sym.section.get() == this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
assert(sym.section.get() == this);
|
||||||
break;
|
break;
|
||||||
case SectionKind::data:
|
case SectionKind::data:
|
||||||
relocBase = RelocBase::data;
|
relocBase = RelocBase::data;
|
||||||
@ -636,7 +669,7 @@ void MultiSegmentApp(string output)
|
|||||||
word(code, 0);
|
word(code, 0);
|
||||||
longword(code, 0);
|
longword(code, 0);
|
||||||
longword(code, 0);
|
longword(code, 0);
|
||||||
longword(code, 0x20 + 8 * sec->firstJTEntryIndex );
|
longword(code, 8 * sec->firstJTEntryIndex );
|
||||||
longword(code, sec->jtEntries.size());
|
longword(code, sec->jtEntries.size());
|
||||||
longword(code, 0); // reloc info for A5
|
longword(code, 0); // reloc info for A5
|
||||||
longword(code, 0); // assumed address for A5
|
longword(code, 0); // assumed address for A5
|
||||||
@ -773,6 +806,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
ofstream out(tmpfile);
|
ofstream out(tmpfile);
|
||||||
CreateLdScript(out, segments);
|
CreateLdScript(out, segments);
|
||||||
|
CreateLdScript(std::cout, segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
args2.push_back("-o");
|
args2.push_back("-o");
|
||||||
|
@ -90,7 +90,6 @@ const char * code1Section = R"ld(/* ld script for Elf2Mac */
|
|||||||
PROVIDE(_rsrc_start = .);
|
PROVIDE(_rsrc_start = .);
|
||||||
. = ALIGN (2);
|
. = ALIGN (2);
|
||||||
_entry_trampoline = .;
|
_entry_trampoline = .;
|
||||||
__break_on_entry = 1;
|
|
||||||
SHORT(DEFINED(__break_on_entry) ? 0xA9FF : 0x4e71);
|
SHORT(DEFINED(__break_on_entry) ? 0xA9FF : 0x4e71);
|
||||||
LONG(0x61000002); /* bsr *+2 */
|
LONG(0x61000002); /* bsr *+2 */
|
||||||
SHORT(0x0697); /* addi.l #_, (a7) */
|
SHORT(0x0697); /* addi.l #_, (a7) */
|
||||||
@ -101,6 +100,8 @@ const char * code1Section = R"ld(/* ld script for Elf2Mac */
|
|||||||
*(.relocvars)
|
*(.relocvars)
|
||||||
*/libretrocrt.a:start.c.obj(.text*)
|
*/libretrocrt.a:start.c.obj(.text*)
|
||||||
*/libretrocrt.a:relocate.c.obj(.text*)
|
*/libretrocrt.a:relocate.c.obj(.text*)
|
||||||
|
*/libretrocrt.a:MultiSegApp.c.obj(.text*)
|
||||||
|
*/libretrocrt.a:LoadSeg.s.obj(.text*)
|
||||||
*/libretrocrt.a:*(.text*)
|
*/libretrocrt.a:*(.text*)
|
||||||
*/libgcc.a:*(.text*)
|
*/libgcc.a:*(.text*)
|
||||||
*/libc.a:*(.text*)
|
*/libc.a:*(.text*)
|
||||||
@ -114,7 +115,16 @@ const char * code1Section = R"ld(/* ld script for Elf2Mac */
|
|||||||
__fini_section_end = . ;
|
__fini_section_end = . ;
|
||||||
|
|
||||||
__EH_FRAME_BEGIN__ = .;
|
__EH_FRAME_BEGIN__ = .;
|
||||||
|
KEEP(*/libretrocrt.a:*(.eh_frame))
|
||||||
|
KEEP(*/libgcc.a:*(.eh_frame))
|
||||||
|
KEEP(*/libc.a:*(.eh_frame))
|
||||||
LONG(0);
|
LONG(0);
|
||||||
|
KEEP(*/libretrocrt.a:*(.gcc_except_table))
|
||||||
|
KEEP(*/libretrocrt.a:*(.gcc_except_table.*))
|
||||||
|
KEEP(*/libgcc.a:*(.gcc_except_table))
|
||||||
|
KEEP(*/libgcc.a:*(.gcc_except_table.*))
|
||||||
|
KEEP(*/libc.a:*(.gcc_except_table))
|
||||||
|
KEEP(*/libc.a:*(.gcc_except_table.*))
|
||||||
|
|
||||||
. = ALIGN(0x4) ;
|
. = ALIGN(0x4) ;
|
||||||
_etext = . ;
|
_etext = . ;
|
||||||
@ -129,21 +139,21 @@ const char * codeSectionTemplate = R"ld(/* ld script for Elf2Mac */
|
|||||||
|
|
||||||
. = ALIGN (4) ;
|
. = ALIGN (4) ;
|
||||||
|
|
||||||
/* KEEP(@FILTER@(.eh_frame))
|
__EH_FRAME_BEGIN__@N@ = .;
|
||||||
|
KEEP(@FILTER@(.eh_frame))
|
||||||
LONG(0);
|
LONG(0);
|
||||||
KEEP(@FILTER@(.gcc_except_table))
|
KEEP(@FILTER@(.gcc_except_table))
|
||||||
KEEP(@FILTER@(.gcc_except_table.*)) */
|
KEEP(@FILTER@(.gcc_except_table.*))
|
||||||
|
|
||||||
. = ALIGN(0x4) ;
|
. = ALIGN(0x4);
|
||||||
|
LONG(0xDEADBEEF);
|
||||||
|
. += 32;
|
||||||
|
LONG(__EH_FRAME_BEGIN__@N@ - .);
|
||||||
}
|
}
|
||||||
)ld";
|
)ld";
|
||||||
|
|
||||||
const char * lastCodeExtra = R"ld(
|
const char * lastCodeExtra = R"ld(
|
||||||
*(.stub)
|
|
||||||
*(.gnu.linkonce.t*)
|
*(.gnu.linkonce.t*)
|
||||||
*(.glue_7t)
|
|
||||||
*(.glue_7)
|
|
||||||
*(.jcr)
|
|
||||||
)ld";
|
)ld";
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#include <Events.h>
|
#include <Events.h>
|
||||||
|
|
||||||
@ -30,8 +32,26 @@ void foobar()
|
|||||||
throw Foo();
|
throw Foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnexpectedExceptionOccurred()
|
||||||
|
{
|
||||||
|
printf("std::unexpected called.\n");
|
||||||
|
printf("Press Enter...\n");
|
||||||
|
getchar();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UncaughtExceptionOccurred()
|
||||||
|
{
|
||||||
|
printf("std::terminate called.\n");
|
||||||
|
printf("Press Enter...\n");
|
||||||
|
getchar();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
std::set_unexpected(&UnexpectedExceptionOccurred);
|
||||||
|
std::set_terminate(&UncaughtExceptionOccurred);
|
||||||
bool throwFail = false;
|
bool throwFail = false;
|
||||||
bool catchFail = true;
|
bool catchFail = true;
|
||||||
for(int i = 0; i < 5; i++)
|
for(int i = 0; i < 5; i++)
|
||||||
@ -53,16 +73,7 @@ int main(int argc, char** argv)
|
|||||||
if(catchFail)
|
if(catchFail)
|
||||||
printf("******** FAILURE: catch block never entered\n");
|
printf("******** FAILURE: catch block never entered\n");
|
||||||
|
|
||||||
const int n = 3;
|
printf("Press Enter...\n");
|
||||||
printf("Click mouse %d times...\n", n);
|
getchar();
|
||||||
for(int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
while(!Button())
|
|
||||||
;
|
|
||||||
while(Button())
|
|
||||||
;
|
|
||||||
printf("Click #%d\n", i+1);
|
|
||||||
}
|
|
||||||
FlushEvents(everyEvent, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
25
libretro/LoadSeg.s
Normal file
25
libretro/LoadSeg.s
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.text
|
||||||
|
.globl PATCHEDLOADSEG
|
||||||
|
|
||||||
|
PATCHEDLOADSEG:
|
||||||
|
|
||||||
|
# Stack on Entry:
|
||||||
|
# (arguments for function)
|
||||||
|
# (return address)
|
||||||
|
# (return address from trap (== address in jt entry))
|
||||||
|
movel %sp@, %sp@-
|
||||||
|
|
||||||
|
# Stack now:
|
||||||
|
# (arguments for function)
|
||||||
|
# (return address)
|
||||||
|
# (don't care)
|
||||||
|
# (return address from trap (== address in jt entry))
|
||||||
|
|
||||||
|
jsr RETRO68LOADSEGMENT
|
||||||
|
|
||||||
|
# Stack now:
|
||||||
|
# (arguments for function)
|
||||||
|
# (return address)
|
||||||
|
# (address of loaded function)
|
||||||
|
|
||||||
|
rts
|
193
libretro/MultiSegApp.c
Normal file
193
libretro/MultiSegApp.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#include <OSUtils.h>
|
||||||
|
#include <Traps.h>
|
||||||
|
#include <Resources.h>
|
||||||
|
#include <Memory.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "PoorMansDebugging.h"
|
||||||
|
|
||||||
|
#include "Retro68Runtime.h"
|
||||||
|
|
||||||
|
static pascal void (*OriginalLoadSeg)(short id);
|
||||||
|
static pascal void (*OriginalUnloadSeg)(void *ptr);
|
||||||
|
static pascal void (*OriginalExitToShell)();
|
||||||
|
|
||||||
|
extern pascal void PatchedLoadSeg();
|
||||||
|
|
||||||
|
typedef union JTEntry
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16_t offset;
|
||||||
|
uint16_t push;
|
||||||
|
int16_t id;
|
||||||
|
uint16_t loadseg;
|
||||||
|
} near;
|
||||||
|
struct {
|
||||||
|
int16_t id;
|
||||||
|
uint16_t loadseg;
|
||||||
|
uint32_t offset;
|
||||||
|
} far;
|
||||||
|
struct {
|
||||||
|
int16_t id;
|
||||||
|
uint16_t jmp;
|
||||||
|
void* addr;
|
||||||
|
} jmp;
|
||||||
|
|
||||||
|
} JTEntry;
|
||||||
|
|
||||||
|
typedef struct CODEHeader
|
||||||
|
{
|
||||||
|
int16_t magic0;
|
||||||
|
int16_t magic1;
|
||||||
|
uint32_t nearEntryOffset;
|
||||||
|
uint32_t nNearEntries;
|
||||||
|
uint32_t farEntryOffset;
|
||||||
|
uint32_t nFarEntries;
|
||||||
|
uint32_t a5relocOffset;
|
||||||
|
uint8_t *currentA5;
|
||||||
|
uint32_t relocOffset;
|
||||||
|
uint8_t *loadAddress;
|
||||||
|
uint32_t reserved;
|
||||||
|
} CODEHeader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct object is an internal data structure in libgcc.
|
||||||
|
Comments in unwind-dw2-fde.h imply that it will not
|
||||||
|
increase in size.
|
||||||
|
*/
|
||||||
|
struct object { long space[8]; };
|
||||||
|
|
||||||
|
extern void __register_frame_info (const void *, struct object *)
|
||||||
|
__attribute__ ((weak));
|
||||||
|
extern void *__deregister_frame_info (const void *)
|
||||||
|
__attribute__ ((weak));
|
||||||
|
|
||||||
|
|
||||||
|
pascal void* Retro68LoadSegment(uint8_t *p)
|
||||||
|
{
|
||||||
|
union JTEntry *jtEntry = (JTEntry*) (p - 4);
|
||||||
|
|
||||||
|
short id = jtEntry->far.id;
|
||||||
|
uint32_t offset = jtEntry->far.offset;
|
||||||
|
|
||||||
|
// TODO: UseResFile?
|
||||||
|
Handle CODE = GetResource('CODE', id);
|
||||||
|
HLock(CODE);
|
||||||
|
|
||||||
|
uint8_t *base = StripAddress((uint8_t *)*CODE);
|
||||||
|
CODEHeader *header = (CODEHeader*) base;
|
||||||
|
uint32_t codeSize = GetHandleSize(CODE);
|
||||||
|
|
||||||
|
// TODO: StripAddress24
|
||||||
|
uint8_t * a5 = (uint8_t*) StripAddress((void*)SetCurrentA5());
|
||||||
|
|
||||||
|
if(header->loadAddress != base || header->currentA5 != a5)
|
||||||
|
{
|
||||||
|
long displacements[4] = {
|
||||||
|
base - header->loadAddress, // code
|
||||||
|
a5 - header->currentA5,
|
||||||
|
a5 - header->currentA5,
|
||||||
|
a5 - header->currentA5
|
||||||
|
};
|
||||||
|
|
||||||
|
header->loadAddress = base;
|
||||||
|
header->currentA5 = a5;
|
||||||
|
|
||||||
|
Handle RELA = NULL;
|
||||||
|
RELA = GetResource('RELA', id);
|
||||||
|
assert(RELA);
|
||||||
|
Retro68ApplyRelocations(base + 40, codeSize, *RELA, displacements);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DebugStr("\prelocation unnecessary???");
|
||||||
|
|
||||||
|
|
||||||
|
/* Update JT Entries */
|
||||||
|
// FIXME: hardcoded JT offset, there is a LM global for this somewhere:
|
||||||
|
jtEntry = (JTEntry*) (a5 + 32 + header->farEntryOffset);
|
||||||
|
int n = header->nFarEntries;
|
||||||
|
while(n--)
|
||||||
|
{
|
||||||
|
void * addr = base + jtEntry->far.offset;
|
||||||
|
//jtEntry->jmp.id = jtEntry->far.id;
|
||||||
|
jtEntry->jmp.jmp = 0x4EF9;
|
||||||
|
jtEntry->jmp.addr = addr;
|
||||||
|
++jtEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Flush cache
|
||||||
|
|
||||||
|
/* Load Exception Information */
|
||||||
|
if (__register_frame_info)
|
||||||
|
{
|
||||||
|
int32_t offset = ((int32_t*) (base + codeSize))[-1];
|
||||||
|
void *eh_frame_info = *(void**) (base + codeSize + offset);
|
||||||
|
struct object *object = (struct object*) (base + codeSize - 36);
|
||||||
|
__register_frame_info(eh_frame_info, object);
|
||||||
|
}
|
||||||
|
return base + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pascal void PatchedUnloadSeg(void *ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
static pascal void PatchedExitToShell()
|
||||||
|
{
|
||||||
|
SetToolTrapAddress((UniversalProcPtr)OriginalLoadSeg, _LoadSeg);
|
||||||
|
SetToolTrapAddress((UniversalProcPtr)OriginalUnloadSeg, _UnLoadSeg);
|
||||||
|
SetToolTrapAddress((UniversalProcPtr)OriginalExitToShell, _ExitToShell);
|
||||||
|
OriginalExitToShell();
|
||||||
|
}
|
||||||
|
|
||||||
|
// section boundaries
|
||||||
|
extern uint8_t _stext, _etext, _sdata, _edata, _sbss, _ebss;
|
||||||
|
|
||||||
|
void Retro68InitMultisegApp()
|
||||||
|
{
|
||||||
|
uint8_t * a5 = (uint8_t*) StripAddress((void*)SetCurrentA5());
|
||||||
|
|
||||||
|
// CODE Segment 1 is already loaded - we are in it.
|
||||||
|
// Update the jump table addresses.
|
||||||
|
JTEntry *jtEntry = (JTEntry*) (a5 + 32 + 16); // TODO: hardcoded offsets
|
||||||
|
while(jtEntry->far.id == 1)
|
||||||
|
{
|
||||||
|
void * addr = &_stext - 4 + jtEntry->far.offset;
|
||||||
|
//jtEntry->jmp.id = jtEntry->far.id;
|
||||||
|
jtEntry->jmp.jmp = 0x4EF9;
|
||||||
|
jtEntry->jmp.addr = addr;
|
||||||
|
++jtEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero-initialize bss
|
||||||
|
for(uint32_t *p = (uint32_t*) &_sbss;
|
||||||
|
p < (uint32_t*) &_ebss; ++p)
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
// Set up patched LoadSeg
|
||||||
|
|
||||||
|
// NOTE: OriginalLoadSeg is the first global variable we can use
|
||||||
|
OriginalLoadSeg = (void(*)(short)) GetToolTrapAddress(_LoadSeg);
|
||||||
|
OriginalUnloadSeg = (void(*)(void*)) GetToolTrapAddress(_UnLoadSeg);
|
||||||
|
OriginalExitToShell = (void(*)()) GetToolTrapAddress(_ExitToShell);
|
||||||
|
SetToolTrapAddress((UniversalProcPtr)&PatchedLoadSeg, _LoadSeg);
|
||||||
|
SetToolTrapAddress((UniversalProcPtr)&PatchedUnloadSeg, _UnLoadSeg);
|
||||||
|
SetToolTrapAddress((UniversalProcPtr)&PatchedExitToShell, _ExitToShell);
|
||||||
|
|
||||||
|
// Load and relocate statically initialized DATA
|
||||||
|
Handle DATA = Get1Resource('DATA', 0);
|
||||||
|
BlockMoveData(*DATA, &_sdata, &_edata - &_sdata);
|
||||||
|
ReleaseResource(DATA);
|
||||||
|
|
||||||
|
long displacements[4] = {
|
||||||
|
0,
|
||||||
|
a5 - (uint8_t*)NULL,
|
||||||
|
a5 - (uint8_t*)NULL,
|
||||||
|
a5 - (uint8_t*)NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
Handle RELA = NULL;
|
||||||
|
RELA = GetResource('RELA', 0);
|
||||||
|
assert(RELA);
|
||||||
|
Retro68ApplyRelocations(&_sdata, &_edata - &_sdata, *RELA, displacements);
|
||||||
|
|
||||||
|
}
|
@ -305,9 +305,9 @@ void Retro68Relocate()
|
|||||||
|
|
||||||
void Retro68CallConstructors()
|
void Retro68CallConstructors()
|
||||||
{
|
{
|
||||||
/*static struct object object;
|
static struct object object;
|
||||||
if (__register_frame_info)
|
if (__register_frame_info)
|
||||||
__register_frame_info(&__EH_FRAME_BEGIN__, &object);*/
|
__register_frame_info(&__EH_FRAME_BEGIN__, &object);
|
||||||
{
|
{
|
||||||
uint8_t *p = &__init_section;
|
uint8_t *p = &__init_section;
|
||||||
uint8_t *e = &__init_section_end;
|
uint8_t *e = &__init_section_end;
|
||||||
@ -342,8 +342,8 @@ void Retro68CallDestructors()
|
|||||||
p += 6;
|
p += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if (__deregister_frame_info)
|
if (__deregister_frame_info)
|
||||||
__deregister_frame_info(&__EH_FRAME_BEGIN__);*/
|
__deregister_frame_info(&__EH_FRAME_BEGIN__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,9 +23,7 @@
|
|||||||
<http://www.gnu.org/licenses/>.
|
<http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "Retro68Runtime.h"
|
#include "Retro68Runtime.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[]);
|
int main(int argc, char* argv[]);
|
||||||
|
Loading…
Reference in New Issue
Block a user