This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Fix ld/418
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Richard Sandiford <rsandifo at redhat dot com>,Jakub Jelinek <jakub at redhat dot com>, binutils at sources dot redhat dot com,mendell at ca dot ibm dot com
- Date: Sat, 9 Oct 2004 00:03:57 +0930
- Subject: Re: Fix ld/418
- References: <20040930143657.GA28227@bubble.modra.org> <87fz4p8izo.fsf@redhat.com> <20041008140953.GB8801@bubble.modra.org>
On Fri, Oct 08, 2004 at 11:39:53PM +0930, Alan Modra wrote:
> On Fri, Oct 08, 2004 at 01:58:03PM +0100, Richard Sandiford wrote:
> > need_lsda_relative is only set for FDEs and never for CIEs.
>
> Blagh. I was just about to go to bed. Silly mistake on my part, but
> will require more than just a one-liner to fix. I'll need to write
> some code that trundles through the struct eh_cie_fde info and ties
> together fdes and cies. Tomorrow.
Like this. Untested. I'll commit tomorrow after some testing.
Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.32
diff -u -p -r1.32 elf-eh-frame.c
--- bfd/elf-eh-frame.c 1 Oct 2004 00:51:37 -0000 1.32
+++ bfd/elf-eh-frame.c 8 Oct 2004 14:31:41 -0000
@@ -812,6 +812,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
unsigned int leb128_tmp;
unsigned int cie_offset = 0;
unsigned int ptr_size;
+ unsigned int last_cie_ndx;
ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
== ELFCLASS64) ? 8 : 4;
@@ -828,6 +829,41 @@ _bfd_elf_write_section_eh_frame (bfd *ab
if (hdr_info->array == NULL)
hdr_info = NULL;
+ /* Copy FDE's need_* flags to CIE. */
+ last_cie_ndx = (unsigned) -1;
+ for (i = 0; i < sec_info->count; ++i)
+ {
+ if (sec_info->entry[i].removed)
+ continue;
+ if (sec_info->entry[i].cie)
+ last_cie_ndx = i;
+ else if (sec_info->entry[i].size > 4)
+ {
+ BFD_ASSERT (last_cie_ndx != (unsigned) -1);
+ sec_info->entry[last_cie_ndx].need_relative
+ |= sec_info->entry[i].need_relative;
+ sec_info->entry[last_cie_ndx].need_lsda_relative
+ |= sec_info->entry[i].need_lsda_relative;
+ }
+ }
+ /* And now from CIE to FDEs. */
+ last_cie_ndx = (unsigned) -1;
+ for (i = 0; i < sec_info->count; ++i)
+ {
+ if (sec_info->entry[i].removed)
+ continue;
+ if (sec_info->entry[i].cie)
+ last_cie_ndx = i;
+ else if (sec_info->entry[i].size > 4)
+ {
+ BFD_ASSERT (last_cie_ndx != (unsigned) -1);
+ sec_info->entry[i].need_relative
+ |= sec_info->entry[last_cie_ndx].need_relative;
+ sec_info->entry[i].need_lsda_relative
+ |= sec_info->entry[last_cie_ndx].need_lsda_relative;
+ }
+ }
+
p = contents;
for (i = 0; i < sec_info->count; ++i)
{
--
Alan Modra
IBM OzLabs - Linux Technology Centre