mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-30 05:23:49 +08:00
* elf32-hppa.c (elf32_hppa_size_dynamic_sections): Always
allocate local .got space. Use shortcuts from hash table for .got and .plt rather than comparing section names. (elf32_hppa_check_relocs): Use local_plt_refcounts var rather than adjusting index into local_got_refcounts to document what we are really doing. (elf32_hppa_relocate_section): Similarly for local_plt_offsets. Tidy .got and .plt error checking.
This commit is contained in:
parent
afe5040c4c
commit
68fb2e56a3
@ -1,3 +1,14 @@
|
|||||||
|
2001-06-21 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf32-hppa.c (elf32_hppa_size_dynamic_sections): Always
|
||||||
|
allocate local .got space. Use shortcuts from hash table for .got
|
||||||
|
and .plt rather than comparing section names.
|
||||||
|
(elf32_hppa_check_relocs): Use local_plt_refcounts var rather than
|
||||||
|
adjusting index into local_got_refcounts to document what we are
|
||||||
|
really doing.
|
||||||
|
(elf32_hppa_relocate_section): Similarly for local_plt_offsets.
|
||||||
|
Tidy .got and .plt error checking.
|
||||||
|
|
||||||
2001-06-20 Catherine Moore <clm@redhat.com>
|
2001-06-20 Catherine Moore <clm@redhat.com>
|
||||||
|
|
||||||
* elf-bfd.h (struct elf_backend_data):
|
* elf-bfd.h (struct elf_backend_data):
|
||||||
|
203
bfd/elf32-hppa.c
203
bfd/elf32-hppa.c
@ -1522,7 +1522,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
|
|||||||
}
|
}
|
||||||
else if (need_entry & PLT_PLABEL)
|
else if (need_entry & PLT_PLABEL)
|
||||||
{
|
{
|
||||||
int indx;
|
bfd_signed_vma *local_plt_refcounts;
|
||||||
|
|
||||||
if (local_got_refcounts == NULL)
|
if (local_got_refcounts == NULL)
|
||||||
{
|
{
|
||||||
@ -1538,11 +1538,12 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
|
|||||||
elf_local_got_refcounts (abfd) = local_got_refcounts;
|
elf_local_got_refcounts (abfd) = local_got_refcounts;
|
||||||
memset (local_got_refcounts, -1, size);
|
memset (local_got_refcounts, -1, size);
|
||||||
}
|
}
|
||||||
indx = r_symndx + symtab_hdr->sh_info;
|
local_plt_refcounts = (local_got_refcounts
|
||||||
if (local_got_refcounts[indx] == -1)
|
+ symtab_hdr->sh_info);
|
||||||
local_got_refcounts[indx] = 1;
|
if (local_plt_refcounts[r_symndx] == -1)
|
||||||
|
local_plt_refcounts[r_symndx] = 1;
|
||||||
else
|
else
|
||||||
local_got_refcounts[indx] += 1;
|
local_plt_refcounts[r_symndx] += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2215,6 +2216,7 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
{
|
{
|
||||||
struct elf32_hppa_link_hash_table *hplink;
|
struct elf32_hppa_link_hash_table *hplink;
|
||||||
bfd *dynobj;
|
bfd *dynobj;
|
||||||
|
bfd *i;
|
||||||
asection *s;
|
asection *s;
|
||||||
boolean relocs;
|
boolean relocs;
|
||||||
boolean reltext;
|
boolean reltext;
|
||||||
@ -2226,7 +2228,6 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
|
|
||||||
if (hplink->root.dynamic_sections_created)
|
if (hplink->root.dynamic_sections_created)
|
||||||
{
|
{
|
||||||
bfd *i;
|
|
||||||
|
|
||||||
/* Set the contents of the .interp section to the interpreter. */
|
/* Set the contents of the .interp section to the interpreter. */
|
||||||
if (! info->shared)
|
if (! info->shared)
|
||||||
@ -2242,45 +2243,64 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
elf_link_hash_traverse (&hplink->root,
|
elf_link_hash_traverse (&hplink->root,
|
||||||
clobber_millicode_symbols,
|
clobber_millicode_symbols,
|
||||||
info);
|
info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Run through the function symbols, looking for any that are
|
||||||
|
PIC, and allocate space for the necessary .plt entries so
|
||||||
|
that %r19 will be set up. */
|
||||||
|
if (! info->shared)
|
||||||
|
elf_link_hash_traverse (&hplink->root,
|
||||||
|
hppa_handle_PIC_calls,
|
||||||
|
info);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up .got and .plt offsets for local syms. */
|
/* Set up .got and .plt offsets for local syms. */
|
||||||
for (i = info->input_bfds; i; i = i->link_next)
|
for (i = info->input_bfds; i; i = i->link_next)
|
||||||
|
{
|
||||||
|
bfd_signed_vma *local_got;
|
||||||
|
bfd_signed_vma *end_local_got;
|
||||||
|
bfd_signed_vma *local_plt;
|
||||||
|
bfd_signed_vma *end_local_plt;
|
||||||
|
bfd_size_type locsymcount;
|
||||||
|
Elf_Internal_Shdr *symtab_hdr;
|
||||||
|
asection *srel;
|
||||||
|
|
||||||
|
if (bfd_get_flavour (i) != bfd_target_elf_flavour)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
local_got = elf_local_got_refcounts (i);
|
||||||
|
if (!local_got)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
symtab_hdr = &elf_tdata (i)->symtab_hdr;
|
||||||
|
locsymcount = symtab_hdr->sh_info;
|
||||||
|
end_local_got = local_got + locsymcount;
|
||||||
|
s = hplink->sgot;
|
||||||
|
srel = hplink->srelgot;
|
||||||
|
for (; local_got < end_local_got; ++local_got)
|
||||||
{
|
{
|
||||||
bfd_signed_vma *local_got;
|
if (*local_got > 0)
|
||||||
bfd_signed_vma *end_local_got;
|
|
||||||
bfd_signed_vma *local_plt;
|
|
||||||
bfd_signed_vma *end_local_plt;
|
|
||||||
bfd_size_type locsymcount;
|
|
||||||
Elf_Internal_Shdr *symtab_hdr;
|
|
||||||
asection *srel;
|
|
||||||
|
|
||||||
if (bfd_get_flavour (i) != bfd_target_elf_flavour)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
local_got = elf_local_got_refcounts (i);
|
|
||||||
if (!local_got)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
symtab_hdr = &elf_tdata (i)->symtab_hdr;
|
|
||||||
locsymcount = symtab_hdr->sh_info;
|
|
||||||
end_local_got = local_got + locsymcount;
|
|
||||||
s = hplink->sgot;
|
|
||||||
srel = hplink->srelgot;
|
|
||||||
for (; local_got < end_local_got; ++local_got)
|
|
||||||
{
|
{
|
||||||
if (*local_got > 0)
|
*local_got = s->_raw_size;
|
||||||
{
|
s->_raw_size += GOT_ENTRY_SIZE;
|
||||||
*local_got = s->_raw_size;
|
if (info->shared)
|
||||||
s->_raw_size += GOT_ENTRY_SIZE;
|
srel->_raw_size += sizeof (Elf32_External_Rela);
|
||||||
if (info->shared)
|
|
||||||
srel->_raw_size += sizeof (Elf32_External_Rela);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*local_got = (bfd_vma) -1;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*local_got = (bfd_vma) -1;
|
||||||
|
}
|
||||||
|
|
||||||
local_plt = end_local_got;
|
local_plt = end_local_got;
|
||||||
end_local_plt = local_plt + locsymcount;
|
end_local_plt = local_plt + locsymcount;
|
||||||
|
if (! hplink->root.dynamic_sections_created)
|
||||||
|
{
|
||||||
|
/* Won't be used, but be safe. */
|
||||||
|
for (; local_plt < end_local_plt; ++local_plt)
|
||||||
|
*local_plt = (bfd_vma) -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s = hplink->splt;
|
s = hplink->splt;
|
||||||
srel = hplink->srelplt;
|
srel = hplink->srelplt;
|
||||||
for (; local_plt < end_local_plt; ++local_plt)
|
for (; local_plt < end_local_plt; ++local_plt)
|
||||||
@ -2297,16 +2317,6 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Run through the function symbols, looking for any that are
|
|
||||||
PIC, and allocate space for the necessary .plt entries so
|
|
||||||
that %r19 will be set up. */
|
|
||||||
if (! info->shared)
|
|
||||||
elf_link_hash_traverse (&hplink->root,
|
|
||||||
hppa_handle_PIC_calls,
|
|
||||||
info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate global sym .plt and .got entries. */
|
/* Allocate global sym .plt and .got entries. */
|
||||||
elf_link_hash_traverse (&hplink->root,
|
elf_link_hash_traverse (&hplink->root,
|
||||||
@ -2332,16 +2342,29 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
reltext = false;
|
reltext = false;
|
||||||
for (s = dynobj->sections; s != NULL; s = s->next)
|
for (s = dynobj->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
const char *name;
|
|
||||||
|
|
||||||
if ((s->flags & SEC_LINKER_CREATED) == 0)
|
if ((s->flags & SEC_LINKER_CREATED) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* It's OK to base decisions on the section name, because none
|
if (s == hplink->splt)
|
||||||
of the dynobj section names depend upon the input files. */
|
{
|
||||||
name = bfd_get_section_name (dynobj, s);
|
if (hplink->need_plt_stub)
|
||||||
|
{
|
||||||
|
/* Make space for the plt stub at the end of the .plt
|
||||||
|
section. We want this stub right at the end, up
|
||||||
|
against the .got section. */
|
||||||
|
int gotalign = bfd_section_alignment (dynobj, hplink->sgot);
|
||||||
|
int pltalign = bfd_section_alignment (dynobj, s);
|
||||||
|
bfd_size_type mask;
|
||||||
|
|
||||||
if (strncmp (name, ".rela", 5) == 0)
|
if (gotalign > pltalign)
|
||||||
|
bfd_set_section_alignment (dynobj, s, gotalign);
|
||||||
|
mask = ((bfd_size_type) 1 << gotalign) - 1;
|
||||||
|
s->_raw_size = (s->_raw_size + sizeof (plt_stub) + mask) & ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (s == hplink->sgot)
|
||||||
|
;
|
||||||
|
else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
|
||||||
{
|
{
|
||||||
if (s->_raw_size != 0)
|
if (s->_raw_size != 0)
|
||||||
{
|
{
|
||||||
@ -2350,7 +2373,7 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
|
|
||||||
/* Remember whether there are any reloc sections other
|
/* Remember whether there are any reloc sections other
|
||||||
than .rela.plt. */
|
than .rela.plt. */
|
||||||
if (strcmp (name+5, ".plt") != 0)
|
if (s != hplink->srelplt)
|
||||||
relocs = true;
|
relocs = true;
|
||||||
|
|
||||||
/* If this relocation section applies to a read only
|
/* If this relocation section applies to a read only
|
||||||
@ -2368,25 +2391,6 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
s->reloc_count = 0;
|
s->reloc_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp (name, ".plt") == 0)
|
|
||||||
{
|
|
||||||
if (hplink->need_plt_stub)
|
|
||||||
{
|
|
||||||
/* Make space for the plt stub at the end of the .plt
|
|
||||||
section. We want this stub right at the end, up
|
|
||||||
against the .got section. */
|
|
||||||
int gotalign = bfd_section_alignment (dynobj, hplink->sgot);
|
|
||||||
int pltalign = bfd_section_alignment (dynobj, s);
|
|
||||||
bfd_size_type mask;
|
|
||||||
|
|
||||||
if (gotalign > pltalign)
|
|
||||||
bfd_set_section_alignment (dynobj, s, gotalign);
|
|
||||||
mask = ((bfd_size_type) 1 << gotalign) - 1;
|
|
||||||
s->_raw_size = (s->_raw_size + sizeof (plt_stub) + mask) & ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp (name, ".got") == 0)
|
|
||||||
;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* It's not one of our sections, so don't allocate space. */
|
/* It's not one of our sections, so don't allocate space. */
|
||||||
@ -3587,6 +3591,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
bfd_reloc_status_type r;
|
bfd_reloc_status_type r;
|
||||||
const char *sym_name;
|
const char *sym_name;
|
||||||
boolean plabel;
|
boolean plabel;
|
||||||
|
bfd_vma off;
|
||||||
|
|
||||||
r_type = ELF32_R_TYPE (rel->r_info);
|
r_type = ELF32_R_TYPE (rel->r_info);
|
||||||
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
|
if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
|
||||||
@ -3690,13 +3695,9 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
offset table. */
|
offset table. */
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
bfd_vma off;
|
|
||||||
boolean dyn;
|
boolean dyn;
|
||||||
|
|
||||||
off = h->elf.got.offset;
|
off = h->elf.got.offset;
|
||||||
if (off == (bfd_vma) -1)
|
|
||||||
abort ();
|
|
||||||
|
|
||||||
dyn = hplink->root.dynamic_sections_created;
|
dyn = hplink->root.dynamic_sections_created;
|
||||||
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf))
|
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf))
|
||||||
{
|
{
|
||||||
@ -3721,18 +3722,15 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
h->elf.got.offset |= 1;
|
h->elf.got.offset |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation = off;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Local symbol case. */
|
/* Local symbol case. */
|
||||||
bfd_vma off;
|
if (local_got_offsets == NULL)
|
||||||
|
|
||||||
if (local_got_offsets == NULL
|
|
||||||
|| (off = local_got_offsets[r_symndx]) == (bfd_vma) -1)
|
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
|
off = local_got_offsets[r_symndx];
|
||||||
|
|
||||||
/* The offset must always be a multiple of 4. We use
|
/* The offset must always be a multiple of 4. We use
|
||||||
the least significant bit to record whether we have
|
the least significant bit to record whether we have
|
||||||
already generated the necessary reloc. */
|
already generated the necessary reloc. */
|
||||||
@ -3766,13 +3764,15 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
|
|
||||||
local_got_offsets[r_symndx] |= 1;
|
local_got_offsets[r_symndx] |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
relocation = off;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (off >= (bfd_vma) -2)
|
||||||
|
abort ();
|
||||||
|
|
||||||
/* Add the base of the GOT to the relocation value. */
|
/* Add the base of the GOT to the relocation value. */
|
||||||
relocation += (hplink->sgot->output_offset
|
relocation = (off
|
||||||
+ hplink->sgot->output_section->vma);
|
+ hplink->sgot->output_offset
|
||||||
|
+ hplink->sgot->output_section->vma);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PARISC_SEGREL32:
|
case R_PARISC_SEGREL32:
|
||||||
@ -3789,8 +3789,6 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
case R_PARISC_PLABEL32:
|
case R_PARISC_PLABEL32:
|
||||||
if (hplink->root.dynamic_sections_created)
|
if (hplink->root.dynamic_sections_created)
|
||||||
{
|
{
|
||||||
bfd_vma off;
|
|
||||||
|
|
||||||
/* If we have a global symbol with a PLT slot, then
|
/* If we have a global symbol with a PLT slot, then
|
||||||
redirect this relocation to it. */
|
redirect this relocation to it. */
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
@ -3817,10 +3815,13 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int indx;
|
bfd_vma *local_plt_offsets;
|
||||||
|
|
||||||
indx = r_symndx + symtab_hdr->sh_info;
|
if (local_got_offsets == NULL)
|
||||||
off = local_got_offsets[indx];
|
abort ();
|
||||||
|
|
||||||
|
local_plt_offsets = local_got_offsets + symtab_hdr->sh_info;
|
||||||
|
off = local_plt_offsets[r_symndx];
|
||||||
|
|
||||||
/* As for the local .got entry case, we use the last
|
/* As for the local .got entry case, we use the last
|
||||||
bit to record whether we've already initialised
|
bit to record whether we've already initialised
|
||||||
@ -3855,11 +3856,11 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
++srelplt->reloc_count;
|
++srelplt->reloc_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_got_offsets[indx] |= 1;
|
local_plt_offsets[r_symndx] |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (off >= (bfd_vma) -2 || (off & 1) != 0)
|
if (off >= (bfd_vma) -2)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
/* PLABELs contain function pointers. Relocation is to
|
/* PLABELs contain function pointers. Relocation is to
|
||||||
@ -3992,7 +3993,13 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
|
|
||||||
outrel.r_info = ELF32_R_INFO (indx, r_type);
|
outrel.r_info = ELF32_R_INFO (indx, r_type);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
/* EH info can cause unaligned DIR32 relocs.
|
||||||
|
Tweak the reloc type for the dynamic linker. */
|
||||||
|
if (r_type == R_PARISC_DIR32 && (outrel.r_offset & 3) != 0)
|
||||||
|
outrel.r_info = ELF32_R_INFO (ELF32_R_SYM (outrel.r_info),
|
||||||
|
R_PARISC_DIR32U);
|
||||||
|
#endif
|
||||||
bfd_elf32_swap_reloca_out (output_bfd, &outrel,
|
bfd_elf32_swap_reloca_out (output_bfd, &outrel,
|
||||||
((Elf32_External_Rela *)
|
((Elf32_External_Rela *)
|
||||||
sreloc->contents
|
sreloc->contents
|
||||||
|
Loading…
Reference in New Issue
Block a user