This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Fix ld segfaults under hppa64-hp-hpux11
- From: ross dot alexander at uk dot neceur dot com
- To: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Cc: amodra at bigpond dot net dot au, binutils at sources dot redhat dot com, law at redhat dot com
- Date: Thu, 13 Jun 2002 17:09:23 +0100
- Subject: Re: Fix ld segfaults under hppa64-hp-hpux11
David et al,
First of all, many thanks. I manually applied the patch to
binutils-020612.
This fixed the segfault problem but dld.sl is complaining the shared
libraries are not valid load modules. The test program works
okay though. ldd also complains, so maybe I'll try to hunt the problem
down that way or using dlopen.
I'll have a crack at it next week.
Many thanks
Ross
---------------------------------------------------------------------------------
Ross Alexander "He knows no more about his
MIS - NEC Europe Limited destiny than a tea leaf knows
Work ph: +44 20 8752 3394 the history of East India Company"
"John David
Anglin" To: binutils@sources.redhat.com
<dave@hiauly1.hia cc: ross.alexander@uk.neceur.com, law@redhat.com, amodra@bigpond.net.au
.nrc.ca> Subject: Fix ld segfaults under hppa64-hp-hpux11
12/06/2002 17:43
The enclosed patch fixes the two problems noted by Ross Alexander in this
message <http://sources.redhat.com/ml/binutils/2002-06/msg00029.html>.
PROBLEM 1 - BUILDING SHARED LIBRARIES WITH UNDEFINED FUNCTION REFERENCES
This was the more complicated of the two. The problem was we were trying
to create an opd for "f1" when linking libtest2.sl when we shouldn't.
f1 is not defined in libtest2.sl (it is defined in libtest1.sl) so we
shouldn't try to create an opd entry for it when we link libtest2.sl.
Thus, I changed allocate_global_data_opd to not request an opd entry
when a symbol has no output section. This fixed the segfault but a
simple application linked against libtest2.sl segfaulted when a call
with (*r1) was performed. A check to see if we want an opd entry
needed to be added to elf64_hppa_finalize_dynreloc to fix this problem.
PROBLEM 2 - BUILDING EXECUTABLE WITH UNDEFINED FUNCTION REFERENCE
We probably shouldn't be creating a dlt entry for an undefined function
reference. However, since an error condition has already occurred,
I simply added a check to see if the section pointer for the symbol
was not NULL to prevent the segfault.
I have tested the patch on Ross's two examples. I have also tested
the patch with a rebuild of binutils and gcc on hppa64-hp-hpux11.00.
Please install if OK.
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX:
952-6605)
2002-06-12 John David Anglin <dave@hiauly1.hia.nrc.ca>
* elf64-hppa.c (allocate_global_data_opd): We don't need an
opd entry
for a symbol that has no output section.
(allocate_dynrel_entries): Correct comment.
(elf64_hppa_finalize_dynreloc): Likewise. Don't create an opd
entry
unless we want one.
(elf64_hppa_finalize_opd): Prevent segfault if dyn_h is NULL.
(elf64_hppa_finalize_dlt): Likewise. Prevent segfault for
symbols
with no section. Remove unnecessary parentheses.
Index: elf64-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-hppa.c,v
retrieving revision 1.21
diff -u -3 -p -r1.21 elf64-hppa.c
--- elf64-hppa.c 6 Jun 2002 00:29:21 -0000 1.21
+++ elf64-hppa.c 12 Jun 2002 16:00:01 -0000
@@ -1159,7 +1159,8 @@ allocate_global_data_opd (dyn_h, data)
/* We never need an opd entry for a symbol which is not
defined by this output file. */
- if (h && h->root.type == bfd_link_hash_undefined)
+ if (h && (h->root.type == bfd_link_hash_undefined
+ || h->root.u.def.section->output_section == NULL))
dyn_h->want_opd = 0;
/* If we are creating a shared library, took the address of a local
@@ -1168,9 +1169,8 @@ allocate_global_data_opd (dyn_h, data)
else if (x->info->shared
|| h == NULL
|| h->dynindx == -1
- || ((h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && h->root.u.def.section->output_section !=
NULL))
+ || (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
{
/* If we are creating a shared library, then we will have to
create a runtime relocation for the symbol to properly
@@ -1535,9 +1535,8 @@ allocate_dynrel_entries (dyn_h, data)
switch (rent->type)
{
case R_PARISC_FPTR64:
- /* Allocate one iff we are not building a shared library and
- !want_opd, which by this point will be true only if we're
- actually allocating one statically in the main
executable. */
+ /* Allocate one iff we are building a shared library and
don't
+ want an opd entry. */
if (!x->info->shared && dyn_h->want_opd)
continue;
break;
@@ -2115,7 +2114,7 @@ elf64_hppa_finalize_opd (dyn_h, data)
{
struct bfd_link_info *info = (struct bfd_link_info *)data;
struct elf64_hppa_link_hash_table *hppa_info;
- struct elf_link_hash_entry *h = dyn_h->h;
+ struct elf_link_hash_entry *h = dyn_h ? dyn_h->h : NULL;
asection *sopd;
asection *sopdrel;
@@ -2123,7 +2122,7 @@ elf64_hppa_finalize_opd (dyn_h, data)
sopd = hppa_info->opd_sec;
sopdrel = hppa_info->opd_rel_sec;
- if (h && dyn_h && dyn_h->want_opd)
+ if (h && dyn_h->want_opd)
{
bfd_vma value;
@@ -2236,7 +2235,7 @@ elf64_hppa_finalize_dlt (dyn_h, data)
struct bfd_link_info *info = (struct bfd_link_info *)data;
struct elf64_hppa_link_hash_table *hppa_info;
asection *sdlt, *sdltrel;
- struct elf_link_hash_entry *h = dyn_h->h;
+ struct elf_link_hash_entry *h = dyn_h ? dyn_h->h : NULL;
hppa_info = elf64_hppa_hash_table (info);
@@ -2247,7 +2246,7 @@ elf64_hppa_finalize_dlt (dyn_h, data)
address, so there is no need to create a relocation. Just install
the proper value into the DLT, note this shortcut can not be
skipped when building a shared library. */
- if (! info->shared && h && dyn_h && dyn_h->want_dlt)
+ if (! info->shared && h && dyn_h->want_dlt)
{
bfd_vma value;
@@ -2263,16 +2262,17 @@ elf64_hppa_finalize_dlt (dyn_h, data)
+ hppa_info->opd_sec->output_offset
+ hppa_info->opd_sec->output_section->vma);
}
- else
+ else if (h->root.u.def.section)
{
- value = (h->root.u.def.value
- + h->root.u.def.section->output_offset);
-
+ value = h->root.u.def.value +
h->root.u.def.section->output_offset;
if (h->root.u.def.section->output_section)
value += h->root.u.def.section->output_section->vma;
else
value += h->root.u.def.section->vma;
}
+ else
+ /* We have an undefined function reference. */
+ value = 0;
/* We do not need to include the output offset of the DLT section
here because we are modifying the in-memory contents. */
@@ -2360,9 +2360,8 @@ elf64_hppa_finalize_dynreloc (dyn_h, dat
switch (rent->type)
{
case R_PARISC_FPTR64:
- /* Allocate one iff we are not building a shared library
and
- !want_opd, which by this point will be true only
if we're
- actually allocating one statically in the main
executable. */
+ /* Allocate one iff we are building a shared library and
don't
+ want an opd entry. */
if (!info->shared && dyn_h->want_opd)
continue;
break;
@@ -2395,7 +2394,7 @@ elf64_hppa_finalize_dynreloc (dyn_h, dat
We use a section symbol recorded by check_relocs as the
base symbol for the relocation. The addend is the
difference
between the section symbol and the address of the .opd
entry. */
- if (info->shared && rent->type == R_PARISC_FPTR64)
+ if (info->shared && rent->type == R_PARISC_FPTR64 &&
dyn_h->want_opd)
{
bfd_vma value, value2;