diff --git a/configure/CONFIG_COMMON b/configure/CONFIG_COMMON index e882697ee..4ef5102e1 100644 --- a/configure/CONFIG_COMMON +++ b/configure/CONFIG_COMMON @@ -292,7 +292,7 @@ ARCMD = $(AR) $(ARFLAGS) $(USR_ARFLAGS) $@ $(LIBRARY_LD_OBJS) #-------------------------------------------------- # 'Munch' link-edit -MUNCH_CMD = $(LD) -o $@ $^ +MUNCH_CMD = $(LD) $(MUNCH_LDFLAGS) -o $@ $^ #-------------------------------------------------- # LEX default options diff --git a/configure/os/CONFIG.Common.vxWorksCommon b/configure/os/CONFIG.Common.vxWorksCommon index 4c0816d85..42c26a0a0 100644 --- a/configure/os/CONFIG.Common.vxWorksCommon +++ b/configure/os/CONFIG.Common.vxWorksCommon @@ -134,6 +134,14 @@ NM_DIR = $(firstword $(NM_DIR_$(VXWORKS_VERSION)) $(GNU_BIN)) NM = $(NM_DIR)/$(CMPLR_PREFIX)nm$(CMPLR_SUFFIX)$(HOSTEXE) +#-------------------------------------------------- +# A linker script is essential for munching from vxWorks 6.6 onwards +# (i.e. with versions that use gcc 4.1.2 or later). It can be used +# with any vxWorks 5 or 6 version, but apparently should not be used +# when compiling for 68K (which isn't supported in vxWorks 6 anyway) +MUNCH_LDFLAGS_6 = -T $(VX_DIR)/target/h/tool/gnu/ldscripts/link.OUT +MUNCH_LDFLAGS = $(MUNCH_LDFLAGS_$(VXWORKS_MAJOR_VERSION)) + #-------------------------------------------------- # The follow 2 exports prevent gnu cross-compiler # from finding wrong assembler (as). diff --git a/src/tools/munch.pl b/src/tools/munch.pl index 83702f37a..5b962f86d 100755 --- a/src/tools/munch.pl +++ b/src/tools/munch.pl @@ -13,12 +13,16 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*- # Creates a ctdt.c file of C++ static constructors and destructors, # as required for all vxWorks binaries containing C++ code. +# Is exception handler frame info required? +my $need_eh_frame = 0; + @ctors = (); %ctors = (); @dtors = (); %dtors = (); while (my $line = ) { chomp $line; + $need_eh_frame++ if m/__?gxx_personality_v[0-9]/; next if ($line =~ m/__?GLOBAL_.F.+/); next if ($line =~ m/__?GLOBAL_.I._GLOBAL_.D.+/); if ($line =~ m/__?GLOBAL_.D.+/) { @@ -39,6 +43,11 @@ print join "\n", "#include ", "\n/* Declarations */", (map cDecl($_), @ctors, @dtors), + ''; + +exceptionHandlerFrame() if $need_eh_frame; + +print join "\n", "\n/* Constructors */", "void (*_ctors[])() = {", (join ",\n", (map " " . cName($_), @ctors), " NULL"), @@ -49,6 +58,35 @@ print join "\n", "};", "\n"; +# Outputs the C code for registering exception handler frame info +sub exceptionHandlerFrame { + my $eh_ctor = 'eh_ctor'; + my $eh_dtor = 'eh_dtor'; + + # Add EH ctor/dtor to _start_ of arrays + unshift @ctors, $eh_ctor; + unshift @dtors, $eh_dtor; + + print join "\n", + '/* Exception handler frame */', + 'extern const unsigned __EH_FRAME_BEGIN__[];', + '', + "static void $eh_ctor(void) {", + ' extern void __register_frame_info (const void *, void *);', + ' static struct { unsigned pad[8]; } object;', + '', + ' __register_frame_info(__EH_FRAME_BEGIN__, &object);', + '}', + '', + "static void $eh_dtor(void) {", + ' extern void *__deregister_frame_info (const void *);', + '', + ' __deregister_frame_info(__EH_FRAME_BEGIN__);', + '}', + ''; + return; +} + sub cName { my ($name) = @_; $name =~ s/^__/_/;