This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Initialization priorities for VxWorks


This patch contains:

* A refactoring of the code that generators the .ctors and .dtors
  table entries in varasm.c.  I needed to expose a couple of
  additional entry points for VxWorks, and I made the existing
  fucntions share more code as well.

* VxWorks-specific initialization priority support.  For VxWorks RTPs,
  even default priority constructors and destructors must go in a
  numbered .[cd]tors.N section, rather than just the default
  .[cd]tors.  (The C runtime library, which we don't control, requires
  that.)  So, I gave VxWorks a vxworks.c file and put the
  asm_out_{constructor,destructor} functions there.  I removed the
  ALWAYS_NUMBER_CTORS_SECTIONS macro from VxWorks.h which, while used
  in CodeSourcery's VxWorks compilers, is vestigial in the FSF tree.

* Joseph noticed that the attribute-handling code for initialization
  priorities was checking for integral constants, but not that the
  integral constants had integral type, so things like "((void*)0)"
  would be accepted as priorities; such cases are now rejected.

Tested on x86_64-unknown-linux-gnu, applied to mainline.  I also
performed by-hand testing with a VxWorks cross compiler built from the
same sources; it's not possible to build a fully working VxWorks
cross-compiler from mainline sources yet.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2007-02-25  Mark Mitchell  <mark@codesourcery.com>

	* output.h (assemble_addr_to_section): Declare.
	(get_cdtor_priority_section): Likewise.
	* varasm.c (assemble_addr_to_section): New function.
	(get_cdtor_priority_section): Likewise.
	(default_named_section_asm_out_destructor): Use them.
	(destor_dtor_section_asm_out_destructor): Likewise.
	(default_named_section_asm_out_constructor): Likewise.
	(default_ctor_section_asm_out_constructor): Likewise.
	* config.gcc (*-*-vxworks*): Include vxworks.o.
	* config/t-vxworks (vxworks.o): New target.
	* config/vxworks.h (ALWAYS_NUMBER_CTORS_SECTIONS): Remove.
	(TARGET_ASM_CONSTRUCTOR): Define.
	(TARGET_ASM_DESTRUCTOR): Likewise.
	(vxworks_asm_out_constructor): Declare.
	(vxworks_asm_out_destructor): Likewise.

	* c-common.c (get_priority): Check that we have not just an
	INTEGER_CST, but an integer constant with integeral type.

2007-02-25  Mark Mitchell  <mark@codesourcery.com>

	* gcc.dg/vxworks/vxworks.exp: New file.
	* gcc.dg/vxworks/initpri1.c: Likewise.
	* gcc.dg/vxworks/initpri2.c: Likewise.
	* gcc.dg/initpri2.c: Add more tests.
	* g++.dg/special/initpri2.C: Likewise.

Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 122315)
+++ gcc/varasm.c	(working copy)
@@ -1448,26 +1448,44 @@ default_stabs_asm_out_destructor (rtx sy
 #endif
 }
 
-void
-default_named_section_asm_out_destructor (rtx symbol, int priority)
+/* Write the address of the entity given by SYMBOL to SEC.  */
+void 
+assemble_addr_to_section (rtx symbol, section *sec)
+{
+  switch_to_section (sec);
+  assemble_align (POINTER_SIZE);
+  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+}
+
+/* Return the numbered .ctors.N (if CONSTRUCTOR_P) or .dtors.N (if
+   not) section for PRIORITY.  */
+section *
+get_cdtor_priority_section (int priority, bool constructor_p)
 {
-  const char *section = ".dtors";
   char buf[16];
 
   /* ??? This only works reliably with the GNU linker.  */
+  sprintf (buf, "%s.%.5u",
+	   constructor_p ? ".ctors" : ".dtors",
+	   /* Invert the numbering so the linker puts us in the proper
+	      order; constructors are run from right to left, and the
+	      linker sorts in increasing order.  */
+	   MAX_INIT_PRIORITY - priority);
+  return get_section (buf, SECTION_WRITE, NULL);
+}
+
+void
+default_named_section_asm_out_destructor (rtx symbol, int priority)
+{
+  section *sec;
+
   if (priority != DEFAULT_INIT_PRIORITY)
-    {
-      sprintf (buf, ".dtors.%.5u",
-	       /* Invert the numbering so the linker puts us in the proper
-		  order; constructors are run from right to left, and the
-		  linker sorts in increasing order.  */
-	       MAX_INIT_PRIORITY - priority);
-      section = buf;
-    }
+    sec = get_cdtor_priority_section (priority, 
+				      /*constructor_p=*/false);
+  else
+    sec = get_section (".dtors", SECTION_WRITE, NULL);
 
-  switch_to_section (get_section (section, SECTION_WRITE, NULL));
-  assemble_align (POINTER_SIZE);
-  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+  assemble_addr_to_section (symbol, sec);
 }
 
 #ifdef DTORS_SECTION_ASM_OP
