public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* gc sections and .eh_frame
@ 2005-06-07 17:48 Jonathan Larmour
  2005-06-07 18:00 ` Eric Botcazou
  2005-06-08  2:09 ` Alan Modra
  0 siblings, 2 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-07 17:48 UTC (permalink / raw)
  To: binutils

After an update to binutils 2.16 from 2.15 I have found that sections 
referenced by .eh_frame with relocs do not get pulled in if linking 
(statically) with --gc-sections. Initially I just put a 
KEEP(*(.gcc_except_table)) in my ldscript to work round this.

But now I'm using the powerpc architecture where the stuff usually in 
.gcc_except_table is placed in .rodata instead. If the object file has 
nothing else in .rodata, then that section is also being GC'd in the final 
link. And Bad Things Happen.

I believe I have tracked this down to a change enclosed in full at the end 
of this mail, made by Eric Botcazou on 2004-04-21. I've looked at the 
mailing list archives, and not found any posting or discussion of the 
patch, or its rationale. Is that right?

Anyway, the most relevant bit in elflink.c:bfd_elf_gc_sections() is:

        for (o = sub->sections; o != NULL; o = o->next)
         {
           if (o->flags & SEC_KEEP)
-           if (!elf_gc_mark (info, o, gc_mark_hook))
-             return FALSE;
+           {
+             /* _bfd_elf_discard_section_eh_frame knows how to discard
+                orphaned FDEs so don't mark sections referenced by the
+                EH frame section.  */
+             if (strcmp (o->name, ".eh_frame") == 0)
+               o->gc_mark = 1;
+             else if (!elf_gc_mark (info, o, gc_mark_hook))
+               return FALSE;
+           }
         }
      }

This change doesn't make sense to me. _bfd_elf_discard_section_eh_frame 
does not set gc_mark on any section. So as a result, I would assume none 
of the reloc dependencies of .eh_frame would ever get marked and that's 
how those sections get GC'd. Am I missing something?

There seems to have been some effort at the time to allow GC of sections 
in dynamically linked programs (I think). Perhaps this was a change which 
is only relevant for dynamic, not static linking? Certainly from my view, 
the correct thing to do is simply revert this part of the change.

Jifl

Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.2501
retrieving revision 1.2502
diff -u -5 -p -r1.2501 -r1.2502
--- ChangeLog   20 Apr 2004 12:17:12 -0000      1.2501
+++ ChangeLog   21 Apr 2004 07:14:15 -0000      1.2502
@@ -1,5 +1,14 @@
+2004-04-21  Eric Botcazou  <ebotcazou@act-europe.fr>
+
+       * elflink.c (elf_gc_mark_dynamic_ref_symbol): New function.
+       (bfd_elf_gc_sections): Fail if a shared object is being created.
+       Do not fail if dynamic sections have been created.  Instead call
+       elf_gc_mark_dynamic_ref_symbol to mark sections that contain
+       dynamically referenced symbols.  Do not mark the whole graph
+       rooted at .eh_frame, only the section proper.
+
  2004-04-20  DJ Delorie  <dj@redhat.com>

         * reloc.c: Add BFD_RELOC_32_SECREL.
         * bfd-in2.h: Regenerate.
         * libbfd.h: Likewise.
Index: elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -5 -p -r1.65 -r1.66
--- elflink.c   15 Apr 2004 02:55:20 -0000      1.65
+++ elflink.c   21 Apr 2004 07:14:15 -0000      1.66
@@ -8410,10 +8410,28 @@ elf_gc_smash_unused_vtentry_relocs (stru
        }

    return TRUE;
  }

+/* Mark sections containing dynamically referenced symbols.  This is called
+   through elf_link_hash_traverse.  */
+
+static bfd_boolean
+elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h,
+                               void *okp ATTRIBUTE_UNUSED)
+{
+  if (h->root.type == bfd_link_hash_warning)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+  if ((h->root.type == bfd_link_hash_defined
+       || h->root.type == bfd_link_hash_defweak)
+      && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC))
+    h->root.u.def.section->flags |= SEC_KEEP;
+
+  return TRUE;
+}
+
  /* Do mark and sweep of unused sections.  */

  bfd_boolean
  bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
  {
@@ -8424,12 +8442,12 @@ bfd_elf_gc_sections (bfd *abfd, struct b
       struct elf_link_hash_entry *h, Elf_Internal_Sym *);

    if (!get_elf_backend_data (abfd)->can_gc_sections
        || info->relocatable
        || info->emitrelocations
-      || !is_elf_hash_table (info->hash)
-      || elf_hash_table (info)->dynamic_sections_created)
+      || info->shared
+      || !is_elf_hash_table (info->hash))
      {
        (*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
        return TRUE;
      }

@@ -8445,12 +8463,19 @@ bfd_elf_gc_sections (bfd *abfd, struct b
                           elf_gc_smash_unused_vtentry_relocs,
                           &ok);
    if (!ok)
      return FALSE;

-  /* Grovel through relocs to find out who stays ...  */
+  /* Mark dynamically referenced symbols.  */
+  if (elf_hash_table (info)->dynamic_sections_created)
+    elf_link_hash_traverse (elf_hash_table (info),
+                           elf_gc_mark_dynamic_ref_symbol,
+                           &ok);
+  if (!ok)
+    return FALSE;

+  /* Grovel through relocs to find out who stays ...  */
    gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
    for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
      {
        asection *o;

@@ -8458,12 +8483,19 @@ bfd_elf_gc_sections (bfd *abfd, struct b
         continue;

        for (o = sub->sections; o != NULL; o = o->next)
         {
           if (o->flags & SEC_KEEP)
-           if (!elf_gc_mark (info, o, gc_mark_hook))
-             return FALSE;
+           {
+             /* _bfd_elf_discard_section_eh_frame knows how to discard
+                orphaned FDEs so don't mark sections referenced by the
+                EH frame section.  */
+             if (strcmp (o->name, ".eh_frame") == 0)
+               o->gc_mark = 1;
+             else if (!elf_gc_mark (info, o, gc_mark_hook))
+               return FALSE;
+           }
         }
      }

    /* ... and mark SEC_EXCLUDE for those that go.  */
    if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook))

-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-07 17:48 gc sections and .eh_frame Jonathan Larmour
@ 2005-06-07 18:00 ` Eric Botcazou
  2005-06-07 18:11   ` Jonathan Larmour
  2005-06-08  2:09 ` Alan Modra
  1 sibling, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-07 18:00 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils

> I believe I have tracked this down to a change enclosed in full at the end
> of this mail, made by Eric Botcazou on 2004-04-21. I've looked at the
> mailing list archives, and not found any posting or discussion of the
> patch, or its rationale. Is that right?

http://sourceware.org/ml/binutils/2004-03/msg00424.html

> Anyway, the most relevant bit in elflink.c:bfd_elf_gc_sections() is:
>
>         for (o = sub->sections; o != NULL; o = o->next)
>          {
>            if (o->flags & SEC_KEEP)
> -           if (!elf_gc_mark (info, o, gc_mark_hook))
> -             return FALSE;
> +           {
> +             /* _bfd_elf_discard_section_eh_frame knows how to discard
> +                orphaned FDEs so don't mark sections referenced by the
> +                EH frame section.  */
> +             if (strcmp (o->name, ".eh_frame") == 0)
> +               o->gc_mark = 1;
> +             else if (!elf_gc_mark (info, o, gc_mark_hook))
> +               return FALSE;
> +           }
>          }
>       }
>
> This change doesn't make sense to me. _bfd_elf_discard_section_eh_frame
> does not set gc_mark on any section. So as a result, I would assume none
> of the reloc dependencies of .eh_frame would ever get marked and that's
> how those sections get GC'd. Am I missing something?

Presumably:

2004-04-21  Eric Botcazou  <ebotcazou@act-europe.fr>

	* scripttempl/elf.sc (.text): Add KEEP for .text.*personality*.
	(.data): Add KEEP for .gnu.linkonce.d.*personality*.
	(.gcc_except_table): Add KEEP for self and accept .gcc_except_table.*.

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-07 18:00 ` Eric Botcazou
@ 2005-06-07 18:11   ` Jonathan Larmour
  0 siblings, 0 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-07 18:11 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

Eric Botcazou wrote:
>Jifl wrote:
>>This change doesn't make sense to me. _bfd_elf_discard_section_eh_frame
>>does not set gc_mark on any section. So as a result, I would assume none
>>of the reloc dependencies of .eh_frame would ever get marked and that's
>>how those sections get GC'd. Am I missing something?
> 
> 
> Presumably:
> 
> 2004-04-21  Eric Botcazou  <ebotcazou@act-europe.fr>
> 
> 	* scripttempl/elf.sc (.text): Add KEEP for .text.*personality*.
> 	(.data): Add KEEP for .gnu.linkonce.d.*personality*.
> 	(.gcc_except_table): Add KEEP for self and accept .gcc_except_table.*.
> 

Yes, as I mentioned briefly that doesn't help for powerpc, where the 
referenced data doesn't go in .gcc_except_table, but instead goes in 
.rodata. Don't ask me why it does, but it does. Probably some weird ABI thing.

It's also worth mentioning that even on other architectures, this new 
requirement (the KEEP) would cause a regression with previously working 
builds. And a pretty difficult to diagnose one at that. On embedded 
systems, custom linker scripts are exceptionally common. The default GNU 
ld template stuff isn't very relevant. For example, have a look at 
newlib/libgloss (although I'm using a different runtime). Of course this 
would only affect people using --gc-sections with recent binutils, which 
is why you probably haven't had people jumping up and down yet :-).

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-07 17:48 gc sections and .eh_frame Jonathan Larmour
  2005-06-07 18:00 ` Eric Botcazou
@ 2005-06-08  2:09 ` Alan Modra
  2005-06-08 11:13   ` Jonathan Larmour
  1 sibling, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-06-08  2:09 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils

On Tue, Jun 07, 2005 at 06:49:00PM +0100, Jonathan Larmour wrote:
> But now I'm using the powerpc architecture where the stuff usually in 
> .gcc_except_table is placed in .rodata instead. If the object file has 
> nothing else in .rodata, then that section is also being GC'd in the final 
> link. And Bad Things Happen.

Which powerpc target?  What compiler version?

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-08  2:09 ` Alan Modra
@ 2005-06-08 11:13   ` Jonathan Larmour
  2005-06-08 19:10     ` Richard Henderson
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-08 11:13 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

Alan Modra wrote:
> On Tue, Jun 07, 2005 at 06:49:00PM +0100, Jonathan Larmour wrote:
> 
>>But now I'm using the powerpc architecture where the stuff usually in 
>>.gcc_except_table is placed in .rodata instead. If the object file has 
>>nothing else in .rodata, then that section is also being GC'd in the final 
>>link. And Bad Things Happen.
> 
> 
> Which powerpc target?  What compiler version?

powerpc-eabi, gcc 3.4.4.

 From a brief foray into the GCC sources, I believe the use of 
gcc_except_table depends on the existence of TARGET_ASM_NAMED_SECTION, 
which is not defined for any powerpc other than rs6000-xcoff.

There are probably other targets than powerpc that don't have 
TARGET_ASM_NAMED_SECTION too. From a glance, SuperH doesn't either at least.

I still don't have an understanding as to why sections referenced (by 
reloc) from .eh_frame shouldn't be kept safe from GC. Marking them as KEEP 
in the linker script just means that you've got one bit of code trying to 
stop such sections being included, and another bit in the linker script 
forcing them to be. It seems pointless and breaks existing working linker 
scripts, nevermind the powerpc issue.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-08 11:13   ` Jonathan Larmour
@ 2005-06-08 19:10     ` Richard Henderson
  2005-06-08 19:29       ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Richard Henderson @ 2005-06-08 19:10 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Alan Modra, binutils

On Wed, Jun 08, 2005 at 12:14:07PM +0100, Jonathan Larmour wrote:
> From a brief foray into the GCC sources, I believe the use of 
> gcc_except_table depends on the existence of TARGET_ASM_NAMED_SECTION, 
> which is not defined for any powerpc other than rs6000-xcoff.

You're confused.  All elf have it.


r~

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

* Re: gc sections and .eh_frame
  2005-06-08 19:10     ` Richard Henderson
@ 2005-06-08 19:29       ` Jonathan Larmour
  2005-06-08 19:32         ` Richard Henderson
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-08 19:29 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Alan Modra, binutils

Richard Henderson wrote:
> On Wed, Jun 08, 2005 at 12:14:07PM +0100, Jonathan Larmour wrote:
> 
>From a brief foray into the GCC sources, I believe the use of 
>>gcc_except_table depends on the existence of TARGET_ASM_NAMED_SECTION, 
>>which is not defined for any powerpc other than rs6000-xcoff.
> 
> 
> You're confused.  All elf have it.

Fair enough, it was only a belief, and it's easy for GCC to confuse me ;). 
But empirically, powerpc-eabi does put exception stuff referenced from 
.eh_frame into .rodata:

dargo:/tmp$ cat >e.cxx
extern void foo(void);

int main()
{
     try {
         foo();
     } catch(...) {
         return 1;
     };
     return 0;
}

dargo:/tmp$ powerpc-eabi-g++ -c e.cxx
dargo:/tmp$ powerpc-eabi-objdump -h e.o

e.o:     file format elf32-powerpc

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
   0 .text         00000060  00000000  00000000  00000034  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
   1 .data         00000000  00000000  00000000  00000094  2**0
                   CONTENTS, ALLOC, LOAD, DATA
   2 .bss          00000000  00000000  00000000  00000094  2**0
                   ALLOC
   3 .rodata       00000014  00000000  00000000  00000094  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
   4 .eh_frame     00000040  00000000  00000000  000000a8  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
   5 .comment      00000020  00000000  00000000  000000e8  2**0
                   CONTENTS, READONLY

The .rodata there contains the exception info referenced by .eh_frame and 
there is no .gcc_except_table section present at all.

This has been the case for years for powerpc-eabi, I don't know how long.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-08 19:29       ` Jonathan Larmour
@ 2005-06-08 19:32         ` Richard Henderson
  2005-06-08 21:36           ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Richard Henderson @ 2005-06-08 19:32 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Alan Modra, binutils

On Wed, Jun 08, 2005 at 08:30:34PM +0100, Jonathan Larmour wrote:
> But empirically, powerpc-eabi does put exception stuff referenced from 
> .eh_frame into .rodata:

Which is correct, that's where it belongs.

> there is no .gcc_except_table section present at all.

This is, and has always been, created by the linker.


r~

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

* Re: gc sections and .eh_frame
  2005-06-08 19:32         ` Richard Henderson
@ 2005-06-08 21:36           ` Jonathan Larmour
  2005-06-08 22:02             ` Richard Henderson
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-08 21:36 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Alan Modra, binutils

Richard Henderson wrote:
> On Wed, Jun 08, 2005 at 08:30:34PM +0100, Jonathan Larmour wrote:
> 
>>But empirically, powerpc-eabi does put exception stuff referenced from 
>>.eh_frame into .rodata:
> 
> 
> Which is correct, that's where it belongs.
> 
> 
>>there is no .gcc_except_table section present at all.
> 
> 
> This is, and has always been, created by the linker.

Now I'm really confused:

dargo:/tmp$ arm-elf-g++ -c e.cxx
dargo:/tmp$ arm-elf-objdump -h e.o

e.o:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
   0 .text         000000a8  00000000  00000000  00000034  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
   1 .data         00000000  00000000  00000000  000000dc  2**0
                   CONTENTS, ALLOC, LOAD, DATA
   2 .bss          00000000  00000000  00000000  000000dc  2**0
                   ALLOC
   3 .gcc_except_table 00000010  00000000  00000000  000000dc  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
   4 .comment      00000020  00000000  00000000  000000ec  2**0
                   CONTENTS, READONLY
dargo:/tmp$ i386-elf-g++ -c e.cxx
dargo:/tmp$ i386-elf-objdump -h e.o

e.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
   0 .text         00000049  00000000  00000000  00000034  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
   1 .data         00000000  00000000  00000000  00000080  2**2
                   CONTENTS, ALLOC, LOAD, DATA
   2 .bss          00000000  00000000  00000000  00000080  2**2
                   ALLOC
   3 .gcc_except_table 00000014  00000000  00000000  00000080  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
   4 .eh_frame     00000040  00000000  00000000  00000094  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
   5 .comment      00000020  00000000  00000000  000000d4  2**0
                   CONTENTS, READONLY
dargo:/tmp$ m68k-elf-g++ -c e.cxx
dargo:/tmp$ m68k-elf-objdump -h e.o

e.o:     file format elf32-m68k

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
   0 .text         00000030  00000000  00000000  00000034  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
   1 .data         00000000  00000000  00000000  00000064  2**2
                   CONTENTS, ALLOC, LOAD, DATA
   2 .bss          00000000  00000000  00000000  00000064  2**2
                   ALLOC
   3 .gcc_except_table 00000014  00000000  00000000  00000064  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
   4 .eh_frame     00000040  00000000  00000000  00000078  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
   5 .comment      00000020  00000000  00000000  000000b8  2**0
                   CONTENTS, READONLY
dargo:/tmp$ mipsisa32-elf-g++ -c e.cxx
dargo:/tmp$ mipsisa32-elf-objdump -h e.o

e.o:     file format elf32-bigmips

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
   0 .text         00000068  00000000  00000000  00000034  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
   1 .data         00000000  00000000  00000000  0000009c  2**0
                   CONTENTS, ALLOC, LOAD, DATA
   2 .bss          00000000  00000000  00000000  0000009c  2**0
                   ALLOC
   3 .reginfo      00000018  00000000  00000000  0000009c  2**2
                   CONTENTS, READONLY, LINK_ONCE_SAME_SIZE
   4 .pdr          00000020  00000000  00000000  000000b4  2**2
                   CONTENTS, RELOC, READONLY
   5 .mdebug.eabi32 00000000  00000000  00000000  000000d4  2**0
                   CONTENTS, READONLY
   6 .gcc_except_table 00000014  00000000  00000000  000000d4  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
   7 .eh_frame     00000040  00000000  00000000  000000e8  2**2
                   CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

and so on.

Are the powerpc-eabi tools the only ones behaving correctly (putting it in 
.rodata) and all the others wrong?

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-08 21:36           ` Jonathan Larmour
@ 2005-06-08 22:02             ` Richard Henderson
  2005-06-09 10:33               ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Richard Henderson @ 2005-06-08 22:02 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Alan Modra, binutils

On Wed, Jun 08, 2005 at 10:36:11PM +0100, Jonathan Larmour wrote:
> >>there is no .gcc_except_table section present at all.
> >
> >This is, and has always been, created by the linker.

Sorry, I was thinking of .eh_frame_hdr.

> Are the powerpc-eabi tools the only ones behaving correctly (putting it in 
> .rodata) and all the others wrong?

*shrug* I'm not sure why ppc-eabi is the only one different.
Probably just an oversight somewhere in the rs6000 port.


r~

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

* Re: gc sections and .eh_frame
  2005-06-08 22:02             ` Richard Henderson
@ 2005-06-09 10:33               ` Jonathan Larmour
  2005-06-09 11:38                 ` Eric Botcazou
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-09 10:33 UTC (permalink / raw)
  To: binutils

Richard Henderson wrote:
> On Wed, Jun 08, 2005 at 10:36:11PM +0100, Jonathan Larmour wrote:
>>Are the powerpc-eabi tools the only ones behaving correctly (putting it in 
>>.rodata) and all the others wrong?
> 
> *shrug* I'm not sure why ppc-eabi is the only one different.
> Probably just an oversight somewhere in the rs6000 port.

Or could be an ABI thing. I don't know. But I don't think that's relevant 
as that clearly is the way it has worked for a long time (probably 
forever), and the elflink.c change in question breaks it. Also as I 
mentioned (but I don't care as much about personally as I'm now 
unaffected), the change breaks existing linker scripts much more widely 
than powerpc-eabi.

So far, no-one has given any rationalisation for the change. It wasn't 
posted to this list, so there's no reason given there. To my eye, the 
change doesn't seem right - if a section is a dependency of .eh_frame, it 
needs to be kept. Needing to forcibly KEEP() all .gcc_except_table 
sections should not have been necessary in the first place.

There may well be a very good reason for the change that I'm not aware of 
or am too dumb to see. That's entirely fair enough if so. As soon as I 
know the reason I'm happy to try and fix things to accomodate that reason 
and maintain existing behaviour.

Until then, I'm attaching a patch against current CVS to revert it. I 
have checkin access to /cvs/src if that helps.

Jifl

2005-06-09  Jonathan Larmour  <jifl@eCosCentric.com>

	* elflink.c (bfd_elf_gc_sections): Revert change of 2004-04-21 to
	not mark dependencies of .eh_frame. There is nowhere else such
	marking would happen so they need to be kept.

Index: elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.167
diff -u -5 -p -r1.167 elflink.c
--- elflink.c	9 Jun 2005 02:02:17 -0000	1.167
+++ elflink.c	9 Jun 2005 10:25:00 -0000
@@ -9124,16 +9124,11 @@ bfd_elf_gc_sections (bfd *abfd, struct b

        for (o = sub->sections; o != NULL; o = o->next)
  	{
  	  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.  */
-	      if (strcmp (o->name, ".eh_frame") == 0)
-		o->gc_mark = 1;
-	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	      if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
  		return FALSE;
  	    }
  	}
      }


-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-09 10:33               ` Jonathan Larmour
@ 2005-06-09 11:38                 ` Eric Botcazou
  2005-06-09 12:07                   ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-09 11:38 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils

> So far, no-one has given any rationalisation for the change. It wasn't
> posted to this list, so there's no reason given there.

Huh... didn't you see the link I posted?  Here is it again:
http://sourceware.org/ml/binutils/2004-03/msg00424.html

> To my eye, the change doesn't seem right - if a section is a dependency
> of .eh_frame, it needs to be kept. Needing to forcibly KEEP()
> all .gcc_except_table sections should not have been necessary in the first
> place. 

Please read the rationale I had given for the change.

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-09 11:38                 ` Eric Botcazou
@ 2005-06-09 12:07                   ` Jonathan Larmour
  2005-06-09 12:49                     ` Alan Modra
  2005-06-09 13:02                     ` Eric Botcazou
  0 siblings, 2 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-09 12:07 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

Eric Botcazou wrote:
>>So far, no-one has given any rationalisation for the change. It wasn't
>>posted to this list, so there's no reason given there.
> 
> 
> Huh... didn't you see the link I posted?  Here is it again:
> http://sourceware.org/ml/binutils/2004-03/msg00424.html

I had missed that in your previous reply, my apologies. I also did not 
find it in the archives because it was over a month until the time it was 
committed.

>>To my eye, the change doesn't seem right - if a section is a dependency
>>of .eh_frame, it needs to be kept. Needing to forcibly KEEP()
>>all .gcc_except_table sections should not have been necessary in the first
>>place. 
> 
> 
> Please read the rationale I had given for the change.


Thank you. However I still fail to understand (my fault I'm sure) why 
dependencies of .eh_frame. should not be marked. Surely if the 
.gcc_except_table section has been split up into multiple sections, 
courtesy of -ffunction-sections, then that's all the more reason to mark 
.eh_frame's dependencies?

Can I ask where the used .gcc_except_table.* sections _are_ meant to be 
marked?  I cannot see anywhere that _bfd_elf_discard_section_eh_frame does 
it, for example. Why would .gcc_except_table.* get marked, but .rodata not 
get marked for powerpc?

Separately, I still consider it an issue to break existing linker scripts 
(and the failure mode is very obscure and difficult to track down when you 
encounter it, I can tell you!). That doesn't bother me personally since 
I've fixed mine (other than ppc), but for others it doesn't seem like a 
good idea to do casually.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-09 12:07                   ` Jonathan Larmour
@ 2005-06-09 12:49                     ` Alan Modra
  2005-06-09 13:02                     ` Eric Botcazou
  1 sibling, 0 replies; 50+ messages in thread
From: Alan Modra @ 2005-06-09 12:49 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Eric Botcazou, binutils

On Thu, Jun 09, 2005 at 01:07:58PM +0100, Jonathan Larmour wrote:
> Can I ask where the used .gcc_except_table.* sections _are_ meant to be 
> marked?  I cannot see anywhere that _bfd_elf_discard_section_eh_frame does 
> it, for example. Why would .gcc_except_table.* get marked, but .rodata not 
> get marked for powerpc?

I think Eric cheated, and put a KEEP in the linker script.

As far as .eh_frame is concerned, the problem is that gcc doesn't emit
eh info to uniquely named sections for each function when compiling with
-ffunction-sections -fdata-sections.  Instead, you get it all lumped
into one section.  Since ld's --gc-sections option works by looking at
relocs on a section by section basis, if .eh_frame is kept, then all
sections referred to by .eh_frame will be kept.  And .eh_frame typically
references function code sections..

Relocation section '.rela.eh_frame' at offset 0x1293c contains 15 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name + Addend
00000012  0000b901 R_PPC_ADDR32           00000000   __gxx_personality_v0 + 0
00000024  00000801 R_PPC_ADDR32           00000000   .text._ZNSt8ios_base17_M_call_callbacksENS_5eventE + 0
0000002d  00000901 R_PPC_ADDR32           00000000   .rodata + 0
00000048  00000a01 R_PPC_ADDR32           00000000   .text._ZNSt8ios_base20_M_dispose_callbacksEv + 0
00000068  00000b01 R_PPC_ADDR32           00000000   .text._ZNSt8ios_baseD2Ev + 0
00000071  00000901 R_PPC_ADDR32           00000000   .rodata + 1d
00000088  00000c01 R_PPC_ADDR32           00000000   .text._ZNSt8ios_baseD1Ev + 0
00000091  00000901 R_PPC_ADDR32           00000000   .rodata + 2a
000000a8  00000d01 R_PPC_ADDR32           00000000   .text._ZNSt8ios_baseD0Ev + 0
000000b1  00000901 R_PPC_ADDR32           00000000   .rodata + 37
000000c8  00001001 R_PPC_ADDR32           00000000   .text._ZNSt8ios_base6xallocEv + 0
000000d1  00000901 R_PPC_ADDR32           00000000   .rodata + 48
000000e4  00001101 R_PPC_ADDR32           00000000   .text._ZNSt8ios_base17register_callbackEPFvNS_5eventERS_iEi + 0
0000010c  00001501 R_PPC_ADDR32           00000000   .text._ZNSt8ios_base13_M_grow_wordsEib + 0
00000115  00000901 R_PPC_ADDR32           00000000   .rodata + 5c


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-09 12:07                   ` Jonathan Larmour
  2005-06-09 12:49                     ` Alan Modra
@ 2005-06-09 13:02                     ` Eric Botcazou
  2005-06-09 13:50                       ` Jonathan Larmour
  1 sibling, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-09 13:02 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils

> Can I ask where the used .gcc_except_table.* sections _are_ meant to be
> marked?  I cannot see anywhere that _bfd_elf_discard_section_eh_frame does
> it, for example.

The (patched) compiler will mark them.

> Why would .gcc_except_table.* get marked, but .rodata not get marked for
> powerpc? 

Clearly .rodata needs to be explicitly KEEPed for your powerpc target, the 
same way .gcc_except_table has been marked as KEEP for generic ELF.

> Separately, I still consider it an issue to break existing linker scripts
> (and the failure mode is very obscure and difficult to track down when you
> encounter it, I can tell you!).

