From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23195 invoked by alias); 29 Jul 2014 21:33:22 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 23180 invoked by uid 89); 29 Jul 2014 21:33:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-oi0-f45.google.com Received: from mail-oi0-f45.google.com (HELO mail-oi0-f45.google.com) (209.85.218.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 29 Jul 2014 21:33:16 +0000 Received: by mail-oi0-f45.google.com with SMTP id e131so273622oig.32 for ; Tue, 29 Jul 2014 14:33:14 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.182.29.234 with SMTP id n10mr7454043obh.67.1406669594243; Tue, 29 Jul 2014 14:33:14 -0700 (PDT) Received: by 10.76.168.8 with HTTP; Tue, 29 Jul 2014 14:33:14 -0700 (PDT) Date: Tue, 29 Jul 2014 21:33:00 -0000 Message-ID: Subject: Move unwind info to read-only section on AIX From: Andrew Dixie To: gcc-patches@gcc.gnu.org Cc: David Edelsohn Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2014-07/txt/msg02014.txt.bz2 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.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 +. */ + +#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");