@@ -1475,9 +1493,7 @@ void
 default_dtor_section_asm_out_destructor (rtx symbol,
 					 int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
-  assemble_align (POINTER_SIZE);
-  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+  assemble_addr_to_section (symbol, dtors_section);
 }
 #endif
 
@@ -1501,23 +1517,15 @@ default_stabs_asm_out_constructor (rtx s
 void
 default_named_section_asm_out_constructor (rtx symbol, int priority)
 {
-  const char *section = ".ctors";
-  char buf[16];
+  section *sec;
 
-  /* ??? This only works reliably with the GNU linker.  */
   if (priority != DEFAULT_INIT_PRIORITY)
-    {
-      sprintf (buf, ".ctors.%.5u",
-	       /* Invert the numbering so the linker puts us in the proper
-		  order; constructors are run from right to left, and the
-		  linker sorts in increasing order.  */
-	       MAX_INIT_PRIORITY - priority);
-      section = buf;
-    }
+    sec = get_cdtor_priority_section (priority, 
+				      /*constructor_p=*/true);
+  else
+    sec = get_section (".ctors", SECTION_WRITE, NULL);
 
-  switch_to_section (get_section (section, SECTION_WRITE, NULL));
-  assemble_align (POINTER_SIZE);
-  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+  assemble_addr_to_section (symbol, sec);
 }
 
 #ifdef CTORS_SECTION_ASM_OP
@@ -1525,9 +1533,7 @@ void
 default_ctor_section_asm_out_constructor (rtx symbol,
 					  int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
-  assemble_align (POINTER_SIZE);
-  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
+  assemble_addr_to_section (symbol, ctors_section);
 }
 #endif
 
Index: gcc/output.h
===================================================================
--- gcc/output.h	(revision 122314)
+++ gcc/output.h	(working copy)
@@ -272,6 +272,9 @@ extern bool assemble_integer (rtx, unsig
 extern void assemble_real (REAL_VALUE_TYPE, enum machine_mode, unsigned);
 #endif
 
+/* Write the address of the entity given by SYMBOL to SEC.  */
+extern void assemble_addr_to_section (rtx, section *);
+
 /* Return the size of the constant pool.  */
 extern int get_pool_size (void);
 
@@ -572,6 +575,10 @@ extern section *function_section (tree);
 extern section *unlikely_text_section (void);
 extern section *current_function_section (void);
 
+/* Return the numbered .ctors.N (if CONSTRUCTOR_P) or .dtors.N (if
+   not) section for PRIORITY.  */
+extern section *get_cdtor_priority_section (int, bool);
+
 extern bool unlikely_text_section_p (section *);
 extern void switch_to_section (section *);
 extern void output_section_asm_op (const void *);
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 122315)
+++ gcc/c-common.c	(working copy)
@@ -4687,11 +4687,14 @@ static priority_type
 get_priority (tree args, bool is_destructor)
 {
   HOST_WIDE_INT pri;
+  tree arg;
 
   if (!args)
     return DEFAULT_INIT_PRIORITY;
-
-  if (!host_integerp (TREE_VALUE (args), /*pos=*/0))
+  
+  arg = TREE_VALUE (args);
+  if (!host_integerp (arg, /*pos=*/0)
+      || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
     goto invalid;
 
   pri = tree_low_cst (TREE_VALUE (args), /*pos=*/0);
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 122314)
+++ gcc/config.gcc	(working copy)
@@ -572,6 +572,7 @@ case ${target} in
   tm_file="${tm_file} elfos.h svr4.h"
   xm_defines=POSIX
   extra_options="${extra_options} vxworks.opt"
+  extra_objs=vxworks.o
   case ${enable_threads} in
     no) ;;
     "" | yes | vxworks) thread_file='vxworks' ;;
