public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Move unwind info to read-only section on AIX
@ 2014-07-29 21:33 Andrew Dixie
  2014-07-31  2:50 ` David Edelsohn
  2014-09-12  0:12 ` Andrew Dixie
  0 siblings, 2 replies; 7+ messages in thread
From: Andrew Dixie @ 2014-07-29 21:33 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Edelsohn

Hi,

The following patch moves dwarf unwind information from the data
section to the read-only/text section on AIX.  This means the memory
for the unwind information can be shared across multiple processes.

The frame tables are still registered through collect2 scanning for
"_GLOBAL_F" symbol names, however these symbols now exist in the
eh_frame section.

Previously all the unwind pointers were absolute (requiring
relocations), these have been changed to PC-relative and data-relative
offsets.

The DW_EH_PE_datarel encoding doesn't appear to have previously been
used in the compiler, but it is already implemented in the runtime
unwind code.
The data relative encoding is needed as a PC relative offset cannot
point from the text section to the data section on AIX.
For the base for the data relative offset, I couldn't find any way to
get a reference to the start of the data segment, so this patch uses
the symbol __dso_handle as an arbitrary base for the data relative
offsets.
I'm considering changing the base to be the TOC.
I'm Interested in thoughts or ideas on a better base for the data
relative offsets?

Thanks,
Andrew

2014-07-25  Andrew Dixie  <andrewd@gentrack.com>

       Move exception tables to read-only memory on AIX.
       * collect2.c (write_c_file_stat): Provide dbase on AIX.
       (scan_prog_file): Don't output __dso_handle.
       * config/rs6000/aix.h (ASM_PREFERRED_EH_DATA_FORMAT): define.
       (EH_TABLES_CAN_BE_READ_ONLY): define.
       (ASM_OUTPUT_DWARF_PCREL): define.
       (ASM_OUTPUT_DWARF_DATAREL): define.
       (EH_FRAME_IN_DATA_SECTION): undefine.
       * config/rs6000/rs6000-aix.c: new file.
       (rs6000_aix_asm_output_dwarf_pcrel): new function.
       (rs6000_aix_asm_output_dwarf_datarel): new function.
       * config/rs6000/rs6000.c (rs6000_xcoff_asm_init_sections): remove
       assignment of exception_section.
       * dwarf2asm.c (dw2_asm_output_encoded_addr_rtx): Add call to
       ASM_OUTPUT_DWARF_DATAREL.
       * dwarf2out.c (switch_to_eh_frame_section): Add call to
       EMIT_COLLECT2_LABELS_FOR_EH_FRAMES.

