Patchwork [VMS/committed] : consolidate ia64_start_function and alpha_start_function, rework crt0

login
register
mail settings
Submitter Tristan Gingold
Date March 26, 2012, 9:41 a.m.
Message ID <361531DC-E0BD-4DAC-BF1A-33D1617AB6E4@adacore.com>
Download mbox | patch
Permalink /patch/148668/
State New
Headers show

Comments

Tristan Gingold - March 26, 2012, 9:41 a.m.
And the corresponding path is below...

On Mar 26, 2012, at 11:37 AM, Tristan Gingold wrote:

> Hi,
> 
> there was duplicated code for dealing with -mdebug-main in ia64_start_function and alpha_start_function.  This patch consolidates that.
> 
> The pointer size is recorded for function 'main', so that crt0 now expand argv[] if needed; likewise of the return status code.
> 
> Manually tested on both ia64 and alpha openvms, committed on trunk.
> 
> Tristan.
> 
> libgcc/
> 2012-03-26  Tristan Gingold  <gingold@adacore.com>
> 
>        * config/alpha/vms.h (LINK_SPEC): Simplify.
>        (STARTFILE_SPEC): Remove -mvms-return-codes handling.
>        (NAME__MAIN, SYMBOL__MAIN): Remove.
>        (VMS_DEBUG_MAIN_POINTER): Remove.
>        * config/ia64/vms.h: Likewise.
>        * config/alpha/alpha.c (alpha_start_function): Move vms_debug_main
>        code to vms.c.  Call vms_start_function.
>        * config/ia64/ia64.c (ia64_start_function): Likewise.
>        * config/vms/vms-protos.h (vms_start_function): Declare.
>        * config/vms/vms.c (vms_start_function): New function.
>        * config/vms/vms.h (MATH_LIBRARY): Define.
>        (VMS_DEBUG_MAIN_POINTER): Define.
> 
> gcc/
> 2012-03-26  Tristan Gingold  <gingold@adacore.com>
> 
>        * config/alpha/vms.h (LINK_SPEC): Simplify.
>        (STARTFILE_SPEC): Remove -mvms-return-codes handling.
>        (NAME__MAIN, SYMBOL__MAIN): Remove.
>        (VMS_DEBUG_MAIN_POINTER): Remove.
>        * config/ia64/vms.h: Likewise.
>        * config/alpha/alpha.c (alpha_start_function): Move vms_debug_main
>        code to vms.c.  Call vms_start_function.
>        * config/ia64/ia64.c (ia64_start_function): Likewise.
>        * config/vms/vms-protos.h (vms_start_function): Declare.
>        * config/vms/vms.c (vms_start_function): New function.
>        * config/vms/vms.h (MATH_LIBRARY): Define.
>        (VMS_DEBUG_MAIN_POINTER): Define.
>

Patch

diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 46c620b..c52fc50 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -7866,14 +7866,7 @@  alpha_start_function (FILE *file, const char *fnname,
   int i;
 
 #if TARGET_ABI_OPEN_VMS
-  if (vms_debug_main
-      && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
-    {
-      targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
-      ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
-      switch_to_section (text_section);
-      vms_debug_main = NULL;
-    }
+  vms_start_function (fnname);
 #endif
 
   alpha_fnname = fnname;
diff --git a/gcc/config/alpha/vms.h b/gcc/config/alpha/vms.h
index b1d46b5..8caec54 100644
--- a/gcc/config/alpha/vms.h
+++ b/gcc/config/alpha/vms.h
@@ -43,8 +43,6 @@  along with GCC; see the file COPYING3.  If not see
         builtin_define ("__IEEE_FLOAT");	\
     } while (0)
 
-#define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
-
 #undef PCC_STATIC_STRUCT_RETURN
 
 #define MAX_OFILE_ALIGNMENT 524288  /* 8 x 2^16 by DEC Ada Test CD40VRA */
@@ -279,21 +277,14 @@  do {                                                \
 #else
 /* Link with vms-dwarf2.o if -g (except -g0). This causes the
    VMS link to pull all the dwarf2 debug sections together.  */
-#define LINK_SPEC "%{g:-g vms-dwarf2.o%s} %{g0} %{g1:-g1 vms-dwarf2.o%s} \
-%{g2:-g2 vms-dwarf2.o%s} %{g3:-g3 vms-dwarf2.o%s} %{shared} %{v} %{map}"
+#define LINK_SPEC "%{g0} %{g*:-g vms-dwarf2.o%s} %{shared} %{v} %{map}"
 #endif
 
 #undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
-"%{!shared:%{mvms-return-codes:vcrt0.o%s} %{!mvms-return-codes:pcrt0.o%s} \
-    crtbegin.o%s} \
+#define STARTFILE_SPEC "%{!shared:crt0.o%s crtbegin.o%s} \
  %{!static:%{shared:crtbeginS.o%s}}"
 
-#define ENDFILE_SPEC \
-"%{!shared:crtend.o%s} %{!static:%{shared:crtendS.o%s}}"
-
-#define NAME__MAIN "__gccmain"
-#define SYMBOL__MAIN __gccmain
+#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{!static:%{shared:crtendS.o%s}}"
 
 #define INIT_SECTION_ASM_OP "\t.section LIB$INITIALIZE,GBL,NOWRT"
 
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 5b2d748..98a6120 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -3649,16 +3649,8 @@  void
 ia64_start_function (FILE *file, const char *fnname,
 		     tree decl ATTRIBUTE_UNUSED)
 {
-#if VMS_DEBUGGING_INFO
-  if (vms_debug_main
-      && debug_info_level > DINFO_LEVEL_NONE
-      && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
-    {
-      targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
-      ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
-      dwarf2out_vms_debug_main_pointer ();
-      vms_debug_main = 0;
-    }
+#if TARGET_ABI_OPEN_VMS
+  vms_start_function (fnname);
 #endif
 
   fputs ("\t.proc ", file);
diff --git a/gcc/config/ia64/vms.h b/gcc/config/ia64/vms.h
index 1908c47..3e0c653 100644
--- a/gcc/config/ia64/vms.h
+++ b/gcc/config/ia64/vms.h
@@ -30,8 +30,6 @@  along with GCC; see the file COPYING3.  If not see
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS)
 
-#define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
-
 #undef MAX_OFILE_ALIGNMENT
 #define MAX_OFILE_ALIGNMENT 524288  /* 8 x 2^16 by DEC Ada Test CD40VRA */
 
@@ -55,19 +53,16 @@  do {                                          \
 } while (0)
 
 #undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
-"%{!shared:%{mvms-return-codes:vcrt0.o%s} %{!mvms-return-codes:pcrt0.o%s} \
-    crtbegin.o%s} \
+#define STARTFILE_SPEC "%{!shared:crt0.o%s crtbegin.o%s} \
  %{!static:%{shared:crtinitS.o%s crtbeginS.o%s}}"
 
 #undef ENDFILE_SPEC
-#define ENDFILE_SPEC \
-"%{!shared:crtend.o%s} %{!static:%{shared:crtendS.o%s}}"
+#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{!static:%{shared:crtendS.o%s}}"
 
 #define LINK_GCC_C_SEQUENCE_SPEC "%G"
 
 #undef LINK_SPEC
-#define LINK_SPEC "%{g*} %{map} %{save-temps} %{shared} %{v}"
+#define LINK_SPEC "%{g0} %{g*:-g} %{map} %{save-temps} %{shared} %{v}"
 
 #undef LIB_SPEC
 #define LIB_SPEC ""
@@ -89,9 +84,6 @@  do {								\
 #undef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS ia64_vms_init_libfuncs
 
-#define NAME__MAIN "__gccmain"
-#define SYMBOL__MAIN __gccmain
-
 #define CTOR_LIST_BEGIN asm (".global\tLIB$INITIALIZE#\n");                  \
 STATIC func_ptr __CTOR_LIST__[1]                                             \
   __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr)))) \
