SegmentMap, code flushing, cleanup

This commit is contained in:
Wolfgang Thaller 2017-09-27 00:30:06 +02:00
parent 8a2038601a
commit 68c43b7a39
9 changed files with 279 additions and 159 deletions

View File

@ -19,7 +19,7 @@ cmake_minimum_required(VERSION 3.1)
find_package(Boost COMPONENTS REQUIRED) find_package(Boost COMPONENTS REQUIRED)
add_executable(Elf2Mac Elf2Mac.h Elf2Mac.cc LdScript.cc) add_executable(Elf2Mac Elf2Mac.h Elf2Mac.cc SegmentMap.cc LdScript.cc)
target_link_libraries(Elf2Mac ResourceFiles ${CMAKE_INSTALL_PREFIX}/lib/libelf.a -lz) target_link_libraries(Elf2Mac ResourceFiles ${CMAKE_INSTALL_PREFIX}/lib/libelf.a -lz)
target_include_directories(Elf2Mac PRIVATE ${CMAKE_INSTALL_PREFIX}/include) target_include_directories(Elf2Mac PRIVATE ${CMAKE_INSTALL_PREFIX}/include)

View File

@ -18,6 +18,7 @@
*/ */
#include "Elf2Mac.h" #include "Elf2Mac.h"
#include "SegmentMap.h"
#include "ResourceFork.h" #include "ResourceFork.h"
#include "BinaryIO.h" #include "BinaryIO.h"
@ -257,15 +258,22 @@ Section::Section(string name, int idx, SectionKind kind, Elf_Scn *elfsec)
void Section::SetRela(Elf_Scn *scn) void Section::SetRela(Elf_Scn *scn)
{ {
relasec = scn; relasec = scn;
GElf_Shdr shdr; GElf_Shdr rshdr;
gelf_getshdr(relasec, &shdr); gelf_getshdr(relasec, &rshdr);
int nRela = shdr.sh_size / shdr.sh_entsize; int nRela = rshdr.sh_size / rshdr.sh_entsize;
Elf_Data *data = elf_getdata(relasec, NULL); Elf_Data *data = elf_getdata(relasec, NULL);
for(int i = 0; i < nRela; i++) for(int i = 0; i < nRela; i++)
{ {
GElf_Rela rela; GElf_Rela rela;
gelf_getrela(data, i, &rela); gelf_getrela(data, i, &rela);
if(rela.r_offset < shdr.sh_addr || rela.r_offset >= shdr.sh_addr + shdr.sh_size)
{
// For some reason, there sometimes are relocations beyond the end of the sections
// in LD output. That's bad. Let's ignore it.
continue;
}
relocs.push_back(rela); relocs.push_back(rela);
} }
@ -370,7 +378,7 @@ void Section::FixRelocs()
{ {
case SectionKind::code: case SectionKind::code:
relocBase = RelocBase::code; relocBase = RelocBase::code;
if(sym.needsJT && (exceptionInfoStart == 0 || rela.r_offset < exceptionInfoStart)) if(sym.needsJT && (exceptionInfoStart == 0 || rela.r_offset < exceptionInfoStart || sym.GetName() == "__gxx_personality_v0"))
{ {
if(rela.r_addend == 0) if(rela.r_addend == 0)
{ {
@ -390,7 +398,20 @@ void Section::FixRelocs()
} }
} }
else else
{
if(sym.section.get() != this)
{
std::cerr << "Invalid ref from "
<< name << ":" << std::hex << rela.r_offset-shdr.sh_addr << std::dec
<< " to " << sym.section->name
<< "(" << sym.GetName() << ")"
<< "+" << rela.r_offset << std::endl;
std::cerr << "needsJT: " << (sym.needsJT ? "true" : "false") << std::endl;
std::cerr << "from addr: " << rela.r_offset << ", exceptionInfoStart: " << exceptionInfoStart << std::endl;
}
assert(sym.section.get() == this); assert(sym.section.get() == this);
}
break; break;
case SectionKind::data: case SectionKind::data:
relocBase = RelocBase::data; relocBase = RelocBase::data;
@ -721,6 +742,11 @@ void MultiSegmentApp(string output)
std::cout << "CODE " << id << ": " << code.str().size() << " bytes\n"; std::cout << "CODE " << id << ": " << code.str().size() << " bytes\n";
if(code.str().size() == 80)
{
std::cout << "... empty. Skipping.\n";
continue;
}
rsrc.addResource(Resource(ResType("CODE"), id, rsrc.addResource(Resource(ResType("CODE"), id,
code.str())); code.str()));
@ -819,6 +845,7 @@ int main(int argc, char *argv[])
{ {
elf2mac = true; elf2mac = true;
flatoutput = true; flatoutput = true;
segments = false;
} }
else if(*p == "--mac-segments") else if(*p == "--mac-segments")
{ {
@ -845,8 +872,20 @@ int main(int argc, char *argv[])
{ {
ofstream out(tmpfile); ofstream out(tmpfile);
CreateLdScript(out, segments); if(segments)
CreateLdScript(std::cout, segments); {
SegmentMap map;
map.CreateLdScript(out);
map.CreateLdScript(std::cout);
ofstream f("/tmp/foo.ld");
map.CreateLdScript(f);
}
else
{
CreateFlatLdScript(out);
CreateFlatLdScript(std::cout);
}
} }
args2.push_back("-o"); args2.push_back("-o");

View File

@ -22,6 +22,6 @@
#include <iosfwd> #include <iosfwd>
void CreateLdScript(std::ostream& out, bool segments); void CreateFlatLdScript(std::ostream& out);
#endif // ELF2MAC_H #endif // ELF2MAC_H

View File

@ -18,9 +18,11 @@
*/ */
#include "Elf2Mac.h" #include "Elf2Mac.h"
#include "SegmentMap.h"
#include <iostream> #include <iostream>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>
#include <string> #include <string>
using std::string; using std::string;
@ -37,21 +39,21 @@ const char * textSection = R"ld(/* ld script for Elf2Mac */
PROVIDE(_rsrc_start = .); PROVIDE(_rsrc_start = .);
*(.rsrcheader) *(.rsrcheader)
. = ALIGN (2); . = ALIGN (2);
/* The entry point. */ /* The entry point. */
_entry_trampoline = .; _entry_trampoline = .;
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) */
LONG(_start - _entry_trampoline - 6); LONG(_start - _entry_trampoline - 6);
PROVIDE(_start = .); /* fallback entry point to a safe spot - needed for libretro bootstrap */ PROVIDE(_start = .); /* fallback entry point to a safe spot - needed for libretro bootstrap */
Retro68InitMultisegApp = .; /* override this for the single-segment case */ Retro68InitMultisegApp = .; /* override this for the single-segment case */
SHORT(0x4e75); /* rts */ SHORT(0x4e75); /* rts */
*(.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:*(.text*) */libretrocrt.a:*(.text*)
*(.text*) *(.text*)
@ -71,7 +73,7 @@ const char * textSection = R"ld(/* ld script for Elf2Mac */
__EH_FRAME_BEGIN__ = .; __EH_FRAME_BEGIN__ = .;
KEEP(*(.eh_frame)) KEEP(*(.eh_frame))
LONG(0); LONG(0);
KEEP(*(.gcc_except_table)) KEEP(*(.gcc_except_table))
KEEP(*(.gcc_except_table.*)) KEEP(*(.gcc_except_table.*))
@ -83,79 +85,6 @@ const char * textSection = R"ld(/* ld script for Elf2Mac */
} }
)ld"; )ld";
const char * code1Section = R"ld(/* ld script for Elf2Mac */
.code1 : {
_stext = . ;
FILL(0x4E71);
PROVIDE(_rsrc_start = .);
. = ALIGN (2);
_entry_trampoline = .;
SHORT(DEFINED(__break_on_entry) ? 0xA9FF : 0x4e71);
LONG(0x61000002); /* bsr *+2 */
SHORT(0x0697); /* addi.l #_, (a7) */
LONG(_start - _entry_trampoline - 6);
PROVIDE(_start = .); /* fallback entry point to a safe spot - needed for libretro bootstrap */
SHORT(0x4e75); /* rts */
*(.relocvars)
*/libretrocrt.a:start.c.obj(.text*)
*/libretrocrt.a:relocate.c.obj(.text*)
*/libretrocrt.a:MultiSegApp.c.obj(.text*)
*/libretrocrt.a:LoadSeg.s.obj(.text*)
*/libretrocrt.a:*(.text*)
*/libgcc.a:*(.text*)
*/libc.a:*(.text*)
. = ALIGN (4) ;
__init_section = . ;
KEEP (*(.init))
__init_section_end = . ;
__fini_section = . ;
KEEP (*(.fini))
__fini_section_end = . ;
__EH_FRAME_BEGIN__ = .;
KEEP(*/libretrocrt.a:*(.eh_frame))
KEEP(*/libgcc.a:*(.eh_frame))
KEEP(*/libc.a:*(.eh_frame))
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) ;
_etext = . ;
}
)ld";
const char * codeSectionTemplate = R"ld(/* ld script for Elf2Mac */
.code@N@ : {
FILL(0x4E71);
@FILTER@(.text*)
@EXTRA@
. = ALIGN (4) ;
__EH_FRAME_BEGIN__@N@ = .;
KEEP(@FILTER@(.eh_frame))
LONG(0);
KEEP(@FILTER@(.gcc_except_table))
KEEP(@FILTER@(.gcc_except_table.*))
. = ALIGN(0x4);
. += 32;
LONG(__EH_FRAME_BEGIN__@N@ - .);
}
)ld";
const char * lastCodeExtra = R"ld(
*(.gnu.linkonce.t*)
)ld";
const char * scriptEnd = R"ld( const char * scriptEnd = R"ld(
.data : { .data : {
_sdata = . ; _sdata = . ;
@ -180,14 +109,14 @@ const char * scriptEnd = R"ld(
KEEP (*(SORT(.ctors.*))) KEEP (*(SORT(.ctors.*)))
__CTOR_END__ = .; __CTOR_END__ = .;
LONG(0); LONG(0);
. = ALIGN(0x4); . = ALIGN(0x4);
__DTOR_LIST__ = .; __DTOR_LIST__ = .;
KEEP (*(.dtors)) KEEP (*(.dtors))
KEEP (*(SORT(.dtors.*))) KEEP (*(SORT(.dtors.*)))
__DTOR_END__ = .; __DTOR_END__ = .;
LONG(0); LONG(0);
. = ALIGN(0x4); . = ALIGN(0x4);
_edata = . ; _edata = . ;
} }
@ -212,7 +141,7 @@ const char * scriptEnd = R"ld(
* Keep them for now, they are discarded by Elf2Mac. */ * Keep them for now, they are discarded by Elf2Mac. */
/DISCARD/ : { *(.note.GNU-stack) } /DISCARD/ : { *(.note.GNU-stack) }
/* Stabs debugging sections. */ /* Stabs debugging sections. */
.stab 0 : { *(.stab) } .stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) } .stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) } .stab.excl 0 : { *(.stab.excl) }
@ -224,50 +153,140 @@ const char * scriptEnd = R"ld(
Symbols in the DWARF debugging sections are relative to the beginning Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */ of the section so we begin them at 0. */
/* DWARF 1 */ /* DWARF 1 */
.debug 0 : { *(.debug) } .debug 0 : { *(.debug) }
.line 0 : { *(.line) } .line 0 : { *(.line) }
/* GNU DWARF 1 extensions */ /* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) } .debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */ /* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) } .debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) } .debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */ /* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) } .debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) } .debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) } .debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) } .debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) } .debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) } .debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */ /* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) } .debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) } .debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) } .debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) } .debug_varnames 0 : { *(.debug_varnames) }
/DISCARD/ : { *(*) } /DISCARD/ : { *(*) }
} }
)ld"; )ld";
void CreateLdScript(std::ostream& out, bool segments) void CreateFlatLdScript(std::ostream& out)
{ {
if(segments) out << "_MULTISEG_APP = 0;\n";
out << scriptStart << textSection << scriptEnd;
}
void SegmentInfo::WriteFilters(std::ostream &out, string section)
{
for(string filter : filters)
{ {
out << "_MULTISEG_APP = 1;\n"; out << " " << filter << "(" << section << ")\n";
out << scriptStart << code1Section; out << " " << filter << "(" << section << ".*)\n";
string code = codeSectionTemplate; }
boost::replace_all(code, "@N@", "2"); }
boost::replace_all(code, "@FILTER@", "*"); void SegmentInfo::WriteFiltersKeep(std::ostream &out, string section)
boost::replace_all(code, "@EXTRA@", lastCodeExtra); {
out << code; for(string filter : filters)
out << scriptEnd; {
out << "\t\tKEEP(" << filter << "(" << section << "))\n";
out << "\t\tKEEP(" << filter << "(" << section << ".*))\n";
}
}
void SegmentInfo::CreateLdScript(std::ostream &out)
{
out << "\t.code" << id << " : {\n";
out << "\t\tFILL(0x4E71);\n";
if(id == 1)
{
out << R"ld(
_stext = .;
FILL(0x4E71);
PROVIDE(_rsrc_start = .);
. = ALIGN (2);
_entry_trampoline = .;
SHORT(DEFINED(__break_on_entry) ? 0xA9FF : 0x4e71);
LONG(0x61000002); /* bsr *+2 */
SHORT(0x0697); /* addi.l #_, (a7) */
LONG(_start - _entry_trampoline - 6);
PROVIDE(_start = .); /* fallback entry point to a safe spot - needed for libretro bootstrap */
SHORT(0x4e75); /* rts */
FILL(0);
*(.relocvars)
FILL(0x4E71);
)ld";
}
WriteFilters(out, ".text");
if(id == 2)
{
out << "\t\t*(.gnu.linkonce.t*)\n";
}
if(id == 1)
{
out << R"ld(
. = ALIGN (4) ;
__init_section = .;
KEEP (*(.init))
__init_section_end = .;
__fini_section = .;
KEEP (*(.fini))
__fini_section_end = .;
)ld";
}
out << "\t\t. = ALIGN (4);\n"; // this is important, for some reason.
if(id == 1)
out << "\t\t__EH_FRAME_BEGIN__" << " = .;\n";
else
out << "\t\t__EH_FRAME_BEGIN__" << id << " = .;\n";
WriteFiltersKeep(out, ".eh_frame");
out << "\t\tLONG(0);\n";
WriteFiltersKeep(out, ".gcc_except_table");
if(id == 1)
{
out << R"ld(
. = ALIGN(0x4) ;
_etext = . ;
)ld";
} }
else else
{ {
out << "_MULTISEG_APP = 0;\n"; out << boost::replace_all_copy<string>(R"ld(
out << scriptStart << textSection << scriptEnd; . = ALIGN(0x4);
} FILL(0);
. += 32;
LONG(__EH_FRAME_BEGIN__@N@ - .);
)ld", "@N@", boost::lexical_cast<string>(id));
}
out << "\t}\n";
}
void SegmentMap::CreateLdScript(std::ostream &out)
{
out << "_MULTISEG_APP = 1;\n";
out << scriptStart;
for(SegmentInfo& seg: segments)
{
seg.CreateLdScript(out);
}
out << scriptEnd;
} }

28
Elf2Mac/SegmentMap.cc Normal file
View File

@ -0,0 +1,28 @@
#include "SegmentMap.h"
SegmentInfo::SegmentInfo()
{
}
SegmentMap::SegmentMap()
{
segments.emplace_back(1, "Runtime",
"*/libretrocrt.a:start.c.obj",
"*/libretrocrt.a:relocate.c.obj",
"*/libretrocrt.a:MultiSegApp.c.obj",
"*/libretrocrt.a:LoadSeg.s.obj",
"*/libretrocrt.a:*",
"*/libgcc.a:*",
"*/libc.a:*"
);
segments.emplace_back(3, "libstdc++",
"*/libstdc++.a:*");
segments.emplace_back(4, "RetroConsole",
"*/libRetroConsole.a:*");
segments.emplace_back(2, "Main",
"*");
}

35
Elf2Mac/SegmentMap.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef SEGMENTMAP_H
#define SEGMENTMAP_H
#include <vector>
#include <string>
class SegmentInfo
{
public:
int id;
//std::string name;
std::vector<std::string> filters;
SegmentInfo();
template<typename... Args>
SegmentInfo(int id, std::string name, Args... args)
: id(id), filters { args... }
{
}
void WriteFilters(std::ostream& out, std::string section);
void WriteFiltersKeep(std::ostream& out, std::string section);
void CreateLdScript(std::ostream& out);
};
class SegmentMap
{
std::vector<SegmentInfo> segments;
public:
SegmentMap();
void CreateLdScript(std::ostream& out);
};
#endif // SEGMENTMAP_H

