dyn_relocs tidy

Many targets define their own dyn_relocs struct when they could use
struct elf_dyn_relocs.  This patch tidies that, and uses
readonly_dynrelocs in a few more places.

The SH adjust_dynamic_symbol had some really weird code dating back to
2002 that looked over dynamic relocations for any in SEC_HAS_CONTENTS
or SEC_READONLY sections, rather than just the usual SEC_READONLY
sections.  So basically any dynamic relocation.  What's more, the SH
relocate_section has no support for emitting dynamic relocations in
non-PIC.  In other words, SH has no support for avoiding copy relocs
in non-PIC.  I've made that more obvious by using "if (0 && ..)" in
asjust_dynamic_symbol.

Unfortunately, LM32, M32R, NDS32, and OR1K copied the bogus SH
adjust_dynamic_symbol code.  So none of those targets would have
avoided copy relocs.  LM32, M32R, NDS32 get the "if (0)" treatment
too.  (LM32 is even more broken in that non_got_ref is never set.)

OR1K relocate_section looks like it might support dynamic relocs in
non-PIC, so I've enabled the copy reloc avoidance code for that
target.

	* elf32-hppa.c (struct elf32_hppa_dyn_reloc_entry): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(elf32_hppa_adjust_dynamic_symbol): Comment tidy.
	* elf32-lm32.c (struct elf_lm32_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(lm32_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
	Disable -z no-copyreloc too.
	* elf32-m32r.c (struct elf_m32r_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(m32r_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
	Disable -z no-copyreloc too.
	* elf32-metag.c (struct elf_metag_dyn_reloc_entry): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(elf_metag_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elf32-microblaze.c (struct elf32_mb_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(readonly_dynrelocs): New function.
	(microblaze_elf_adjust_dynamic_symbol): Use it.
	* elf32-nds32.c (struct elf_nds32_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(nds32_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
	Disable -z no-copyreloc too.
	* elf32-nios2.c (struct elf32_nios2_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	* elf32-or1k.c (struct elf_or1k_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(or1k_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elf32-sh.c (struct elf_sh_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(sh_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
	Disable -z no-copyreloc too.
	* elf32-tilepro.c (struct tilepro_elf_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(tilepro_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elfnn-riscv.c (struct riscv_elf_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(riscv_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elfxx-sparc.c (struct _bfd_sparc_elf_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(_bfd_sparc_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elfxx-tilegx.c (struct tilegx_elf_dyn_relocs): Delete.  Use
	struct elf_dyn_relocs throughout file instead.
	(tilegx_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Use readonly_dynrelocs.
	* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Use readonly_dynrelocs.
This commit is contained in:
Alan Modra 2017-12-05 10:03:03 +10:30
parent dce2246a6c
commit 3bf083ed23
16 changed files with 295 additions and 627 deletions

View file

@ -1,3 +1,50 @@
2017-12-06 Alan Modra <amodra@gmail.com>
* elf32-hppa.c (struct elf32_hppa_dyn_reloc_entry): Delete. Use
struct elf_dyn_relocs throughout file instead.
(elf32_hppa_adjust_dynamic_symbol): Comment tidy.
* elf32-lm32.c (struct elf_lm32_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(lm32_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elf32-m32r.c (struct elf_m32r_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(m32r_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
Disable -z no-copyreloc too.
* elf32-metag.c (struct elf_metag_dyn_reloc_entry): Delete. Use
struct elf_dyn_relocs throughout file instead.
(elf_metag_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elf32-microblaze.c (struct elf32_mb_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(readonly_dynrelocs): New function.
(microblaze_elf_adjust_dynamic_symbol): Use it.
* elf32-nds32.c (struct elf_nds32_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(nds32_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
Disable -z no-copyreloc too.
* elf32-nios2.c (struct elf32_nios2_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
* elf32-or1k.c (struct elf_or1k_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(or1k_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elf32-sh.c (struct elf_sh_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(sh_elf_adjust_dynamic_symbol): Use readonly_dynrelocs, but disable.
Disable -z no-copyreloc too.
* elf32-tilepro.c (struct tilepro_elf_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(tilepro_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elfnn-riscv.c (struct riscv_elf_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(riscv_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elfxx-sparc.c (struct _bfd_sparc_elf_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(_bfd_sparc_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elfxx-tilegx.c (struct tilegx_elf_dyn_relocs): Delete. Use
struct elf_dyn_relocs throughout file instead.
(tilegx_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elf32-s390.c (elf_s390_adjust_dynamic_symbol): Use readonly_dynrelocs.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol): Use readonly_dynrelocs.
2017-12-06 Alan Modra <amodra@gmail.com> 2017-12-06 Alan Modra <amodra@gmail.com>
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Comment tidy. * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Comment tidy.

View file

@ -132,8 +132,6 @@
bfd_hash_table containing stubs "bstab" bfd_hash_table containing stubs "bstab"
elf32_hppa_stub_hash_entry "hsh" elf32_hppa_stub_hash_entry "hsh"
elf32_hppa_dyn_reloc_entry "hdh"
Always remember to use GNU Coding Style. */ Always remember to use GNU Coding Style. */
#define PLT_ENTRY_SIZE 8 #define PLT_ENTRY_SIZE 8
@ -226,22 +224,7 @@ struct elf32_hppa_link_hash_entry
/* Used to count relocations for delayed sizing of relocation /* Used to count relocations for delayed sizing of relocation
sections. */ sections. */
struct elf32_hppa_dyn_reloc_entry struct elf_dyn_relocs *dyn_relocs;
{
/* Next relocation in the chain. */
struct elf32_hppa_dyn_reloc_entry *hdh_next;
/* The input section of the reloc. */
asection *sec;
/* Number of relocs copied in this section. */
bfd_size_type count;
#if RELATIVE_DYNRELOCS
/* Number of relative relocs copied for the input section. */
bfd_size_type relative_count;
#endif
} *dyn_relocs;
ENUM_BITFIELD (_tls_type) tls_type : 8; ENUM_BITFIELD (_tls_type) tls_type : 8;
@ -1026,29 +1009,29 @@ elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (hh_dir->dyn_relocs != NULL) if (hh_dir->dyn_relocs != NULL)
{ {
struct elf32_hppa_dyn_reloc_entry **hdh_pp; struct elf_dyn_relocs **hdh_pp;
struct elf32_hppa_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
{ {
struct elf32_hppa_dyn_reloc_entry *hdh_q; struct elf_dyn_relocs *hdh_q;
for (hdh_q = hh_dir->dyn_relocs; for (hdh_q = hh_dir->dyn_relocs;
hdh_q != NULL; hdh_q != NULL;
hdh_q = hdh_q->hdh_next) hdh_q = hdh_q->next)
if (hdh_q->sec == hdh_p->sec) if (hdh_q->sec == hdh_p->sec)
{ {
#if RELATIVE_DYNRELOCS #if RELATIVE_DYNRELOCS
hdh_q->relative_count += hdh_p->relative_count; hdh_q->pc_count += hdh_p->pc_count;
#endif #endif
hdh_q->count += hdh_p->count; hdh_q->count += hdh_p->count;
*hdh_pp = hdh_p->hdh_next; *hdh_pp = hdh_p->next;
break; break;
} }
if (hdh_q == NULL) if (hdh_q == NULL)
hdh_pp = &hdh_p->hdh_next; hdh_pp = &hdh_p->next;
} }
*hdh_pp = hh_dir->dyn_relocs; *hdh_pp = hh_dir->dyn_relocs;
} }
@ -1451,8 +1434,8 @@ elf32_hppa_check_relocs (bfd *abfd,
&& (hh->eh.root.type == bfd_link_hash_defweak && (hh->eh.root.type == bfd_link_hash_defweak
|| !hh->eh.def_regular))) || !hh->eh.def_regular)))
{ {
struct elf32_hppa_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
struct elf32_hppa_dyn_reloc_entry **hdh_head; struct elf_dyn_relocs **hdh_head;
/* Create a reloc section in dynobj and make room for /* Create a reloc section in dynobj and make room for
this reloc. */ this reloc. */
@ -1493,7 +1476,7 @@ elf32_hppa_check_relocs (bfd *abfd,
sr = sec; sr = sec;
vpp = &elf_section_data (sr)->local_dynrel; vpp = &elf_section_data (sr)->local_dynrel;
hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp; hdh_head = (struct elf_dyn_relocs **) vpp;
} }
hdh_p = *hdh_head; hdh_p = *hdh_head;
@ -1502,19 +1485,19 @@ elf32_hppa_check_relocs (bfd *abfd,
hdh_p = bfd_alloc (htab->etab.dynobj, sizeof *hdh_p); hdh_p = bfd_alloc (htab->etab.dynobj, sizeof *hdh_p);
if (hdh_p == NULL) if (hdh_p == NULL)
return FALSE; return FALSE;
hdh_p->hdh_next = *hdh_head; hdh_p->next = *hdh_head;
*hdh_head = hdh_p; *hdh_head = hdh_p;
hdh_p->sec = sec; hdh_p->sec = sec;
hdh_p->count = 0; hdh_p->count = 0;
#if RELATIVE_DYNRELOCS #if RELATIVE_DYNRELOCS
hdh_p->relative_count = 0; hdh_p->pc_count = 0;
#endif #endif
} }
hdh_p->count += 1; hdh_p->count += 1;
#if RELATIVE_DYNRELOCS #if RELATIVE_DYNRELOCS
if (!IS_ABSOLUTE_RELOC (rtype)) if (!IS_ABSOLUTE_RELOC (rtype))
hdh_p->relative_count += 1; hdh_p->pc_count += 1;
#endif #endif
} }
} }
@ -1643,10 +1626,10 @@ static asection *
readonly_dynrelocs (struct elf_link_hash_entry *eh) readonly_dynrelocs (struct elf_link_hash_entry *eh)
{ {
struct elf32_hppa_link_hash_entry *hh; struct elf32_hppa_link_hash_entry *hh;
struct elf32_hppa_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
hh = hppa_elf_hash_entry (eh); hh = hppa_elf_hash_entry (eh);
for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next)
{ {
asection *sec = hdh_p->sec->output_section; asection *sec = hdh_p->sec->output_section;
@ -1770,13 +1753,11 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
if (info->nocopyreloc) if (info->nocopyreloc)
return TRUE; return TRUE;
/* If we don't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (ELIMINATE_COPY_RELOCS if (ELIMINATE_COPY_RELOCS
&& !alias_readonly_dynrelocs (eh)) && !alias_readonly_dynrelocs (eh))
{ return TRUE;
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
return TRUE;
}
/* We must allocate the symbol in our .dynbss section, which will /* We must allocate the symbol in our .dynbss section, which will
become part of the .bss section of the executable. There will be become part of the .bss section of the executable. There will be
@ -1935,7 +1916,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
struct elf32_hppa_link_hash_table *htab; struct elf32_hppa_link_hash_table *htab;
asection *sec; asection *sec;
struct elf32_hppa_link_hash_entry *hh; struct elf32_hppa_link_hash_entry *hh;
struct elf32_hppa_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
if (eh->root.type == bfd_link_hash_indirect) if (eh->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2011,16 +1992,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
#if RELATIVE_DYNRELOCS #if RELATIVE_DYNRELOCS
if (SYMBOL_CALLS_LOCAL (info, eh)) if (SYMBOL_CALLS_LOCAL (info, eh))
{ {
struct elf32_hppa_dyn_reloc_entry **hdh_pp; struct elf_dyn_relocs **hdh_pp;
for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
{ {
hdh_p->count -= hdh_p->relative_count; hdh_p->count -= hdh_p->pc_count;
hdh_p->relative_count = 0; hdh_p->pc_count = 0;
if (hdh_p->count == 0) if (hdh_p->count == 0)
*hdh_pp = hdh_p->hdh_next; *hdh_pp = hdh_p->next;
else else
hdh_pp = &hdh_p->hdh_next; hdh_pp = &hdh_p->next;
} }
} }
#endif #endif
@ -2052,7 +2033,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
} }
/* Finally, allocate space. */ /* Finally, allocate space. */
for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next)
{ {
asection *sreloc = elf_section_data (hdh_p->sec)->sreloc; asection *sreloc = elf_section_data (hdh_p->sec)->sreloc;
sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela); sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela);
@ -2163,12 +2144,12 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (sec = ibfd->sections; sec != NULL; sec = sec->next) for (sec = ibfd->sections; sec != NULL; sec = sec->next)
{ {
struct elf32_hppa_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
for (hdh_p = ((struct elf32_hppa_dyn_reloc_entry *) for (hdh_p = ((struct elf_dyn_relocs *)
elf_section_data (sec)->local_dynrel); elf_section_data (sec)->local_dynrel);
hdh_p != NULL; hdh_p != NULL;
hdh_p = hdh_p->hdh_next) hdh_p = hdh_p->next)
{ {
if (!bfd_is_abs_section (hdh_p->sec) if (!bfd_is_abs_section (hdh_p->sec)
&& bfd_is_abs_section (hdh_p->sec->output_section)) && bfd_is_abs_section (hdh_p->sec->output_section))

View file

@ -50,26 +50,6 @@ extern const bfd_target lm32_elf32_fdpic_vec;
static bfd_reloc_status_type lm32_elf_gprel_reloc static bfd_reloc_status_type lm32_elf_gprel_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
/* The linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf_lm32_dyn_relocs
{
struct elf_lm32_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* lm32 ELF linker hash entry. */ /* lm32 ELF linker hash entry. */
struct elf_lm32_link_hash_entry struct elf_lm32_link_hash_entry
@ -77,7 +57,7 @@ struct elf_lm32_link_hash_entry
struct elf_link_hash_entry root; struct elf_link_hash_entry root;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf_lm32_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
}; };
/* lm32 ELF linker hash table. */ /* lm32 ELF linker hash table. */
@ -1648,7 +1628,7 @@ lm32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct elf_lm32_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_lm32_link_hash_entry *eh = (struct elf_lm32_link_hash_entry *) h; struct elf_lm32_link_hash_entry *eh = (struct elf_lm32_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next) for (p = eh->dyn_relocs; p != NULL; p = p->next)
@ -1672,8 +1652,6 @@ lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct elf_lm32_link_hash_table *htab; struct elf_lm32_link_hash_table *htab;
struct elf_lm32_link_hash_entry *eh;
struct elf_lm32_dyn_relocs *p;
bfd *dynobj; bfd *dynobj;
asection *s; asection *s;
@ -1741,24 +1719,15 @@ lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
/* If -z nocopyreloc was given, we won't generate them either. */ /* If -z nocopyreloc was given, we won't generate them either. */
if (info->nocopyreloc) if (0 && info->nocopyreloc)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
} }
eh = (struct elf_lm32_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next) we'll be keeping the dynamic relocs and avoiding the copy reloc. */
{ if (0 && !readonly_dynrelocs (h))
s = p->sec->output_section;
if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
break;
}
/* If we didn't find any dynamic relocs in sections which needs the
copy reloc, then we'll be keeping the dynamic relocs and avoiding
the copy reloc. */
if (p == NULL)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -1807,7 +1776,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_lm32_link_hash_table *htab; struct elf_lm32_link_hash_table *htab;
struct elf_lm32_link_hash_entry *eh; struct elf_lm32_link_hash_entry *eh;
struct elf_lm32_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -1916,7 +1885,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
&& (h->forced_local && (h->forced_local
|| info->symbolic)) || info->symbolic))
{ {
struct elf_lm32_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
{ {
@ -2063,9 +2032,9 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf_lm32_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = ((struct elf_lm32_dyn_relocs *) for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
p != NULL; p != NULL;
p = p->next) p = p->next)
@ -2483,14 +2452,14 @@ lm32_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf_lm32_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf_lm32_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
{ {
struct elf_lm32_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)

View file

@ -1485,27 +1485,6 @@ struct elf_m32r_pcrel_relocs_copied
bfd_size_type count; bfd_size_type count;
}; };
/* The sh linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf_m32r_dyn_relocs
{
struct elf_m32r_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* m32r ELF linker hash entry. */ /* m32r ELF linker hash entry. */
struct elf_m32r_link_hash_entry struct elf_m32r_link_hash_entry
@ -1513,7 +1492,7 @@ struct elf_m32r_link_hash_entry
struct elf_link_hash_entry root; struct elf_link_hash_entry root;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf_m32r_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
}; };
/* m32r ELF linker hash table. */ /* m32r ELF linker hash table. */
@ -1726,14 +1705,14 @@ m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf_m32r_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf_m32r_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
{ {
struct elf_m32r_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -1762,7 +1741,7 @@ m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct elf_m32r_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_m32r_link_hash_entry *eh = (struct elf_m32r_link_hash_entry *) h; struct elf_m32r_link_hash_entry *eh = (struct elf_m32r_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next) for (p = eh->dyn_relocs; p != NULL; p = p->next)
@ -1786,8 +1765,6 @@ m32r_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct elf_m32r_link_hash_table *htab; struct elf_m32r_link_hash_table *htab;
struct elf_m32r_link_hash_entry *eh;
struct elf_m32r_dyn_relocs *p;
bfd *dynobj; bfd *dynobj;
asection *s; asection *s;
@ -1859,24 +1836,15 @@ m32r_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
/* If -z nocopyreloc was given, we won't generate them either. */ /* If -z nocopyreloc was given, we won't generate them either. */
if (info->nocopyreloc) if (0 && info->nocopyreloc)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
} }
eh = (struct elf_m32r_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next) we'll be keeping the dynamic relocs and avoiding the copy reloc. */
{ if (0 && !readonly_dynrelocs (h))
s = p->sec->output_section;
if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
break;
}
/* If we didn't find any dynamic relocs in sections which needs the
copy reloc, then we'll be keeping the dynamic relocs and avoiding
the copy reloc. */
if (p == NULL)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -1925,7 +1893,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_m32r_link_hash_table *htab; struct elf_m32r_link_hash_table *htab;
struct elf_m32r_link_hash_entry *eh; struct elf_m32r_link_hash_entry *eh;
struct elf_m32r_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2034,7 +2002,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
&& (h->forced_local && (h->forced_local
|| info->symbolic)) || info->symbolic))
{ {
struct elf_m32r_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
{ {
@ -2185,9 +2153,9 @@ m32r_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf_m32r_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = ((struct elf_m32r_dyn_relocs *) for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
p != NULL; p != NULL;
p = p->next) p = p->next)
@ -3739,8 +3707,8 @@ m32r_elf_check_relocs (bfd *abfd,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct elf_m32r_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_m32r_dyn_relocs **head; struct elf_dyn_relocs **head;
if (dynobj == NULL) if (dynobj == NULL)
htab->root.dynobj = dynobj = abfd; htab->root.dynobj = dynobj = abfd;
@ -3778,7 +3746,7 @@ m32r_elf_check_relocs (bfd *abfd,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct elf_m32r_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;

View file

@ -86,8 +86,6 @@ static const unsigned int plt_pic_entry[] =
bfd_hash_table containing stubs "bstab" bfd_hash_table containing stubs "bstab"
elf_metag_stub_hash_entry "hsh" elf_metag_stub_hash_entry "hsh"
elf_metag_dyn_reloc_entry "hdh"
Always remember to use GNU Coding Style. */ Always remember to use GNU Coding Style. */
#define PLT_ENTRY_SIZE sizeof(plt_entry) #define PLT_ENTRY_SIZE sizeof(plt_entry)
@ -789,20 +787,7 @@ struct elf_metag_link_hash_entry
/* Used to count relocations for delayed sizing of relocation /* Used to count relocations for delayed sizing of relocation
sections. */ sections. */
struct elf_metag_dyn_reloc_entry { struct elf_dyn_relocs *dyn_relocs;
/* Next relocation in the chain. */
struct elf_metag_dyn_reloc_entry *hdh_next;
/* The input section of the reloc. */
asection *sec;
/* Number of relocs copied in this section. */
bfd_size_type count;
/* Number of relative relocs copied for the input section. */
bfd_size_type relative_count;
} *dyn_relocs;
enum enum
{ {
@ -2312,8 +2297,8 @@ elf_metag_check_relocs (bfd *abfd,
&& (hh->eh.root.type == bfd_link_hash_defweak && (hh->eh.root.type == bfd_link_hash_defweak
|| !hh->eh.def_regular))) || !hh->eh.def_regular)))
{ {
struct elf_metag_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
struct elf_metag_dyn_reloc_entry **hdh_head; struct elf_dyn_relocs **hdh_head;
if (dynobj == NULL) if (dynobj == NULL)
htab->etab.dynobj = dynobj = abfd; htab->etab.dynobj = dynobj = abfd;
@ -2350,26 +2335,26 @@ elf_metag_check_relocs (bfd *abfd,
sr = sec; sr = sec;
vpp = &elf_section_data (sr)->local_dynrel; vpp = &elf_section_data (sr)->local_dynrel;
hdh_head = (struct elf_metag_dyn_reloc_entry **) vpp; hdh_head = (struct elf_dyn_relocs **) vpp;
} }
hdh_p = *hdh_head; hdh_p = *hdh_head;
if (hdh_p == NULL || hdh_p->sec != sec) if (hdh_p == NULL || hdh_p->sec != sec)
{ {
hdh_p = ((struct elf_metag_dyn_reloc_entry *) hdh_p = ((struct elf_dyn_relocs *)
bfd_alloc (dynobj, sizeof *hdh_p)); bfd_alloc (dynobj, sizeof *hdh_p));
if (hdh_p == NULL) if (hdh_p == NULL)
return FALSE; return FALSE;
hdh_p->hdh_next = *hdh_head; hdh_p->next = *hdh_head;
*hdh_head = hdh_p; *hdh_head = hdh_p;
hdh_p->sec = sec; hdh_p->sec = sec;
hdh_p->count = 0; hdh_p->count = 0;
hdh_p->relative_count = 0; hdh_p->pc_count = 0;
} }
hdh_p->count += 1; hdh_p->count += 1;
if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH) if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH)
hdh_p->relative_count += 1; hdh_p->pc_count += 1;
} }
break; break;
@ -2411,8 +2396,8 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (hh_dir->dyn_relocs != NULL) if (hh_dir->dyn_relocs != NULL)
{ {
struct elf_metag_dyn_reloc_entry **hdh_pp; struct elf_dyn_relocs **hdh_pp;
struct elf_metag_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
if (eh_ind->root.type == bfd_link_hash_indirect) if (eh_ind->root.type == bfd_link_hash_indirect)
abort (); abort ();
@ -2421,19 +2406,19 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
{ {
struct elf_metag_dyn_reloc_entry *hdh_q; struct elf_dyn_relocs *hdh_q;
for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL; for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL;
hdh_q = hdh_q->hdh_next) hdh_q = hdh_q->next)
if (hdh_q->sec == hdh_p->sec) if (hdh_q->sec == hdh_p->sec)
{ {
hdh_q->relative_count += hdh_p->relative_count; hdh_q->pc_count += hdh_p->pc_count;
hdh_q->count += hdh_p->count; hdh_q->count += hdh_p->count;
*hdh_pp = hdh_p->hdh_next; *hdh_pp = hdh_p->next;
break; break;
} }
if (hdh_q == NULL) if (hdh_q == NULL)
hdh_pp = &hdh_p->hdh_next; hdh_pp = &hdh_p->next;
} }
*hdh_pp = hh_dir->dyn_relocs; *hdh_pp = hh_dir->dyn_relocs;
} }
@ -2457,9 +2442,9 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct elf_metag_dyn_reloc_entry *p; struct elf_dyn_relocs *p;
for (p = metag_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->hdh_next) for (p = metag_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
asection *s = p->sec->output_section; asection *s = p->sec->output_section;
@ -2480,8 +2465,6 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *eh) struct elf_link_hash_entry *eh)
{ {
struct elf_metag_link_hash_table *htab; struct elf_metag_link_hash_table *htab;
struct elf_metag_link_hash_entry *hh;
struct elf_metag_dyn_reloc_entry *hdh_p;
asection *s, *srel; asection *s, *srel;
/* 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
@ -2544,17 +2527,9 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
hh = (struct elf_metag_link_hash_entry *) eh; /* If we don't find any dynamic relocs in read-only sections, then
for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
{
s = hdh_p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (hdh_p == NULL) if (!readonly_dynrelocs (eh))
{ {
eh->non_got_ref = 0; eh->non_got_ref = 0;
return TRUE; return TRUE;
@ -2603,7 +2578,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_metag_link_hash_table *htab; struct elf_metag_link_hash_table *htab;
struct elf_metag_link_hash_entry *hh; struct elf_metag_link_hash_entry *hh;
struct elf_metag_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
if (eh->root.type == bfd_link_hash_indirect) if (eh->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2722,16 +2697,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, eh)) if (SYMBOL_CALLS_LOCAL (info, eh))
{ {
struct elf_metag_dyn_reloc_entry **hdh_pp; struct elf_dyn_relocs **hdh_pp;
for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
{ {
hdh_p->count -= hdh_p->relative_count; hdh_p->count -= hdh_p->pc_count;
hdh_p->relative_count = 0; hdh_p->pc_count = 0;
if (hdh_p->count == 0) if (hdh_p->count == 0)
*hdh_pp = hdh_p->hdh_next; *hdh_pp = hdh_p->next;
else else
hdh_pp = &hdh_p->hdh_next; hdh_pp = &hdh_p->next;
} }
} }
@ -2787,7 +2762,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
} }
/* Finally, allocate space. */ /* Finally, allocate space. */
for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next)
{ {
asection *sreloc = elf_section_data (hdh_p->sec)->sreloc; asection *sreloc = elf_section_data (hdh_p->sec)->sreloc;
sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela); sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela);
@ -2869,12 +2844,12 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf_metag_dyn_reloc_entry *hdh_p; struct elf_dyn_relocs *hdh_p;
for (hdh_p = ((struct elf_metag_dyn_reloc_entry *) for (hdh_p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
hdh_p != NULL; hdh_p != NULL;
hdh_p = hdh_p->hdh_next) hdh_p = hdh_p->next)
{ {
if (!bfd_is_abs_section (hdh_p->sec) if (!bfd_is_abs_section (hdh_p->sec)
&& bfd_is_abs_section (hdh_p->sec->output_section)) && bfd_is_abs_section (hdh_p->sec->output_section))

View file

@ -678,26 +678,6 @@ microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
return _bfd_elf_is_local_label_name (abfd, name); return _bfd_elf_is_local_label_name (abfd, name);
} }
/* The microblaze linker (like many others) needs to keep track of
the number of relocs that it decides to copy as dynamic relocs in
check_relocs for each symbol. This is so that it can later discard
them if they are found to be unnecessary. We store the information
in a field extending the regular ELF linker hash table. */
struct elf32_mb_dyn_relocs
{
struct elf32_mb_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* ELF linker hash entry. */ /* ELF linker hash entry. */
struct elf32_mb_link_hash_entry struct elf32_mb_link_hash_entry
@ -705,7 +685,7 @@ struct elf32_mb_link_hash_entry
struct elf_link_hash_entry elf; struct elf_link_hash_entry elf;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf32_mb_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
/* TLS Reference Types for the symbol; Updated by check_relocs */ /* TLS Reference Types for the symbol; Updated by check_relocs */
#define TLS_GD 1 /* GD reloc. */ #define TLS_GD 1 /* GD reloc. */
@ -2429,8 +2409,8 @@ microblaze_elf_check_relocs (bfd * abfd,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct elf32_mb_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf32_mb_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
relocs into the output file. We create a reloc relocs into the output file. We create a reloc
@ -2474,14 +2454,14 @@ microblaze_elf_check_relocs (bfd * abfd,
return FALSE; return FALSE;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct elf32_mb_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct elf32_mb_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->elf.dynobj, amt)); bfd_alloc (htab->elf.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -2520,8 +2500,8 @@ microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf32_mb_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf32_mb_dyn_relocs *p; struct elf_dyn_relocs *p;
if (ind->root.type == bfd_link_hash_indirect) if (ind->root.type == bfd_link_hash_indirect)
abort (); abort ();
@ -2530,7 +2510,7 @@ microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct elf32_mb_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -2555,13 +2535,28 @@ microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
_bfd_elf_link_hash_copy_indirect (info, dir, ind); _bfd_elf_link_hash_copy_indirect (info, dir, ind);
} }
/* Find dynamic relocs for H that apply to read-only sections. */
static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h)
{
struct elf_dyn_relocs *p;
for (p = elf32_mb_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{
asection *s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
return p->sec;
}
return NULL;
}
static bfd_boolean static bfd_boolean
microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info, microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct elf32_mb_link_hash_table *htab; struct elf32_mb_link_hash_table *htab;
struct elf32_mb_link_hash_entry * eh;
struct elf32_mb_dyn_relocs *p;
asection *s, *srel; asection *s, *srel;
unsigned int power_of_two; unsigned int power_of_two;
@ -2633,17 +2628,9 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
eh = (struct elf32_mb_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL) if (!readonly_dynrelocs (h))
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -2710,7 +2697,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf32_mb_link_hash_table *htab; struct elf32_mb_link_hash_table *htab;
struct elf32_mb_link_hash_entry *eh; struct elf32_mb_link_hash_entry *eh;
struct elf32_mb_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2843,7 +2830,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
&& (h->forced_local && (h->forced_local
|| info->symbolic)) || info->symbolic))
{ {
struct elf32_mb_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -2935,9 +2922,9 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf32_mb_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = ((struct elf32_mb_dyn_relocs *) for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
p != NULL; p != NULL;
p = p->next) p = p->next)

View file

@ -192,26 +192,6 @@ struct elf_nds32_pcrel_relocs_copied
bfd_size_type count; bfd_size_type count;
}; };
/* The sh linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf_nds32_dyn_relocs
{
struct elf_nds32_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* Nds32 ELF linker hash entry. */ /* Nds32 ELF linker hash entry. */
struct elf_nds32_link_hash_entry struct elf_nds32_link_hash_entry
@ -219,7 +199,7 @@ struct elf_nds32_link_hash_entry
struct elf_link_hash_entry root; struct elf_link_hash_entry root;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf_nds32_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
/* For checking relocation type. */ /* For checking relocation type. */
#define GOT_UNKNOWN 0 #define GOT_UNKNOWN 0
@ -3473,8 +3453,8 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf_nds32_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf_nds32_dyn_relocs *p; struct elf_dyn_relocs *p;
if (ind->root.type == bfd_link_hash_indirect) if (ind->root.type == bfd_link_hash_indirect)
abort (); abort ();
@ -3483,7 +3463,7 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
{ {
struct elf_nds32_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -3511,7 +3491,7 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct elf_nds32_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
@ -3534,8 +3514,6 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct elf_nds32_link_hash_table *htab; struct elf_nds32_link_hash_table *htab;
struct elf_nds32_link_hash_entry *eh;
struct elf_nds32_dyn_relocs *p;
bfd *dynobj; bfd *dynobj;
asection *s; asection *s;
unsigned int power_of_two; unsigned int power_of_two;
@ -3602,24 +3580,15 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
/* If -z nocopyreloc was given, we won't generate them either. */ /* If -z nocopyreloc was given, we won't generate them either. */
if (info->nocopyreloc) if (0 && info->nocopyreloc)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
} }
eh = (struct elf_nds32_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next) we'll be keeping the dynamic relocs and avoiding the copy reloc. */
{ if (0 && !readonly_dynrelocs (h))
s = p->sec->output_section;
if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
break;
}
/* If we didn't find any dynamic relocs in sections which needs the
copy reloc, then we'll be keeping the dynamic relocs and avoiding
the copy reloc. */
if (p == NULL)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -3686,7 +3655,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_nds32_link_hash_table *htab; struct elf_nds32_link_hash_table *htab;
struct elf_nds32_link_hash_entry *eh; struct elf_nds32_link_hash_entry *eh;
struct elf_nds32_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -3800,7 +3769,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{ {
if (h->def_regular && (h->forced_local || info->symbolic)) if (h->def_regular && (h->forced_local || info->symbolic))
{ {
struct elf_nds32_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
{ {
@ -3924,9 +3893,9 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf_nds32_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = ((struct elf_nds32_dyn_relocs *) for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
p != NULL; p = p->next) p != NULL; p = p->next)
{ {
@ -6352,8 +6321,8 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct elf_nds32_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_nds32_dyn_relocs **head; struct elf_dyn_relocs **head;
if (dynobj == NULL) if (dynobj == NULL)
htab->root.dynobj = dynobj = abfd; htab->root.dynobj = dynobj = abfd;
@ -6415,14 +6384,14 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return FALSE; return FALSE;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct elf_nds32_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof (*p); bfd_size_type amt = sizeof (*p);
p = (struct elf_nds32_dyn_relocs *) bfd_alloc (dynobj, amt); p = (struct elf_dyn_relocs *) bfd_alloc (dynobj, amt);
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
p->next = *head; p->next = *head;

View file

@ -1726,26 +1726,6 @@ struct elf32_nios2_stub_hash_entry
bfd_hash_lookup ((table), (string), (create), (copy))) bfd_hash_lookup ((table), (string), (create), (copy)))
/* The Nios II linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf32_nios2_dyn_relocs
{
struct elf32_nios2_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* Nios II ELF linker hash entry. */ /* Nios II ELF linker hash entry. */
struct elf32_nios2_link_hash_entry struct elf32_nios2_link_hash_entry
@ -1757,7 +1737,7 @@ struct elf32_nios2_link_hash_entry
struct elf32_nios2_stub_hash_entry *hsh_cache; struct elf32_nios2_stub_hash_entry *hsh_cache;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf32_nios2_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
#define GOT_UNKNOWN 0 #define GOT_UNKNOWN 0
#define GOT_NORMAL 1 #define GOT_NORMAL 1
@ -4633,14 +4613,14 @@ nios2_elf32_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf32_nios2_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf32_nios2_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct elf32_nios2_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -4894,8 +4874,8 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
|| (h != NULL && ! h->needs_plt || (h != NULL && ! h->needs_plt
&& (! SYMBOLIC_BIND (info, h) || ! h->def_regular)))) && (! SYMBOLIC_BIND (info, h) || ! h->def_regular))))
{ {
struct elf32_nios2_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf32_nios2_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
reloc types into the output file. We create a reloc reloc types into the output file. We create a reloc
@ -4935,14 +4915,14 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct elf32_nios2_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct elf32_nios2_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->root.dynobj, amt)); bfd_alloc (htab->root.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -5477,7 +5457,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf32_nios2_link_hash_table *htab; struct elf32_nios2_link_hash_table *htab;
struct elf32_nios2_link_hash_entry *eh; struct elf32_nios2_link_hash_entry *eh;
struct elf32_nios2_dyn_relocs *p; struct elf_dyn_relocs *p;
int use_plt; int use_plt;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
@ -5633,7 +5613,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
if (h->def_regular if (h->def_regular
&& (h->forced_local || SYMBOLIC_BIND (info, h))) && (h->forced_local || SYMBOLIC_BIND (info, h)))
{ {
struct elf32_nios2_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -5759,7 +5739,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf32_nios2_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
{ {

View file

@ -556,26 +556,6 @@ static const struct or1k_reloc_map or1k_reloc_map[] =
{ BFD_RELOC_OR1K_TLS_LE_LO16, R_OR1K_TLS_LE_LO16 }, { BFD_RELOC_OR1K_TLS_LE_LO16, R_OR1K_TLS_LE_LO16 },
}; };
/* The linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf_or1k_dyn_relocs
{
struct elf_or1k_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
#define TLS_UNKNOWN 0 #define TLS_UNKNOWN 0
#define TLS_NONE 1 #define TLS_NONE 1
#define TLS_GD 2 #define TLS_GD 2
@ -589,7 +569,7 @@ struct elf_or1k_link_hash_entry
struct elf_link_hash_entry root; struct elf_link_hash_entry root;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf_or1k_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
/* Track type of TLS access. */ /* Track type of TLS access. */
unsigned char tls_type; unsigned char tls_type;
@ -1515,8 +1495,8 @@ or1k_elf_check_relocs (bfd *abfd,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct elf_or1k_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_or1k_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
relocs into the output file. We create a reloc relocs into the output file. We create a reloc
@ -1581,14 +1561,14 @@ or1k_elf_check_relocs (bfd *abfd,
return FALSE; return FALSE;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct elf_or1k_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct elf_or1k_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->root.dynobj, amt)); bfd_alloc (htab->root.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -1926,7 +1906,7 @@ or1k_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct elf_or1k_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_or1k_link_hash_entry *eh = (struct elf_or1k_link_hash_entry *) h; struct elf_or1k_link_hash_entry *eh = (struct elf_or1k_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next) for (p = eh->dyn_relocs; p != NULL; p = p->next)
@ -1950,8 +1930,6 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct elf_or1k_link_hash_table *htab; struct elf_or1k_link_hash_table *htab;
struct elf_or1k_link_hash_entry *eh;
struct elf_or1k_dyn_relocs *p;
bfd *dynobj; bfd *dynobj;
asection *s, *srel; asection *s, *srel;
@ -2025,18 +2003,9 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
eh = (struct elf_or1k_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next) we'll be keeping the dynamic relocs and avoiding the copy reloc. */
{ if (!readonly_dynrelocs (h))
s = p->sec->output_section;
if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
break;
}
/* If we didn't find any dynamic relocs in sections which needs the
copy reloc, then we'll be keeping the dynamic relocs and avoiding
the copy reloc. */
if (p == NULL)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -2088,7 +2057,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_or1k_link_hash_table *htab; struct elf_or1k_link_hash_table *htab;
struct elf_or1k_link_hash_entry *eh; struct elf_or1k_link_hash_entry *eh;
struct elf_or1k_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2208,7 +2177,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, h)) if (SYMBOL_CALLS_LOCAL (info, h))
{ {
struct elf_or1k_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
{ {
@ -2356,9 +2325,9 @@ or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf_or1k_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = ((struct elf_or1k_dyn_relocs *) for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
p != NULL; p != NULL;
p = p->next) p = p->next)
@ -2549,14 +2518,14 @@ or1k_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf_or1k_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf_or1k_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
{ {
struct elf_or1k_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)

View file

@ -1560,26 +1560,12 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
if (ELIMINATE_COPY_RELOCS) /* If we don't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
{ {
struct elf_s390_link_hash_entry * eh; h->non_got_ref = 0;
struct elf_dyn_relocs *p; return TRUE;
eh = (struct elf_s390_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL)
{
h->non_got_ref = 0;
return TRUE;
}
} }
/* We must allocate the symbol in our .dynbss section, which will /* We must allocate the symbol in our .dynbss section, which will

View file

@ -2367,26 +2367,6 @@ get_plt_offset (const struct elf_sh_plt_info *info, bfd_vma plt_index)
+ (plt_index * info->symbol_entry_size)); + (plt_index * info->symbol_entry_size));
} }
/* The sh linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct elf_sh_dyn_relocs
{
struct elf_sh_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
union gotref union gotref
{ {
bfd_signed_vma refcount; bfd_signed_vma refcount;
@ -2408,7 +2388,7 @@ struct elf_sh_link_hash_entry
#endif #endif
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct elf_sh_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
bfd_signed_vma gotplt_refcount; bfd_signed_vma gotplt_refcount;
@ -2800,7 +2780,7 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct elf_sh_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = sh_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) for (p = sh_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
@ -2823,8 +2803,6 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct elf_sh_link_hash_table *htab; struct elf_sh_link_hash_table *htab;
struct elf_sh_link_hash_entry *eh;
struct elf_sh_dyn_relocs *p;
asection *s; asection *s;
htab = sh_elf_hash_table (info); htab = sh_elf_hash_table (info);
@ -2894,24 +2872,15 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
/* If -z nocopyreloc was given, we won't generate them either. */ /* If -z nocopyreloc was given, we won't generate them either. */
if (info->nocopyreloc) if (0 && info->nocopyreloc)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
} }
eh = (struct elf_sh_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next) we'll be keeping the dynamic relocs and avoiding the copy reloc. */
{ if (0 && !readonly_dynrelocs (h))
s = p->sec->output_section;
if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
break;
}
/* If we didn't find any dynamic relocs in sections which needs the
copy reloc, then we'll be keeping the dynamic relocs and avoiding
the copy reloc. */
if (p == NULL)
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -2956,7 +2925,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct elf_sh_link_hash_table *htab; struct elf_sh_link_hash_table *htab;
struct elf_sh_link_hash_entry *eh; struct elf_sh_link_hash_entry *eh;
struct elf_sh_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -3207,7 +3176,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, h)) if (SYMBOL_CALLS_LOCAL (info, h))
{ {
struct elf_sh_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -3222,7 +3191,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (htab->vxworks_p) if (htab->vxworks_p)
{ {
struct elf_sh_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -3391,9 +3360,9 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct elf_sh_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = ((struct elf_sh_dyn_relocs *) for (p = ((struct elf_dyn_relocs *)
elf_section_data (s)->local_dynrel); elf_section_data (s)->local_dynrel);
p != NULL; p != NULL;
p = p->next) p = p->next)
@ -5710,14 +5679,14 @@ sh_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct elf_sh_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct elf_sh_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct elf_sh_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -6259,8 +6228,8 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct elf_sh_dyn_relocs *p; struct elf_dyn_relocs *p;
struct elf_sh_dyn_relocs **head; struct elf_dyn_relocs **head;
if (htab->root.dynobj == NULL) if (htab->root.dynobj == NULL)
htab->root.dynobj = abfd; htab->root.dynobj = abfd;
@ -6298,7 +6267,7 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct elf_sh_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;

View file

@ -679,26 +679,6 @@ static const reloc_map tilepro_reloc_map [] =
/* The TILEPro linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct tilepro_elf_dyn_relocs
{
struct tilepro_elf_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* TILEPRO ELF linker hash entry. */ /* TILEPRO ELF linker hash entry. */
struct tilepro_elf_link_hash_entry struct tilepro_elf_link_hash_entry
@ -706,7 +686,7 @@ struct tilepro_elf_link_hash_entry
struct elf_link_hash_entry elf; struct elf_link_hash_entry elf;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct tilepro_elf_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
#define GOT_UNKNOWN 0 #define GOT_UNKNOWN 0
#define GOT_NORMAL 1 #define GOT_NORMAL 1
@ -1313,14 +1293,14 @@ tilepro_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct tilepro_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct tilepro_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct tilepro_elf_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -1755,8 +1735,8 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct tilepro_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
struct tilepro_elf_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
relocs into the output file. We create a reloc relocs into the output file. We create a reloc
@ -1795,14 +1775,14 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct tilepro_elf_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct tilepro_elf_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->elf.dynobj, amt)); bfd_alloc (htab->elf.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -1894,7 +1874,7 @@ tilepro_elf_gc_mark_hook (asection *sec,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct tilepro_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = tilepro_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) for (p = tilepro_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
@ -1917,8 +1897,6 @@ tilepro_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct tilepro_elf_link_hash_table *htab; struct tilepro_elf_link_hash_table *htab;
struct tilepro_elf_link_hash_entry * eh;
struct tilepro_elf_dyn_relocs *p;
asection *s, *srel; asection *s, *srel;
htab = tilepro_elf_hash_table (info); htab = tilepro_elf_hash_table (info);
@ -1991,17 +1969,9 @@ tilepro_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
eh = (struct tilepro_elf_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL) if (!readonly_dynrelocs (h))
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -2049,7 +2019,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct tilepro_elf_link_hash_table *htab; struct tilepro_elf_link_hash_table *htab;
struct tilepro_elf_link_hash_entry *eh; struct tilepro_elf_link_hash_entry *eh;
struct tilepro_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2171,7 +2141,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, h)) if (SYMBOL_CALLS_LOCAL (info, h))
{ {
struct tilepro_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -2338,7 +2308,7 @@ tilepro_elf_size_dynamic_sections (bfd *output_bfd,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct tilepro_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
{ {

View file

@ -1492,26 +1492,12 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
if (ELIMINATE_COPY_RELOCS) /* If we don't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
{ {
struct elf_s390_link_hash_entry * eh; h->non_got_ref = 0;
struct elf_dyn_relocs *p; return TRUE;
eh = (struct elf_s390_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL)
{
h->non_got_ref = 0;
return TRUE;
}
} }
/* We must allocate the symbol in our .dynbss section, which will /* We must allocate the symbol in our .dynbss section, which will

View file

@ -55,26 +55,6 @@
#define ELF_MAXPAGESIZE 0x1000 #define ELF_MAXPAGESIZE 0x1000
#define ELF_COMMONPAGESIZE 0x1000 #define ELF_COMMONPAGESIZE 0x1000
/* The RISC-V linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct riscv_elf_dyn_relocs
{
struct riscv_elf_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* RISC-V ELF linker hash entry. */ /* RISC-V ELF linker hash entry. */
struct riscv_elf_link_hash_entry struct riscv_elf_link_hash_entry
@ -82,7 +62,7 @@ struct riscv_elf_link_hash_entry
struct elf_link_hash_entry elf; struct elf_link_hash_entry elf;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct riscv_elf_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
#define GOT_UNKNOWN 0 #define GOT_UNKNOWN 0
#define GOT_NORMAL 1 #define GOT_NORMAL 1
@ -398,14 +378,14 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct riscv_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct riscv_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct riscv_elf_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -657,8 +637,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct riscv_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
struct riscv_elf_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
relocs into the output file. We create a reloc relocs into the output file. We create a reloc
@ -697,14 +677,14 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct riscv_elf_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct riscv_elf_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->elf.dynobj, amt)); bfd_alloc (htab->elf.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -762,7 +742,7 @@ riscv_elf_gc_mark_hook (asection *sec,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct riscv_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = riscv_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) for (p = riscv_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
@ -786,7 +766,6 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
{ {
struct riscv_elf_link_hash_table *htab; struct riscv_elf_link_hash_table *htab;
struct riscv_elf_link_hash_entry * eh; struct riscv_elf_link_hash_entry * eh;
struct riscv_elf_dyn_relocs *p;
bfd *dynobj; bfd *dynobj;
asection *s, *srel; asection *s, *srel;
@ -861,17 +840,9 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
eh = (struct riscv_elf_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL) if (!readonly_dynrelocs (h))
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -891,6 +862,7 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
to copy the initial value out of the dynamic object and into the to 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. We need to remember the offset into the
.rel.bss section we are going to use. */ .rel.bss section we are going to use. */
eh = (struct riscv_elf_link_hash_entry *) h;
if (eh->tls_type & ~GOT_NORMAL) if (eh->tls_type & ~GOT_NORMAL)
{ {
s = htab->sdyntdata; s = htab->sdyntdata;
@ -924,7 +896,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct riscv_elf_link_hash_table *htab; struct riscv_elf_link_hash_table *htab;
struct riscv_elf_link_hash_entry *eh; struct riscv_elf_link_hash_entry *eh;
struct riscv_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -1045,7 +1017,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, h)) if (SYMBOL_CALLS_LOCAL (info, h))
{ {
struct riscv_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -1187,7 +1159,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct riscv_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
{ {

View file

@ -663,26 +663,6 @@ _bfd_sparc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
#define SPARC_INSN_BYTES 4 #define SPARC_INSN_BYTES 4
/* The SPARC linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct _bfd_sparc_elf_dyn_relocs
{
struct _bfd_sparc_elf_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* Is an undefined weak symbol resolved to 0 ? /* Is an undefined weak symbol resolved to 0 ?
Reference to an undefined weak symbol is resolved to 0 when Reference to an undefined weak symbol is resolved to 0 when
building an executable if it isn't dynamic and building an executable if it isn't dynamic and
@ -704,7 +684,7 @@ struct _bfd_sparc_elf_link_hash_entry
struct elf_link_hash_entry elf; struct elf_link_hash_entry elf;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct _bfd_sparc_elf_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
#define GOT_UNKNOWN 0 #define GOT_UNKNOWN 0
#define GOT_NORMAL 1 #define GOT_NORMAL 1
@ -1303,14 +1283,14 @@ _bfd_sparc_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct _bfd_sparc_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct _bfd_sparc_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct _bfd_sparc_elf_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -1813,8 +1793,8 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& h != NULL && h != NULL
&& h->type == STT_GNU_IFUNC)) && h->type == STT_GNU_IFUNC))
{ {
struct _bfd_sparc_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
struct _bfd_sparc_elf_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
relocs into the output file. We create a reloc relocs into the output file. We create a reloc
@ -1847,14 +1827,14 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct _bfd_sparc_elf_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct _bfd_sparc_elf_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->elf.dynobj, amt)); bfd_alloc (htab->elf.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -1974,7 +1954,7 @@ _bfd_sparc_elf_fixup_symbol (struct bfd_link_info *info,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct _bfd_sparc_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = _bfd_sparc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) for (p = _bfd_sparc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
@ -1997,8 +1977,6 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct _bfd_sparc_elf_link_hash_table *htab; struct _bfd_sparc_elf_link_hash_table *htab;
struct _bfd_sparc_elf_link_hash_entry * eh;
struct _bfd_sparc_elf_dyn_relocs *p;
asection *s, *srel; asection *s, *srel;
htab = _bfd_sparc_elf_hash_table (info); htab = _bfd_sparc_elf_hash_table (info);
@ -2082,17 +2060,9 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
eh = (struct _bfd_sparc_elf_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL) if (!readonly_dynrelocs (h))
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -2140,7 +2110,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct _bfd_sparc_elf_link_hash_table *htab; struct _bfd_sparc_elf_link_hash_table *htab;
struct _bfd_sparc_elf_link_hash_entry *eh; struct _bfd_sparc_elf_link_hash_entry *eh;
struct _bfd_sparc_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
bfd_boolean resolved_to_zero; bfd_boolean resolved_to_zero;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
@ -2324,7 +2294,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, h)) if (SYMBOL_CALLS_LOCAL (info, h))
{ {
struct _bfd_sparc_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -2339,7 +2309,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (htab->is_vxworks) if (htab->is_vxworks)
{ {
struct _bfd_sparc_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -2365,7 +2335,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{ {
/* Keep dynamic non-GOT/non-PLT relocation so that we /* Keep dynamic non-GOT/non-PLT relocation so that we
can branch to 0 without PLT. */ can branch to 0 without PLT. */
struct _bfd_sparc_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
if (p->pc_count == 0) if (p->pc_count == 0)
@ -2555,7 +2525,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct _bfd_sparc_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
{ {

View file

@ -779,26 +779,6 @@ static const reloc_map tilegx_reloc_map [] =
/* The TILE-Gx linker needs to keep track of the number of relocs that it
decides to copy as dynamic relocs in check_relocs for each symbol.
This is so that it can later discard them if they are found to be
unnecessary. We store the information in a field extending the
regular ELF linker hash table. */
struct tilegx_elf_dyn_relocs
{
struct tilegx_elf_dyn_relocs *next;
/* The input section of the reloc. */
asection *sec;
/* Total number of relocs copied for the input section. */
bfd_size_type count;
/* Number of pc-relative relocs copied for the input section. */
bfd_size_type pc_count;
};
/* TILEGX ELF linker hash entry. */ /* TILEGX ELF linker hash entry. */
struct tilegx_elf_link_hash_entry struct tilegx_elf_link_hash_entry
@ -806,7 +786,7 @@ struct tilegx_elf_link_hash_entry
struct elf_link_hash_entry elf; struct elf_link_hash_entry elf;
/* Track dynamic relocs copied for this symbol. */ /* Track dynamic relocs copied for this symbol. */
struct tilegx_elf_dyn_relocs *dyn_relocs; struct elf_dyn_relocs *dyn_relocs;
#define GOT_UNKNOWN 0 #define GOT_UNKNOWN 0
#define GOT_NORMAL 1 #define GOT_NORMAL 1
@ -1518,14 +1498,14 @@ tilegx_elf_copy_indirect_symbol (struct bfd_link_info *info,
{ {
if (edir->dyn_relocs != NULL) if (edir->dyn_relocs != NULL)
{ {
struct tilegx_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
struct tilegx_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
/* Add reloc counts against the indirect sym to the direct sym /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */ list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{ {
struct tilegx_elf_dyn_relocs *q; struct elf_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next) for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec) if (q->sec == p->sec)
@ -1993,8 +1973,8 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& (h->root.type == bfd_link_hash_defweak && (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))) || !h->def_regular)))
{ {
struct tilegx_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
struct tilegx_elf_dyn_relocs **head; struct elf_dyn_relocs **head;
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
relocs into the output file. We create a reloc relocs into the output file. We create a reloc
@ -2034,14 +2014,14 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
s = sec; s = sec;
vpp = &elf_section_data (s)->local_dynrel; vpp = &elf_section_data (s)->local_dynrel;
head = (struct tilegx_elf_dyn_relocs **) vpp; head = (struct elf_dyn_relocs **) vpp;
} }
p = *head; p = *head;
if (p == NULL || p->sec != sec) if (p == NULL || p->sec != sec)
{ {
bfd_size_type amt = sizeof *p; bfd_size_type amt = sizeof *p;
p = ((struct tilegx_elf_dyn_relocs *) p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->elf.dynobj, amt)); bfd_alloc (htab->elf.dynobj, amt));
if (p == NULL) if (p == NULL)
return FALSE; return FALSE;
@ -2133,7 +2113,7 @@ tilegx_elf_gc_mark_hook (asection *sec,
static asection * static asection *
readonly_dynrelocs (struct elf_link_hash_entry *h) readonly_dynrelocs (struct elf_link_hash_entry *h)
{ {
struct tilegx_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = tilegx_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) for (p = tilegx_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
{ {
@ -2156,8 +2136,6 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h) struct elf_link_hash_entry *h)
{ {
struct tilegx_elf_link_hash_table *htab; struct tilegx_elf_link_hash_table *htab;
struct tilegx_elf_link_hash_entry * eh;
struct tilegx_elf_dyn_relocs *p;
bfd *dynobj; bfd *dynobj;
asection *s, *srel; asection *s, *srel;
@ -2233,17 +2211,9 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE; return TRUE;
} }
eh = (struct tilegx_elf_link_hash_entry *) h; /* If we don't find any dynamic relocs in read-only sections, then
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{
s = p->sec->output_section;
if (s != NULL && (s->flags & SEC_READONLY) != 0)
break;
}
/* If we didn't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL) if (!readonly_dynrelocs (h))
{ {
h->non_got_ref = 0; h->non_got_ref = 0;
return TRUE; return TRUE;
@ -2291,7 +2261,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
struct bfd_link_info *info; struct bfd_link_info *info;
struct tilegx_elf_link_hash_table *htab; struct tilegx_elf_link_hash_table *htab;
struct tilegx_elf_link_hash_entry *eh; struct tilegx_elf_link_hash_entry *eh;
struct tilegx_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
if (h->root.type == bfd_link_hash_indirect) if (h->root.type == bfd_link_hash_indirect)
return TRUE; return TRUE;
@ -2413,7 +2383,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{ {
if (SYMBOL_CALLS_LOCAL (info, h)) if (SYMBOL_CALLS_LOCAL (info, h))
{ {
struct tilegx_elf_dyn_relocs **pp; struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{ {
@ -2574,7 +2544,7 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
for (s = ibfd->sections; s != NULL; s = s->next) for (s = ibfd->sections; s != NULL; s = s->next)
{ {
struct tilegx_elf_dyn_relocs *p; struct elf_dyn_relocs *p;
for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
{ {