diff -Nrup orig/gcc-4.10-20140706/gcc/collect2.c
gcc-4.10-20140706/gcc/collect2.c
--- orig/gcc-4.10-20140706/gcc/collect2.c       2014-06-26
21:16:28.000000000 +1200
+++ gcc-4.10-20140706/gcc/collect2.c    2014-07-28 12:41:54.852926208 +1200
@@ -2101,12 +2110,23 @@ write_c_file_stat (FILE *stream, const c
       fprintf (stream, "  struct object *next;\n");
       fprintf (stream, "};\n");

+      fprintf (stream, "extern void __register_frame_info_table_bases
(void *, struct object *, void *tbase, void *dbase);\n");
       fprintf (stream, "extern void __register_frame_info_table (void
*, struct object *);\n");
       fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
+#ifdef TARGET_AIX_VERSION
+      fprintf (stream, "extern void *__dso_handle;\n");
+#endif

       fprintf (stream, "static void reg_frame () {\n");
       fprintf (stream, "\tstatic struct object ob;\n");
+#ifdef TARGET_AIX_VERSION
+      /* As per config/rs6000/rs6000-aix.c, we use __dso_handle as
the dbase on AIX.
+        This might not be the start of the segment, we assume signed offsets.
+       */
+      fprintf (stream, "\t__register_frame_info_table_bases
(frame_table, &ob, (void *)0, &__dso_handle);\n");
+#else
       fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
+#endif
       fprintf (stream, "\t}\n");

       fprintf (stream, "static void dereg_frame () {\n");
@@ -2868,7 +2888,15 @@ scan_prog_file (const char *prog_name, s
                             provides an explicit export list.  */
                          if (shared_obj && !is_shared
                              && which_pass == PASS_OBJ && !export_flag)
-                           add_to_list (&exports, name);
+                           {
+                                   /* Do not auto-export __dso_handle.
+                                      It is required to be local to
each module.
+                                    */
+                              if (strcmp(name, "__dso_handle") != 0)
+                                {
+                                  add_to_list (&exports, name);
+                                }
+                           }
 #endif
                          continue;
                        }
diff -Nrup orig/gcc-4.10-20140706/gcc/config/rs6000/rs6000-aix.c
gcc-4.10-20140706/gcc/config/rs6000/rs6000-aix.c
--- orig/gcc-4.10-20140706/gcc/config/rs6000/rs6000-aix.c
1970-01-01 12:00:00.000000000 +1200
+++ gcc-4.10-20140706/gcc/config/rs6000/rs6000-aix.c    2014-07-28
12:41:54.852926208 +1200
@@ -0,0 +1,54 @@
+/* Functions for AIX on PowerPC.
+   Copyright (C) 2014 Free Software Foundation, 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 3, 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 COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "output.h"
+
+/* The AIX assembler cannot handle the SYMBOL-. syntax.
+   Instead create a new symbol at the current point in the file and output
+   a relative reference to this new symbol. */
+void rs6000_asm_output_dwarf_pcrel(FILE *file, int size, const char *label)
+{
+       static int pcrel_no = 0;
+       ++pcrel_no;
+
+       fprintf(file, "AIXPCREL..%i:\n", pcrel_no);
+       fputs (integer_asm_op (size, FALSE), file);
+       assemble_name (file, label);
+       fprintf(file, "-AIXPCREL..%i", pcrel_no);
+}
+
+/* Output a symbol offset relative to the dbase for the current object.
+   We use __dso_handle as an arbitrary base for dbase and assume
signed offsets.
+
+   __dso_handle is embedded in all executables/libraries through
+   libgcc/config/rs6000/crtcxa.c
+ */
+void rs6000_asm_output_dwarf_datarel(FILE *file, int size, const char *label)
+{
+       fputs (integer_asm_op (size, FALSE), file);
+       assemble_name (file, label);
+       fputs("-__dso_handle", file);
+}
+
diff -Nrup orig/gcc-4.10-20140706/gcc/config/rs6000/rs6000.c
gcc-4.10-20140706/gcc/config/rs6000/rs6000.c
--- orig/gcc-4.10-20140706/gcc/config/rs6000/rs6000.c   2014-07-03
18:13:48.000000000 +1200
+++ gcc-4.10-20140706/gcc/config/rs6000/rs6000.c        2014-07-25
13:43:54.151118199 +1200
@@ -29251,7 +29251,6 @@ rs6000_xcoff_asm_init_sections (void)
     = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);

   readonly_data_section = read_only_data_section;
-  exception_section = data_section;
 }

 static int
diff -Nrup orig/gcc-4.10-20140706/gcc/config/rs6000/rs6000-protos.h
gcc-4.10-20140706/gcc/config/rs6000/rs6000-protos.h
--- orig/gcc-4.10-20140706/gcc/config/rs6000/rs6000-protos.h
2014-06-26 02:46:08.000000000 +1200
+++ gcc-4.10-20140706/gcc/config/rs6000/rs6000-protos.h 2014-07-28
12:41:54.852926208 +1200
@@ -195,6 +195,8 @@ extern void rs6000_aix_asm_output_dwarf_
 extern void get_ppc476_thunk_name (char name[32]);
 extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
 extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
+extern void rs6000_asm_output_dwarf_pcrel(FILE *file, int size, const
char *label);
+extern void rs6000_asm_output_dwarf_datarel(FILE *file, int size,
const char *label);

 /* Declare functions in rs6000-c.c */

diff -Nrup orig/gcc-4.10-20140706/gcc/config/rs6000/t-aix52
gcc-4.10-20140706/gcc/config/rs6000/t-aix52
--- orig/gcc-4.10-20140706/gcc/config/rs6000/t-aix52    2014-01-03
11:23:26.000000000 +1300
+++ gcc-4.10-20140706/gcc/config/rs6000/t-aix52 2014-07-25
13:43:54.151118199 +1200
@@ -24,3 +24,7 @@ MULTILIB_OPTIONS      = pthread maix64
 MULTILIB_DIRNAMES      = pthread ppc64

 MULTILIB_MATCHES       =
+
+rs6000-aix.o: $(srcdir)/config/rs6000/rs6000-aix.c
+       $(COMPILE) $<
+       $(POSTCOMPILE)
diff -Nrup orig/gcc-4.10-20140706/gcc/config/rs6000/xcoff.h
gcc-4.10-20140706/gcc/config/rs6000/xcoff.h
--- orig/gcc-4.10-20140706/gcc/config/rs6000/xcoff.h    2014-06-26
02:46:08.000000000 +1200
+++ gcc-4.10-20140706/gcc/config/rs6000/xcoff.h 2014-07-28
12:48:43.361071782 +1200
@@ -299,8 +299,25 @@
 #define DATA_SECTION_ASM_OP \
   "\t.csect .data[RW]," XCOFF_CSECT_DEFAULT_ALIGNMENT_STR

+/* The eh_frames are put in the read-only text segment.
+   Local code labels/function will also be in the local text segment so use
+   PC relative addressing.
+   Global symbols must be in the data segment to allow loader relocations.
+   So use DW_EH_PE_indirect to allocate a slot in the local data segment.
+   There is no constant offset to this data segment from the text segment,
+   so use addressing relative to the data segment.
+ */
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
+       ((GLOBAL) ? (DW_EH_PE_indirect | DW_EH_PE_datarel |
DW_EH_PE_sdata4) : (DW_EH_PE_pcrel | DW_EH_PE_sdata4))

-/* Define to prevent DWARF2 unwind info in the data section rather
-   than in the .eh_frame section.  We do this because the AIX linker
-   would otherwise garbage collect these sections.  */
-#define EH_FRAME_IN_DATA_SECTION 1
+#define EMIT_COLLECT2_LABELS_FOR_EH_FRAMES 1
+
+#define TARGET_TERMINATE_DW2_EH_FRAME_INFO true
+
+#define EH_TABLES_CAN_BE_READ_ONLY 1
+
+#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL)       \
+       rs6000_asm_output_dwarf_pcrel(FILE, SIZE, LABEL);
+
+#define ASM_OUTPUT_DWARF_DATAREL(FILE, SIZE, LABEL)       \
+       rs6000_asm_output_dwarf_datarel(FILE, SIZE, LABEL);
diff -Nrup orig/gcc-4.10-20140706/gcc/config.gcc
gcc-4.10-20140706/gcc/config.gcc
--- orig/gcc-4.10-20140706/gcc/config.gcc       2014-07-04
19:18:19.000000000 +1200
+++ gcc-4.10-20140706/gcc/config.gcc    2014-07-25 13:43:54.155118031 +1200
@@ -2369,6 +2369,7 @@ rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1
 rs6000-ibm-aix5.2.* | powerpc-ibm-aix5.2.*)
        tm_file="${tm_file} rs6000/aix.h rs6000/aix52.h rs6000/xcoff.h