The alternative is a useless -function-sections --gc-sections with DWARF-2 EH.

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-09 13:02                     ` Eric Botcazou
@ 2005-06-09 13:50                       ` Jonathan Larmour
  2005-06-09 14:22                         ` Eric Botcazou
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-09 13:50 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

Eric Botcazou wrote:
>>Can I ask where the used .gcc_except_table.* sections _are_ meant to be
>>marked?  I cannot see anywhere that _bfd_elf_discard_section_eh_frame does
>>it, for example.
> 
> 
> The (patched) compiler will mark them.

I can't see the changes in GCC CVS, so I guess they are not even in the 
4.0.0 release. So it will be a long time before powerpc-eabi can start 
working again courtesy of that.

>>Why would .gcc_except_table.* get marked, but .rodata not get marked for
>>powerpc? 
> 
> 
> Clearly .rodata needs to be explicitly KEEPed for your powerpc target, the 
> same way .gcc_except_table has been marked as KEEP for generic ELF.

That's quite a sledgehammer approach! The overhead of garbage collectable 
stuff in .rodata is substantially more than .gcc_except_table. For my own 
use, right now, I've just reverted the patch.

But how do we fix this in binutils for other powerpc-eabi users?

Is it possible that instead of just immediately going ahead with not 
marking .eh_frame dependencies, we only do that if there _is_ a section 
named .gcc_except_table in the object? That would both catch the case of 
powerpc-eabi and any others we don't yet know about (there's no reason to 
think powerpc-eabi is definitely the only one).

In other words, something like the following?

       for (o = sub->sections; o != NULL; o = o->next)
	{
	  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.  */
	      if ((strcmp (o->name, ".eh_frame") == 0) &&
                   (bfd_get_section_by_name (abfd, ".gcc_except_table") != 
NULL))
		o->gc_mark = 1;
	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
		return FALSE;
	    }
	}
     }

If you think this looks right and you agree with the principle, I can try 
it out.

>>Separately, I still consider it an issue to break existing linker scripts
>>(and the failure mode is very obscure and difficult to track down when you
>>encounter it, I can tell you!).
> 
> 
> The alternative is a useless -function-sections --gc-sections with DWARF-2 EH.

Not quite useless, just more limited. And if it's a choice between not 
working and limited, I'd choose the latter! :-)

Seriously, if it's a conscious decision to break existing linker scripts 
in this case, that's fine. I just want to make sure people are aware that 
that's the effect.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-09 13:50                       ` Jonathan Larmour
@ 2005-06-09 14:22                         ` Eric Botcazou
  2005-06-09 14:33                           ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-09 14:22 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils

> That's quite a sledgehammer approach! The overhead of garbage collectable
> stuff in .rodata is substantially more than .gcc_except_table. For my own
> use, right now, I've just reverted the patch.

Since -function-sections --gc-sections doesn't work in presence of DWARF-2 EH, 
you could simply not pass -function-sections to the compiler.

> Is it possible that instead of just immediately going ahead with not
> marking .eh_frame dependencies, we only do that if there _is_ a section
> named .gcc_except_table in the object? That would both catch the case of
> powerpc-eabi and any others we don't yet know about (there's no reason to
> think powerpc-eabi is definitely the only one).
>
> In other words, something like the following?
>
>        for (o = sub->sections; o != NULL; o = o->next)
> 	{
> 	  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.  */
> 	      if ((strcmp (o->name, ".eh_frame") == 0) &&
>                    (bfd_get_section_by_name (abfd, ".gcc_except_table") !=
> NULL))
> 		o->gc_mark = 1;
> 	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
> 		return FALSE;
> 	    }
> 	}
>      }
>
> If you think this looks right and you agree with the principle, I can try
> it out.

I'm not sure the .gcc_except_table section has already been created by the 
time bfd_elf_gc_sections is invoked.  I'm looking into it.

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-09 14:22                         ` Eric Botcazou
@ 2005-06-09 14:33                           ` Jonathan Larmour
  2005-06-10  4:23                             ` Alan Modra
  2005-06-10 11:55                             ` Eric Botcazou
  0 siblings, 2 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-09 14:33 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils

Eric Botcazou wrote:
>>That's quite a sledgehammer approach! The overhead of garbage collectable
>>stuff in .rodata is substantially more than .gcc_except_table. For my own
>>use, right now, I've just reverted the patch.
> 
> 
> Since -function-sections --gc-sections doesn't work in presence of DWARF-2 EH, 
> you could simply not pass -function-sections to the compiler.

Ah, the issue being on embedded targets (as powerpc-eabi is implicitly), 
people are normally selective about what they allow to be compiled without 
-fno-exceptions. In the case of eCos, the OS is fully linked to the 
application, and almost none of the OS wants to use C++ exceptions. This 
translates to large savings with gc sections.

I expect anyone else using eCos or their own embedded OS would be 
similarly selective.

> I'm not sure the .gcc_except_table section has already been created by the 
> time bfd_elf_gc_sections is invoked.  I'm looking into it.

Great, thanks. I guess looping over the input BFDs would be better.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-09 14:33                           ` Jonathan Larmour
@ 2005-06-10  4:23                             ` Alan Modra
  2005-06-10  6:46                               ` Eric Botcazou
  2005-06-10 11:55                             ` Eric Botcazou
  1 sibling, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-06-10  4:23 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Eric Botcazou, binutils, gcc-patches, David Edelsohn

On Thu, Jun 09, 2005 at 03:34:20PM +0100, Jonathan Larmour wrote:
> Eric Botcazou wrote:
> >>That's quite a sledgehammer approach! The overhead of garbage collectable
> >>stuff in .rodata is substantially more than .gcc_except_table. For my own
> >>use, right now, I've just reverted the patch.
> >
> >Since -function-sections --gc-sections doesn't work in presence of DWARF-2 
> >EH, you could simply not pass -function-sections to the compiler.
> 
> Ah, the issue being on embedded targets (as powerpc-eabi is implicitly), 
> people are normally selective about what they allow to be compiled without 
> -fno-exceptions. In the case of eCos, the OS is fully linked to the 
> application, and almost none of the OS wants to use C++ exceptions. This 
> translates to large savings with gc sections.

Actually, it's not just eabi that is affected by this problem, but all
sysv4 abi powerpc targets, which includes powerpc-linux.  I've done some
digging through gcc CVS to see why this problem occurred, and found:

Geoff introduced #define EXCEPTION_SECTION readonly_data_section
here: http://gcc.gnu.org/ml/gcc-patches/2001-05/msg00812.html
All well and good, it was an improvement over using data_section

Over time though, we eventually had a default_exception_section that
could generate a read-only .gcc_except_table, so there is now no need
for the define in rs6000/sysv4.h, and of course using .rodata can result
in ld --gc-sections deleting needed exception information.  I'll be
committing a gcc patch soon to fix this on all active gcc branches,
pre-approved by David Edelsohn.

	* config/rs6000/sysv4.h (TARGET_ASM_EXCEPTION_SECTION): Delete.

Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.163
diff -u -p -r1.163 sysv4.h
--- gcc/config/rs6000/sysv4.h	1 Jun 2005 00:30:22 -0000	1.163
+++ gcc/config/rs6000/sysv4.h	10 Jun 2005 04:19:39 -0000
@@ -1284,8 +1284,6 @@ ncrtn.o%s"
    ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
    : DW_EH_PE_absptr)
 
-#define TARGET_ASM_EXCEPTION_SECTION readonly_data_section
-
 #define DOUBLE_INT_ASM_OP "\t.quad\t"
 
 /* Generate entries in .fixup for relocatable addresses.  */

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-10  4:23                             ` Alan Modra
@ 2005-06-10  6:46                               ` Eric Botcazou
  2005-06-10 11:49                                 ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-10  6:46 UTC (permalink / raw)
  To: Alan Modra; +Cc: gcc-patches, Jonathan Larmour, binutils, David Edelsohn

> I'll be committing a gcc patch soon to fix this on all active gcc branches,
> pre-approved by David Edelsohn.
>
> 	* config/rs6000/sysv4.h (TARGET_ASM_EXCEPTION_SECTION): Delete.

Thanks for tracking this down!

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-10  6:46                               ` Eric Botcazou
@ 2005-06-10 11:49                                 ` Jonathan Larmour
  0 siblings, 0 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-10 11:49 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Alan Modra, binutils

Eric Botcazou wrote:
>>I'll be committing a gcc patch soon to fix this on all active gcc branches,
>>pre-approved by David Edelsohn.
>>
>>	* config/rs6000/sysv4.h (TARGET_ASM_EXCEPTION_SECTION): Delete.
> 
> 
> Thanks for tracking this down!

Agreed, thanks! And hopefully that does mean it won't affect other 
architectures after all.

But that still leaves us with a huge time gap between now, and when GCC 
CVS after the patch finally reaches gcc 4.1.0.

So I would still be keen on pursuing a workaround in binutils, perhaps 
along the lines of what I suggested (seeing if .gcc_except_table is in the 
input sections), or anything else anyone thinks would work. Adding a 
special case for powerpc probably wouldn't be wise as it wouldn't be 
appropriate for gcc 4.1.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-09 14:33                           ` Jonathan Larmour
  2005-06-10  4:23                             ` Alan Modra
@ 2005-06-10 11:55                             ` Eric Botcazou
  2005-06-10 12:09                               ` Alan Modra
  1 sibling, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-10 11:55 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 309 bytes --]

> Great, thanks. I guess looping over the input BFDs would be better.

Right, I think it's the best approach.  Not very pretty but it works for me.


	* elflink.c (bfd_elf_gc_sections): Mark again the sections rooted
	at .eh_frame if the EH tables are not in .gcc_except_table.* sections.


-- 
Eric Botcazou

[-- Attachment #2: d106-019_linker-2.diff --]
[-- Type: text/x-diff, Size: 1785 bytes --]

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	10 Jun 2005 11:43:48 -0000
@@ -9031,6 +9031,8 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   asection * (*gc_mark_hook)
     (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
      struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+  bfd_boolean has_gcc_except_table = FALSE;
+  asection *eh_frame = NULL;
 
   if (!get_elf_backend_data (abfd)->can_gc_sections
       || info->relocatable
@@ -9081,13 +9083,31 @@ bfd_elf_gc_sections (bfd *abfd, struct b
 		 orphaned FDEs so don't mark sections referenced by the
 		 EH frame section.  */  
 	      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;
 	    }
+
+	  /* Detect .gcc_except_table.* sections in the input files.  */
+	  if (!has_gcc_except_table
+	      && strncmp (o->name, ".gcc_except_table", 17) == 0)
+	    has_gcc_except_table = TRUE;
 	}
     }
 
+  /* If we have not detected .gcc_except_table.* sections in the input files,
+     that probably means the target uses a specific section for the EH tables.
+     Play safe and let .eh_frame mark the sections it really needs, since we
+     will not be able to do it explicitly.  */
+  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.  */
   if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook))
     return FALSE;

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

* Re: gc sections and .eh_frame
  2005-06-10 11:55                             ` Eric Botcazou
@ 2005-06-10 12:09                               ` Alan Modra
  2005-06-10 12:51                                 ` Jonathan Larmour
  2005-06-10 13:35                                 ` Eric Botcazou
  0 siblings, 2 replies; 50+ messages in thread
From: Alan Modra @ 2005-06-10 12:09 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Jonathan Larmour, binutils

On Fri, Jun 10, 2005 at 01:54:36PM +0200, Eric Botcazou wrote:
> > Great, thanks. I guess looping over the input BFDs would be better.
> 
> Right, I think it's the best approach.  Not very pretty but it works for me.
> 
> 
> 	* elflink.c (bfd_elf_gc_sections): Mark again the sections rooted
> 	at .eh_frame if the EH tables are not in .gcc_except_table.* sections.

Won't that mark all the function text sections too?

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-10 12:09                               ` Alan Modra
@ 2005-06-10 12:51                                 ` Jonathan Larmour
  2005-06-10 13:44                                   ` Eric Botcazou
  2005-06-10 13:35                                 ` Eric Botcazou
  1 sibling, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-10 12:51 UTC (permalink / raw)
  To: Alan Modra; +Cc: Eric Botcazou, binutils

Alan Modra wrote:
> On Fri, Jun 10, 2005 at 01:54:36PM +0200, Eric Botcazou wrote:
> 
>>>Great, thanks. I guess looping over the input BFDs would be better.
>>
>>Right, I think it's the best approach.  Not very pretty but it works for me.
>>
>>
>>	* elflink.c (bfd_elf_gc_sections): Mark again the sections rooted
>>	at .eh_frame if the EH tables are not in .gcc_except_table.* sections.
> 
> 
> Won't that mark all the function text sections too?

Only if there aren't any .gcc_except_table* sections surely? In which case 
that's no worse than previous behaviour.

Anyway, unfortunately the patch doesn't quite work. There are multiple 
input .eh_frame sections, and only the most recently seen one will get its 
dependencies marked.

While it would be good to reuse the loop, I think we're going to have to 
do a separate loop to search for .gcc_except_table*. I'll rework the patch.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-10 12:09                               ` Alan Modra
  2005-06-10 12:51                                 ` Jonathan Larmour
@ 2005-06-10 13:35                                 ` Eric Botcazou
  1 sibling, 0 replies; 50+ messages in thread
From: Eric Botcazou @ 2005-06-10 13:35 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jonathan Larmour, binutils

> > 	* elflink.c (bfd_elf_gc_sections): Mark again the sections rooted
> > 	at .eh_frame if the EH tables are not in .gcc_except_table.* sections.
>
> Won't that mark all the function text sections too?

Aren't they automatically marked if the EH tables are?

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-10 12:51                                 ` Jonathan Larmour
@ 2005-06-10 13:44                                   ` Eric Botcazou
  2005-06-10 14:26                                     ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-10 13:44 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Alan Modra, binutils

[-- Attachment #1: Type: text/plain, Size: 484 bytes --]

> Anyway, unfortunately the patch doesn't quite work. There are multiple
> input .eh_frame sections, and only the most recently seen one will get its
> dependencies marked.

Oops.  Totally broken would be the right wording. :-)

> While it would be good to reuse the loop, I think we're going to have to
> do a separate loop to search for .gcc_except_table*.

Could we not simply move the invocation of _bfd_elf_gc_mark inside the loop?
A new revision is attached.

-- 
Eric Botcazou

[-- Attachment #2: d106-019_linker-2b.diff --]
[-- Type: text/x-diff, Size: 1691 bytes --]

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	10 Jun 2005 13:42:38 -0000
@@ -9068,6 +9068,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)
@@ -9081,11 +9083,29 @@ bfd_elf_gc_sections (bfd *abfd, struct b
 		 orphaned FDEs so don't mark sections referenced by the
 		 EH frame section.  */  
 	      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;
 	    }
+
+	  /* Detect .gcc_except_table.* sections in the input file.  */
+	  if (!has_gcc_except_table
+	      && strncmp (o->name, ".gcc_except_table", 17) == 0)
+	    has_gcc_except_table = TRUE;
 	}
+
+      /* If we have not detected .gcc_except_table.* sections in the input
+	 file, that probably means the target uses a specific section for
+	 the EH tables.  Play safe and let .eh_frame mark the sections it
+	 really needs, since we will not be able to do it explicitly.  */
+      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.  */

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

