* elf32-hppa.c (elf32_hppa_check_relocs): Update comment since we

no longer allocate here.  Localise some vars to blocks where they
	are used.
	(elf32_hppa_adjust_dynamic_symbol): Correct a comment.  Delay
	setting of vars until needed.
	(allocate_dynrelocs): Don't create a .plt entry without a reloc
	when symbol visibilty makes a function local.
	(elf32_hppa_finish_dynamic_symbol): Move expressions out of
	swap_reloca_out function calls.
	(elf32_hppa_relocate_section): Likewies.  Comment typo fix.
	(elf32_hppa_finish_dynamic_sections): Migrate common code out of
	switch statement.
This commit is contained in:
Alan Modra 2001-09-28 08:56:51 +00:00
parent b43d14f89c
commit 3ac8354b40
2 changed files with 98 additions and 89 deletions

View File

@ -1,5 +1,18 @@
2001-09-28 Alan Modra <amodra@bigpond.net.au> 2001-09-28 Alan Modra <amodra@bigpond.net.au>
* elf32-hppa.c (elf32_hppa_check_relocs): Update comment since we
no longer allocate here. Localise some vars to blocks where they
are used.
(elf32_hppa_adjust_dynamic_symbol): Correct a comment. Delay
setting of vars until needed.
(allocate_dynrelocs): Don't create a .plt entry without a reloc
when symbol visibilty makes a function local.
(elf32_hppa_finish_dynamic_symbol): Move expressions out of
swap_reloca_out function calls.
(elf32_hppa_relocate_section): Likewies. Comment typo fix.
(elf32_hppa_finish_dynamic_sections): Migrate common code out of
switch statement.
* elf32-i386.c (elf_i386_check_relocs): Update comment since we * elf32-i386.c (elf_i386_check_relocs): Update comment since we
no longer allocate here. Localise some vars to blocks where they no longer allocate here. Localise some vars to blocks where they
are used. Remove separate switch stmt for creating .got sec. are used. Remove separate switch stmt for creating .got sec.

View File