rs6000/aix-stdint.h"
        tmake_file="rs6000/t-aix52 t-slibgcc"
+       extra_objs="$extra_objs rs6000-aix.o"
        extra_options="${extra_options} rs6000/aix64.opt"
        use_collect2=yes
        thread_file='aix'
@@ -2378,6 +2379,7 @@ rs6000-ibm-aix5.2.* | powerpc-ibm-aix5.2
 rs6000-ibm-aix5.3.* | powerpc-ibm-aix5.3.*)
        tm_file="${tm_file} rs6000/aix.h rs6000/aix53.h rs6000/xcoff.h
rs6000/aix-stdint.h"
        tmake_file="rs6000/t-aix52 t-slibgcc"
+       extra_objs="$extra_objs rs6000-aix.o"
        extra_options="${extra_options} rs6000/aix64.opt"
        use_collect2=yes
        thread_file='aix'
@@ -2387,6 +2389,7 @@ rs6000-ibm-aix5.3.* | powerpc-ibm-aix5.3
 rs6000-ibm-aix[6789].* | powerpc-ibm-aix[6789].*)
        tm_file="${tm_file} rs6000/aix.h rs6000/aix61.h rs6000/xcoff.h
rs6000/aix-stdint.h"
        tmake_file="rs6000/t-aix52 t-slibgcc"
+       extra_objs="$extra_objs rs6000-aix.o"
        extra_options="${extra_options} rs6000/aix64.opt"
        use_collect2=yes
        thread_file='aix'
