Take responsibility: don't use standard crtbegin/end anymore, now that we control the linker script

This commit is contained in:
Wolfgang Thaller 2017-09-24 20:04:11 +02:00
parent 68150e1c23
commit 33a2744643
7 changed files with 172 additions and 42 deletions

View File

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

View File

@ -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
}

View File

@ -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++)

View File

@ -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"

View File

@ -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 ""

View File

@ -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. */

View File

@ -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__);
}