From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4494 invoked by alias); 27 Jun 2005 11:56:03 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 4442 invoked by uid 22791); 27 Jun 2005 11:55:58 -0000 Received: from dublin.act-europe.fr (HELO dublin.act-europe.fr) (212.157.227.154) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Mon, 27 Jun 2005 11:55:58 +0000 Received: from localhost (province.act-europe.fr [10.10.0.214]) by filtered-dublin.act-europe.fr (Postfix) with ESMTP id B7260229F3B; Mon, 27 Jun 2005 13:55:55 +0200 (MET DST) Received: from dublin.act-europe.fr ([10.10.0.154]) by localhost (province.act-europe.fr [10.10.0.214]) (amavisd-new, port 10024) with ESMTP id 89237-09; Mon, 27 Jun 2005 13:55:55 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by dublin.act-europe.fr (Postfix) with ESMTP id F227F229F3A; Mon, 27 Jun 2005 13:55:54 +0200 (MET DST) From: Eric Botcazou To: Alan Modra Subject: Re: gc sections and .eh_frame Date: Mon, 27 Jun 2005 11:56:00 -0000 User-Agent: KMail/1.7.1 Cc: binutils@sources.redhat.com, Jonathan Larmour References: <42A5DE0C.9050108@eCosCentric.com> <42B94F8D.6000405@eCosCentric.com> <20050625172807.GD1530@bubble.grove.modra.org> In-Reply-To: <20050625172807.GD1530@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_Fl+vC575P7NFhrC" Message-Id: <200506271355.49260.ebotcazou@adacore.com> X-SW-Source: 2005-06/txt/msg00590.txt.bz2 --Boundary-00=_Fl+vC575P7NFhrC Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1536 > None of the proposed solutions is right. If you take a look at a > typical .eh_frame, you'll see relocs pointing at text sections and > .gcc_except_table (or .rodata for broken ppc compilers). Changing > garbage collection to process .rela.eh_frame thus runs into the problem > of distinguishing the two types of reloc: You need to ignore the > former, and mark sections for the latter. That's exactly what I proposed in my last message, but I suggested passing a parameter to _bfd_elf_gc_mark to make it "forget" code sections. It seems autodetecting .eh_frame is more straightforward. > Try the following totally untested patch. > > * elflink.c (_bfd_elf_gc_mark): Handle .eh_frame relocs specially.. > (bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame. > Don't recheck sections we have already marked. I think it doesn't work (alone) either, because you unconditionally mark all .gcc_except_table* sections, which themselves point to the functions. In normal mode (i.e. with a non broken ppc compiler), we really need avoid marking any sections referenced by .eh_frame, them being code or data. So I think that, before invoking _bfd_elf_gc_mark on .eh_frame, we need to make sure that it doesn't reference .gcc_except_table* sections. Hence the attached patch. * elflink.c (_bfd_elf_gc_mark): Don't mark code sections referenced by .eh_frame. (bfd_elf_gc_sections): Mark again the sections referenced by .eh_frame if the EH tables are not in .gcc_except_table* sections. -- Eric Botcazou --Boundary-00=_Fl+vC575P7NFhrC Content-Type: text/x-diff; charset="iso-8859-1"; name="d106-019_linker-3.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="d106-019_linker-3.diff" Content-length: 3311 Index: elflink.c =================================================================== RCS file: /cvs/src/src/bfd/elflink.c,v retrieving revision 1.136.2.3 diff -u -p -r1.136.2.3 elflink.c --- elflink.c 27 Apr 2005 16:47:24 -0000 1.136.2.3 +++ elflink.c 27 Jun 2005 11:47:06 -0000 @@ -8687,6 +8687,7 @@ _bfd_elf_gc_mark (struct bfd_link_info * gc_mark_hook_fn gc_mark_hook) { bfd_boolean ret; + bfd_boolean is_eh; asection *group_sec; sec->gc_mark = 1; @@ -8699,6 +8700,7 @@ _bfd_elf_gc_mark (struct bfd_link_info * /* Look through the section relocs. */ ret = TRUE; + is_eh = strcmp (sec->name, ".eh_frame") == 0; if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0) { Elf_Internal_Rela *relstart, *rel, *relend; @@ -8771,7 +8773,11 @@ _bfd_elf_gc_mark (struct bfd_link_info * rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]); } - if (rsec && !rsec->gc_mark) + if (rsec + && !rsec->gc_mark + /* elf-eh-frame.c knows how to discard orphaned FDEs so don't + mark code sections referenced by the .eh_frame section. */ + && !(is_eh && (rsec->flags & SEC_CODE) != 0)) { if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) rsec->gc_mark = 1; @@ -9068,6 +9074,8 @@ bfd_elf_gc_sections (bfd *abfd, struct b gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) { + bfd_boolean has_gcc_except_table = FALSE; + asection *eh_frame = NULL; asection *o; if (bfd_get_flavour (sub) != bfd_target_elf_flavour) @@ -9077,15 +9085,41 @@ bfd_elf_gc_sections (bfd *abfd, struct b { if (o->flags & SEC_KEEP) { - /* _bfd_elf_discard_section_eh_frame knows how to discard - orphaned FDEs so don't mark sections referenced by the - EH frame section. */ + /* Marking all sections referenced by .eh_frame effectively + disables GC because FDEs contain relocs against both the + functions' code and exception table. So we mark none, + relying on elf-eh-frame.c to deal with the former type of + relocs (it will discard orphaned FDEs) and on the linker + script to deal with the latter type if necessary. */ if (strcmp (o->name, ".eh_frame") == 0) - o->gc_mark = 1; + { + o->gc_mark = 1; + eh_frame = o; + } else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) return FALSE; } - } + +#define GCC_EXCEPT_TABLE_PREFIX ".gcc_except_table" + + /* Detect .gcc_except_table* sections in the input file. */ + if (!has_gcc_except_table + && strncmp (o->name, + GCC_EXCEPT_TABLE_PREFIX, + strlen (GCC_EXCEPT_TABLE_PREFIX)) == 0) + has_gcc_except_table = TRUE; + } + + /* If we have not detected .gcc_except_table* sections in the input + file, that can mean the target uses a specific section for the + EH tables. Play safe and let .eh_frame mark the non-code + sections it really needs, since we will presumably not be able + to do so explicitly via the linker script if necessary. */ + if (eh_frame && !has_gcc_except_table) + { + if (!_bfd_elf_gc_mark (info, eh_frame, gc_mark_hook)) + return FALSE; + } } /* ... and mark SEC_EXCLUDE for those that go. */ --Boundary-00=_Fl+vC575P7NFhrC--