From patchwork Fri Sep 18 17:26:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Edelsohn X-Patchwork-Id: 519498 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9F26A1401B5 for ; Sat, 19 Sep 2015 03:26:49 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=RHqGFWCr; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; q=dns; s=default; b=OVDQqew4t81Zjm/r7ogcdkwtbZ7Aaov+zNfi91TsaEB NK04dZS3PvHEVpqv3K018oHDxUdSEBfUBXcN0WYFbtDKOAHrnPW5iqB0oAMWyolA nEZTY5yNuSsF9txUvJYexDIccvN1Kyu3T3abuSDngR0THHYWuqVLm1JvnA3LLsdM = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; s=default; bh=3XA6c6wMZuvyVfMKl6X1zw7C6s8=; b=RHqGFWCrw1FK9rDLc tF2Bjp3CuIwJLCBJ8oVo+dL85hcP7ixDmLwH5TfM26uv6KJWAUWva9OHJyuP7Yrb q/BgPRnRmic3iOI5CrBE/ou4fOlnaIo2Ffij9lrUlcZ91lQm56F/xGSSM3f1DgPW EjYw7+HpNFKaCW+Mtr5kCphDuw= Received: (qmail 114829 invoked by alias); 18 Sep 2015 17:26:36 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 114739 invoked by uid 89); 18 Sep 2015 17:26:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.5 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-io0-f179.google.com Received: from mail-io0-f179.google.com (HELO mail-io0-f179.google.com) (209.85.223.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 18 Sep 2015 17:26:31 +0000 Received: by ioii196 with SMTP id i196so63693375ioi.3 for ; Fri, 18 Sep 2015 10:26:29 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.107.160.194 with SMTP id j185mr14455958ioe.37.1442597189657; Fri, 18 Sep 2015 10:26:29 -0700 (PDT) Received: by 10.36.133.5 with HTTP; Fri, 18 Sep 2015 10:26:29 -0700 (PDT) Date: Fri, 18 Sep 2015 13:26:29 -0400 Message-ID: Subject: [PATCH,committed] Read-only DWARF2 frame tables on AIX From: David Edelsohn To: GCC Patches Cc: Andrew Dixie Attached is the final version of the patch that allows AIX to use a read-only version of DWARF2 frame tables for exception handling instead of placing the tables in the data section. This allows the tables to be shared by multiple processes on AIX and reduces memory requirements. The common bits were approved by Jason Merrill during an earlier round of reviews. Bootstrapped on powerpc-ibm-aix7.1.0.0. libgcc/ * config.host (powerpc-ibm-aix*): Add crtdbase.o to extra_parts. * config/rs6000/crtdbase.S: New file. * config/rs6000/t-aix-cxa: Build crtdbase.o. gcc/ * defaults.h (EH_FRAME_SECTION_NAME): Depend on EH_FRAME_THROUGH_COLLECT2. * dwarf2asm.c (dw2_asm_output_encoded_addr_rtx): Add case for DW_EH_PE_datarel. * dwarf2out.c (switch_to_eh_frame_section): Use a read-only section even if EH_FRAME_SECTION_NAME is undefined. Restrict special collect2 labels 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 export __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_THROUGH_COLLECT2): Define. (EH_FRAME_IN_DATA_SECTION): Delete. * config/rs6000/aix61.h (STARTFILE_SPEC): Add crtdbase.o. * config/rs6000/rs6000-protos.h (rs6000_asm_output_dwarf_pcrel): Declare. (rs6000_asm_output_dwarf_datarel): Declare. * config/rs6000/rs6000.c (rs6000_aix_asm_output_dwarf_pcrel): New. (rs6000_aix_asm_output_dwarf_datarel): New. (rs6000_xcoff_asm_init_sections): Don't set exception_section. * config/spu/spu-elf.h (EH_FRAME_IN_DATA_SECTION): Delete. (EH_FRAME_THROUGH_COLLECT2): Define. * config/i386/i386-interix.h (EH_FRAME_IN_DATA_SECTION): Delete. (EH_FRAME_THROUGH_COLLECT2): Define. (EH_TABLES_CAN_BE_READ_ONLY): Define. * doc/tm.texi.in (EH_FRAME_IN_DATA_SECTION): Delete. (EH_FRAME_THROUGH_COLLECT2): New. (ASM_OUTPUT_DWARF_DATAREL): New. * doc/tm.texi: Regenerate. Index: libgcc/config.host =================================================================== --- libgcc/config.host (revision 227905) +++ libgcc/config.host (working copy) @@ -1085,7 +1085,7 @@ rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) md_unwind_header=rs6000/aix-unwind.h tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble rs6000/t-aix-cxa" - extra_parts="crtcxa.o crtcxa_s.o" + extra_parts="crtcxa.o crtcxa_s.o crtdbase.o" ;; rl78-*-elf) tmake_file="$tm_file t-fdpbit rl78/t-rl78" Index: libgcc/config/rs6000/crtdbase.S =================================================================== --- libgcc/config/rs6000/crtdbase.S (revision 0) +++ libgcc/config/rs6000/crtdbase.S (revision 0) @@ -0,0 +1,31 @@ +/* Defines __gcc_unwind_dbase + + Copyright (C) 2014 Free Software Foundation, Inc. + + This file 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. + + This file 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* Symbol used as an arbitrary base for offsets inside the data + * segment for unwind information. */ + .file "crtdbase.S" + .globl __gcc_unwind_dbase + .csect __gcc_unwind_dbase[RW],2 + .align 2 +__gcc_unwind_dbase: + .long 0 Index: libgcc/config/rs6000/t-aix-cxa =================================================================== --- libgcc/config/rs6000/t-aix-cxa (revision 227905) +++ libgcc/config/rs6000/t-aix-cxa (working copy) @@ -5,6 +5,9 @@ SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-aix-cxa.ver +crtdbase.o: $(srcdir)/config/rs6000/crtdbase.S + $(crt_compile) -c $< + crtcxa.o: $(srcdir)/config/rs6000/crtcxa.c $(crt_compile) -c $< Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in (revision 227905) +++ gcc/doc/tm.texi.in (working copy) @@ -6477,14 +6477,15 @@ 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. +@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. -Do not define this macro unless @code{TARGET_ASM_NAMED_SECTION} is -also defined. +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 @@ -7033,6 +7034,11 @@ 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 Index: gcc/dwarf2asm.c =================================================================== --- gcc/dwarf2asm.c (revision 227905) +++ gcc/dwarf2asm.c (working copy) @@ -984,6 +984,13 @@ 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 Index: gcc/defaults.h =================================================================== --- gcc/defaults.h (revision 227905) +++ gcc/defaults.h (working copy) @@ -351,7 +351,7 @@ /* 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 Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 227905) +++ gcc/dwarf2out.c (working copy) @@ -438,7 +438,6 @@ { tree label; -#ifdef EH_FRAME_SECTION_NAME if (eh_frame_section == 0) { int flags; @@ -466,27 +465,29 @@ } else flags = SECTION_WRITE; + +#ifdef EH_FRAME_SECTION_NAME eh_frame_section = get_section (EH_FRAME_SECTION_NAME, flags, NULL); +#else + eh_frame_section = ((flags == SECTION_WRITE) + ? data_section : readonly_data_section); +#endif /* EH_FRAME_SECTION_NAME */ } -#endif /* EH_FRAME_SECTION_NAME */ - if (eh_frame_section) - switch_to_section (eh_frame_section); - else + switch_to_section (eh_frame_section); + +#ifdef EH_FRAME_THROUGH_COLLECT2 + /* We have no special eh_frame section. Emit special labels to guide + collect2. */ + if (!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); - - if (!back) - { - label = get_file_function_name ("F"); - ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); - targetm.asm_out.globalize_label (asm_out_file, - IDENTIFIER_POINTER (label)); - ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); - } + label = get_file_function_name ("F"); + ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE)); + targetm.asm_out.globalize_label (asm_out_file, + IDENTIFIER_POINTER (label)); + ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label)); } +#endif } /* Switch [BACK] to the eh or debug frame table section, depending on Index: gcc/except.c =================================================================== --- gcc/except.c (revision 227905) +++ gcc/except.c (working copy) @@ -2838,24 +2838,24 @@ s = exception_section; else { + int flags; + + if (EH_TABLES_CAN_BE_READ_ONLY) + { + int tt_format = + ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1); + flags = ((! flag_pic + || ((tt_format & 0x70) != DW_EH_PE_absptr + && (tt_format & 0x70) != DW_EH_PE_aligned)) + ? 0 : SECTION_WRITE); + } + else + flags = SECTION_WRITE; + /* Compute the section and cache it into exception_section, unless it depends on the function name. */ if (targetm_common.have_named_sections) { - int flags; - - if (EH_TABLES_CAN_BE_READ_ONLY) - { - int tt_format = - ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1); - flags = ((! flag_pic - || ((tt_format & 0x70) != DW_EH_PE_absptr - && (tt_format & 0x70) != DW_EH_PE_aligned)) - ? 0 : SECTION_WRITE); - } - else - flags = SECTION_WRITE; - #ifdef HAVE_LD_EH_GC_SECTIONS if (flag_function_sections || (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)) @@ -2876,7 +2876,7 @@ } else exception_section - = s = flag_pic ? data_section : readonly_data_section; + = s = flags == SECTION_WRITE ? data_section : readonly_data_section; } switch_to_section (s); Index: gcc/system.h =================================================================== --- gcc/system.h (revision 227905) +++ gcc/system.h (working copy) @@ -956,7 +956,7 @@ EXTRA_ADDRESS_CONSTRAINT CONST_DOUBLE_OK_FOR_CONSTRAINT_P \ CALLER_SAVE_PROFITABLE LARGEST_EXPONENT_IS_NORMAL \ ROUND_TOWARDS_ZERO SF_SIZE DF_SIZE XF_SIZE TF_SIZE LIBGCC2_TF_CEXT \ - LIBGCC2_LONG_DOUBLE_TYPE_SIZE STRUCT_VALUE + LIBGCC2_LONG_DOUBLE_TYPE_SIZE STRUCT_VALUE EH_FRAME_IN_DATA_SECTION /* Hooks that are no longer used. */ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ Index: gcc/config/spu/spu-elf.h =================================================================== --- gcc/config/spu/spu-elf.h (revision 227905) +++ gcc/config/spu/spu-elf.h (working copy) @@ -61,7 +61,7 @@ #undef TARGET_ASM_NAMED_SECTION #define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section -#define EH_FRAME_IN_DATA_SECTION 1 +#define EH_FRAME_THROUGH_COLLECT2 1 #define LINK_SPEC "%{mlarge-mem: --defsym __stack=0xfffffff0 }" Index: gcc/config/i386/i386-interix.h =================================================================== --- gcc/config/i386/i386-interix.h (revision 227905) +++ gcc/config/i386/i386-interix.h (working copy) @@ -153,8 +153,6 @@ #define drectve_section() /* nothing */ -#define EH_FRAME_IN_DATA_SECTION - #define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rdata,\"r\"" /* Define this macro if references to a symbol must be treated @@ -326,7 +324,8 @@ : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (int) (n)+8 \ : (int) (-1)) -#define EH_FRAME_IN_DATA_SECTION +#define EH_FRAME_THROUGH_COLLECT2 +#define EH_TABLES_CAN_BE_READ_ONLY 0 /* the following are OSF linker (not gld) specific... we don't want them */ #undef HAS_INIT_SECTION Index: gcc/config/rs6000/rs6000-protos.h =================================================================== --- gcc/config/rs6000/rs6000-protos.h (revision 227905) +++ gcc/config/rs6000/rs6000-protos.h (working copy) @@ -203,6 +203,10 @@ 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 */ Index: gcc/config/rs6000/xcoff.h =================================================================== --- gcc/config/rs6000/xcoff.h (revision 227905) +++ gcc/config/rs6000/xcoff.h (working copy) @@ -264,7 +264,7 @@ #ifdef HAVE_AS_TLS #define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \ - do { fputs(COMMON_ASM_OP, (FILE)); \ + do { fputs (COMMON_ASM_OP, (FILE)); \ RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ fprintf ((FILE), "[UL]," HOST_WIDE_INT_PRINT_UNSIGNED"\n", \ (SIZE)); \ @@ -296,10 +296,26 @@ "\t.csect .data[RW]," XCOFF_CSECT_DEFAULT_ALIGNMENT_STR -/* 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 +/* 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 EH_FRAME_THROUGH_COLLECT2 1 +#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)); + #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 227905) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -30790,7 +30790,6 @@ = 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 @@ -31159,6 +31158,31 @@ symtab_node::get (decl)->call_for_symbol_and_aliases (rs6000_declare_alias, &data, true); } +/* Overide the default 'SYMBOL-.' syntax with AIX compatible 'SYMBOL-$'. */ + +void +rs6000_asm_output_dwarf_pcrel (FILE *file, int size, const char *label) +{ + fputs (integer_asm_op (size, FALSE), file); + assemble_name (file, label); + fputs ("-$", file); +} + +/* Output a symbol offset relative to the dbase for the current object. + We use __gcc_unwind_dbase as an arbitrary base for dbase and assume + signed offsets. + + __gcc_unwind_dbase is embedded in all executables/libraries through + libgcc/config/rs6000/crtdbase.S. */ + +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("-__gcc_unwind_dbase", file); +} + #ifdef HAVE_AS_TLS static void rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first) Index: gcc/config/rs6000/aix61.h =================================================================== --- gcc/config/rs6000/aix61.h (revision 227905) +++ gcc/config/rs6000/aix61.h (working copy) @@ -167,7 +167,7 @@ %{!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". */ Index: gcc/collect2.c =================================================================== --- gcc/collect2.c (revision 227888) +++ gcc/collect2.c (working copy) @@ -2108,12 +2108,23 @@ 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 + /* Use __gcc_unwind_dbase as the base address for data on AIX. + This might not be the start of the segment, signed offsets assumed. + */ + 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"); @@ -2878,7 +2889,16 @@ 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; }