* Re: gc sections and .eh_frame
  2005-06-10 13:44                                   ` Eric Botcazou
@ 2005-06-10 14:26                                     ` Jonathan Larmour
  2005-06-10 14:50                                       ` Eric Botcazou
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-10 14:26 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Alan Modra, binutils

Eric Botcazou wrote:
> Could we not simply move the invocation of _bfd_elf_gc_mark inside the loop?
> A new revision is attached.

Indeed so, well thought! I've tested it with powerpc-eabi and it works 
fine. I'm happy with that, great work, thanks!

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-10 14:26                                     ` Jonathan Larmour
@ 2005-06-10 14:50                                       ` Eric Botcazou
  2005-06-10 14:58                                         ` Jonathan Larmour
  2005-06-22 11:46                                         ` Jonathan Larmour
  0 siblings, 2 replies; 50+ messages in thread
From: Eric Botcazou @ 2005-06-10 14:50 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils, Alan Modra

> Indeed so, well thought! I've tested it with powerpc-eabi and it works
> fine. I'm happy with that, great work, thanks!

Thanks for confirming.  However I think I've grasped Alan's remark and we 
indeed risk marking all the functions in a given input file if it happens to 
contain no EH tables because its functions don't need them.

I can think of 2 solutions: a second loop as you initially suggested or to add 
a new parameter 'skip_code' to _bfd_elf_gc_mark to skip SEC_CODE sections 
when it is invoked on .eh_frame.  Alan will decide whether the latter approach 
is easily implementable.

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-10 14:50                                       ` Eric Botcazou
@ 2005-06-10 14:58                                         ` Jonathan Larmour
  2005-06-10 15:13                                           ` Eric Botcazou
  2005-06-22 11:46                                         ` Jonathan Larmour
  1 sibling, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-10 14:58 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Alan Modra

Eric Botcazou wrote:
>>Indeed so, well thought! I've tested it with powerpc-eabi and it works
>>fine. I'm happy with that, great work, thanks!
> 
> 
> Thanks for confirming.  However I think I've grasped Alan's remark and we 
> indeed risk marking all the functions in a given input file if it happens to 
> contain no EH tables because its functions don't need them.

Can that really happen in practice? Doesn't that mean having a .eh_frame 
input section present and (on non-powerpc targets) no .gcc_except_frame?

> I can think of 2 solutions: a second loop as you initially suggested or to add 
> a new parameter 'skip_code' to _bfd_elf_gc_mark to skip SEC_CODE sections 
> when it is invoked on .eh_frame.  Alan will decide whether the latter approach 
> is easily implementable.

Since I'm not sure I understand the issue, I'll certainly leave it to you 
two to decide.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-10 14:58                                         ` Jonathan Larmour
@ 2005-06-10 15:13                                           ` Eric Botcazou
  0 siblings, 0 replies; 50+ messages in thread
From: Eric Botcazou @ 2005-06-10 15:13 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: binutils, Alan Modra

> > Thanks for confirming.  However I think I've grasped Alan's remark and we
> > indeed risk marking all the functions in a given input file if it happens
> > to contain no EH tables because its functions don't need them.
>
> Can that really happen in practice? Doesn't that mean having a .eh_frame
> input section present and (on non-powerpc targets) no .gcc_except_frame?

Yes, that can happen if no functions in the file use EH constructs, which is 
not uncommon I think.  For example in Ada:

with U;
procedure Ma is
i : Integer := 10;
begin
   U.Used (i);
end Ma;


        .file   "ma.adb"
        .section        .rodata
.LC0:
        .string "ma.adb"
        .zero   1
        .section        .text._ada_ma,"ax",@progbits
.globl _ada_ma
        .type   _ada_ma, @function
_ada_ma:
.LFB2:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $8, %esp
.LCFI2:
        movl    $10, -4(%ebp)
        subl    $12, %esp
        cmpl    $0, -4(%ebp)
        js      .L4
        cmpl    $10, -4(%ebp)
        jg      .L4
        jmp     .L2
.L4:
        subl    $12, %esp
        pushl   $5
        pushl   $.LC0
.LCFI3:
        call    __gnat_rcheck_11
.L2:
        movl    -4(%ebp), %eax
        pushl   %eax
.LCFI4:
        call    u__used
        addl    $16, %esp
        movl    %eax, -4(%ebp)
        leave
        ret
.LFE2:
        .size   _ada_ma, .-_ada_ma
        .section        .eh_frame,"a",@progbits
.Lframe1:
        .long   .LECIE1-.LSCIE1
.LSCIE1:
        .long   0x0
        .byte   0x1
        .string "zP"
        .uleb128 0x1
        .sleb128 -4
        .byte   0x8
        .uleb128 0x5
        .byte   0x0
        .long   __gnat_eh_personality
        .byte   0xc
        .uleb128 0x4
        .uleb128 0x4
        .byte   0x88
        .uleb128 0x1
        .align 4
.LECIE1:
.LSFDE1:
        .long   .LEFDE1-.LASFDE1
.LASFDE1:
        .long   .LASFDE1-.Lframe1
        .long   .LFB2
        .long   .LFE2-.LFB2
        .uleb128 0x0
        .byte   0x4
        .long   .LCFI0-.LFB2
        .byte   0xe
        .uleb128 0x8
        .byte   0x85
        .uleb128 0x2
        .byte   0x4
        .long   .LCFI1-.LCFI0
        .byte   0xd
        .uleb128 0x5
        .byte   0x4
        .long   .LCFI3-.LCFI1
        .byte   0x2e
        .uleb128 0x14
        .byte   0x4
        .long   .LCFI4-.LCFI3
        .byte   0x2e
        .uleb128 0x10
        .align 4
.LEFDE1:
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.4.5 20050607 (prerelease)"

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-10 14:50                                       ` Eric Botcazou
  2005-06-10 14:58                                         ` Jonathan Larmour
@ 2005-06-22 11:46                                         ` Jonathan Larmour
  2005-06-25 17:28                                           ` Alan Modra
  1 sibling, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-22 11:46 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Alan Modra

Eric Botcazou wrote:
>>Indeed so, well thought! I've tested it with powerpc-eabi and it works
>>fine. I'm happy with that, great work, thanks!
> 
> 
> Thanks for confirming.  However I think I've grasped Alan's remark and we 
> indeed risk marking all the functions in a given input file if it happens to 
> contain no EH tables because its functions don't need them.
> 
> I can think of 2 solutions: a second loop as you initially suggested or to add 
> a new parameter 'skip_code' to _bfd_elf_gc_mark to skip SEC_CODE sections 
> when it is invoked on .eh_frame.  Alan will decide whether the latter approach 
> is easily implementable.

I think Alan maybe didn't notice his name being mentioned :). Alan, do you 
have any guidance on the best approach?

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-22 11:46                                         ` Jonathan Larmour
@ 2005-06-25 17:28                                           ` Alan Modra
  2005-06-27 11:56                                             ` Eric Botcazou
  0 siblings, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-06-25 17:28 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Eric Botcazou, binutils

On Wed, Jun 22, 2005 at 12:46:21PM +0100, Jonathan Larmour wrote:
> I think Alan maybe didn't notice his name being mentioned :). Alan, do you 
> have any guidance on the best approach?

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.

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.

--- bfd/elflink.c~	2005-06-16 12:18:15.000000000 +0930
+++ bfd/elflink.c	2005-06-26 02:17:09.464213143 +0930
@@ -8733,6 +8733,7 @@
 		  gc_mark_hook_fn gc_mark_hook)
 {
   bfd_boolean ret;
+  bfd_boolean is_eh;
   asection *group_sec;
 
   sec->gc_mark = 1;
@@ -8745,6 +8746,7 @@
 
   /* 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;
@@ -8817,7 +8819,10 @@
 	      rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]);
 	    }
 
-	  if (rsec && !rsec->gc_mark)
+	  if (rsec && !rsec->gc_mark
+	      /* Don't mark code sections referenced by .eh_frame,
+		 otherwise we'll mark all code sections in this file.  */
+	      && !(is_eh && (rsec->flags & SEC_CODE) != 0))
 	    {
 	      if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
 		rsec->gc_mark = 1;
@@ -9123,18 +9128,9 @@
 	continue;
 
       for (o = sub->sections; o != NULL; o = o->next)
-	{
-	  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.  */
-	      if (strcmp (o->name, ".eh_frame") == 0)
-		o->gc_mark = 1;
-	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
-		return FALSE;
-	    }
-	}
+	if ((o->flags & SEC_KEEP) != 0 && !o->gc_mark)
+	  if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	    return FALSE;
     }
 
   /* ... and mark SEC_EXCLUDE for those that go.  */

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-25 17:28                                           ` Alan Modra
@ 2005-06-27 11:56                                             ` Eric Botcazou
  2005-06-28  2:58                                               ` Alan Modra
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-27 11:56 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Jonathan Larmour

[-- Attachment #1: Type: text/plain, Size: 1536 bytes --]

> 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

[-- Attachment #2: d106-019_linker-3.diff --]
[-- Type: text/x-diff, Size: 3311 bytes --]

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.  */

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

* Re: gc sections and .eh_frame
  2005-06-27 11:56                                             ` Eric Botcazou
@ 2005-06-28  2:58                                               ` Alan Modra
  2005-06-28  7:40                                                 ` Eric Botcazou
  0 siblings, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-06-28  2:58 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Jonathan Larmour

On Mon, Jun 27, 2005 at 01:55:49PM +0200, Eric Botcazou wrote:
> > 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 

Sorry, I was just going by memory.

> 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.

That doesn't make any difference, because .gcc_except_table* is marked
via KEEP() in the linker script.  So I don't think you need anything
more than the patch I posted.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-28  2:58                                               ` Alan Modra
@ 2005-06-28  7:40                                                 ` Eric Botcazou
  2005-06-28 11:42                                                   ` Alan Modra
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-28  7:40 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Jonathan Larmour

> > I think it doesn't work (alone) either, because you unconditionally mark
> > all .gcc_except_table* sections, which themselves point to the functions.
>
> That doesn't make any difference, because .gcc_except_table* is marked
> via KEEP() in the linker script.  So I don't think you need anything
> more than the patch I posted.

That's not quite true, .gcc_except_table is indeed marked as KEEP, but 
not .gcc_except_table.* :-)

That's the crux of the mechanism: an unpatched (non broken) compiler will only 
emit .gcc_except_table.  But a patched compiler (i.e. the AdaCore compiler or 
the FSF compiler + http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01433.html) 
will emit .gcc_except_table.* with -ffunction-sections, making it possible to 
have a working --gc-sections for languages with EH.

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-28  7:40                                                 ` Eric Botcazou
@ 2005-06-28 11:42                                                   ` Alan Modra
  2005-06-28 11:58                                                     ` Eric Botcazou
  0 siblings, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-06-28 11:42 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Jonathan Larmour

On Tue, Jun 28, 2005 at 09:40:28AM +0200, Eric Botcazou wrote:
> That's not quite true, .gcc_except_table is indeed marked as KEEP, but 
> not .gcc_except_table.* :-)

