* 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:
parent
a1675ea138
commit
ce757d1518
3 changed files with 150 additions and 139 deletions
|
@ -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
|
||||
|
|
246
bfd/elf32-hppa.c
246
bfd/elf32-hppa.c
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue