ia64 unwind sorting fix
Richard Henderson
rth@redhat.com
Tue Nov 7 23:58:00 GMT 2000
It turns out that re-reading the section contents from
the file doesn't always work, because the output file
is opened write-only. So I've tweeked section.c to be
able to cache the relocated contents.
r~
* elf64-ia64.c (elf64_ia64_final_link): New local unwind_output_sec.
Set it before bfd_elf64_bfd_final_link call. Use it after the call.
* section.c (bfd_set_section_contents): Call memcpy if
section->contents set and location not equal to contents plus offset.
Index: elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.1
diff -c -p -d -r1.1 elfxx-ia64.c
*** elfxx-ia64.c 2000/11/07 00:43:26 1.1
--- elfxx-ia64.c 2000/11/08 07:18:56
*************** elfNN_ia64_final_link (abfd, info)
*** 2998,3003 ****
--- 2998,3005 ----
struct bfd_link_info *info;
{
struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *unwind_output_sec;
+
ia64_info = elfNN_ia64_hash_table (info);
/* Make sure we've got ourselves a nice fat __gp value. */
*************** elfNN_ia64_final_link (abfd, info)
*** 3152,3184 ****
}
}
- /* Invoke the regular ELF backend linker to do all the work. */
- if (!bfd_elfNN_bfd_final_link (abfd, info))
- return false;
-
/* If we're producing a final executable, we need to sort the contents
! of the .IA_64.unwind section. */
if (!info->relocateable)
{
asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
if (s)
{
! bfd_size_type size = s->output_section->_raw_size;
! char *contents = bfd_malloc (size);
!
! if (contents == NULL)
! return false;
! if (! bfd_get_section_contents (abfd, s->output_section,
! contents, (file_ptr) 0, size))
return false;
! elfNN_ia64_unwind_entry_compare_bfd = abfd;
! qsort (contents, size / 24, 24, elfNN_ia64_unwind_entry_compare);
! if (! bfd_set_section_contents (abfd, s->output_section,
! contents, (file_ptr) 0, size))
! return false;
! }
}
return true;
--- 3154,3190 ----
}
}
/* If we're producing a final executable, we need to sort the contents
! of the .IA_64.unwind section. Force this section to be relocated
! into memory rather than written immediately to the output file. */
! unwind_output_sec = NULL;
if (!info->relocateable)
{
asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
if (s)
{
! unwind_output_sec = s->output_section;
! unwind_output_sec->contents
! = bfd_malloc (unwind_output_sec->_raw_size);
! if (unwind_output_sec->contents == NULL)
return false;
+ }
+ }
! /* Invoke the regular ELF backend linker to do all the work. */
! if (!bfd_elfNN_bfd_final_link (abfd, info))
! return false;
! if (unwind_output_sec)
! {
! elfNN_ia64_unwind_entry_compare_bfd = abfd;
! qsort (unwind_output_sec->contents, unwind_output_sec->_raw_size / 24,
! 24, elfNN_ia64_unwind_entry_compare);
!
! if (! bfd_set_section_contents (abfd, unwind_output_sec,
! unwind_output_sec->contents, 0,
! unwind_output_sec->_raw_size))
! return false;
}
return true;
Index: section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.25
diff -c -p -d -r1.25 section.c
*** section.c 2000/10/12 03:44:50 1.25
--- section.c 2000/11/08 07:18:56
*************** bfd_set_section_contents (abfd, section,
*** 1081,1086 ****
--- 1081,1091 ----
break;
}
+ /* Record a copy of the data in memory if desired. */
+ if (section->contents
+ && location != section->contents + offset)
+ memcpy (section->contents + offset, location, count);
+
if (BFD_SEND (abfd, _bfd_set_section_contents,
(abfd, section, location, offset, count)))
{
More information about the Binutils
mailing list