@ -1154,9 +1154,9 @@ elf32_hppa_copy_indirect_symbol (dir, ind)
} }
/* Look through the relocs for a section during the first phase, and /* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage calculate needed space in the global offset table, procedure linkage
table. At this point we haven't necessarily read all the input table, and dynamic reloc sections. At this point we haven't
files. */ necessarily read all the input files. */
static boolean static boolean
elf32_hppa_check_relocs (abfd, info, sec, relocs) elf32_hppa_check_relocs (abfd, info, sec, relocs)
@ -1165,10 +1165,8 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
asection *sec; asection *sec;
const Elf_Internal_Rela *relocs; const Elf_Internal_Rela *relocs;
{ {
bfd *dynobj;
Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes; struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end; const Elf_Internal_Rela *rel_end;
struct elf32_hppa_link_hash_table *htab; struct elf32_hppa_link_hash_table *htab;
@ -1179,10 +1177,8 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
return true; return true;
htab = hppa_link_hash_table (info); htab = hppa_link_hash_table (info);
dynobj = htab->elf.dynobj;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr; symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd); sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
sreloc = NULL; sreloc = NULL;
stubreloc = NULL; stubreloc = NULL;
@ -1353,12 +1349,11 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
{ {
/* Allocate space for a GOT entry, as well as a dynamic /* Allocate space for a GOT entry, as well as a dynamic
relocation for this entry. */ relocation for this entry. */
if (dynobj == NULL)
htab->elf.dynobj = dynobj = abfd;
if (htab->sgot == NULL) if (htab->sgot == NULL)
{ {
if (! elf32_hppa_create_dynamic_sections (dynobj, info)) if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (!elf32_hppa_create_dynamic_sections (htab->elf.dynobj, info))
return false; return false;
} }
@ -1371,7 +1366,10 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
} }
else else
{ {
bfd_signed_vma *local_got_refcounts;
/* This is a global offset table entry for a local symbol. */ /* This is a global offset table entry for a local symbol. */
local_got_refcounts = elf_local_got_refcounts (abfd);
if (local_got_refcounts == NULL) if (local_got_refcounts == NULL)
{ {
bfd_size_type size; bfd_size_type size;
@ -1422,8 +1420,10 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
} }
else if (need_entry & PLT_PLABEL) else if (need_entry & PLT_PLABEL)
{ {
bfd_signed_vma *local_got_refcounts;
bfd_signed_vma *local_plt_refcounts; bfd_signed_vma *local_plt_refcounts;
local_got_refcounts = elf_local_got_refcounts (abfd);
if (local_got_refcounts == NULL) if (local_got_refcounts == NULL)
{ {
bfd_size_type size; bfd_size_type size;
@ -1501,9 +1501,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
if (sreloc == NULL) if (sreloc == NULL)
{ {
char *name; char *name;
bfd *dynobj;
if (dynobj == NULL)
htab->elf.dynobj = dynobj = abfd;
name = (bfd_elf_string_from_elf_section name = (bfd_elf_string_from_elf_section
(abfd, (abfd,
@ -1518,6 +1516,10 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
return false; return false;
} }
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
dynobj = htab->elf.dynobj;
sreloc = bfd_get_section_by_name (dynobj, name); sreloc = bfd_get_section_by_name (dynobj, name);
if (sreloc == NULL) if (sreloc == NULL)
{ {
@ -1547,7 +1549,8 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
p = ((struct elf32_hppa_dyn_reloc_entry *) p = ((struct elf32_hppa_dyn_reloc_entry *)
bfd_alloc (dynobj, (bfd_size_type) sizeof *p)); bfd_alloc (htab->elf.dynobj,
(bfd_size_type) sizeof *p));
if (p == NULL) if (p == NULL)
return false; return false;
p->next = h->dyn_relocs; p->next = h->dyn_relocs;
@ -1802,14 +1805,11 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
{ {
bfd *dynobj;
struct elf32_hppa_link_hash_table *htab; struct elf32_hppa_link_hash_table *htab;
struct elf32_hppa_link_hash_entry *eh; struct elf32_hppa_link_hash_entry *eh;
struct elf32_hppa_dyn_reloc_entry *p; struct elf32_hppa_dyn_reloc_entry *p;
asection *s; asection *s;
unsigned int power_of_two;
htab = hppa_link_hash_table (info);
dynobj = htab->elf.dynobj;
/* If this is a function, put it in the procedure linkage table. We /* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later, will fill in the contents of the procedure linkage table later,
@ -1906,39 +1906,34 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
both the dynamic object and the regular object will refer to the both the dynamic object and the regular object will refer to the
same memory location for the variable. */ same memory location for the variable. */
s = htab->sdynbss; htab = hppa_link_hash_table (info);
/* We must generate a COPY reloc to tell the dynamic linker to /* We must generate a COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the copy the initial value out of the dynamic object and into the
runtime process image. We need to remember the offset into the runtime process image. */
.rela.bss section we are going to use. */
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
{ {
asection *srel; htab->srelbss->_raw_size += sizeof (Elf32_External_Rela);
srel = htab->srelbss;
srel->_raw_size += sizeof (Elf32_External_Rela);
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
} }
{ /* We need to figure out the alignment required for this symbol. I
/* We need to figure out the alignment required for this symbol. I have no idea how other ELF linkers handle this. */
have no idea how other ELF linkers handle this. */
unsigned int power_of_two;
power_of_two = bfd_log2 (h->size); power_of_two = bfd_log2 (h->size);
if (power_of_two > 3) if (power_of_two > 3)
power_of_two = 3; power_of_two = 3;
/* Apply the required alignment. */
s = htab->sdynbss;
s->_raw_size = BFD_ALIGN (s->_raw_size,
(bfd_size_type) (1 << power_of_two));
if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
{
if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
return false;
}
/* Apply the required alignment. */
s->_raw_size = BFD_ALIGN (s->_raw_size,
(bfd_size_type) (1 << power_of_two));
if (power_of_two > bfd_get_section_alignment (dynobj, s))
{
if (! bfd_set_section_alignment (dynobj, s, power_of_two))
return false;
}
}
/* Define the symbol as being at this point in the section. */ /* Define the symbol as being at this point in the section. */
h->root.u.def.section = s; h->root.u.def.section = s;
h->root.u.def.value = s->_raw_size; h->root.u.def.value = s->_raw_size;
@ -2010,25 +2005,33 @@ allocate_dynrelocs (h, inf)
return false; return false;
} }
/* Make an entry in the .plt section. */ if (((struct elf32_hppa_link_hash_entry *) h)->pic_call
s = htab->splt; || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
h->plt.offset = s->_raw_size;
if (PLABEL_PLT_ENTRY_SIZE != PLT_ENTRY_SIZE
&& ((struct elf32_hppa_link_hash_entry *) h)->plabel
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{ {
/* Add some extra space for the dynamic linker to use. */ /* Make an entry in the .plt section. */
s->_raw_size += PLABEL_PLT_ENTRY_SIZE; s = htab->splt;
h->plt.offset = s->_raw_size;
if (PLABEL_PLT_ENTRY_SIZE != PLT_ENTRY_SIZE
&& ((struct elf32_hppa_link_hash_entry *) h)->plabel
&& (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
{
/* Add some extra space for the dynamic linker to use. */
s->_raw_size += PLABEL_PLT_ENTRY_SIZE;
}
else
s->_raw_size += PLT_ENTRY_SIZE;
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
{
/* We also need to make an entry in the .rela.plt section. */
htab->srelplt->_raw_size += sizeof (Elf32_External_Rela);
htab->need_plt_stub = 1;
}
} }
else else
s->_raw_size += PLT_ENTRY_SIZE;
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call
&& WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
{ {
/* We also need to make an entry in the .rela.plt section. */ h->plt.offset = (bfd_vma) -1;
htab->srelplt->_raw_size += sizeof (Elf32_External_Rela); h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
htab->need_plt_stub = 1;
} }
} }
else else
@ -3531,7 +3534,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
if (info->relocateable) if (info->relocateable)
{ {
/* This is a relocateable link. We don't have to change /* This is a relocatable link. We don't have to change
anything, unless the reloc is against a section symbol, anything, unless the reloc is against a section symbol,
in which case we have to adjust according to where the in which case we have to adjust according to where the
section symbol winds up in the output section. */ section symbol winds up in the output section. */
@ -3673,17 +3676,16 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
is zero. */ is zero. */
Elf_Internal_Rela outrel; Elf_Internal_Rela outrel;
asection *srelgot = htab->srelgot; asection *srelgot = htab->srelgot;
Elf32_External_Rela *loc;
outrel.r_offset = (off outrel.r_offset = (off
+ htab->sgot->output_offset + htab->sgot->output_offset
+ htab->sgot->output_section->vma); + htab->sgot->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32); outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
outrel.r_addend = relocation; outrel.r_addend = relocation;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc = (Elf32_External_Rela *) srelgot->contents;
((Elf32_External_Rela *) loc += srelgot->reloc_count++;
srelgot->contents bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ srelgot->reloc_count));
++srelgot->reloc_count;
} }
local_got_offsets[r_symndx] |= 1; local_got_offsets[r_symndx] |= 1;
@ -3765,17 +3767,16 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
PLT entry. */ PLT entry. */
Elf_Internal_Rela outrel; Elf_Internal_Rela outrel;
asection *srelplt = htab->srelplt; asection *srelplt = htab->srelplt;
Elf32_External_Rela *loc;
outrel.r_offset = (off outrel.r_offset = (off
+ htab->splt->output_offset + htab->splt->output_offset
+ htab->splt->output_section->vma); + htab->splt->output_section->vma);
outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT); outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
outrel.r_addend = relocation; outrel.r_addend = relocation;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc = (Elf32_External_Rela *) srelplt->contents;
((Elf32_External_Rela *) loc += srelplt->reloc_count++;
srelplt->contents bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ srelplt->reloc_count));
++srelplt->reloc_count;
} }
local_plt_offsets[r_symndx] |= 1; local_plt_offsets[r_symndx] |= 1;
@ -3926,9 +3927,8 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
if (sreloc == NULL) if (sreloc == NULL)
abort (); abort ();
loc = ((Elf32_External_Rela *) sreloc->contents loc = (Elf32_External_Rela *) sreloc->contents;
+ sreloc->reloc_count); loc += sreloc->reloc_count++;
sreloc->reloc_count += 1;
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
} }
break; break;
@ -4051,6 +4051,7 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call) if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
{ {
Elf_Internal_Rela rel; Elf_Internal_Rela rel;
Elf32_External_Rela *loc;
/* Create a dynamic IPLT relocation for this entry. */ /* Create a dynamic IPLT relocation for this entry. */
rel.r_offset = (h->plt.offset rel.r_offset = (h->plt.offset
@ -4079,12 +4080,10 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
rel.r_addend = value; rel.r_addend = value;
} }
loc = (Elf32_External_Rela *) htab->srelplt->contents;
loc += htab->srelplt->reloc_count++;
bfd_elf32_swap_reloca_out (htab->splt->output_section->owner, bfd_elf32_swap_reloca_out (htab->splt->output_section->owner,
&rel, &rel, loc);
((Elf32_External_Rela *)
htab->srelplt->contents
+ htab->srelplt->reloc_count));
htab->srelplt->reloc_count++;
} }
bfd_put_32 (htab->splt->owner, bfd_put_32 (htab->splt->owner,
@ -4112,6 +4111,7 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
if (h->got.offset != (bfd_vma) -1) if (h->got.offset != (bfd_vma) -1)
{ {
Elf_Internal_Rela rel; Elf_Internal_Rela rel;
Elf32_External_Rela *loc;
/* This symbol has an entry in the global offset table. Set it /* This symbol has an entry in the global offset table. Set it
up. */ up. */
@ -4144,17 +4144,16 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
rel.r_addend = 0; rel.r_addend = 0;
} }
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc = (Elf32_External_Rela *) htab->srelgot->contents;
((Elf32_External_Rela *) loc += htab->srelgot->reloc_count++;
htab->srelgot->contents bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ htab->srelgot->reloc_count));
++htab->srelgot->reloc_count;
} }
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
{ {
asection *s; asection *s;
Elf_Internal_Rela rel; Elf_Internal_Rela rel;
Elf32_External_Rela *loc;
/* This symbol needs a copy reloc. Set it up. */ /* This symbol needs a copy reloc. Set it up. */
@ -4170,10 +4169,8 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
+ h->root.u.def.section->output_section->vma); + h->root.u.def.section->output_section->vma);
rel.r_addend = 0; rel.r_addend = 0;
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY); rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_COPY);
bfd_elf32_swap_reloca_out (output_bfd, &rel, loc = (Elf32_External_Rela *) s->contents + s->reloc_count++;
((Elf32_External_Rela *) s->contents bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ s->reloc_count));
++s->reloc_count;
} }
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
@ -4243,18 +4240,16 @@ elf32_hppa_finish_dynamic_sections (output_bfd, info)
switch (dyn.d_tag) switch (dyn.d_tag)
{ {
default: default:
break; continue;
case DT_PLTGOT: case DT_PLTGOT:
/* Use PLTGOT to set the GOT register. */ /* Use PLTGOT to set the GOT register. */
dyn.d_un.d_ptr = elf_gp (output_bfd); dyn.d_un.d_ptr = elf_gp (output_bfd);
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break; break;
case DT_JMPREL: case DT_JMPREL:
s = htab->srelplt; s = htab->srelplt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break; break;
case DT_PLTRELSZ: case DT_PLTRELSZ:
@ -4263,9 +4258,10 @@ elf32_hppa_finish_dynamic_sections (output_bfd, info)
dyn.d_un.d_val = s->_cooked_size; dyn.d_un.d_val = s->_cooked_size;
else else
dyn.d_un.d_val = s->_raw_size; dyn.d_un.d_val = s->_raw_size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
break; break;
} }
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
} }
} }