Index: gcc/config/t-vxworks
===================================================================
--- gcc/config/t-vxworks	(revision 122314)
+++ gcc/config/t-vxworks	(working copy)
@@ -25,3 +25,7 @@ EXTRA_HEADERS += $(srcdir)/gthr-vxworks.
 LIBGCC2_INCLUDES="-I$(SYSTEM_HEADER_DIR)"
 
 EXTRA_MULTILIB_PARTS = 
+
+vxworks.o: $(srcdir)/config/vxworks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+	output.h $(TM_H)
+	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
Index: gcc/config/vxworks.h
===================================================================
--- gcc/config/vxworks.h	(revision 122314)
+++ gcc/config/vxworks.h	(working copy)
@@ -90,11 +90,12 @@ Software Foundation, 51 Franklin Street,
   targetm.have_ctors_dtors = TARGET_VXWORKS_RTP; \
 } while (0)
 
-/* The VxWorks runtime uses a clever trick to get the sentinel entry
-   (-1) inserted at the beginning of the .ctors segment.  This trick
-   will not work if we ever generate any entries in plain .ctors
-   sections; we must always use .ctors.PRIORITY.  */
-#define ALWAYS_NUMBER_CTORS_SECTIONS 1
+/* VxWorks requires special handling of constructors and destructors.
+   All VxWorks configurations must use these functions.  */
+#define TARGET_ASM_CONSTRUCTOR vxworks_asm_out_constructor
+#define TARGET_ASM_DESTRUCTOR vxworks_asm_out_destructor
+extern void vxworks_asm_out_constructor (rtx symbol, int priority);
+extern void vxworks_asm_out_destructor (rtx symbol, int priority);
 
 /* The name of the symbol for the table of GOTs in a particular
    RTP.  */
