* elflink.h (elf_link_input_bfd): Zero the reloc instead of doing

bfd_reloc_type_lookup (bfd, BFD_RELOC_NONE) as bfd_reloc_type_lookup
	doesn't accept BFD_RELOC_* on some targets, eg. hppa.

	* elf32-hppa.c (elf32_hppa_link_hash_entry): Remove plt_abs.
	(hppa_link_hash_newfunc): Likewise.
	(elf32_hppa_finish_dynamic_symbol): Likewise.
	(allocate_dynrelocs): Always allocate .got relocs if shared.
	(elf32_hppa_relocate_section): Output them too.  Similarly
	consolidate .plt reloc code, and no longer initialise .plt
	when a reloc is output.
	(elf32_hppa_finish_dynamic_symbol): Only initialise .plt entries
	when no reloc is output.

	From Herbert Xu <herbert@gondor.apana.org.au>
	* elf32-hppa.c (final_link_relocate): Call bfd_set_error for
	unreachable branches.
This commit is contained in:
Alan Modra 2001-10-23 03:55:24 +00:00
parent a1675ea138
commit ce757d1518
3 changed files with 150 additions and 139 deletions

View file

@ -1,3 +1,23 @@
2001-10-23 Alan Modra <amodra@bigpond.net.au>
* elflink.h (elf_link_input_bfd): Zero the reloc instead of doing
bfd_reloc_type_lookup (bfd, BFD_RELOC_NONE) as bfd_reloc_type_lookup
doesn't accept BFD_RELOC_* on some targets, eg. hppa.
* elf32-hppa.c (elf32_hppa_link_hash_entry): Remove plt_abs.
(hppa_link_hash_newfunc): Likewise.
(elf32_hppa_finish_dynamic_symbol): Likewise.
(allocate_dynrelocs): Always allocate .got relocs if shared.
(elf32_hppa_relocate_section): Output them too. Similarly
consolidate .plt reloc code, and no longer initialise .plt
when a reloc is output.
(elf32_hppa_finish_dynamic_symbol): Only initialise .plt entries
when no reloc is output.
From Herbert Xu <herbert@gondor.apana.org.au>
* elf32-hppa.c (final_link_relocate): Call bfd_set_error for
unreachable branches.
2001-10-22 H.J. Lu <hjl@gnu.org>
* configure.in (WIN32LIBADD): Use -L../libiberty for

View file

@ -213,10 +213,6 @@ struct elf32_hppa_link_hash_entry {
/* Set if this symbol is used by a plabel reloc. */
unsigned int plabel:1;
/* Set if this symbol is an init or fini function and thus should
use an absolute reloc. */
unsigned int plt_abs:1;
};
struct elf32_hppa_link_hash_table {
@ -462,7 +458,6 @@ hppa_link_hash_newfunc (entry, table, string)
eh->maybe_pic_call = 0;
eh->pic_call = 0;
eh->plabel = 0;
eh->plt_abs = 0;
}
return entry;
@ -2065,8 +2060,6 @@ allocate_dynrelocs (h, inf)
if (h->got.refcount > 0)
{
boolean dyn;
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
if (h->dynindx == -1
@ -2080,9 +2073,13 @@ allocate_dynrelocs (h, inf)
s = htab->sgot;
h->got.offset = s->_raw_size;
s->_raw_size += GOT_ENTRY_SIZE;
dyn = htab->elf.dynamic_sections_created;
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
if (htab->elf.dynamic_sections_created
&& (info->shared
|| (h->dynindx != -1
&& h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0))
{
htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
}
}
else
h->got.offset = (bfd_vma) -1;
@ -3468,6 +3465,7 @@ final_link_relocate (input_section, contents, rel, value, htab, sym_sec, h)
input_section->name,
(long) rel->r_offset,
stub_entry->root.string);
bfd_set_error (bfd_error_bad_value);
return bfd_reloc_notsupported;
}
@ -3539,7 +3537,6 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_reloc_status_type r;
const char *sym_name;
boolean plabel;
bfd_vma off;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
@ -3639,87 +3636,88 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
case R_PARISC_DLTIND14F:
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND21L:
/* Relocation is to the entry for this symbol in the global
offset table. */
if (h != NULL)
{
boolean dyn;
{
bfd_vma off;
boolean do_got = 0;
off = h->elf.got.offset;
dyn = htab->elf.dynamic_sections_created;
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
this entry in the global offset table. Since the
offset must always be a multiple of 4, we use the
least significant bit to record whether we have
initialized it already.
/* Relocation is to the entry for this symbol in the
global offset table. */
if (h != NULL)
{
boolean dyn;
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off);
h->elf.got.offset |= 1;
}
}
}
else
{
/* Local symbol case. */
if (local_got_offsets == NULL)
abort ();
off = h->elf.got.offset;
dyn = htab->elf.dynamic_sections_created;
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf))
{
/* If we aren't going to call finish_dynamic_symbol,
then we need to handle initialisation of the .got
entry and create needed relocs here. Since the
offset must always be a multiple of 4, we use the
least significant bit to record whether we have
initialised it already. */
if ((off & 1) != 0)
off &= ~1;
else
{
h->elf.got.offset |= 1;
do_got = 1;
}
}
}
else
{
/* Local symbol case. */
if (local_got_offsets == NULL)
abort ();
off = local_got_offsets[r_symndx];
off = local_got_offsets[r_symndx];
/* The offset must always be a multiple of 4. We use
the least significant bit to record whether we have
already generated the necessary reloc. */
if ((off & 1) != 0)
off &= ~1;
else
{
/* The offset must always be a multiple of 4. We use
the least significant bit to record whether we have
already generated the necessary reloc. */
if ((off & 1) != 0)
off &= ~1;
else
{
local_got_offsets[r_symndx] |= 1;
do_got = 1;
}
}
if (do_got)
{
if (info->shared)
{
/* Output a dynamic relocation for this GOT entry.
In this case it is relative to the base of the
object because the symbol index is zero. */
Elf_Internal_Rela outrel;
asection *srelgot = htab->srelgot;
Elf32_External_Rela *loc;
outrel.r_offset = (off
+ htab->sgot->output_offset
+ htab->sgot->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
outrel.r_addend = relocation;
loc = (Elf32_External_Rela *) srelgot->contents;
loc += srelgot->reloc_count++;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
else
bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off);
}
if (info->shared)
{
/* Output a dynamic relocation for this GOT
entry. In this case it is relative to the
base of the object because the symbol index
is zero. */
Elf_Internal_Rela outrel;
asection *srelgot = htab->srelgot;
Elf32_External_Rela *loc;
if (off >= (bfd_vma) -2)
abort ();
outrel.r_offset = (off
+ htab->sgot->output_offset
+ htab->sgot->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
outrel.r_addend = relocation;
loc = (Elf32_External_Rela *) srelgot->contents;
loc += srelgot->reloc_count++;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
local_got_offsets[r_symndx] |= 1;
}
}
if (off >= (bfd_vma) -2)
abort ();
/* Add the base of the GOT to the relocation value. */
relocation = (off
+ htab->sgot->output_offset
+ htab->sgot->output_section->vma);
/* Add the base of the GOT to the relocation value. */
relocation = (off
+ htab->sgot->output_offset
+ htab->sgot->output_section->vma);
}
break;
case R_PARISC_SEGREL32:
@ -3734,6 +3732,9 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
case R_PARISC_PLABEL32:
if (htab->elf.dynamic_sections_created)
{
bfd_vma off;
boolean do_plt = 0;
/* If we have a global symbol with a PLT slot, then
redirect this relocation to it. */
if (h != NULL)
@ -3748,13 +3749,8 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
off &= ~1;
else
{
bfd_put_32 (output_bfd,
relocation,
htab->splt->contents + off);
bfd_put_32 (output_bfd,
elf_gp (htab->splt->output_section->owner),
htab->splt->contents + off + 4);
h->elf.plt.offset |= 1;
do_plt = 1;
}
}
}
@ -3773,6 +3769,32 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
this local .plt entry. */
if ((off & 1) != 0)
off &= ~1;
else
{
local_plt_offsets[r_symndx] |= 1;
do_plt = 1;
}
}
if (do_plt)
{
if (info->shared)
{
/* Output a dynamic IPLT relocation for this
PLT entry. */
Elf_Internal_Rela outrel;
asection *srelplt = htab->srelplt;
Elf32_External_Rela *loc;
outrel.r_offset = (off
+ htab->splt->output_offset
+ htab->splt->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
outrel.r_addend = relocation;
loc = (Elf32_External_Rela *) srelplt->contents;
loc += srelplt->reloc_count++;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
else
{
bfd_put_32 (output_bfd,
@ -3781,26 +3803,6 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_put_32 (output_bfd,
elf_gp (htab->splt->output_section->owner),
htab->splt->contents + off + 4);
if (info->shared)
{
/* Output a dynamic IPLT relocation for this
PLT entry. */
Elf_Internal_Rela outrel;
asection *srelplt = htab->srelplt;
Elf32_External_Rela *loc;
outrel.r_offset = (off
+ htab->splt->output_offset
+ htab->splt->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
outrel.r_addend = relocation;
loc = (Elf32_External_Rela *) srelplt->contents;
loc += srelplt->reloc_count++;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
local_plt_offsets[r_symndx] |= 1;
}
}
@ -3881,6 +3883,8 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
skip = false;
if (elf_section_data (input_section)->stab_info != NULL)
{
bfd_vma off;
off = (_bfd_stab_section_offset
(output_bfd, &htab->elf.stab_info,
input_section,
@ -4076,8 +4080,7 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
rel.r_offset = (h->plt.offset
+ htab->splt->output_offset
+ htab->splt->output_section->vma);
if (! ((struct elf32_hppa_link_hash_entry *) h)->plt_abs
&& h->dynindx != -1)
if (h->dynindx != -1)
{
/* To support lazy linking, the function pointer is
initialised to point to a special stub stored at the
@ -4104,19 +4107,14 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd_elf32_swap_reloca_out (htab->splt->output_section->owner,
&rel, loc);
}
bfd_put_32 (htab->splt->owner,
value,
htab->splt->contents + h->plt.offset);
bfd_put_32 (htab->splt->owner,
elf_gp (htab->splt->output_section->owner),
htab->splt->contents + h->plt.offset + 4);
if (PLABEL_PLT_ENTRY_SIZE != PLT_ENTRY_SIZE
&& ((struct elf32_hppa_link_hash_entry *) h)->plabel
&& h->dynindx != -1)
else
{
memset (htab->splt->contents + h->plt.offset + 8,
0, PLABEL_PLT_ENTRY_SIZE - PLT_ENTRY_SIZE);
bfd_put_32 (htab->splt->owner,
value,
htab->splt->contents + h->plt.offset);
bfd_put_32 (htab->splt->owner,
elf_gp (htab->splt->output_section->owner),
htab->splt->contents + h->plt.offset + 4);
}
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)

View file

@ -5897,8 +5897,6 @@ elf_link_input_bfd (finfo, input_bfd)
asection *o;
struct elf_backend_data *bed;
boolean emit_relocs;
reloc_howto_type *none_howto;
bfd_vma none_r_info;
output_bfd = finfo->output_bfd;
bed = get_elf_backend_data (output_bfd);
@ -6070,9 +6068,6 @@ elf_link_input_bfd (finfo, input_bfd)
return false;
}
none_howto = bfd_reloc_type_lookup (output_bfd, BFD_RELOC_NONE);
none_r_info = ELF_R_INFO (0, none_howto->type);
/* Relocate the contents of each section. */
for (o = input_bfd->sections; o != NULL; o = o->next)
{
@ -6125,13 +6120,12 @@ elf_link_input_bfd (finfo, input_bfd)
{
Elf_Internal_Rela *rel, *relend;
/* Run through the relocs looking for any against section
symbols from removed link-once sections. Set any such
relocs to be against 0. We should really complain if
anything in the final link tries to use it, but
DWARF-based exception handling might have an entry in
.eh_frame to describe a routine in the linkonce section,
and it turns out to be hard to remove the .eh_frame entry
too. FIXME. */
symbols from removed link-once sections. Zero any such
relocs. We should really complain if anything in the
final link tries to use it, but DWARF-based exception
handling might have an entry in .eh_frame to describe a
routine in the linkonce section, and it turns out to be
hard to remove the .eh_frame entry too. FIXME. */
rel = internal_relocs;
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
for ( ; rel < relend; rel++)
@ -6151,21 +6145,20 @@ elf_link_input_bfd (finfo, input_bfd)
&& (sec->flags & SEC_LINK_ONCE) != 0
&& bfd_is_abs_section (sec->output_section))
{
rel->r_info = none_r_info;
#if BFD_VERSION_DATE > 20021005
(*finfo->info->callbacks->warning)
(finfo->info,
_("warning: relocation against removed section; zeroing"),
NULL, input_bfd, o, rel->r_offset);
#endif
memset (rel, 0, sizeof (*rel));
}
}
}
}
}
#else
#error "This kludge ought to be fixed properly in gcc by now"
#error "gcc should be fixed by now, and this kludge no longer needed"
#endif
/* Relocate the section by invoking a back end routine.