This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFA: Remove duplicated section cache from elf32-arm.c
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: binutils at sourceware dot org
- Date: Thu, 18 Nov 2010 16:38:07 +0000
- Subject: RFA: Remove duplicated section cache from elf32-arm.c
Another prerequisite for the prototype STT_GNU_IFUNC support. ARM caches
the .got, .got.plt, .rel(a).got, .plt and .rel(a).plt section pointers
in its hash table, but those sections are now also stored in the parent
ELF table. This patch removes the duplication.
While there, I fixed some caes in which we were unnecessarily looking
up cached sections by name. I also removed uses of htab->blah in
cases where blah was already cached in a local variable. (The latter
change is needed for IFUNC, because those local variables might instead
point to .igot, .iplt, etc.)
Tested on arm-linux-gnueabi. OK to install?
Richard
bfd/
* elf32-arm.c (elf32_arm_link_hash_table): Remove sgot, sgotplt,
srelgot, splt, srelplt.
(create_got_section, elf32_arm_link_hash_table_create): Don't set them.
(elf32_arm_create_dynamic_sections): Likewise. Use htab->root
fields instead.
(arm_type_of_stub): Use the root fields instead of the removed ones.
(cortex_a8_erratum_scan, elf32_arm_size_stubs): Likewise.
(bfd_elf32_arm_process_before_allocation): Likewise.
(elf32_arm_check_relocs, allocate_dynrelocs): Likewise.
(elf32_arm_size_dynamic_sections): Likewise.
(elf32_arm_output_arch_local_syms): Likewise.
(elf32_arm_final_link_relocate): Set sgot, splt and srelgot from the
htab fields instead of looking them up by name. Consistently use
these local variables instead of htab fields.
(elf32_arm_finish_dynamic_symbol): Likewise sgot, splt and srel.
Use srelbss instead of looking it up by name.
(elf32_arm_finish_dynamic_sections): Use sgotplt, splt and srelplt
instead of looking up the symbols by name. Use the root fields
instead of the removed ones.
Index: bfd/elf32-arm.c
===================================================================
--- bfd/elf32-arm.c 2010-11-18 16:07:09.000000000 +0000
+++ bfd/elf32-arm.c 2010-11-18 16:19:53.000000000 +0000
@@ -2595,11 +2595,6 @@ struct elf32_arm_link_hash_table
int use_rel;
/* Short-cuts to get to dynamic linker sections. */
- asection *sgot;
- asection *sgotplt;
- asection *srelgot;
- asection *splt;
- asection *srelplt;
asection *sdynbss;
asection *srelbss;
@@ -2741,15 +2736,6 @@ create_got_section (bfd *dynobj, struct
if (! _bfd_elf_create_got_section (dynobj, info))
return FALSE;
- htab->sgot = bfd_get_section_by_name (dynobj, ".got");
- htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
- if (!htab->sgot || !htab->sgotplt)
- abort ();
-
- htab->srelgot = bfd_get_section_by_name (dynobj,
- RELOC_SECTION (htab, ".got"));
- if (htab->srelgot == NULL)
- return FALSE;
return TRUE;
}
@@ -2766,15 +2752,12 @@ elf32_arm_create_dynamic_sections (bfd *
if (htab == NULL)
return FALSE;
- if (!htab->sgot && !create_got_section (dynobj, info))
+ if (!htab->root.sgot && !create_got_section (dynobj, info))
return FALSE;
if (!_bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
- htab->splt = bfd_get_section_by_name (dynobj, ".plt");
- htab->srelplt = bfd_get_section_by_name (dynobj,
- RELOC_SECTION (htab, ".plt"));
htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
if (!info->shared)
htab->srelbss = bfd_get_section_by_name (dynobj,
@@ -2800,8 +2783,8 @@ elf32_arm_create_dynamic_sections (bfd *
}
}
- if (!htab->splt
- || !htab->srelplt
+ if (!htab->root.splt
+ || !htab->root.srelplt
|| !htab->sdynbss
|| (!info->shared && !htab->srelbss))
abort ();
@@ -2891,11 +2874,6 @@ elf32_arm_link_hash_table_create (bfd *a
return NULL;
}
- ret->sgot = NULL;
- ret->sgotplt = NULL;
- ret->srelgot = NULL;
- ret->splt = NULL;
- ret->srelplt = NULL;
ret->sdynbss = NULL;
ret->srelbss = NULL;
ret->srelplt2 = NULL;
@@ -3074,7 +3052,7 @@ arm_type_of_stub (struct bfd_link_info *
r_type = ELF32_R_TYPE (rel->r_info);
/* Keep a simpler condition, for the sake of clarity. */
- if (globals->splt != NULL
+ if (globals->root.splt != NULL
&& hash != NULL
&& hash->root.plt.offset != (bfd_vma) -1)
{
@@ -3089,8 +3067,8 @@ arm_type_of_stub (struct bfd_link_info *
because it avoids spreading offset corrections in several
places. */
- destination = (globals->splt->output_section->vma
- + globals->splt->output_offset
+ destination = (globals->root.splt->output_section->vma
+ + globals->root.splt->output_offset
+ hash->root.plt.offset);
st_type = STT_FUNC;
}
@@ -4112,7 +4090,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
found->non_a8_stub = TRUE;
/* Keep a simpler condition, for the sake of clarity. */
- if (htab->splt != NULL && found->hash != NULL
+ if (htab->root.splt != NULL && found->hash != NULL
&& found->hash->root.plt.offset != (bfd_vma) -1)
use_plt = TRUE;
@@ -4532,11 +4510,11 @@ elf32_arm_size_stubs (bfd *output_bfd,
decide whether a branch stub is
needed. */
if (globals != NULL
- && globals->splt != NULL
+ && globals->root.splt != NULL
&& hash != NULL
&& hash->root.plt.offset != (bfd_vma) -1)
{
- sym_sec = globals->splt;
+ sym_sec = globals->root.splt;
sym_value = hash->root.plt.offset;
if (sym_sec->output_section != NULL)
destination = (sym_value
@@ -4559,11 +4537,11 @@ elf32_arm_size_stubs (bfd *output_bfd,
elf32_arm_hash_table (info);
if (globals != NULL
- && globals->splt != NULL
+ && globals->root.splt != NULL
&& hash != NULL
&& hash->root.plt.offset != (bfd_vma) -1)
{
- sym_sec = globals->splt;
+ sym_sec = globals->root.splt;
sym_value = hash->root.plt.offset;
if (sym_sec->output_section != NULL)
destination = (sym_value
@@ -5554,7 +5532,7 @@ bfd_elf32_arm_process_before_allocation
/* If the call will go through a PLT entry then we do not need
glue. */
- if (globals->splt != NULL && h->plt.offset != (bfd_vma) -1)
+ if (globals->root.splt != NULL && h->plt.offset != (bfd_vma) -1)
continue;
switch (r_type)
@@ -6855,11 +6833,11 @@ elf32_arm_final_link_relocate (reloc_how
unsigned long r_type = howto->type;
unsigned long r_symndx;
bfd_byte * hit_data = contents + rel->r_offset;
- bfd * dynobj = NULL;
bfd_vma * local_got_offsets;
asection * sgot = NULL;
asection * splt = NULL;
asection * sreloc = NULL;
+ asection * srelgot;
bfd_vma addend;
bfd_signed_vma signed_addend;
struct elf32_arm_link_hash_table * globals;
@@ -6888,12 +6866,9 @@ elf32_arm_final_link_relocate (reloc_how
if (bfd_get_start_address (output_bfd) != 0)
elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
- dynobj = elf_hash_table (info)->dynobj;
- if (dynobj)
- {
- sgot = bfd_get_section_by_name (dynobj, ".got");
- splt = bfd_get_section_by_name (dynobj, ".plt");
- }
+ sgot = globals->root.sgot;
+ splt = globals->root.splt;
+ srelgot = globals->root.srelgot;
local_got_offsets = elf_local_got_offsets (input_bfd);
r_symndx = ELF32_R_SYM (rel->r_info);
@@ -7951,12 +7926,9 @@ elf32_arm_final_link_relocate (reloc_how
if (info->shared)
{
- asection * srelgot;
Elf_Internal_Rela outrel;
bfd_byte *loc;
- srelgot = (bfd_get_section_by_name
- (dynobj, RELOC_SECTION (globals, ".got")));
BFD_ASSERT (srelgot != NULL);
outrel.r_addend = addend + value;
@@ -7992,7 +7964,7 @@ elf32_arm_final_link_relocate (reloc_how
{
bfd_vma off;
- if (globals->sgot == NULL)
+ if (sgot == NULL)
abort ();
off = globals->tls_ldm_got.offset;
@@ -8008,29 +7980,29 @@ elf32_arm_final_link_relocate (reloc_how
Elf_Internal_Rela outrel;
bfd_byte *loc;
- if (globals->srelgot == NULL)
+ if (srelgot == NULL)
abort ();
outrel.r_addend = 0;
- outrel.r_offset = (globals->sgot->output_section->vma
- + globals->sgot->output_offset + off);
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
outrel.r_info = ELF32_R_INFO (0, R_ARM_TLS_DTPMOD32);
if (globals->use_rel)
bfd_put_32 (output_bfd, outrel.r_addend,
- globals->sgot->contents + off);
+ sgot->contents + off);
- loc = globals->srelgot->contents;
- loc += globals->srelgot->reloc_count++ * RELOC_SIZE (globals);
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * RELOC_SIZE (globals);
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
}
else
- bfd_put_32 (output_bfd, 1, globals->sgot->contents + off);
+ bfd_put_32 (output_bfd, 1, sgot->contents + off);
globals->tls_ldm_got.offset |= 1;
}
- value = globals->sgot->output_section->vma + globals->sgot->output_offset + off
+ value = sgot->output_section->vma + sgot->output_offset + off
- (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
return _bfd_final_link_relocate (howto, input_bfd, input_section,
@@ -8045,7 +8017,7 @@ elf32_arm_final_link_relocate (reloc_how
int indx;
char tls_type;
- if (globals->sgot == NULL)
+ if (sgot == NULL)
abort ();
indx = 0;
@@ -8093,10 +8065,10 @@ elf32_arm_final_link_relocate (reloc_how
|| h->root.type != bfd_link_hash_undefweak))
{
need_relocs = TRUE;
- if (globals->srelgot == NULL)
+ if (srelgot == NULL)
abort ();
- loc = globals->srelgot->contents;
- loc += globals->srelgot->reloc_count * RELOC_SIZE (globals);
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count * RELOC_SIZE (globals);
}
if (tls_type & GOT_TLS_GD)
@@ -8104,22 +8076,22 @@ elf32_arm_final_link_relocate (reloc_how
if (need_relocs)
{
outrel.r_addend = 0;
- outrel.r_offset = (globals->sgot->output_section->vma
- + globals->sgot->output_offset
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ cur_off);
outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32);
if (globals->use_rel)
bfd_put_32 (output_bfd, outrel.r_addend,
- globals->sgot->contents + cur_off);
+ sgot->contents + cur_off);
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- globals->srelgot->reloc_count++;
+ srelgot->reloc_count++;
loc += RELOC_SIZE (globals);
if (indx == 0)
bfd_put_32 (output_bfd, value - dtpoff_base (info),
- globals->sgot->contents + cur_off + 4);
+ sgot->contents + cur_off + 4);
else
{
outrel.r_addend = 0;
@@ -8129,11 +8101,11 @@ elf32_arm_final_link_relocate (reloc_how
if (globals->use_rel)
bfd_put_32 (output_bfd, outrel.r_addend,
- globals->sgot->contents + cur_off + 4);
+ sgot->contents + cur_off + 4);
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- globals->srelgot->reloc_count++;
+ srelgot->reloc_count++;
loc += RELOC_SIZE (globals);
}
}
@@ -8145,9 +8117,9 @@ elf32_arm_final_link_relocate (reloc_how
symbol binding locally. Mark it as belonging
to module 1, the executable. */
bfd_put_32 (output_bfd, 1,
- globals->sgot->contents + cur_off);
+ sgot->contents + cur_off);
bfd_put_32 (output_bfd, value - dtpoff_base (info),
- globals->sgot->contents + cur_off + 4);
+ sgot->contents + cur_off + 4);
}
cur_off += 8;
@@ -8161,22 +8133,22 @@ elf32_arm_final_link_relocate (reloc_how
outrel.r_addend = value - dtpoff_base (info);
else
outrel.r_addend = 0;
- outrel.r_offset = (globals->sgot->output_section->vma
- + globals->sgot->output_offset
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ cur_off);
outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_TPOFF32);
if (globals->use_rel)
bfd_put_32 (output_bfd, outrel.r_addend,
- globals->sgot->contents + cur_off);
+ sgot->contents + cur_off);
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- globals->srelgot->reloc_count++;
+ srelgot->reloc_count++;
loc += RELOC_SIZE (globals);
}
else
bfd_put_32 (output_bfd, tpoff (info, value),
- globals->sgot->contents + cur_off);
+ sgot->contents + cur_off);
cur_off += 4;
}
@@ -8188,7 +8160,7 @@ elf32_arm_final_link_relocate (reloc_how
if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
off += 8;
- value = globals->sgot->output_section->vma + globals->sgot->output_offset + off
+ value = sgot->output_section->vma + sgot->output_offset + off
- (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
return _bfd_final_link_relocate (howto, input_bfd, input_section,
@@ -10879,7 +10851,7 @@ elf32_arm_check_relocs (bfd *abfd, struc
case R_ARM_GOTOFF32:
case R_ARM_GOTPC:
- if (htab->sgot == NULL)
+ if (htab->root.sgot == NULL)
{
if (htab->root.dynobj == NULL)
htab->root.dynobj = abfd;
@@ -11436,7 +11408,7 @@ allocate_dynrelocs (struct elf_link_hash
if (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{
- asection *s = htab->splt;
+ asection *s = htab->root.splt;
/* If this is the first .plt entry, make room for the special
first entry. */
@@ -11482,12 +11454,12 @@ allocate_dynrelocs (struct elf_link_hash
{
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- eh->plt_got_offset = htab->sgotplt->size;
- htab->sgotplt->size += 4;
+ eh->plt_got_offset = htab->root.sgotplt->size;
+ htab->root.sgotplt->size += 4;
}
/* We also need to make an entry in the .rel(a).plt section. */
- htab->srelplt->size += RELOC_SIZE (htab);
+ htab->root.srelplt->size += RELOC_SIZE (htab);
/* VxWorks executables have a second set of relocations for
each PLT entry. They go in a separate relocation section,
@@ -11535,7 +11507,7 @@ allocate_dynrelocs (struct elf_link_hash
if (!htab->symbian_p)
{
- s = htab->sgot;
+ s = htab->root.sgot;
h->got.offset = s->size;
if (tls_type == GOT_UNKNOWN)
@@ -11568,19 +11540,19 @@ allocate_dynrelocs (struct elf_link_hash
|| h->root.type != bfd_link_hash_undefweak))
{
if (tls_type & GOT_TLS_IE)
- htab->srelgot->size += RELOC_SIZE (htab);
+ htab->root.srelgot->size += RELOC_SIZE (htab);
if (tls_type & GOT_TLS_GD)
- htab->srelgot->size += RELOC_SIZE (htab);
+ htab->root.srelgot->size += RELOC_SIZE (htab);
if ((tls_type & GOT_TLS_GD) && indx != 0)
- htab->srelgot->size += RELOC_SIZE (htab);
+ htab->root.srelgot->size += RELOC_SIZE (htab);
}
else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
&& (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
- htab->srelgot->size += RELOC_SIZE (htab);
+ htab->root.srelgot->size += RELOC_SIZE (htab);
}
}
else
@@ -11864,8 +11836,8 @@ elf32_arm_size_dynamic_sections (bfd * o
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
local_tls_type = elf32_arm_local_got_tls_type (ibfd);
- s = htab->sgot;
- srel = htab->srelgot;
+ s = htab->root.sgot;
+ srel = htab->root.srelgot;
for (; local_got < end_local_got; ++local_got, ++local_tls_type)
{
if (*local_got > 0)
@@ -11891,10 +11863,10 @@ elf32_arm_size_dynamic_sections (bfd * o
{
/* Allocate two GOT entries and one dynamic relocation (if necessary)
for R_ARM_TLS_LDM32 relocations. */
- htab->tls_ldm_got.offset = htab->sgot->size;
- htab->sgot->size += 8;
+ htab->tls_ldm_got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += 8;
if (info->shared)
- htab->srelgot->size += RELOC_SIZE (htab);
+ htab->root.srelgot->size += RELOC_SIZE (htab);
}
else
htab->tls_ldm_got.offset = -1;
@@ -11949,7 +11921,7 @@ elf32_arm_size_dynamic_sections (bfd * o
{
/* Remember whether there are any reloc sections other
than .rel(a).plt and .rela.plt.unloaded. */
- if (s != htab->srelplt && s != htab->srelplt2)
+ if (s != htab->root.srelplt && s != htab->srelplt2)
relocs = TRUE;
/* We use the reloc_count field as a counter if we need
@@ -12061,11 +12033,9 @@ elf32_arm_finish_dynamic_symbol (bfd * o
struct elf_link_hash_entry * h,
Elf_Internal_Sym * sym)
{
- bfd * dynobj;
struct elf32_arm_link_hash_table *htab;
struct elf32_arm_link_hash_entry *eh;
- dynobj = elf_hash_table (info)->dynobj;
htab = elf32_arm_hash_table (info);
if (htab == NULL)
return FALSE;
@@ -12085,8 +12055,8 @@ elf32_arm_finish_dynamic_symbol (bfd * o
BFD_ASSERT (h->dynindx != -1);
- splt = bfd_get_section_by_name (dynobj, ".plt");
- srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (htab, ".plt"));
+ splt = htab->root.splt;
+ srel = htab->root.srelplt;
BFD_ASSERT (splt != NULL && srel != NULL);
/* Fill in the entry in the procedure linkage table. */
@@ -12119,7 +12089,7 @@ elf32_arm_finish_dynamic_symbol (bfd * o
asection * sgot;
bfd_byte * ptr;
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgot = htab->root.sgotplt;
BFD_ASSERT (sgot != NULL);
/* Get the offset into the .got.plt table of the entry that
@@ -12143,7 +12113,7 @@ elf32_arm_finish_dynamic_symbol (bfd * o
+ splt->output_offset
+ h->plt.offset);
- ptr = htab->splt->contents + h->plt.offset;
+ ptr = splt->contents + h->plt.offset;
if (htab->vxworks_p && info->shared)
{
unsigned int i;
@@ -12281,8 +12251,8 @@ elf32_arm_finish_dynamic_symbol (bfd * o
/* This symbol has an entry in the global offset table. Set it
up. */
- sgot = bfd_get_section_by_name (dynobj, ".got");
- srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (htab, ".got"));
+ sgot = htab->root.sgot;
+ srel = htab->root.srelgot;
BFD_ASSERT (sgot != NULL && srel != NULL);
offset = (h->got.offset & ~(bfd_vma) 1);
@@ -12329,8 +12299,7 @@ elf32_arm_finish_dynamic_symbol (bfd * o
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak));
- s = bfd_get_section_by_name (h->root.u.def.section->owner,
- RELOC_SECTION (htab, ".bss"));
+ s = htab->srelbss;
BFD_ASSERT (s != NULL);
rel.r_addend = 0;
@@ -12368,7 +12337,7 @@ elf32_arm_finish_dynamic_sections (bfd *
dynobj = elf_hash_table (info)->dynobj;
- sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ sgot = htab->root.sgotplt;
BFD_ASSERT (htab->symbian_p || sgot != NULL);
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
@@ -12377,7 +12346,7 @@ elf32_arm_finish_dynamic_sections (bfd *
asection *splt;
Elf32_External_Dyn *dyncon, *dynconend;
- splt = bfd_get_section_by_name (dynobj, ".plt");
+ splt = htab->root.splt;
BFD_ASSERT (splt != NULL && sdyn != NULL);
dyncon = (Elf32_External_Dyn *) sdyn->contents;
@@ -12444,8 +12413,7 @@ elf32_arm_finish_dynamic_sections (bfd *
break;
case DT_PLTRELSZ:
- s = bfd_get_section_by_name (output_bfd,
- RELOC_SECTION (htab, ".plt"));
+ s = htab->root.srelplt;
BFD_ASSERT (s != NULL);
dyn.d_un.d_val = s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
@@ -12464,8 +12432,7 @@ elf32_arm_finish_dynamic_sections (bfd *
the linker script arranges for .rel(a).plt to follow all
other relocation sections, we don't have to worry
about changing the DT_REL entry. */
- s = bfd_get_section_by_name (output_bfd,
- RELOC_SECTION (htab, ".plt"));
+ s = htab->root.srelplt;
if (s != NULL)
dyn.d_un.d_val -= s->size;
bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
@@ -12596,14 +12563,14 @@ elf32_arm_finish_dynamic_sections (bfd *
if (splt->output_section->owner == output_bfd)
elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
- if (htab->vxworks_p && !info->shared && htab->splt->size > 0)
+ if (htab->vxworks_p && !info->shared && htab->root.splt->size > 0)
{
/* Correct the .rel(a).plt.unloaded relocations. They will have
incorrect symbol indexes. */
int num_plts;
unsigned char *p;
- num_plts = ((htab->splt->size - htab->plt_header_size)
+ num_plts = ((htab->root.splt->size - htab->plt_header_size)
/ htab->plt_entry_size);
p = htab->srelplt2->contents + RELOC_SIZE (htab);
@@ -13141,12 +13108,12 @@ elf32_arm_output_arch_local_syms (bfd *o
}
/* Finally, output mapping symbols for the PLT. */
- if (!htab->splt || htab->splt->size == 0)
+ if (!htab->root.splt || htab->root.splt->size == 0)
return TRUE;
+ osi.sec = htab->root.splt;
osi.sec_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
- htab->splt->output_section);
- osi.sec = htab->splt;
+ osi.sec->output_section);
/* Output mapping symbols for the plt header. SymbianOS does not have a
plt header. */
if (htab->vxworks_p)