mirror of
https://github.com/autc04/Retro68.git
synced 2025-02-18 02:30:48 +00:00
SegmentMap, code flushing, cleanup
This commit is contained in:
parent
8a2038601a
commit
68c43b7a39
@ -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)
|
||||||
|
@ -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");
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
@ -41,12 +43,12 @@ const char * textSection = R"ld(/* ld script for Elf2Mac */
|
|||||||
/* 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)
|
||||||
@ -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 = . ;
|
||||||
@ -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,27 +153,27 @@ 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/ : { *(*) }
|
||||||
}
|
}
|
||||||
@ -252,22 +181,112 @@ const char * scriptEnd = R"ld(
|
|||||||
)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
28
Elf2Mac/SegmentMap.cc
Normal 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
35
Elf2Mac/SegmentMap.h
Normal 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
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
@ -179,6 +161,8 @@ void Retro68Relocate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user