So how do you ensure .gcc_except_table.* is marked, if not by looking
through .eh_frame relocs?

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-28 11:42                                                   ` Alan Modra
@ 2005-06-28 11:58                                                     ` Eric Botcazou
  2005-06-29  1:24                                                       ` Alan Modra
  0 siblings, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-28 11:58 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Jonathan Larmour

> So how do you ensure .gcc_except_table.* is marked, if not by looking
> through .eh_frame relocs?

Take a look at the change to output_function_exception_table in the 
aforementioned GCC patch. :-)

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-28 11:58                                                     ` Eric Botcazou
@ 2005-06-29  1:24                                                       ` Alan Modra
  2005-06-29  6:52                                                         ` Eric Botcazou
  2005-06-29 13:54                                                         ` Alan Modra
  0 siblings, 2 replies; 50+ messages in thread
From: Alan Modra @ 2005-06-29  1:24 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: binutils, Jonathan Larmour

On Tue, Jun 28, 2005 at 01:57:58PM +0200, Eric Botcazou wrote:
> > So how do you ensure .gcc_except_table.* is marked, if not by looking
> > through .eh_frame relocs?
> 
> Take a look at the change to output_function_exception_table in the 
> aforementioned GCC patch. :-)

I see.  That extra word emitted just to tie .gcc_except_table.* to the
function code is no doubt one reason why the gcc patch hasn't been
approved.  Hmm, I think we can do without it by marking sections
referenced from .eh_frame specially, and keeping them iff the associated
.text section is marked.  Patch in progress.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-29  1:24                                                       ` Alan Modra
@ 2005-06-29  6:52                                                         ` Eric Botcazou
  2005-06-29 12:45                                                           ` Jonathan Larmour
  2005-06-29 13:54                                                         ` Alan Modra
  1 sibling, 1 reply; 50+ messages in thread
From: Eric Botcazou @ 2005-06-29  6:52 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Jonathan Larmour

> I see.  That extra word emitted just to tie .gcc_except_table.* to the
> function code is no doubt one reason why the gcc patch hasn't been
> approved.

The official reason was that COMDAT groups had been introduced in-between and 
that the patch should be rewritten to use them.  On my list, but very, very 
low-priority given the very, very low interest for this stuff outside the Ada 
world.

> Hmm, I think we can do without it by marking sections referenced
> from .eh_frame specially, and keeping them iff the associated 
> .text section is marked.  Patch in progress.

That would be a nice improvement.  I could try to propose an updated version 
of the GCC patch before the end of Stage 2 if you came up with something for 
the linker.

In the meantime, do you want me to apply the patch on Binutils mainline?  On 
Binutils 2.16 branch?

-- 
Eric Botcazou

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

* Re: gc sections and .eh_frame
  2005-06-29  6:52                                                         ` Eric Botcazou
@ 2005-06-29 12:45                                                           ` Jonathan Larmour
  0 siblings, 0 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-29 12:45 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Alan Modra, binutils

Eric Botcazou wrote:
> 
> In the meantime, do you want me to apply the patch on Binutils mainline?  On 
> Binutils 2.16 branch?

So should I try out the patch Eric sent on the 27th 12:55 to check it 
works as expected? Is that the final version?

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-29  1:24                                                       ` Alan Modra
  2005-06-29  6:52                                                         ` Eric Botcazou
@ 2005-06-29 13:54                                                         ` Alan Modra
  2005-06-29 22:31                                                           ` Jonathan Larmour
  2005-07-26 11:30                                                           ` Alan Modra
  1 sibling, 2 replies; 50+ messages in thread
From: Alan Modra @ 2005-06-29 13:54 UTC (permalink / raw)
  To: Eric Botcazou, binutils, Jonathan Larmour

On Wed, Jun 29, 2005 at 10:54:01AM +0930, Alan Modra wrote:
> I think we can do without it by marking sections
> referenced from .eh_frame specially, and keeping them iff the associated
> .text section is marked.

Committing mainline.