diff --git a/gcc/config/vms/vms-protos.h b/gcc/config/vms/vms-protos.h
index ff97c31..dcff824 100644
--- a/gcc/config/vms/vms-protos.h
+++ b/gcc/config/vms/vms-protos.h
@@ -31,4 +31,5 @@  extern section *vms_function_section (tree decl ATTRIBUTE_UNUSED,
                                       enum node_frequency freq ATTRIBUTE_UNUSED,
                                       bool startup ATTRIBUTE_UNUSED,
                                       bool exit ATTRIBUTE_UNUSED);
+extern void vms_start_function (const char *fname);
 #endif /* TREE_CODE */
diff --git a/gcc/config/vms/vms.c b/gcc/config/vms/vms.c
index 4a7386f..a85fb3f 100644
--- a/gcc/config/vms/vms.c
+++ b/gcc/config/vms/vms.c
@@ -23,8 +23,9 @@  along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tree.h"
 #include "vms-protos.h"
-#include "tm.h"
 #include "ggc.h"
+#include "target.h"
+#include "output.h"
 
 /* Correlation of standard CRTL names with DECCRTL function names.  */
 
@@ -194,4 +195,43 @@  vms_function_section (tree decl ATTRIBUTE_UNUSED,
   return NULL;
 }
 
+/* Additionnal VMS specific code for start_function.  */
+
+/* Must be kept in sync with libgcc/config/vms/vms-ucrt0.c  */
+#define VMS_MAIN_FLAGS_SYMBOL "__gcc_main_flags"
+#define MAIN_FLAG_64BIT (1 << 0)
+#define MAIN_FLAG_POSIX (1 << 1)
+
+void
+vms_start_function (const char *fnname)
+{
+#if VMS_DEBUGGING_INFO
+  if (vms_debug_main
+      && debug_info_level > DINFO_LEVEL_NONE
+      && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
+    {
+      targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
+      ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
+      dwarf2out_vms_debug_main_pointer ();
+      vms_debug_main = 0;
+    }
+#endif
+
+  /* Registers flags used for function main.  This is necessary for
+     crt0 code.  */
+  if (strcmp (fnname, "main") == 0)
+    {
+      unsigned int flags = 0;
+
+      if (flag_vms_pointer_size == VMS_POINTER_SIZE_64)
+	flags |= MAIN_FLAG_64BIT;
+      if (!flag_vms_return_codes)
+	flags |= MAIN_FLAG_POSIX;
+
+      targetm.asm_out.globalize_label (asm_out_file, VMS_MAIN_FLAGS_SYMBOL);
+      assemble_name (asm_out_file, VMS_MAIN_FLAGS_SYMBOL);
+      fprintf (asm_out_file, " = %u\n", flags);
+    }
+}
+
 #include "gt-vms.h"
diff --git a/gcc/config/vms/vms.h b/gcc/config/vms/vms.h
index 47028c8..8eb5606 100644
--- a/gcc/config/vms/vms.h
+++ b/gcc/config/vms/vms.h
@@ -75,10 +75,15 @@  extern void vms_c_register_includes (const char *, const char *, int);
 #define C_COMMON_OVERRIDE_OPTIONS vms_c_common_override_options ()
 
 /* VMS doesn't support other sections than .text for code.  */
-
 #define TARGET_ASM_FUNCTION_SECTION vms_function_section
 
 /* Always use 8 bytes addresses in dwarf2 debug info.  The default value doesn't
    work as it may be 4 bytes, which won't match gas default (8 bytes for ia64),
    and will thus produce incorrect values.  */
 #define DWARF2_ADDR_SIZE 8
+
+/* No libm on VMS.  */
+#define MATH_LIBRARY ""
+
+/* Special VMS debugger symbol to record the entry point.  */
+#define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
diff --git a/libgcc/config.host b/libgcc/config.host
index 1e81518..fdafc48 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -255,7 +255,7 @@  case ${host} in
   ;;
 *-*-*vms*)
   tmake_file="vms/t-vms"
-  extra_parts="vcrt0.o pcrt0.o crtbegin.o crtbeginS.o crtend.o crtendS.o"
+  extra_parts="crt0.o crtbegin.o crtbeginS.o crtend.o crtendS.o"
   ;;
 *-*-vxworks*)
   tmake_file=t-vxworks
diff --git a/libgcc/config/vms/t-vms b/libgcc/config/vms/t-vms
index 93d8255..21e09ff 100644
--- a/libgcc/config/vms/t-vms
+++ b/libgcc/config/vms/t-vms
@@ -1,6 +1,3 @@ 
-# Assemble startup files.
-vcrt0.o: $(srcdir)/config/vms/vms-ucrt0.c
-	$(gcc_compile) -c $<
-
-pcrt0.o: $(srcdir)/config/vms/vms-ucrt0.c
-	$(gcc_compile) -c -DCRT0_POSIX_EXIT $<
+# Assemble startup file.
+crt0.o: $(srcdir)/config/vms/vms-ucrt0.c
+	$(gcc_compile) -mpointer-size=64 -c $<
diff --git a/libgcc/config/vms/vms-ucrt0.c b/libgcc/config/vms/vms-ucrt0.c
index 344b595..02b7bdb 100644
--- a/libgcc/config/vms/vms-ucrt0.c
+++ b/libgcc/config/vms/vms-ucrt0.c
@@ -1,5 +1,5 @@ 
 /* VMS crt0 returning Unix style condition codes.
-   Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2009, 2010, 2012 Free Software Foundation, Inc.
    Contributed by Douglas B. Rupp (rupp@gnat.com).
 
    This file is part of GCC.
@@ -25,12 +25,16 @@ 
 
 #include <stdlib.h>
 
+/* Sanity check.  */
+#if __INITIAL_POINTER_SIZE != 64
+#error "vms-ucrt0.c must be compiled with -mpointer-size=64"
+#endif
+
 /* Lots of cheat to handle 32bits/64bits pointer conversions.
    We use 'long long' for 64 bits pointers and 'int' for 32 bits pointers.  */
 
-extern void decc$main (void *arg1, void *arg2, void *arg3,
-                       void *image_file_desc, void *arg5, void *arg6,
-                       int *, int *, int *);
+extern void decc$main (void *, void *, void *, void *, unsigned int,
+		       unsigned int, int *, int *, int *);
 extern int main (int, char **, char **);
 extern int _malloc32 (int);
 
@@ -40,8 +44,8 @@  extern int _malloc32 (int);
 #define MAIN_ASM_NAME
 #endif
 
-int __main (void *arg1, void *arg2, void *arg3,
-            void *image_file_desc, void *arg5, void *arg6) MAIN_ASM_NAME;
+int __main (void *, void *, void *, void *,
+	    unsigned int, unsigned int) MAIN_ASM_NAME;
 
 /* From errnodef.h, but we need to emulate the globalval.  */
 extern int C$_EXIT1;
@@ -49,79 +53,90 @@  extern int C$_EXIT1;
 /* From stsdef.h  */
 #define STS$V_MSG_NO 0x03
 #define STS$M_INHIB_MSG 0x10000000
+/* Symbol defined while main() is compiled to record the flags used.
+   (Note that the symbol defines the value, ie extract the bits from the
+    address).
+   bit 0 set for 64 bit pointers
+   bit 1 set for posix return value.  */
+extern char __gcc_main_flags;
 
 /* From ssdef.h  */
 #define SS$_NORMAL 1
+#define MAIN_FLAG_64BIT (1 << 0)
+#define MAIN_FLAG_POSIX (1 << 1)
 
 int
-__main (void *arg1, void *arg2, void *arg3,
-        void *image_file_desc, void *arg5, void *arg6)
+__main (void *progxfer, void *cli_util, void *imghdr, void *image_file_desc,
+	unsigned int linkflag, unsigned int cliflag)
 {
   int argc;
   int argv;
   int envp;
   int status;
-  int i;
-  long long *long_argv;
-  long long *long_envp;
+  char **argv64;
+  char **envp64;
+  unsigned int flags = (unsigned __int64)&__gcc_main_flags;
 
   /* The argv and envp arrays are 32 bits pointers to 32 bits pointers.  */
-  decc$main (arg1, arg2, arg3, image_file_desc,
-	     arg5, arg6, &argc, &argv, &envp);
+  decc$main (progxfer, cli_util, imghdr, image_file_desc,
+	     linkflag, cliflag, &argc, &argv, &envp);
 
-  if (sizeof (void *) == 8)
+  if (flags & MAIN_FLAG_64BIT)
     {
+      int i;
+
       /* Reallocate argv and envp with 64 bit pointers.  */
-      long_argv = (long long *)
-        (long long) _malloc32 (sizeof (long long) * (argc + 1));
+      argv64 = (char **) _malloc32 (sizeof (char *) * (argc + 1));
 
       for (i = 0; i < argc; i++)
-        long_argv[i] = ((int *) (long long) argv)[i];
+        argv64[i] = (char *) (__int64)(((int *) (__int64) argv)[i]);
 
-      long_argv[argc] = 0;
+      argv64[argc] = NULL;
 
-      for (i = 0; ((int *) (long long) envp)[i]; i++)
+      for (i = 0; ((int *) (__int64) envp)[i]; i++)
         ;
-      long_envp = (long long *)
-        (long long) _malloc32 (sizeof (long long) * (i + 1));
+      envp64 = (char **) _malloc32 (sizeof (char *) * (i + 1));
 
-      for (i = 0; ((int *) (long long) envp)[i]; i++)
-        long_envp[i] = ((int *) (long long) envp)[i];
+      for (i = 0; ((int *) (__int64) envp)[i]; i++)
+        envp64[i] = (char *)(__int64)(((int *) (__int64) envp)[i]);
 
-      long_envp[i] = 0;
+      envp64[i] = NULL;
     }
   else
     {
-      long_argv = (long long *) argv;
-      long_envp = (long long *) envp;
+      argv64 = (char **)(__int64)argv;
+      envp64 = (char **)(__int64)envp;
     }
-  status = main (argc, (char **)long_argv, (char **)long_envp);
 
-#ifdef CRT0_POSIX_EXIT
-  /* Map into a range of 0 - 255.  */
-  status = status & 255;
+  status = main (argc, argv64, envp64);
 
-  if (status > 0)
+  if (flags & MAIN_FLAG_POSIX)
     {
-      int save_status = status;
+      /* Map into a range of 0 - 255.  */
+      status &= 255;
 
-      status = (long) &C$_EXIT1 + ((status - 1) << STS$V_MSG_NO);
-
-      /* An exit failure status requires a "severe" error.  All status values
-	 are defined in errno with a successful (1) severity but can be
-	 changed to an error (2) severity by adding 1.  In addition for
-	 compatibility with UNIX exit() routines we inhibit a run-time error
-	 message from being generated on exit(1).  */
-
-      if (save_status == 1)
+      if (status != 0)
 	{
-	  status++;
-	  status |= STS$M_INHIB_MSG;
+	  int save_status = status;
+
+	  status = (__int64) &C$_EXIT1 + ((status - 1) << STS$V_MSG_NO);
+
+	  /* An exit failure status requires a "severe" error.  All
+	     status values are defined in errno with a successful (1)
+	     severity but can be changed to an error (2) severity by
+	     adding 1.  In addition for compatibility with UNIX exit()
+	     routines we inhibit a run-time error message from being
+	     generated on exit(1).  */
+
+	  if (save_status == 1)
+	    {
+	      status++;
+	      status |= STS$M_INHIB_MSG;
+	    }
 	}
+      else
+	status = SS$_NORMAL;
     }
-  else
-    status = SS$_NORMAL;
-#endif /* CRT0_POSIX_EXIT */
 
   return status;
 }