This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
elf32-hppa.c fixes.
- To: binutils at sourceware dot cygnus dot com
- Subject: elf32-hppa.c fixes.
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Fri, 22 Sep 2000 01:02:08 +1100 (EST)
This patch fixes a segfault caused by scribbling past the end of a
malloc'ed array, and skips non-interesting sections when checking for stub
groups. _bfd_strip_section_from_output has some curious effects on
output_bfd sections. a) output_section->index may be larger than
output_bfd->section_count - 1. b) input_section->output_section->owner
== output_bfd but input_section->output_section isn't on output_bfd->
sections list.
The diff here combines my last two commits - those interested in
seeing the bloopers in the previous commit can go dig it out of CVS.
bfd/ChangeLog
* elf32-hppa.c (elf32_hppa_check_relocs): Fix weak sym handling in
currently unused RELATIVE_DYNAMIC_RELOCS code.
(hppa_discard_copies): Likewise.
(elf32_hppa_size_stubs): Size `input_list' array correctly. Correct
comments. Don't check non-code output sections for stub grouping.
Alan Modra
--
Linuxcare. Support for the Revolution.
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.17
diff -u -p -r1.17 elf32-hppa.c
--- elf32-hppa.c 2000/09/18 12:22:41 1.17
+++ elf32-hppa.c 2000/09/21 13:33:44
@@ -1537,8 +1537,7 @@ elf32_hppa_check_relocs (abfd, info, sec
|| is_absolute_reloc (r_type)
|| (h != NULL
&& ((h->elf.elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0
- || h->elf.root.type == bfd_link_hash_defweak)))
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)))
#endif
)
{
@@ -2096,7 +2095,7 @@ hppa_discard_copies (h, inf)
any relocs. */
if (eh->elf.dynindx == -1
|| ((eh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
- && eh->elf.root.type != bfd_link_hash_defweak
+ && !is_absolute_reloc (r_type)
&& info->symbolic))
{
for (s = eh->reloc_entries; s != NULL; s = s->next)
@@ -2441,7 +2440,7 @@ elf32_hppa_size_stubs (output_bfd, stub_
hplink->add_stub_section = add_stub_section;
hplink->layout_sections_again = layout_sections_again;
- /* Count the number of input BFDs and find the top section id. */
+ /* Count the number of input BFDs and find the top input section id. */
for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
input_bfd != NULL;
input_bfd = input_bfd->link_next)
@@ -2461,11 +2460,12 @@ elf32_hppa_size_stubs (output_bfd, stub_
if (hplink->stub_group == NULL)
return false;
- /* Now make a list of input sections for each output section.
- We can't use output_bfd->section_count here as some sections may
- have been removed, and _bfd_strip_section_from_output doesn't
- renumber the indices. Sections may also be re-ordered, so the
- last section index isn't necessarily the biggest. */
+ /* Make a list of input sections for each output section included in
+ the link.
+
+ We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ _bfd_strip_section_from_output doesn't renumber the indices. */
for (section = output_bfd->sections, top_index = 0;
section != NULL;
section = section->next)
@@ -2473,11 +2473,28 @@ elf32_hppa_size_stubs (output_bfd, stub_
if (top_index < section->index)
top_index = section->index;
}
+
input_list
- = (asection **) bfd_zmalloc (sizeof (asection *) * (top_index + 1));
+ = (asection **) bfd_malloc (sizeof (asection *) * (top_index + 1));
if (input_list == NULL)
return false;
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if ((section->flags & SEC_CODE) != 0 && section->index <= top_index)
+ input_list[section->index] = NULL;
+ }
+
+ /* Now actually build the lists. */
for (input_bfd = info->input_bfds;
input_bfd != NULL;
input_bfd = input_bfd->link_next)
@@ -2487,15 +2504,19 @@ elf32_hppa_size_stubs (output_bfd, stub_
section = section->next)
{
if (section->output_section != NULL
- && section->output_section->owner == output_bfd)
+ && section->output_section->owner == output_bfd
+ && section->output_section->index <= top_index)
{
list = input_list + section->output_section->index;
- /* Steal the link_sec pointer for our list. */
+ if (*list != bfd_abs_section_ptr)
+ {
+ /* Steal the link_sec pointer for our list. */
#define PREV_SEC(sec) (hplink->stub_group[(sec)->id].link_sec)
- /* This happens to make the list in reverse order, which
- is what we want. */
- PREV_SEC (section) = *list;
- *list = section;
+ /* This happens to make the list in reverse order,
+ which is what we want. */
+ PREV_SEC (section) = *list;
+ *list = section;
+ }
}
}
}
@@ -2506,10 +2527,12 @@ elf32_hppa_size_stubs (output_bfd, stub_
.fini output sections respectively, because glibc splits the
_init and _fini functions into multiple parts. Putting a stub in
the middle of a function is not a good idea. */
- list = input_list + output_bfd->section_count;
- while (list-- != input_list)
+ list = input_list + top_index;
+ do
{
asection *tail = *list;
+ if (tail == bfd_abs_section_ptr)
+ continue;
while (tail != NULL)
{
asection *curr;
@@ -2559,7 +2582,9 @@ elf32_hppa_size_stubs (output_bfd, stub_
tail = prev;
}
}
+ while (list-- != input_list);
free (input_list);
+#undef PREV_SEC
/* We want to read in symbol extension records only once. To do this
we need to read in the local symbols in parallel and save them for