Take responsibility: don't use standard crtbegin/end anymore, now that we control the linker script
This commit is contained in:
parent
68150e1c23
commit
33a2744643
|
@ -22,6 +22,6 @@
|
|||
|
||||
#include <iosfwd>
|
||||
|
||||
void CreateLdScript(std::ofstream& out);
|
||||
void CreateLdScript(std::ostream& out);
|
||||
|
||||
#endif // ELF2MAC_H
|
||||
|
|
|
@ -19,18 +19,26 @@
|
|||
|
||||
#include "Elf2Mac.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <string>
|
||||
|
||||
const char * defaultLdScript = R"ld(/* ld script for Elf2Mac */
|
||||
using std::string;
|
||||
|
||||
const char * scriptStart = R"ld(/* ld script for Elf2Mac */
|
||||
ENTRY( _start )
|
||||
SECTIONS
|
||||
{
|
||||
)ld";
|
||||
|
||||
const char * textSection = R"ld(/* ld script for Elf2Mac */
|
||||
.text : {
|
||||
_stext = . ;
|
||||
PROVIDE(_rsrc_start = .);
|
||||
*(.rsrcheader)
|
||||
. = ALIGN (2);
|
||||
_entry_trampoline = .;
|
||||
|
||||
SHORT(DEFINED(__break_on_entry) ? 0xA9FF : 0x4e71);
|
||||
LONG(0x61000002); /* bsr *+2 */
|
||||
SHORT(0x0697); /* addi.l #_, (a7) */
|
||||
|
@ -57,8 +65,10 @@ SECTIONS
|
|||
KEEP (*(.fini))
|
||||
__fini_section_end = . ;
|
||||
|
||||
*(.eh_frame_hdr)
|
||||
__EH_FRAME_BEGIN__ = .;
|
||||
KEEP(*(.eh_frame))
|
||||
LONG(0);
|
||||
|
||||
KEEP(*(.gcc_except_table))
|
||||
KEEP(*(.gcc_except_table.*))
|
||||
|
||||
|
@ -68,6 +78,67 @@ SECTIONS
|
|||
. = ALIGN(0x4) ;
|
||||
_etext = . ;
|
||||
}
|
||||
)ld";
|
||||
|
||||
const char * code1Section = R"ld(/* ld script for Elf2Mac */
|
||||
.code1 : {
|
||||
_stext = . ;
|
||||
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*)
|
||||
|
||||
. = ALIGN (4) ;
|
||||
__init_section = . ;
|
||||
KEEP (*(.init))
|
||||
__init_section_end = . ;
|
||||
__fini_section = . ;
|
||||
KEEP (*(.fini))
|
||||
__fini_section_end = . ;
|
||||
|
||||
__EH_FRAME_BEGIN__ = .;
|
||||
LONG(0);
|
||||
|
||||
. = ALIGN(0x4) ;
|
||||
_etext = . ;
|
||||
}
|
||||
)ld";
|
||||
const char * codeSectionTemplate = R"ld(/* ld script for Elf2Mac */
|
||||
.code@N@ : {
|
||||
@FILTER@(.text*)
|
||||
|
||||
@EXTRA@
|
||||
|
||||
. = ALIGN (4) ;
|
||||
|
||||
KEEP(@FILTER@(.eh_frame))
|
||||
LONG(0);
|
||||
KEEP(@FILTER@(.gcc_except_table))
|
||||
KEEP(@FILTER@(.gcc_except_table.*))
|
||||
|
||||
. = ALIGN(0x4) ;
|
||||
}
|
||||
)ld";
|
||||
|
||||
const char * lastCodeExtra = R"ld(
|
||||
*(.stub)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7t)
|
||||
*(.glue_7)
|
||||
*(.jcr)
|
||||
)ld";
|
||||
|
||||
|
||||
const char * scriptEnd = R"ld(
|
||||
.data : {
|
||||
_sdata = . ;
|
||||
*(.got.plt)
|
||||
|
@ -86,29 +157,19 @@ SECTIONS
|
|||
*(.gnu.linkonce.d*)
|
||||
|
||||
. = ALIGN(4) ;
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin*.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
__CTOR_LIST__ = .;
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin*.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
__CTOR_END__ = .;
|
||||
LONG(0);
|
||||
|
||||
. = ALIGN(0x4);
|
||||
__DTOR_LIST__ = .;
|
||||
KEEP (*(.dtors))
|
||||
|
||||
*(.tm_clone_table)
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
__DTOR_END__ = .;
|
||||
LONG(0);
|
||||
|
||||
. = ALIGN(0x4);
|
||||
_edata = . ;
|
||||
}
|
||||
|
@ -171,7 +232,17 @@ SECTIONS
|
|||
)ld";
|
||||
|
||||
|
||||
void CreateLdScript(std::ofstream& out)
|
||||
void CreateLdScript(std::ostream& out)
|
||||
{
|
||||
out << defaultLdScript;
|
||||
#if 1
|
||||
out << scriptStart << textSection << scriptEnd;
|
||||
#else
|
||||
out << scriptStart << code1Section;
|
||||
string code = codeSectionTemplate;
|
||||
boost::replace_all(code, "@N@", "2");
|
||||
boost::replace_all(code, "@FILTER@", "*");
|
||||
boost::replace_all(code, "@EXTRA@", lastCodeExtra);
|
||||
out << code;
|
||||
out << scriptEnd;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ void foobar()
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
bool throwFail = false;
|
||||
bool catchFail = true;
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
int n = i == 0 ? 1 : 100;
|
||||
|
@ -39,13 +41,18 @@ int main(int argc, char** argv)
|
|||
long start = TickCount();
|
||||
for(int j = 0; j < n; j++)
|
||||
{
|
||||
try { foobar(); } catch(...) {}
|
||||
try { foobar(); throwFail = true; } catch(...) { catchFail = false; }
|
||||
}
|
||||
long end = TickCount();
|
||||
|
||||
printf("%g ms per throw/catch\n",(end-start)*1000 / 60.0 / n);
|
||||
}
|
||||
|
||||
if(throwFail)
|
||||
printf("******** FAILURE: throw didn't really throw\n");
|
||||
if(catchFail)
|
||||
printf("******** FAILURE: catch block never entered\n");
|
||||
|
||||
const int n = 3;
|
||||
printf("Click mouse %d times...\n", n);
|
||||
for(int i = 0; i < n; i++)
|
||||
|
|
|
@ -1934,6 +1934,15 @@ m68k-*-elf* | fido-*-elf*)
|
|||
esac
|
||||
;;
|
||||
m68k-*-macos* | fido-*-elf*)
|
||||
default_m68k_cpu=68020
|
||||
default_cf_cpu=5206
|
||||
tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h newlib-stdint.h m68k/m68kemb.h m68k/m68k-macos.h"
|
||||
tm_defines="${tm_defines} MOTOROLA=1"
|
||||
tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
|
||||
tmake_file="$tmake_file m68k/t-mlibs"
|
||||
;;
|
||||
|
||||
fido-*-elf*)
|
||||
default_m68k_cpu=68020
|
||||
default_cf_cpu=5206
|
||||
tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h newlib-stdint.h m68k/m68kemb.h m68k/m68020-elf.h"
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#define LIBGCC_SPEC "-lretrocrt -lgcc"
|
||||
#define LINK_SPEC "-elf2mac -q -undefined=_consolewrite"
|
||||
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC ""
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC ""
|
||||
|
|
@ -54,8 +54,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
#define SUBTARGET_EXTRA_SPECS
|
||||
|
||||
#define LIBGCC_SPEC "-lretrocrt -lgcc"
|
||||
#define LINK_SPEC "-elf2mac -q -undefined=_consolewrite"
|
||||
|
||||
/* Note that some other tm.h files include this one and then override
|
||||
many of the definitions that relate to assembler syntax. */
|
||||
|
|
|
@ -51,6 +51,22 @@ extern uint8_t __fini_section, __fini_section_end;
|
|||
// usually equal to _stext, but can be overridden.
|
||||
extern uint8_t _rsrc_start;
|
||||
|
||||
extern voidFunction __CTOR_LIST__, __DTOR_LIST__;
|
||||
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 *)
|
||||
__attribute__ ((weak));
|
||||
extern void *__deregister_frame_info (const void *)
|
||||
__attribute__ ((weak));
|
||||
|
||||
|
||||
typedef struct Retro68RelocState
|
||||
{
|
||||
Ptr bssPtr;
|
||||
|
@ -240,26 +256,45 @@ void Retro68Relocate()
|
|||
|
||||
void Retro68CallConstructors()
|
||||
{
|
||||
uint8_t *p = &__init_section;
|
||||
uint8_t *e = &__init_section_end;
|
||||
p += 2;
|
||||
while( p < e )
|
||||
static struct object object;
|
||||
if (__register_frame_info)
|
||||
__register_frame_info(&__EH_FRAME_BEGIN__, &object);
|
||||
{
|
||||
(*(voidFunction)(*(long*)p))();
|
||||
p += 6;
|
||||
uint8_t *p = &__init_section;
|
||||
uint8_t *e = &__init_section_end;
|
||||
p += 2;
|
||||
while( p < e )
|
||||
{
|
||||
(*(voidFunction)(*(long*)p))();
|
||||
p += 6;
|
||||
}
|
||||
}
|
||||
{
|
||||
voidFunction *p, f;
|
||||
for(p = &__CTOR_LIST__; (f = *p); p++)
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
void Retro68CallDestructors()
|
||||
{
|
||||
uint8_t *p = &__fini_section;
|
||||
uint8_t *e = &__fini_section_end;
|
||||
p += 2;
|
||||
while( p < e )
|
||||
{
|
||||
(*(voidFunction)(*(long*)p))();
|
||||
p += 6;
|
||||
voidFunction *p, f;
|
||||
for(p = &__DTOR_LIST__; (f = *p); p++)
|
||||
f();
|
||||
}
|
||||
{
|
||||
uint8_t *p = &__fini_section;
|
||||
uint8_t *e = &__fini_section_end;
|
||||
p += 2;
|
||||
while( p < e )
|
||||
{
|
||||
(*(voidFunction)(*(long*)p))();
|
||||
p += 6;
|
||||
}
|
||||
}
|
||||
if (__deregister_frame_info)
|
||||
__deregister_frame_info(&__EH_FRAME_BEGIN__);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue