diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95683954718..5884c5fb0e6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2002-11-26 Jakub Jelinek + + * varasm.c (default_exception_section): Move to... + * except.c (default_exception_section): ... here. Make + .gcc_except_table read-only if it is not expected to have any + dynamic relocations and linker handles it. + * dwarf2out.c (default_eh_frame_section): Make .eh_frame read-only + if it is not expected to have any dynamic relocations and linker + handles it. + * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Check what ld does + when linking read-only and read-write sections together. + * configure, config.in: Rebuilt. + * crtstuff.c (EH_FRAME_SECTION_CONST): Define. + (__EH_FRAME_BEGIN__, __FRAME_END__): Add it. + 2002-11-25 Aldy Hernandez * config/rs6000/spe.h (__ev_create_sfix32_fs): Change macro into diff --git a/gcc/config.in b/gcc/config.in index 6c6a74dffd9..d26ddfe23d8 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -586,6 +586,10 @@ /* Define if your assembler supports the --gstabs option. */ #undef HAVE_AS_GSTABS_DEBUG_FLAG +/* Define if your linker links a mix of read-only + and read-write sections into a read-write section. */ +#undef HAVE_LD_RO_RW_SECTION_MIXING + /* Define if your linker supports --eh-frame-hdr option. */ #undef HAVE_LD_EH_FRAME_HDR diff --git a/gcc/configure b/gcc/configure index 8d75a25934c..c041d8d59c5 100755 --- a/gcc/configure +++ b/gcc/configure @@ -8113,6 +8113,44 @@ EOF fi echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6 +echo $ac_n "checking linker read-only and read-write section mixing""... $ac_c" 1>&6 +echo "configure:8118: checking linker read-only and read-write section mixing" >&5 +gcc_cv_ld_ro_rw_mix=unknown +if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then + gcc_cv_ld_ro_rw_mix=read-write + fi +elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then + echo '.section "myfoosect", "a"' > conftest1.s + echo '.section "myfoosect", "aw"' > conftest2.s + echo '.byte 1' >> conftest2.s + echo '.section "myfoosect", "a"' > conftest3.s + echo '.byte 0' >> conftest3.s + if $gcc_cv_as -o conftest1.o conftest1.s \ + && $gcc_cv_as -o conftest2.o conftest2.s \ + && $gcc_cv_as -o conftest3.o conftest3.s \ + && $gcc_cv_ld -shared -o conftest1.so conftest1.o \ + conftest2.o conftest3.o; then + gcc_cv_ld_ro_rw_mix=`$gcc_cv_objdump -h conftest1.so \ + | grep -A1 myfoosect` + if echo "$gcc_cv_ld_ro_rw_mix" | grep CONTENTS > /dev/null; then + if echo "$gcc_cv_ld_ro_rw_mix" | grep READONLY > /dev/null; then + gcc_cv_ld_ro_rw_mix=read-only + else + gcc_cv_ld_ro_rw_mix=read-write + fi + fi + fi + rm -f conftest.* conftest[123].* +fi +if test x$gcc_cv_ld_ro_rw_mix = xread-write; then + cat >> confdefs.h <<\EOF +#define HAVE_LD_RO_RW_SECTION_MIXING 1 +EOF + +fi +echo "$ac_t""$gcc_cv_ld_ro_rw_mix" 1>&6 + echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6 echo "configure:8118: checking linker PT_GNU_EH_FRAME support" >&5 gcc_cv_ld_eh_frame_hdr=no diff --git a/gcc/configure.in b/gcc/configure.in index efc99240706..7e1628091a3 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -2209,6 +2209,44 @@ if test x"$gcc_cv_as_gstabs_flag" = xyes; then fi AC_MSG_RESULT($gcc_cv_as_gstabs_flag) +AC_MSG_CHECKING(linker read-only and read-write section mixing) +gcc_cv_ld_ro_rw_mix=unknown +if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then + gcc_cv_ld_ro_rw_mix=read-write + fi +elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then + echo '.section "myfoosect", "a"' > conftest1.s + echo '.section "myfoosect", "aw"' > conftest2.s + echo '.byte 1' >> conftest2.s + echo '.section "myfoosect", "a"' > conftest3.s + echo '.byte 0' >> conftest3.s + if $gcc_cv_as -o conftest1.o conftest1.s \ + && $gcc_cv_as -o conftest2.o conftest2.s \ + && $gcc_cv_as -o conftest3.o conftest3.s \ + && $gcc_cv_ld -shared -o conftest1.so conftest1.o \ + conftest2.o conftest3.o; then + gcc_cv_ld_ro_rw_mix=`$gcc_cv_objdump -h conftest1.so \ + | grep -A1 myfoosect` + if echo "$gcc_cv_ld_ro_rw_mix" | grep CONTENTS > /dev/null; then + if echo "$gcc_cv_ld_ro_rw_mix" | grep READONLY > /dev/null; then + gcc_cv_ld_ro_rw_mix=read-only + else + gcc_cv_ld_ro_rw_mix=read-write + fi + fi + fi +changequote(,)dnl + rm -f conftest.* conftest[123].* +changequote([,])dnl +fi +if test x$gcc_cv_ld_ro_rw_mix = xread-write; then + AC_DEFINE(HAVE_LD_RO_RW_SECTION_MIXING, 1, + [Define if your linker links a mix of read-only + and read-write sections into a read-write section.]) +fi +AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix) + AC_MSG_CHECKING(linker PT_GNU_EH_FRAME support) gcc_cv_ld_eh_frame_hdr=no if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c index e5f5d78aeea..cdc447d248d 100644 --- a/gcc/crtstuff.c +++ b/gcc/crtstuff.c @@ -90,6 +90,11 @@ call_ ## FUNC (void) \ #if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME) # define USE_EH_FRAME_REGISTRY #endif +#if defined(EH_FRAME_SECTION_NAME) && defined(HAVE_LD_RO_RW_SECTION_MIXING) +# define EH_FRAME_SECTION_CONST const +#else +# define EH_FRAME_SECTION_CONST +#endif /* We do not want to add the weak attribute to the declarations of these routines in unwind-dw2-fde.h because that will cause the definition of @@ -188,7 +193,7 @@ STATIC func_ptr __DTOR_LIST__[1] #ifdef USE_EH_FRAME_REGISTRY /* Stick a label at the beginning of the frame unwind info so we can register and deregister it with the exception handling library code. */ -STATIC char __EH_FRAME_BEGIN__[] +STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[] __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4))) = { }; #endif /* USE_EH_FRAME_REGISTRY */ @@ -453,7 +458,7 @@ STATIC func_ptr __DTOR_END__[1] #ifdef EH_FRAME_SECTION_NAME /* Terminate the frame unwind info section with a 4byte 0 as a sentinel; this would be the 'length' field in a real FDE. */ -STATIC int __FRAME_END__[] +STATIC EH_FRAME_SECTION_CONST int __FRAME_END__[] __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME), aligned(4))) = { 0 }; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index ed2a0ecd00e..2e8fe614188 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -117,7 +117,24 @@ void default_eh_frame_section () { #ifdef EH_FRAME_SECTION_NAME +#ifdef HAVE_LD_RO_RW_SECTION_MIXING + int fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); + int per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1); + int lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); + int flags; + + flags = (! flag_pic + || ((fde_encoding & 0x70) != DW_EH_PE_absptr + && (fde_encoding & 0x70) != DW_EH_PE_aligned + && (per_encoding & 0x70) != DW_EH_PE_absptr + && (per_encoding & 0x70) != DW_EH_PE_aligned + && (lsda_encoding & 0x70) != DW_EH_PE_absptr + && (lsda_encoding & 0x70) != DW_EH_PE_aligned)) + ? 0 : SECTION_WRITE; + named_section_flags (EH_FRAME_SECTION_NAME, flags); +#else named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE); +#endif #else tree label = get_file_function_name ('F'); diff --git a/gcc/except.c b/gcc/except.c index 08c0aa27ab2..0a5e49fa813 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -3589,6 +3589,33 @@ sjlj_output_call_site_table () call_site_base += n; } +/* Tell assembler to switch to the section for the exception handling + table. */ + +void +default_exception_section () +{ + if (targetm.have_named_sections) + { + int tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1); + int flags; + +#ifdef HAVE_LD_RO_RW_SECTION_MIXING + flags = (! flag_pic + || ((tt_format & 0x70) != DW_EH_PE_absptr + && (tt_format & 0x70) != DW_EH_PE_aligned)) + ? 0 : SECTION_WRITE; +#else + flags = SECTION_WRITE; +#endif + named_section_flags (".gcc_except_table", flags); + } + else if (flag_pic) + data_section (); + else + readonly_data_section (); +} + void output_function_exception_table () { diff --git a/gcc/varasm.c b/gcc/varasm.c index b158b92a9b9..a3d283a8b56 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -582,20 +582,6 @@ variable_section (decl, reloc) (*targetm.asm_out.select_section) (decl, reloc, DECL_ALIGN (decl)); } -/* Tell assembler to switch to the section for the exception handling - table. */ - -void -default_exception_section () -{ - if (targetm.have_named_sections) - named_section (NULL_TREE, ".gcc_except_table", 0); - else if (flag_pic) - data_section (); - else - readonly_data_section (); -} - /* Tell assembler to switch to the section for string merging. */ void