Re: Move dwarf2 frame tables to read-only section for AIX

2014-11-25 Thread Andrew Dixie
Hi,

The following patch substantially reduces the memory requirements of
GCC compiled C++ programs on AIX.

Currently there are two different pieces of code to decide if a
read-only or a read-write section is required for exception
information:
- If the target supports named sections, there is good logic which
considers the dwarf encoding types, flag_pic and also has a target
hook for override.
- If the target doesn't support named sections, the only consideration
is flag_pic.

The key part of this patch is removing the second sub-optimal code and
using the optimal logic on all targets.

I understand David has approved the target specifics, and this just
needs a review for the dwarf changes.  I believe I have CCed the dwarf
maintainers on this email.

https://gcc.gnu.org/ml/gcc-patches/2014-09/msg01897.html

Thanks,
Andrew


Re: Move unwind info to read-only section on AIX

2014-09-11 Thread Andrew Dixie
Hi David,

As discussed, I have updated the to use SYMBOL-$ syntax for
PC-relative addressing and to use a new symbol, __gcc_unwind_dbase,
rather than overloading __dso_handle.

Regards,
Andrew

2014-09-09  Andrew Dixie  

   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 nor __gcc_unwind_dbase.
   * 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 -rupN 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.0 +1200
+++ gcc-4.10-20140706/gcc/collect2.c2014-09-09 19:37:49.383271225 +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 *__gcc_unwind_dbase;\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 __gcc_unwind_dbase
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, &__gcc_unwind_dbase);\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,16 @@ 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
or __gcc_unwind_dbase.
+  They are required to be local
to each module.
+*/
+  if (strcmp(name, "__dso_handle") != 0
+  && strcmp(name,
"__gcc_unwind_dbase") != 0)
+{
+  add_to_list (&exports, name);
+}
+   }
 #endif
  continue;
}
diff -rupN orig/gcc-4.10-20140706/gcc/config/rs6000/aix61.h
gcc-4.10-20140706/gcc/config/rs6000/aix61.h
--- orig/gcc-4.10-20140706/gcc/config/rs6000/aix61.h2014-01-03
11:23:26.0 +1300
+++ gcc-4.10-20140706/gcc/config/rs6000/aix61.h 2014-09-10
17:52:02.125993022 +1200
@@ -167,7 +167,7 @@ do {
 \
%{!maix64:\
  %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
  %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}\
-   %{shared:crtcxa_s%O%s;:crtcxa%O%s}"
+   %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s"

 /* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int".  */

diff -rupN 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.0 +1200
+++ gcc-4.10-20140706/gcc/config/rs6000/rs6000-aix.c2014-09-09
19:39:34.770296080 +1200
@@ -0,0 +1,48 @@
+/* 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

Re: Move unwind info to read-only section on AIX

2014-09-16 Thread Andrew Dixie
Hi David,

On AIX, mixing objects from different GCC versions should work as long
as the newest GCC is used for linking.  I tested a library with some
objects compiled by GCC-4.4 and some objects compiled by a patched
GCC-5.0.  Exceptions passed through the mixed objects without issue.
Did you have a specific example or reason to think it wouldn't work?

If one attempts to mix C++ objects from GCC-3.3 and GCC-4.4 on Linux
or Solaris there are link time errors.  If you're worried about the
risk of runtime problems, would you rather have a deliberate link time
error on AIX?

Regards,
Andrew

On Wed, Sep 17, 2014 at 6:37 AM, David Edelsohn  wrote:
> My concern is this really is an ABI change.  One cannot mix object
> files compiled with the old EH format and with the new EH format. One
> can mix shared libraries of different styles, but not object files.
> I'm not certain how much of a problem it is to require recompiling
> everything from scratch.


Move dwarf2 frame tables to read-only section for AIX

2014-09-21 Thread Andrew Dixie
Hi,

The following patch moves dwarf2 exception frame tables to read-only
memory so they can be properly shared by multiple processes on AIX.

There are two main mechanisms to register frame tables:
- EH_FRAME_SECTION_NAME puts the frames in a specially named section,
which are then registered by crtstuff.c
- EH_FRAME_IN_DATA_SECTION assigns special labels to the frames, these
labels are then located by collect2.c and loaded by generated code.

The AIX linker doesn't meet the requirements of EH_FRAME_SECTION_NAME,
and the other option EH_FRAME_IN_DATA_SECTION defaults to the
read-write data section.

I altered the dwarf2 frame and exception table generation so the
decision on whether to use a read-only or read-write section is an
independent decision from how the frame tables are registered.
I renamed EH_FRAME_IN_DATA_SECTION to EH_FRAME_THROUGH_COLLECT2, as it
now supports read-only, has slightly changed semantics, and I think
this name better reflects what it currently does rather than what it
historically did.

The spu port may see frame tables for executables move to read-only
memory.  I assume this will work and is beneficial.  Alternately
#define EH_TABLES_CAN_BE_READ_ONLY 0 should make it see no semantic
changes.

I believe I have an OK for the AIX changes:
https://gcc.gnu.org/ml/gcc-patches/2014-09/msg01305.html.
Can I please have a review for the dwarf2 changes?

Thanks,
Andrew

2014-09-22  Andrew Dixie  

  Move exception tables to read-only memory on AIX.
   * dwarf2asm.c (dw2_asm_output_encoded_addr_rtx): Add call to
   ASM_OUTPUT_DWARF_DATAREL.
   * dwarf2out.c (switch_to_eh_frame_section): Use a read-only section
   even if EH_FRAME_SECTION_NAME is undefined.  Add call to
   EH_FRAME_THROUGH_COLLECT2.
   * except.c (switch_to_exception_section):  Use a read-only section
   even if EH_FRAME_SECTION_NAME is undefined.
  * collect2.c (write_c_file_stat): Provide dbase on AIX.
   (scan_prog_file): Don't output __dso_handle nor __gcc_unwind_dbase.
   * 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.
   (EH_FRAME_THROUGH_COLLECT2): define.
   * 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.

diff -rupN orig/gcc-4.10-20140706/gcc/doc/tm.texi
gcc-4.10-20140706/gcc/doc/tm.texi
--- orig/gcc-4.10-20140706/gcc/doc/tm.texi  2014-07-03
01:03:14.0 +1200
+++ gcc-4.10-20140706/gcc/doc/tm.texi   2014-09-19 21:53:11.593386708 +1200
@@ -8780,14 +8780,15 @@ You should define this symbol if your ta
 unwind information and the default definition does not work.
 @end defmac

-@defmac EH_FRAME_IN_DATA_SECTION
-If defined, DWARF 2 frame unwind information will be placed in the
-data section even though the target supports named sections.  This
-might be necessary, for instance, if the system linker does garbage
-collection and sections cannot be marked as not to be collected.
-
-Do not define this macro unless @code{TARGET_ASM_NAMED_SECTION} is
-also defined.
+@defmac EH_FRAME_THROUGH_COLLECT2
+If defined, DWARF 2 frame unwind information will identified by
+specially named labels.  The collect2 process will locate these
+labels and generate code to register the frames.
+
+This might be necessary, for instance, if the system linker will not
+place the frames in-between the sentinals from @file{crtstuff.c},
+or if the system linker does garbage collection and sections cannot
+be marked as not to be collected.
 @end defmac

 @defmac EH_TABLES_CAN_BE_READ_ONLY
@@ -9400,6 +9401,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 -rupN 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.0 +1200
+++ gcc-4.10-20140706/gcc/doc/tm.texi.in2014-09-19
21:22:37.062429084 +1200
@@ -6515,14 +6515,15 @@ You should define this symbol if your ta
 unwind information and the default definition does not work.
 @end defmac

-@defmac EH_FRAME_IN_DATA_SECTION
-If defined, DWARF 2 frame unwind information will be placed in the
-data se

Re: Move dwarf2 frame tables to read-only section for AIX

2014-09-22 Thread Andrew Dixie
Hi,

On Tue, Sep 23, 2014 at 2:47 AM, Joseph S. Myers
 wrote:
> If you rename a target macro, the old target macro name needs to be
> poisoned in system.h.
Fixed in patch below.

> This ChangeLog entry seems very incomplete.  It doesn't mention the
> changes for other architectures, or to defaults.h, or to the
> documentation, for example.
I believe the changelog below covers everything now.

Regards,
Andrew


2014-09-23  Andrew Dixie  

Move exception tables to read-only memory on AIX.

* defaults.h (EH_FRAME_SECTION_NAME): Make dependent on
EH_FRAME_THROUGH_COLLECT2.
* tm.texi: Regenerate.
* tm.texi.in (EH_FRAME_IN_DATA_SECTION): Remove.
(EH_FRAME_THROUGH_COLLECT2): Document.
(ASM_OUTPUT_DWARF_DATAREL): Document.
* dwarf2asm.c (dw2_asm_output_encoded_addr_rtx): Add call to
ASM_OUTPUT_DWARF_DATAREL.
* dwarf2out.c (switch_to_eh_frame_section): Use a read-only section
even if EH_FRAME_SECTION_NAME is undefined.  Add call to
EH_FRAME_THROUGH_COLLECT2.
* except.c (switch_to_exception_section):  Use a read-only section
even if EH_FRAME_SECTION_NAME is undefined.
* system.h (EH_FRAME_IN_DATA_SECTION): Poison.
* collect2.c (write_c_file_stat): Provide dbase on AIX.
(scan_prog_file): Don't output __dso_handle nor __gcc_unwind_dbase.
* 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.
(EH_FRAME_THROUGH_COLLECT2): define.
* 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.
* config/spu/spu-elf.h: Replace EH_FRAME_IN_DATA_SECTION with
EH_FRAME_THROUGH_COLLECT2.
* config/i386/i386-interix.h: Replace EH_FRAME_IN_DATA_SECTION with
EH_FRAME_THROUGH_COLLECT2 and EH_TABLES_CAN_BE_READ_ONLY.
* config.gcc (powerpc-ibm-aix-*): Add rs6000-aix.o.

libgcc:
* config.host (powerpc-ibm-aix-*): Add crtdbase.o.
* config/rs6000/crtdbase.c: New file.
* config/rs6000/t-aix-cxa: New file.

diff -rupN orig/gcc-4.10-20140706/gcc/defaults.h
gcc-4.10-20140706/gcc/defaults.h
--- orig/gcc-4.10-20140706/gcc/defaults.h   2014-06-03
19:27:13.0 +1200
+++ gcc-4.10-20140706/gcc/defaults.h2014-09-20 03:58:41.421848000 +1200
@@ -351,7 +351,7 @@ see the files COPYING3 and COPYING.RUNTI
 /* If we have named sections, and we're using crtstuff to run ctors,
use them for registering eh frame information.  */
 #if defined (TARGET_ASM_NAMED_SECTION) && DWARF2_UNWIND_INFO \
-&& !defined (EH_FRAME_IN_DATA_SECTION)
+&& !defined (EH_FRAME_THROUGH_COLLECT2)
 #ifndef EH_FRAME_SECTION_NAME
 #define EH_FRAME_SECTION_NAME ".eh_frame"
 #endif
diff -rupN orig/gcc-4.10-20140706/gcc/doc/tm.texi
gcc-4.10-20140706/gcc/doc/tm.texi
--- orig/gcc-4.10-20140706/gcc/doc/tm.texi  2014-07-03
01:03:14.0 +1200
+++ gcc-4.10-20140706/gcc/doc/tm.texi   2014-09-19 21:56:14.303290995 +1200
@@ -8780,14 +8780,15 @@ You should define this symbol if your ta
 unwind information and the default definition does not work.
 @end defmac

-@defmac EH_FRAME_IN_DATA_SECTION
-If defined, DWARF 2 frame unwind information will be placed in the
-data section even though the target supports named sections.  This
-might be necessary, for instance, if the system linker does garbage
-collection and sections cannot be marked as not to be collected.
-
-Do not define this macro unless @code{TARGET_ASM_NAMED_SECTION} is
-also defined.
+@defmac EH_FRAME_THROUGH_COLLECT2
+If defined, DWARF 2 frame unwind information will identified by
+specially named labels.  The collect2 process will locate these
+labels and generate code to register the frames.
+
+This might be necessary, for instance, if the system linker will not
+place the eh_frames in-between the sentinals from @file{crtstuff.c},
+or if the system linker does garbage collection and sections cannot
+be marked as not to be collected.
 @end defmac

 @defmac EH_TABLES_CAN_BE_READ_ONLY
@@ -9400,6 +9401,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

Move unwind info to read-only section on AIX

2014-07-29 Thread Andrew Dixie
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  

   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.0 +1200
+++ gcc-4.10-20140706/gcc/collect2.c2014-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.0 +1200
+++ gcc-4.10-20140706/gcc/config/rs6000/rs6000-aix.c2014-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 softwar

Re: Move unwind info to read-only section on AIX

2014-07-30 Thread Andrew Dixie
Hi David,

On Thu, Jul 31, 2014 at 2:22 PM, David Edelsohn  wrote:
> As the comment in the code states DWARF2 unwind info was placed in the
> data section to prevent the AIX linker from garbage collecting it.
> How are you avoiding that problem?

That comment is very old.  I'm not sure what the original problem was.
The code generated by collect2 which calls register_frame_info_table
has explicit references to the DWARF unwind info.  The linker won't
garbage collect the unwind info as the linker will see it as used
through these references.

> Also, the AIX linker uses "$" for the current location, so the kludge
> of creating PCREL symbols should not be necessary.

I will swap it over to this.

> Using __dso_handle as the base address is underwhelming.

Does the using the TOC sound like a reasonable solution?
Or do you know how to get a reference to the start of the data section
from the AIX assembler/linker?
The ld manpage lists _data, but this symbol doesn't work for shared libraries.

Thanks,
Andrew