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] Make .eh_frame and .gcc_except_table read-only if possible (take 3)


On Mon, Nov 25, 2002 at 09:55:44AM -0800, Richard Henderson wrote:
> On Mon, Nov 25, 2002 at 10:29:40AM -0500, Jakub Jelinek wrote:
> > Argh, just tested it. Don't see any sense in the apparent rule
> > "if any input section is read-only, output is read-only,
> > otherwise read-write" which Solaris ld uses.
> 
> Err, the rule I saw is that the ro sections got placed in the
> ro segment and the rw sections got placed in the rw segment.
> I.e. not all of the same-name sections were placed sequentially.

You're right, am not familiar with Solaris elfdump too much and overlooked
it in there (did not have binutils on that box).
Anyway, the latest patch I posted configury bits should handle this too,
ie. if there will be at least one output myfoosect section readonly with
readonly, readwrite and readonly myfoosect input sections combined together,
then crtstuff.c will not use const for __EH_FRAME_BEGIN__ and __FRAME_END__.

Unfortunately this means that with Solaris ld .eh_frame and .gcc_except_table
has to stay SECTION_WRITE forever, because otherwise mixing GCC 3.2.x and
earlier -fexceptions objects with -fexceptions objects created by GCC with
this patch would create two different .eh_frame sections.

2002-11-25  Jakub Jelinek  <jakub@redhat.com>

	* 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.

--- gcc/except.c.jj	2002-09-27 14:21:54.000000000 +0200
+++ gcc/except.c	2002-11-25 22:31:07.000000000 +0100
@@ -3589,6 +3590,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 ()
 {
--- gcc/varasm.c.jj	2002-11-14 01:12:10.000000000 +0100
+++ gcc/varasm.c	2002-11-25 18:53:03.000000000 +0100
@@ -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
--- gcc/crtstuff.c.jj	2002-11-14 00:54:14.000000000 +0100
+++ gcc/crtstuff.c	2002-11-25 17:42:13.000000000 +0100
@@ -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 };
--- gcc/dwarf2out.c.jj	2002-10-29 16:30:44.000000000 +0100
+++ gcc/dwarf2out.c	2002-11-25 22:24:57.000000000 +0100
@@ -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');
 
--- gcc/configure.in.jj	2002-11-24 00:43:11.000000000 +0100
+++ gcc/configure.in	2002-11-25 22:23:09.000000000 +0100
@@ -2209,6 +2209,44 @@ if test x"$gcc_cv_as_gstabs_flag" = xyes
 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
--- gcc/configure.jj	2002-11-24 00:43:11.000000000 +0100
+++ gcc/configure	2002-11-25 22:23:18.000000000 +0100
@@ -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
--- gcc/config.in.jj	2002-11-24 00:43:10.000000000 +0100
+++ gcc/config.in	2002-11-25 17:21:11.000000000 +0100
@@ -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
 

	Jakub


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