bfd/
	* elflink.c (_bfd_elf_gc_mark): Mark sections referenced by
	.eh_frame specially..
	(bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
	Don't recheck sections we have already marked.
	(elf_gc_sweep): Keep non-code sections referenced from .eh_frame.
	* section.c (struct bfd_section): Add gc_mark_from_eh.
	(STD_SECTION): Adjust.
	* ecoff.c (bfd_debug_section): Adjust.
	* bfd-in2.h: Regenerate.

ld/
	* scripttempl/elf.sc (.gcc_except_table): Don't KEEP.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.168
diff -u -p -r1.168 elflink.c
--- bfd/elflink.c	14 Jun 2005 19:25:45 -0000	1.168
+++ bfd/elflink.c	29 Jun 2005 13:02:15 -0000
@@ -8733,6 +8733,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;
@@ -8745,6 +8746,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;
@@ -8821,6 +8823,8 @@ _bfd_elf_gc_mark (struct bfd_link_info *
 	    {
 	      if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
 		rsec->gc_mark = 1;
+	      else if (is_eh)
+		rsec->gc_mark_from_eh = 1;
 	      else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
 		{
 		  ret = FALSE;
@@ -8891,6 +8895,41 @@ elf_gc_sweep (struct bfd_link_info *info
 	  if (o->gc_mark)
 	    continue;
 
+	  /* Keep .gcc_except_table.* if the associated .text.* is
+	     marked.  This isn't very nice, but the proper solution,
+	     splitting .eh_frame up and using comdat doesn't pan out 
+	     easily due to needing special relocs to handle the
+	     difference of two symbols in separate sections.
+	     Don't keep code sections referenced by .eh_frame.  */
+	  if (o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
+	    {
+	      if (strncmp (o->name, ".gcc_except_table.", 18) == 0)
+		{
+		  unsigned long len;
+		  char *fn_name;
+		  asection *fn_text;
+
+		  len = strlen (o->name + 18) + 1;
+		  fn_name = bfd_malloc (len + 6);
+		  if (fn_name == NULL)
+		    return FALSE;
+		  memcpy (fn_name, ".text.", 6);
+		  memcpy (fn_name + 6, o->name + 18, len);
+		  fn_text = bfd_get_section_by_name (sub, fn_name);
+		  free (fn_name);
+		  if (fn_text != NULL && fn_text->gc_mark)
+		    o->gc_mark = 1;
+		}
+
+	      /* If not using specially named exception table section,
+		 then keep whatever we are using.  */
+	      else
+		o->gc_mark = 1;
+
+	      if (o->gc_mark)
+		continue;
+	    }
+
 	  /* Skip sweeping sections already excluded.  */
 	  if (o->flags & SEC_EXCLUDE)
 	    continue;
@@ -9123,18 +9164,9 @@ bfd_elf_gc_sections (bfd *abfd, struct b
 	continue;
 
       for (o = sub->sections; o != NULL; o = o->next)
-	{
-	  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.  */
-	      if (strcmp (o->name, ".eh_frame") == 0)
-		o->gc_mark = 1;
-	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
-		return FALSE;
-	    }
-	}
+	if ((o->flags & SEC_KEEP) != 0 && !o->gc_mark)
+	  if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	    return FALSE;
     }
 
   /* ... and mark SEC_EXCLUDE for those that go.  */
Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.88
diff -u -p -r1.88 section.c
--- bfd/section.c	17 May 2005 19:44:55 -0000	1.88
+++ bfd/section.c	29 Jun 2005 13:02:16 -0000
@@ -354,8 +354,9 @@ CODE_FRAGMENT
 .     output sections that have an input section.  *}
 .  unsigned int linker_has_input : 1;
 .
-.  {* A mark flag used by some linker backends for garbage collection.  *}
+.  {* Mark flags used by some linker backends for garbage collection.  *}
 .  unsigned int gc_mark : 1;
+.  unsigned int gc_mark_from_eh : 1;
 .
 .  {* The following flags are used by the ELF linker. *}
 .
@@ -661,18 +662,18 @@ static const asymbol global_syms[] =
 
 #define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)				\
   const asymbol * const SYM = (asymbol *) &global_syms[IDX]; 		\
-  asection SEC = 							\
+  asection SEC =							\
     /* name, id,  index, next, prev, flags, user_set_vma,            */	\
     { NAME,  IDX, 0,     NULL, NULL, FLAGS, 0,				\
 									\
-    /* linker_mark, linker_has_input, gc_mark, segment_mark,         */	\
+    /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh,      */	\
        0,           0,                1,       0,			\
 									\
-    /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc,       */ \
-       0,	      0,	  0,		 0,			\
+    /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       */	\
+       0,            0,             0,          0,			\
 									\
-    /* need_finalize_relax, reloc_done,                              */ \
-       0,		    0,						\
+    /* has_gp_reloc, need_finalize_relax, reloc_done,                */	\
+       0,            0,                   0,				\
 									\
     /* vma, lma, size, rawsize                                       */	\
        0,   0,   0,    0,						\
@@ -686,8 +687,8 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */	\
        0,            NULL,     NULL,     NULL,   0,			\
 									\
-    /* entsize, kept_section, moving_line_filepos,	           */	\
-       0,       NULL,	      0,					\
+    /* entsize, kept_section, moving_line_filepos,                   */	\
+       0,       NULL,         0,					\
 									\
     /* target_index, used_by_bfd, constructor_chain, owner,          */	\
        0,            NULL,        NULL,              NULL,		\
Index: bfd/ecoff.c
===================================================================
RCS file: /cvs/src/src/bfd/ecoff.c,v
retrieving revision 1.45
diff -u -p -r1.45 ecoff.c
--- bfd/ecoff.c	4 May 2005 15:53:07 -0000	1.45
+++ bfd/ecoff.c	29 Jun 2005 13:02:04 -0000
@@ -54,12 +54,12 @@ static asection bfd_debug_section =
 {
   /* name,      id,  index, next, prev, flags, user_set_vma,       */
      "*DEBUG*", 0,   0,     NULL, NULL, 0,     0,
-  /* linker_mark, linker_has_input, gc_mark, segment_mark,         */
-     0,           0,                0,       0,
-  /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc,       */
-     0,		    0,		0,	       0,
-  /* need_finalize_relax, reloc_done,                              */
-     0,			  0,
+  /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh,      */
+     0,           0,                1,       0,
+  /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       */
+     0,            0,             0,          0,
+  /* has_gp_reloc, need_finalize_relax, reloc_done,                */
+     0,            0,                   0,
   /* vma, lma, size, rawsize,                                      */
      0,   0,   0,    0,
   /* output_offset, output_section, alignment_power,               */
@@ -68,7 +68,7 @@ static asection bfd_debug_section =
      NULL,       NULL,        0,           0,       0,
   /* line_filepos, userdata, contents, lineno, lineno_count,       */
      0,            NULL,     NULL,     NULL,   0,
-  /* entsize, kept_section, moving_line_filepos,	           */
+  /* entsize, kept_section, moving_line_filepos,                   */
      0,       NULL,         0,
   /* target_index, used_by_bfd, constructor_chain, owner,          */
      0,            NULL,        NULL,              NULL,
Index: ld/scripttempl/elf.sc
===================================================================
RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v
retrieving revision 1.59
diff -u -p -r1.59 elf.sc
--- ld/scripttempl/elf.sc	10 Jun 2005 00:39:56 -0000	1.59
+++ ld/scripttempl/elf.sc	29 Jun 2005 13:02:21 -0000
@@ -329,7 +329,7 @@ cat <<EOF
   ${OTHER_READONLY_SECTIONS}
   .eh_frame_hdr : { *(.eh_frame_hdr) }
   .eh_frame     ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+  .gcc_except_table ${RELOCATING-0} : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
 
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
@@ -339,7 +339,7 @@ cat <<EOF
 
   /* Exception handling  */
   .eh_frame     ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
+  .gcc_except_table ${RELOCATING-0} : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
 
   /* Thread Local Storage sections  */
   .tdata	${RELOCATING-0} : { *(.tdata${RELOCATING+ .tdata.* .gnu.linkonce.td.*}) }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-29 13:54                                                         ` Alan Modra
@ 2005-06-29 22:31                                                           ` Jonathan Larmour
  2005-06-30 22:28                                                             ` Alan Modra
  2005-07-26 11:30                                                           ` Alan Modra
  1 sibling, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-06-29 22:31 UTC (permalink / raw)
  To: Alan Modra; +Cc: Eric Botcazou, binutils

Alan Modra wrote:
> On Wed, Jun 29, 2005 at 10:54:01AM +0930, Alan Modra wrote:
> 
>>I think we can do without it by marking sections
>>referenced from .eh_frame specially, and keeping them iff the associated
>>.text section is marked.
> 
> 
> Committing mainline.
> 
> bfd/
> 	* elflink.c (_bfd_elf_gc_mark): Mark sections referenced by
> 	.eh_frame specially..
> 	(bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
> 	Don't recheck sections we have already marked.
> 	(elf_gc_sweep): Keep non-code sections referenced from .eh_frame.
> 	* section.c (struct bfd_section): Add gc_mark_from_eh.
> 	(STD_SECTION): Adjust.
> 	* ecoff.c (bfd_debug_section): Adjust.
> 	* bfd-in2.h: Regenerate.
> 
> ld/
> 	* scripttempl/elf.sc (.gcc_except_table): Don't KEEP.

I updated my sources to current binutils CVS and rebuuilt my 
powerpc-eabi-ld. Unfortunately I now get the following when linking an 
application that uses C++ exceptions:
`DW.ref._ZTISt9exception' referenced in section `.rodata' of 
/local/builds/toolchains/powerpc-eabi/tools/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/lib/nof/libsupc++.a(vterminate.o): 
defined in discarded section `.gnu.linkonce.s.DW.ref._ZTISt9exception' of 
/local/builds/toolchains/powerpc-eabi/tools/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/lib/nof/libsupc++.a(vterminate.o)collect2: 
ld returned 1 exit status

I'll have a closer look tomorrow, although my hunch is that it's something 
to do with being a .gnu.linkonce section specifically - possibly there are 
multiple instances of that section name, and only one is marked to be 
kept, but when duplicate .gnu.linkonce sections are removed, it is the 
other instance that is kept, and later when GC happens, even that one is 
removed.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-29 22:31                                                           ` Jonathan Larmour
@ 2005-06-30 22:28                                                             ` Alan Modra
  2005-07-01 13:31                                                               ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-06-30 22:28 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Eric Botcazou, binutils

On Wed, Jun 29, 2005 at 11:31:02PM +0100, Jonathan Larmour wrote:
> I updated my sources to current binutils CVS and rebuuilt my 
> powerpc-eabi-ld. Unfortunately I now get the following when linking an 
> application that uses C++ exceptions:
> `DW.ref._ZTISt9exception' referenced in section `.rodata' of 
> /local/builds/toolchains/powerpc-eabi/tools/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/lib/nof/libsupc++.a(vterminate.o): 
> defined in discarded section `.gnu.linkonce.s.DW.ref._ZTISt9exception' of 
> /local/builds/toolchains/powerpc-eabi/tools/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/lib/nof/libsupc++.a(vterminate.o)collect2: 
> ld returned 1 exit status
> 
> I'll have a closer look tomorrow, although my hunch is that it's something 
> to do with being a .gnu.linkonce section specifically - possibly there are 

Yes.

> multiple instances of that section name, and only one is marked to be 
> kept, but when duplicate .gnu.linkonce sections are removed, it is the 
> other instance that is kept, and later when GC happens, even that one is 
> removed.

No, GC isn't removing too many sections.  The problem is that .eh_frame,
.gcc_exception_table, debug sections, and other sections on some targets
are not split per-function.  When linkonce sections are removed, you are
left with references from these sections to the removed sections.  The
linker knows this happens for certain section names, so doesn't warn,
but powerpc has been using .rodata instead of .gcc_exception_table..
A workaround is to link with --noinhibit-exec.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-06-30 22:28                                                             ` Alan Modra
@ 2005-07-01 13:31                                                               ` Jonathan Larmour
  2005-07-04  4:50                                                                 ` Alan Modra
  0 siblings, 1 reply; 50+ messages in thread
From: Jonathan Larmour @ 2005-07-01 13:31 UTC (permalink / raw)
  To: Alan Modra; +Cc: Eric Botcazou, binutils

Alan Modra wrote:
> On Wed, Jun 29, 2005 at 11:31:02PM +0100, Jonathan Larmour wrote:
> 
>>I updated my sources to current binutils CVS and rebuuilt my 
>>powerpc-eabi-ld. Unfortunately I now get the following when linking an 
>>application that uses C++ exceptions:
>>`DW.ref._ZTISt9exception' referenced in section `.rodata' of 
>>/local/builds/toolchains/powerpc-eabi/tools/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/lib/nof/libsupc++.a(vterminate.o): 
>>defined in discarded section `.gnu.linkonce.s.DW.ref._ZTISt9exception' of 
>>/local/builds/toolchains/powerpc-eabi/tools/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/lib/nof/libsupc++.a(vterminate.o)collect2: 
>>ld returned 1 exit status
[snip]
>>multiple instances of that section name, and only one is marked to be 
>>kept, but when duplicate .gnu.linkonce sections are removed, it is the 
>>other instance that is kept, and later when GC happens, even that one is 
>>removed.
> 
> 
> No, GC isn't removing too many sections.  The problem is that .eh_frame,
> .gcc_exception_table, debug sections, and other sections on some targets
> are not split per-function.  When linkonce sections are removed, you are
> left with references from these sections to the removed sections.  The
> linker knows this happens for certain section names, so doesn't warn,
> but powerpc has been using .rodata instead of .gcc_exception_table..

Thanks for the explanation. I see that now.

Unfortunately it doesn't leave any sysv4 powerpc target users (including 
powerpc-linux as you said before) much better off, since the GCC change to 
stop using .rodata hasn't even been committed to the trunk yet, nevermind 
any current release branches, and won't be widely disseminated until a 
while after that. Well, they're slightly better off since at least they 
now get an error rather than silent failure :-).

But I've even less of an idea of how this could be addressed in binutils. 
The only way I can think of to identify the problematic powerpc GCC is the 
presence of .eh_frame with an absence of .gcc_except_table, and putting 
that knowledge in place in elf_link_input_bfd is a bit of a kludge. Any 
other ideas?

> A workaround is to link with --noinhibit-exec.

Ick. I'm sure we should be recommending something better than that.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-07-01 13:31                                                               ` Jonathan Larmour
@ 2005-07-04  4:50                                                                 ` Alan Modra
  2005-07-04 10:55                                                                   ` Jonathan Larmour
  0 siblings, 1 reply; 50+ messages in thread
From: Alan Modra @ 2005-07-04  4:50 UTC (permalink / raw)
  To: Jonathan Larmour; +Cc: Eric Botcazou, binutils

On Fri, Jul 01, 2005 at 02:31:44PM +0100, Jonathan Larmour wrote:
> >A workaround is to link with --noinhibit-exec.
> 
> Ick. I'm sure we should be recommending something better than that.

The reason I haven't worried too much is that --gc-sections doing
anything on dynamic executables is a relatively new feature.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-07-04  4:50                                                                 ` Alan Modra
@ 2005-07-04 10:55                                                                   ` Jonathan Larmour
  0 siblings, 0 replies; 50+ messages in thread
From: Jonathan Larmour @ 2005-07-04 10:55 UTC (permalink / raw)
  To: Alan Modra; +Cc: Eric Botcazou, binutils

Alan Modra wrote:
> On Fri, Jul 01, 2005 at 02:31:44PM +0100, Jonathan Larmour wrote:
> 
>>>A workaround is to link with --noinhibit-exec.
>>
>>Ick. I'm sure we should be recommending something better than that.
> 
> 
> The reason I haven't worried too much is that --gc-sections doing
> anything on dynamic executables is a relatively new feature.

Ah well, we (the eCos project), have been using it on static builds for 
embedded targets since before it was publically released (it was written 
for us) :-). 1998 I think. powerpc-eabi was one of the first.

Jifl
-- 
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

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

* Re: gc sections and .eh_frame
  2005-06-29 13:54                                                         ` Alan Modra
  2005-06-29 22:31                                                           ` Jonathan Larmour
@ 2005-07-26 11:30                                                           ` Alan Modra
  2005-07-26 12:05                                                             ` Alan Modra
  2005-08-25  0:06                                                             ` Jim Blandy
  1 sibling, 2 replies; 50+ messages in thread
From: Alan Modra @ 2005-07-26 11:30 UTC (permalink / raw)
  To: binutils

I've been playing with enabling gc-sections for shared libs, and hit
a problem with the way .gcc_except_table is handled.  We were keeping
.gcc_except_table itself, but not sections referenced from there.

	* elflink.c (elf_gc_sweep): Move gcc_except_table code..
	(bfd_elf_gc_sections): ..to here.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.179
diff -u -p -r1.179 elflink.c
--- bfd/elflink.c	25 Jul 2005 15:35:37 -0000	1.179
+++ bfd/elflink.c	26 Jul 2005 10:58:51 -0000
@@ -8912,41 +8912,6 @@ elf_gc_sweep (struct bfd_link_info *info
 	  if (o->gc_mark)
 	    continue;
 
-	  /* Keep .gcc_except_table.* if the associated .text.* is
-	     marked.  This isn't very nice, but the proper solution,
-	     splitting .eh_frame up and using comdat doesn't pan out 
-	     easily due to needing special relocs to handle the
-	     difference of two symbols in separate sections.
-	     Don't keep code sections referenced by .eh_frame.  */
-	  if (o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
-	    {
-	      if (strncmp (o->name, ".gcc_except_table.", 18) == 0)
-		{
-		  unsigned long len;
-		  char *fn_name;
-		  asection *fn_text;
-
-		  len = strlen (o->name + 18) + 1;
-		  fn_name = bfd_malloc (len + 6);
-		  if (fn_name == NULL)
-		    return FALSE;
-		  memcpy (fn_name, ".text.", 6);
-		  memcpy (fn_name + 6, o->name + 18, len);
-		  fn_text = bfd_get_section_by_name (sub, fn_name);
-		  free (fn_name);
-		  if (fn_text != NULL && fn_text->gc_mark)
-		    o->gc_mark = 1;
-		}
-
-	      /* If not using specially named exception table section,
-		 then keep whatever we are using.  */
-	      else
-		o->gc_mark = 1;
-
-	      if (o->gc_mark)
-		continue;
-	    }
-
 	  /* Skip sweeping sections already excluded.  */
 	  if (o->flags & SEC_EXCLUDE)
 	    continue;
@@ -9183,6 +9151,48 @@ bfd_elf_gc_sections (bfd *abfd, struct b
 	    return FALSE;
     }
 
+  /* ... again for sections marked from eh_frame.  */
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+    {
+      asection *o;
+
+      if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
+	continue;
+
+      /* Keep .gcc_except_table.* if the associated .text.* is
+	 marked.  This isn't very nice, but the proper solution,
+	 splitting .eh_frame up and using comdat doesn't pan out 
+	 easily due to needing special relocs to handle the
+	 difference of two symbols in separate sections.
+	 Don't keep code sections referenced by .eh_frame.  */
+      for (o = sub->sections; o != NULL; o = o->next)
+	if (!o->gc_mark && o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
+	  {
+	    if (strncmp (o->name, ".gcc_except_table.", 18) == 0)
+	      {
+		unsigned long len;
+		char *fn_name;
+		asection *fn_text;
+
+		len = strlen (o->name + 18) + 1;
+		fn_name = bfd_malloc (len + 6);
+		if (fn_name == NULL)
+		  return FALSE;
+		memcpy (fn_name, ".text.", 6);
+		memcpy (fn_name + 6, o->name + 18, len);
+		fn_text = bfd_get_section_by_name (sub, fn_name);
+		free (fn_name);
+		if (fn_text == NULL || !fn_text->gc_mark)
+		  continue;
+	      }
+
+	    /* If not using specially named exception table section,
+	       then keep whatever we are using.  */
+	    if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	      return FALSE;
+	  }
+    }
+
   /* ... and mark SEC_EXCLUDE for those that go.  */
   if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook))
     return FALSE;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-07-26 11:30                                                           ` Alan Modra
@ 2005-07-26 12:05                                                             ` Alan Modra
  2005-08-25  0:06                                                             ` Jim Blandy
  1 sibling, 0 replies; 50+ messages in thread
From: Alan Modra @ 2005-07-26 12:05 UTC (permalink / raw)
  To: binutils

On Tue, Jul 26, 2005 at 08:59:47PM +0930, Alan Modra wrote:
> I've been playing with enabling gc-sections for shared libs, and hit
> a problem with the way .gcc_except_table is handled.  We were keeping
> .gcc_except_table itself, but not sections referenced from there.

I should have said that this problem likely affects dynamic apps too.
The code to do gc-sections when building shared libs is like this:

	* elflink.c (elf_gc_mark_dynamic_ref_symbol): Handle -shared.
	(bfd_elf_gc_sections): Allow -gc-sections when -shared.
	* elf32-ppc.c (ppc_elf_gc_sweep_hook): Correct for -shared.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.179
diff -u -p -r1.179 elflink.c
--- bfd/elflink.c	25 Jul 2005 15:35:37 -0000	1.179
+++ bfd/elflink.c	26 Jul 2005 10:58:51 -0000
@@ -9107,19 +9072,25 @@ elf_gc_smash_unused_vtentry_relocs (stru
   return TRUE;
 }
 
-/* Mark sections containing dynamically referenced symbols.  This is called
-   through elf_link_hash_traverse.  */
+/* Mark sections containing dynamically referenced symbols.  When
+   building shared libraries, we must assume that any visible symbol is
+   referenced.  */
 
 static bfd_boolean
-elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h,
-				void *okp ATTRIBUTE_UNUSED)
+elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
 {
+  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   if ((h->root.type == bfd_link_hash_defined
        || h->root.type == bfd_link_hash_defweak)
-      && h->ref_dynamic)
+      && (h->ref_dynamic
+	  || (info->shared
+	      && h->def_regular
+	      && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
+	      && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN)))
     h->root.u.def.section->flags |= SEC_KEEP;
 
   return TRUE;
@@ -9139,7 +9110,6 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   if (!get_elf_backend_data (abfd)->can_gc_sections
       || info->relocatable
       || info->emitrelocations
-      || info->shared
       || !is_elf_hash_table (info->hash))
     {
       (*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
@@ -9164,9 +9134,7 @@ bfd_elf_gc_sections (bfd *abfd, struct b
   if (elf_hash_table (info)->dynamic_sections_created)
     elf_link_hash_traverse (elf_hash_table (info),
 			    elf_gc_mark_dynamic_ref_symbol,
-			    &ok);
-  if (!ok)
-    return FALSE;
+			    info);
 
   /* Grovel through relocs to find out who stays ...  */
   gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.174
diff -u -p -r1.174 elf32-ppc.c
--- bfd/elf32-ppc.c	16 Jul 2005 03:30:23 -0000	1.174
+++ bfd/elf32-ppc.c	26 Jul 2005 10:58:46 -0000
@@ -3728,8 +3778,12 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
 	case R_PPC_ADDR14_BRNTAKEN:
 	case R_PPC_UADDR32:
 	case R_PPC_UADDR16:
+	  if (info->shared)
+	    break;
+
 	case R_PPC_PLT32:
 	case R_PPC_PLTREL24:
+	case R_PPC_PLTREL32:
 	case R_PPC_PLT16_LO:
 	case R_PPC_PLT16_HI:
 	case R_PPC_PLT16_HA:


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: gc sections and .eh_frame
  2005-07-26 11:30                                                           ` Alan Modra
  2005-07-26 12:05                                                             ` Alan Modra
@ 2005-08-25  0:06                                                             ` Jim Blandy
  2005-08-25  0:48                                                               ` Alan Modra
  1 sibling, 1 reply; 50+ messages in thread
From: Jim Blandy @ 2005-08-25  0:06 UTC (permalink / raw)
  To: binutils


Alan Modra <amodra@bigpond.net.au> writes:
> I've been playing with enabling gc-sections for shared libs, and hit
> a problem with the way .gcc_except_table is handled.  We were keeping
> .gcc_except_table itself, but not sections referenced from there.

If I'm understanding the whole saga here correctly, then one way of
describing what makes section GC interact with exception tables so
oddly is that the relocs point backwards from the way they normally
do.

That is, normally, if the GC keeps some section A, and A has relocs
referring to (symbols defined in) some section B, then the GC should
also keep B.  Conversely, if there are no kept sections with relocs
referring to B, then B should be dropped.

For exception handling tables, however, the relocs point in the
opposite direction: if the GC keeps some code section A, and some
exception table B has relocs referring to A, then the GC should also
keep B.  Conversely, if there are no kept code sections that an
exception table B has relocs referring to, then B should be dropped.

Not that folks don't already know this; I just thought it was a
helpfully clear way to describe things.

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

* Re: gc sections and .eh_frame
  2005-08-25  0:06                                                             ` Jim Blandy
@ 2005-08-25  0:48                                                               ` Alan Modra
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Modra @ 2005-08-25  0:48 UTC (permalink / raw)
  To: Jim Blandy; +Cc: binutils

On Wed, Aug 24, 2005 at 05:04:48PM -0700, Jim Blandy wrote:
> That is, normally, if the GC keeps some section A, and A has relocs
> referring to (symbols defined in) some section B, then the GC should
> also keep B.  Conversely, if there are no kept sections with relocs
> referring to B, then B should be dropped.

Yes, and yes.

> For exception handling tables, however, the relocs point in the
> opposite direction: if the GC keeps some code section A, and some
> exception table B has relocs referring to A, then the GC should also
> keep B.  Conversely, if there are no kept code sections that an
> exception table B has relocs referring to, then B should be dropped.

No.  gc marking of sections referenced from .gcc_except_table* should be
as for any other section.  If we had per-function .eh_frame sections
then there wouldn't be anything special at all about .eh_frame* and
.gcc_except_table*.  ie. relocs in .eh_frame* would reference
.gcc_except_table*.  The trouble is that we have a monolithic .eh_frame,
so we can't treat its relocs normally (and we can't break up .eh_frame
easily, but that's another story).

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

end of thread, other threads:[~2005-08-25  0:48 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-07 17:48 gc sections and .eh_frame Jonathan Larmour
2005-06-07 18:00 ` Eric Botcazou
2005-06-07 18:11   ` Jonathan Larmour
2005-06-08  2:09 ` Alan Modra
2005-06-08 11:13   ` Jonathan Larmour
2005-06-08 19:10     ` Richard Henderson
2005-06-08 19:29       ` Jonathan Larmour
2005-06-08 19:32         ` Richard Henderson
2005-06-08 21:36           ` Jonathan Larmour
2005-06-08 22:02             ` Richard Henderson
2005-06-09 10:33               ` Jonathan Larmour
2005-06-09 11:38                 ` Eric Botcazou
2005-06-09 12:07                   ` Jonathan Larmour
2005-06-09 12:49                     ` Alan Modra
2005-06-09 13:02                     ` Eric Botcazou
2005-06-09 13:50                       ` Jonathan Larmour
2005-06-09 14:22                         ` Eric Botcazou
2005-06-09 14:33                           ` Jonathan Larmour
2005-06-10  4:23                             ` Alan Modra
2005-06-10  6:46                               ` Eric Botcazou
2005-06-10 11:49                                 ` Jonathan Larmour
2005-06-10 11:55                             ` Eric Botcazou
2005-06-10 12:09                               ` Alan Modra
2005-06-10 12:51                                 ` Jonathan Larmour
2005-06-10 13:44                                   ` Eric Botcazou
2005-06-10 14:26                                     ` Jonathan Larmour
2005-06-10 14:50                                       ` Eric Botcazou
2005-06-10 14:58                                         ` Jonathan Larmour
2005-06-10 15:13                                           ` Eric Botcazou
2005-06-22 11:46                                         ` Jonathan Larmour
2005-06-25 17:28                                           ` Alan Modra
2005-06-27 11:56                                             ` Eric Botcazou
2005-06-28  2:58                                               ` Alan Modra
2005-06-28  7:40                                                 ` Eric Botcazou
2005-06-28 11:42                                                   ` Alan Modra
2005-06-28 11:58                                                     ` Eric Botcazou
2005-06-29  1:24                                                       ` Alan Modra
2005-06-29  6:52                                                         ` Eric Botcazou
2005-06-29 12:45                                                           ` Jonathan Larmour
2005-06-29 13:54                                                         ` Alan Modra
2005-06-29 22:31                                                           ` Jonathan Larmour
2005-06-30 22:28                                                             ` Alan Modra
2005-07-01 13:31                                                               ` Jonathan Larmour
2005-07-04  4:50                                                                 ` Alan Modra
2005-07-04 10:55                                                                   ` Jonathan Larmour
2005-07-26 11:30                                                           ` Alan Modra
2005-07-26 12:05                                                             ` Alan Modra
2005-08-25  0:06                                                             ` Jim Blandy
2005-08-25  0:48                                                               ` Alan Modra
2005-06-10 13:35                                 ` Eric Botcazou

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).