elf32-hppa.c fixes.
Alan Modra
alan@linuxcare.com.au
Thu Sep 21 07:02:00 GMT 2000
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
More information about the Binutils
mailing list