Index: gcc/config/vxworks.c
===================================================================
--- gcc/config/vxworks.c	(revision 0)
+++ gcc/config/vxworks.c	(revision 0)
@@ -0,0 +1,56 @@
+/* Common VxWorks target definitions for GNU compiler.
+   Copyright (C) 2007
+   Free Software Foundation, Inc.
+   Contributed by CodeSourcery, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "output.h"
+#include "tm.h"
+
+/* Like default_named_section_asm_out_constructor, except that even
+   constructors with DEFAULT_INIT_PRIORITY must go in a numbered
+   section on VxWorks.  The VxWorks runtime uses a clever trick to get
+   the sentinel entry (-1) inserted at the beginning of the .ctors
+   segment.  This trick will not work if we ever generate any entries
+   in plain .ctors sections; we must always use .ctors.PRIORITY.  */
+
+void
+vxworks_asm_out_constructor (rtx symbol, int priority)
+{
+  section *sec;
+
+  sec = get_cdtor_priority_section (priority,
+				    /*constructor_p=*/true);
+  assemble_addr_to_section (symbol, sec);
+}
+
+/* See comment for vxworks_asm_out_constructor.  */
+
+void
+vxworks_asm_out_destructor (rtx symbol, int priority)
+{
+  section *sec;
+
+  sec = get_cdtor_priority_section (priority,
+				    /*constructor_p=*/false);
+  assemble_addr_to_section (symbol, sec);
+}
Index: gcc/testsuite/gcc.dg/vxworks/vxworks.exp
===================================================================
--- gcc/testsuite/gcc.dg/vxworks/vxworks.exp	(revision 0)
+++ gcc/testsuite/gcc.dg/vxworks/vxworks.exp	(revision 0)
@@ -0,0 +1,36 @@
+#   Copyright (C) 1997 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cSi\]]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
Index: gcc/testsuite/gcc.dg/vxworks/initpri1.c
===================================================================
--- gcc/testsuite/gcc.dg/vxworks/initpri1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/vxworks/initpri1.c	(revision 0)
@@ -0,0 +1,19 @@
+/* On VxWorks, in RTP mode, constructors and destructors go in named
+   sections.  The section names must include the initialization
+   priority, even for constructors and destructors with the default
+   priority.  */
+
+/* The selector below excludes VxWorks AE because AE does not support
+   RTP mode.  */
+/* { dg-do compile { target { *-*-vxworks* && { ! *-*-vxworksae* } } } } */
+/* { dg-options "-mrtp" } */
+/* { dg-final { scan-assembler "ctors\.00000" } } */
+/* { dg-final { scan-assembler "dtors\.00000" } } */
+
+volatile int i;
+
+void c1 () __attribute__((constructor));
+void c1 () { ++i; }
+
+void d1 () __attribute__((destructor));
+void d1 () { --i; }
Index: gcc/testsuite/gcc.dg/vxworks/initpri2.c
===================================================================
--- gcc/testsuite/gcc.dg/vxworks/initpri2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/vxworks/initpri2.c	(revision 0)
@@ -0,0 +1,15 @@
+/* On VxWorks, in kernel mode, there is no support for .ctors/.dtors.
+   Instead, initialization is handled by munch.  */
+
+/* { dg-do compile { target *-*-vxworks* } } */
+/* { dg-final { scan-assembler-not "\.ctors" } } */
+/* { dg-final { scan-assembler-not "\.dtors" } } */
+
+volatile int i;
+
+void c1 () __attribute__((constructor));
+void c1 () { ++i; }
+
+void d1 () __attribute__((destructor));
+void d1 () { --i; }
+
Index: gcc/testsuite/gcc.dg/initpri2.c
===================================================================
--- gcc/testsuite/gcc.dg/initpri2.c	(revision 122315)
+++ gcc/testsuite/gcc.dg/initpri2.c	(working copy)
@@ -16,3 +16,24 @@ void c3() 
 void d3() 
      __attribute__((constructor (50))); /* { dg-warning "reserved" } */
 
+/* Priorities must be integral constants.  */
+
+/* Pointers, even with constant values, are not allowed.  */
+void c4() 
+     __attribute__((constructor ((void*) 500))); /* { dg-error "priorities" } */
+void d4()    
+     __attribute__((destructor ((void*) 500))); /* { dg-error "priorities" } */
+
+/* Integer variables are not allowed.  */
+int i;
+void c5() 
+     __attribute__((constructor ((i)))); /* { dg-error "priorities" } */
+void d5()    
+     __attribute__((destructor ((i)))); /* { dg-error "priorities" } */
+
+/* Enumeration constants are allowed.  */
+enum E { e = 500 };
+void c6() 
+     __attribute__((constructor ((e))));
+void d6()    
+     __attribute__((destructor ((e))));
Index: gcc/testsuite/g++.dg/special/initpri2.C
===================================================================
--- gcc/testsuite/g++.dg/special/initpri2.C	(revision 122315)
+++ gcc/testsuite/g++.dg/special/initpri2.C	(working copy)
@@ -16,3 +16,24 @@ void c3() 
 void d3() 
      __attribute__((constructor (50))); /* { dg-warning "reserved" } */
 
+/* Priorities must be integral constants.  */
+
+/* Pointers, even with constant values, are not allowed.  */
+void c4() 
+     __attribute__((constructor ((void*) 500))); /* { dg-error "priorities" } */
+void d4()    
+     __attribute__((destructor ((void*) 500))); /* { dg-error "priorities" } */
+
+/* Integer variables are not allowed.  */
+int i;
+void c5() 
+     __attribute__((constructor ((i)))); /* { dg-error "priorities" } */
+void d5()    
+     __attribute__((destructor ((i)))); /* { dg-error "priorities" } */
+
+/* Enumeration constants are allowed.  */
+enum E { e = 500 };
+void c6() 
+     __attribute__((constructor ((e))));
+void d6()    
+     __attribute__((destructor ((e))));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]