View File

@ -49,18 +49,7 @@ typedef struct CODEHeader
uint32_t reserved; uint32_t reserved;
} CODEHeader; } CODEHeader;
/* #define StripAddressCompat(p) (relocState.hasStripAddr ? StripAddress(p) : StripAddress24(p))
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) pascal void* Retro68LoadSegment(uint8_t *p)
{ {
@ -73,12 +62,12 @@ pascal void* Retro68LoadSegment(uint8_t *p)
Handle CODE = GetResource('CODE', id); Handle CODE = GetResource('CODE', id);
HLock(CODE); HLock(CODE);
uint8_t *base = StripAddress((uint8_t *)*CODE); uint8_t *base = StripAddressCompat((uint8_t *)*CODE);
CODEHeader *header = (CODEHeader*) base; CODEHeader *header = (CODEHeader*) base;
uint32_t codeSize = GetHandleSize(CODE); uint32_t codeSize = GetHandleSize(CODE);
// TODO: StripAddress24 // TODO: StripAddress24
uint8_t * a5 = (uint8_t*) StripAddress((void*)SetCurrentA5()); uint8_t * a5 = (uint8_t*) StripAddressCompat((void*)SetCurrentA5());
if(header->loadAddress != base || header->currentA5 != a5) if(header->loadAddress != base || header->currentA5 != a5)
{ {
@ -114,7 +103,8 @@ pascal void* Retro68LoadSegment(uint8_t *p)
++jtEntry; ++jtEntry;
} }
// TODO: Flush cache if(relocState.needFlushCache)
FlushCodeCache();
/* Load Exception Information */ /* Load Exception Information */
if (__register_frame_info) if (__register_frame_info)
@ -144,7 +134,7 @@ extern uint8_t _stext, _etext, _sdata, _edata, _sbss, _ebss;
void Retro68InitMultisegApp() void Retro68InitMultisegApp()
{ {
uint8_t * a5 = (uint8_t*) StripAddress((void*)SetCurrentA5()); uint8_t * a5 = (uint8_t*) StripAddressCompat((void*)SetCurrentA5());
// CODE Segment 1 is already loaded - we are in it. // CODE Segment 1 is already loaded - we are in it.
// Update the jump table addresses. // Update the jump table addresses.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2015 Wolfgang Thaller. Copyright 2017 Wolfgang Thaller.
This file is part of Retro68. This file is part of Retro68.
@ -24,6 +24,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <Types.h>
#define _RETRO68_GET_DISPLACEMENT(DISPLACEMENT, STRIP) \ #define _RETRO68_GET_DISPLACEMENT(DISPLACEMENT, STRIP) \
do { \ do { \
@ -69,3 +70,27 @@ void Retro68InitMultisegApp();
void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, uint32_t displacements[]); void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, uint32_t displacements[]);
#define RETRO68_RELOCATE() RETRO68_CALL_UNRELOCATED(Retro68Relocate,()) #define RETRO68_RELOCATE() RETRO68_CALL_UNRELOCATED(Retro68Relocate,())
/*
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));
typedef struct Retro68RelocState
{
Ptr bssPtr;
Handle codeHandle;
char hasStripAddr;
char needFlushCache;
} Retro68RelocState;
extern Retro68RelocState relocState;

View File

@ -59,27 +59,9 @@ extern uint8_t _rsrc_start;
extern voidFunction __CTOR_LIST__, __DTOR_LIST__; extern voidFunction __CTOR_LIST__, __DTOR_LIST__;
extern uint8_t __EH_FRAME_BEGIN__; extern uint8_t __EH_FRAME_BEGIN__;
/*
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 *) Retro68RelocState relocState __attribute__ ((section(".relocvars"))) = {
__attribute__ ((weak)); NULL, NULL, false, false
extern void *__deregister_frame_info (const void *)
__attribute__ ((weak));
typedef struct Retro68RelocState
{
Ptr bssPtr;
Handle codeHandle;
} Retro68RelocState;
static Retro68RelocState relocState __attribute__ ((section(".relocvars"))) = {
NULL, NULL
}; };
@ -162,8 +144,8 @@ void Retro68Relocate()
struct Retro68RelocState *rState = (Retro68RelocState*) struct Retro68RelocState *rState = (Retro68RelocState*)
((char*)&relocState + displacement); ((char*)&relocState + displacement);
// rState now points to the global relocState variable // rState now points to the global relocState variable
//
if(displacement == 0) if(displacement == 0)
{ {
if(rState->bssPtr) if(rState->bssPtr)
@ -178,6 +160,8 @@ void Retro68Relocate()
return; return;
} }
} }
rState->hasStripAddr = hasStripAddr;
// Locate the start of the FLT file header inside the code resource // Locate the start of the FLT file header inside the code resource
uint8_t *orig_stext, *orig_etext, *orig_sdata, *orig_edata, *orig_sbss, *orig_ebss; uint8_t *orig_stext, *orig_etext, *orig_sdata, *orig_edata, *orig_sbss, *orig_ebss;
@ -256,7 +240,7 @@ void Retro68Relocate()
void *reloc; void *reloc;
Handle RELA = NULL; Handle RELA = NULL;
uint32_t relocatableSize; uint32_t relocatableSize;
if(&_MULTISEG_APP) if(&_MULTISEG_APP == (uint8_t*)1)
{ {
RELA = Get1Resource('RELA', 1); RELA = Get1Resource('RELA', 1);
assert(RELA); assert(RELA);
@ -289,6 +273,7 @@ void Retro68Relocate()
SysEnvirons(0, &env); SysEnvirons(0, &env);
if(env.processor >= env68040) if(env.processor >= env68040)
{ {
rState->needFlushCache = true;
FlushCodeCache(); FlushCodeCache();
} }
} }
@ -355,4 +340,3 @@ void Retro68FreeGlobals()
relocState.bssPtr = (Ptr) -1; relocState.bssPtr = (Ptr) -1;
} }
} }