From b2f4bed8376bb0fd12110ca1eb25d6d5e5b6fb24 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 26 Feb 2007 15:53:51 +0000 Subject: [PATCH] output.h (assemble_addr_to_section): Declare. * 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. * 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. From-SVN: r122335 --- gcc/ChangeLog | 21 +++++++ gcc/c-common.c | 7 ++- gcc/config.gcc | 1 + gcc/config/t-vxworks | 4 ++ gcc/config/vxworks.c | 56 +++++++++++++++++ gcc/config/vxworks.h | 11 ++-- gcc/output.h | 7 +++ gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/special/initpri2.C | 21 +++++++ gcc/testsuite/gcc.dg/initpri2.c | 21 +++++++ gcc/testsuite/gcc.dg/vxworks/initpri1.c | 19 ++++++ gcc/testsuite/gcc.dg/vxworks/initpri2.c | 15 +++++ gcc/testsuite/gcc.dg/vxworks/vxworks.exp | 36 +++++++++++ gcc/varasm.c | 76 +++++++++++++----------- 14 files changed, 259 insertions(+), 42 deletions(-) create mode 100644 gcc/config/vxworks.c create mode 100644 gcc/testsuite/gcc.dg/vxworks/initpri1.c create mode 100644 gcc/testsuite/gcc.dg/vxworks/initpri2.c create mode 100644 gcc/testsuite/gcc.dg/vxworks/vxworks.exp diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 118559971fb..c71aec1f10e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2007-02-26 Mark Mitchell + + * 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 Uros Bizjak PR tree-optimization/30938 diff --git a/gcc/c-common.c b/gcc/c-common.c index 4eb0265a7a2..6d1606c0b0e 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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); diff --git a/gcc/config.gcc b/gcc/config.gcc index 877d25c1842..59df9fb0aa0 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -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' ;; diff --git a/gcc/config/t-vxworks b/gcc/config/t-vxworks index 1eac999d870..9a6a6b0d120 100644 --- a/gcc/config/t-vxworks +++ b/gcc/config/t-vxworks @@ -25,3 +25,7 @@ EXTRA_HEADERS += $(srcdir)/gthr-vxworks.h gthr-default.h 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) $< diff --git a/gcc/config/vxworks.c b/gcc/config/vxworks.c new file mode 100644 index 00000000000..4ac33ab6c3e --- /dev/null +++ b/gcc/config/vxworks.c @@ -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); +} diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h index 2d07b621969..4c668116c31 100644 --- a/gcc/config/vxworks.h +++ b/gcc/config/vxworks.h @@ -90,11 +90,12 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 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. */ diff --git a/gcc/output.h b/gcc/output.h index 4e7ccf61308..3c9bcc444f8 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -272,6 +272,9 @@ extern bool assemble_integer (rtx, unsigned, unsigned, int); 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 *); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5e15b90a0d..23039a5d2be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2007-02-25 Mark Mitchell + * 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. + * gcc.dg/initpri1.c: New test. * gcc.dg/initpri2.c: Likewise. * g++.dg/special/initpri1.C: New test. diff --git a/gcc/testsuite/g++.dg/special/initpri2.C b/gcc/testsuite/g++.dg/special/initpri2.C index 100027430a5..fa9fda0d7f3 100644 --- a/gcc/testsuite/g++.dg/special/initpri2.C +++ b/gcc/testsuite/g++.dg/special/initpri2.C @@ -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)))); diff --git a/gcc/testsuite/gcc.dg/initpri2.c b/gcc/testsuite/gcc.dg/initpri2.c index 100027430a5..fa9fda0d7f3 100644 --- a/gcc/testsuite/gcc.dg/initpri2.c +++ b/gcc/testsuite/gcc.dg/initpri2.c @@ -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)))); diff --git a/gcc/testsuite/gcc.dg/vxworks/initpri1.c b/gcc/testsuite/gcc.dg/vxworks/initpri1.c new file mode 100644 index 00000000000..555bffe738d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vxworks/initpri1.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/vxworks/initpri2.c b/gcc/testsuite/gcc.dg/vxworks/initpri2.c new file mode 100644 index 00000000000..a2b2c77c7aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vxworks/initpri2.c @@ -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; } + diff --git a/gcc/testsuite/gcc.dg/vxworks/vxworks.exp b/gcc/testsuite/gcc.dg/vxworks/vxworks.exp new file mode 100644 index 00000000000..826bcf3f3a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vxworks/vxworks.exp @@ -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 diff --git a/gcc/varasm.c b/gcc/varasm.c index 6c221459285..c92a5a08f42 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1448,26 +1448,44 @@ default_stabs_asm_out_destructor (rtx symbol ATTRIBUTE_UNUSED, #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. */ - 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; - } + 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); +} - switch_to_section (get_section (section, SECTION_WRITE, NULL)); - assemble_align (POINTER_SIZE); - assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); +void +default_named_section_asm_out_destructor (rtx symbol, int priority) +{ + section *sec; + + if (priority != DEFAULT_INIT_PRIORITY) + sec = get_cdtor_priority_section (priority, + /*constructor_p=*/false); + else + sec = get_section (".dtors", SECTION_WRITE, NULL); + + 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 symbol ATTRIBUTE_UNUSED, 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