aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2000-10-09 23:16:30 +0000
committerRichard Henderson <rth@redhat.com>2000-10-09 23:16:30 +0000
commitf3b6f7c34d3b6d5024a66ab4e35d115c1c207bec (patch)
treefdde43fd8e690886445bf625342724888387279b
parent16d6ab64288329eca1c794645e5bda4b333a35f3 (diff)
downloadfsf-binutils-gdb-f3b6f7c34d3b6d5024a66ab4e35d115c1c207bec.zip
fsf-binutils-gdb-f3b6f7c34d3b6d5024a66ab4e35d115c1c207bec.tar.gz
fsf-binutils-gdb-f3b6f7c34d3b6d5024a66ab4e35d115c1c207bec.tar.bz2
* elf64-ia64.c (elf64_ia64_unwind_entry_compare_bfd): New.
(elf64_ia64_unwind_entry_compare): New. (elf64_ia64_final_link): Sort the .IA_64.unwind section.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf64-ia64.c49
2 files changed, 54 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c683b4d..249a4bf 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2000-10-09 Richard Henderson <rth@cygnus.com
+
+ * elf64-ia64.c (elf64_ia64_unwind_entry_compare_bfd): New.
+ (elf64_ia64_unwind_entry_compare): New.
+ (elf64_ia64_final_link): Sort the .IA_64.unwind section.
+
2000-10-07 Alan Modra <alan@linuxcare.com.au>
* elflink.h (size_dynamic_sections): Don't create various tags if
diff --git a/bfd/elf64-ia64.c b/bfd/elf64-ia64.c
index cc63838..03985fe 100644
--- a/bfd/elf64-ia64.c
+++ b/bfd/elf64-ia64.c
@@ -2973,6 +2973,25 @@ set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
return value;
}
+/* Called through qsort to sort the .IA_64.unwind section during a
+ non-relocatable link. Set elf64_ia64_unwind_entry_compare_bfd
+ to the output bfd so we can do proper endianness frobbing. */
+
+static bfd *elf64_ia64_unwind_entry_compare_bfd;
+
+static int
+elf64_ia64_unwind_entry_compare (a, b)
+ PTR a;
+ PTR b;
+{
+ bfd_vma av, bv;
+
+ av = bfd_get_64 (elf64_ia64_unwind_entry_compare_bfd, a);
+ bv = bfd_get_64 (elf64_ia64_unwind_entry_compare_bfd, b);
+
+ return (av < bv ? -1 : av > bv ? 1 : 0);
+}
+
static boolean
elf64_ia64_final_link (abfd, info)
bfd *abfd;
@@ -3134,7 +3153,35 @@ elf64_ia64_final_link (abfd, info)
}
/* Invoke the regular ELF backend linker to do all the work. */
- return bfd_elf64_bfd_final_link (abfd, info);
+ if (!bfd_elf64_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;
+
+ elf64_ia64_unwind_entry_compare_bfd = abfd;
+ qsort (contents, size / 24, 24, elf64_ia64_unwind_entry_compare);
+
+ if (! bfd_set_section_contents (abfd, s->output_section,
+ contents, (file_ptr) 0, size))
+ return false;
+ }
+ }
+
+ return true;
}
static boolean