diff -Nrup orig/gcc-4.10-20140706/gcc/doc/tm.texi.in
gcc-4.10-20140706/gcc/doc/tm.texi.in
--- orig/gcc-4.10-20140706/gcc/doc/tm.texi.in   2014-06-06
13:04:22.000000000 +1200
+++ gcc-4.10-20140706/gcc/doc/tm.texi.in        2014-07-28
12:41:54.852926208 +1200
@@ -6525,6 +6525,15 @@ Do not define this macro unless @code{TA
 also defined.
 @end defmac

+@defmac EMIT_COLLECT2_LABELS_FOR_EH_FRAMES
+If defined, gcc will output specially named labels for DWARF 2 frame unwind
+information, and collect2 will detect these labels and emit code to register
+the frames at runtime.
+
+If not defined, the target must register frame unwind tables
+through another mechanism.
+@end defmac
+
 @defmac EH_TABLES_CAN_BE_READ_ONLY
 Define this macro to 1 if your target is such that no frame unwind
 information encoding used with non-PIC code will ever require a
@@ -7067,6 +7076,11 @@ A C statement to issue assembly directiv
 reference to the given @var{label}, using an integer of the given @var{size}.
 @end defmac

+@defmac ASM_OUTPUT_DWARF_DATAREL (@var{stream}, @var{size}, @var{label})
+A C statement to issue assembly directives that create a reference to the
+given @var{label} relative to the dbase, using an integer of the
given @var{size}.
+@end defmac
+
 @defmac ASM_OUTPUT_DWARF_TABLE_REF (@var{label})
 A C statement to issue assembly directives that create a reference to
 the DWARF table identifier @var{label} from the current section.  This
diff -Nrup orig/gcc-4.10-20140706/gcc/dwarf2asm.c
gcc-4.10-20140706/gcc/dwarf2asm.c
--- orig/gcc-4.10-20140706/gcc/dwarf2asm.c      2014-01-03
11:23:26.000000000 +1300
+++ gcc-4.10-20140706/gcc/dwarf2asm.c   2014-07-25 14:07:57.050230529 +1200
@@ -992,6 +992,13 @@ dw2_asm_output_encoded_addr_rtx (int enc
          dw2_assemble_integer (size, addr);
          break;

+#ifdef ASM_OUTPUT_DWARF_DATAREL
+       case DW_EH_PE_datarel:
+         gcc_assert (GET_CODE (addr) == SYMBOL_REF);
+         ASM_OUTPUT_DWARF_DATAREL (asm_out_file, size, XSTR (addr, 0));
+         break;
+#endif
+
        case DW_EH_PE_pcrel:
          gcc_assert (GET_CODE (addr) == SYMBOL_REF);
 #ifdef ASM_OUTPUT_DWARF_PCREL
diff -Nrup orig/gcc-4.10-20140706/gcc/dwarf2out.c
gcc-4.10-20140706/gcc/dwarf2out.c
--- orig/gcc-4.10-20140706/gcc/dwarf2out.c      2014-07-02
09:35:41.000000000 +1200
+++ gcc-4.10-20140706/gcc/dwarf2out.c   2014-07-28 12:48:12.925359014 +1200
@@ -424,6 +424,11 @@ static void
 switch_to_eh_frame_section (bool back)
 {
   tree label;
+#ifdef EMIT_COLLECT2_LABELS_FOR_EH_FRAMES
+  bool emit_collect2_labels = EMIT_COLLECT2_LABELS_FOR_EH_FRAMES;
+#else
+  bool emit_collect2_labels = false;
+#endif

 #ifdef EH_FRAME_SECTION_NAME
   if (eh_frame_section == 0)
@@ -464,7 +469,11 @@ switch_to_eh_frame_section (bool back)
       /* We have no special eh_frame section.  Put the information in
         the data section and emit special labels to guide collect2.  */
       switch_to_section (data_section);
+      emit_collect2_labels = true;
+    }

+  if (emit_collect2_labels)
+    {
       if (!back)
        {
          label = get_file_function_name ("F");

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-09-16 21:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-29 21:33 Move unwind info to read-only section on AIX Andrew Dixie
2014-07-31  2:50 ` David Edelsohn
2014-07-31  3:10   ` Andrew Dixie
2014-09-12  0:12 ` Andrew Dixie
2014-09-16 18:37   ` David Edelsohn
2014-09-16 21:04     ` Andrew Dixie
2014-09-16 21:09       ` David Edelsohn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).