bfd/
* elf32-arm.c (elf32_arm_relocs_copied): Delete. (elf32_arm_link_hash_entry): Replace relocs_copied with dyn_relocs. (elf32_arm_link_hash_newfunc): Update accordingly. (elf32_arm_copy_indirect_symbol, elf32_arm_gc_sweep_hook): Likewise. (elf32_arm_check_relocs, allocate_dynrelocs): Likewise. (elf32_arm_readonly_dynrelocs): Likewise. (elf32_arm_size_dynamic_sections): Likewise.
This commit is contained in:
parent
c969da6473
commit
0bdcacaf71
2 changed files with 58 additions and 71 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
2010-12-02 Richard Sandiford <richard.sandiford@linaro.org>
|
||||||
|
|
||||||
|
* elf32-arm.c (elf32_arm_relocs_copied): Delete.
|
||||||
|
(elf32_arm_link_hash_entry): Replace relocs_copied with dyn_relocs.
|
||||||
|
(elf32_arm_link_hash_newfunc): Update accordingly.
|
||||||
|
(elf32_arm_copy_indirect_symbol, elf32_arm_gc_sweep_hook): Likewise.
|
||||||
|
(elf32_arm_check_relocs, allocate_dynrelocs): Likewise.
|
||||||
|
(elf32_arm_readonly_dynrelocs): Likewise.
|
||||||
|
(elf32_arm_size_dynamic_sections): Likewise.
|
||||||
|
|
||||||
2010-12-02 Paul Koning <ni1d@arrl.net>
|
2010-12-02 Paul Koning <ni1d@arrl.net>
|
||||||
|
|
||||||
* pdp11.c (aout_link_add_symbols): Ignore debug symbols.
|
* pdp11.c (aout_link_add_symbols): Ignore debug symbols.
|
||||||
|
|
119
bfd/elf32-arm.c
119
bfd/elf32-arm.c
|
@ -2451,26 +2451,6 @@ elf32_arm_mkobject (bfd *abfd)
|
||||||
ARM_ELF_DATA);
|
ARM_ELF_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The ARM linker needs to keep track of the number of relocs that it
|
|
||||||
decides to copy in check_relocs for each symbol. This is so that
|
|
||||||
it can discard PC relative relocs if it doesn't need them when
|
|
||||||
linking with -Bsymbolic. We store the information in a field
|
|
||||||
extending the regular ELF linker hash table. */
|
|
||||||
|
|
||||||
/* This structure keeps track of the number of relocs we have copied
|
|
||||||
for a given symbol. */
|
|
||||||
struct elf32_arm_relocs_copied
|
|
||||||
{
|
|
||||||
/* Next section. */
|
|
||||||
struct elf32_arm_relocs_copied * next;
|
|
||||||
/* A section in dynobj. */
|
|
||||||
asection * section;
|
|
||||||
/* Number of relocs copied in this section. */
|
|
||||||
bfd_size_type count;
|
|
||||||
/* Number of PC-relative relocs copied in this section. */
|
|
||||||
bfd_size_type pc_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent))
|
#define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent))
|
||||||
|
|
||||||
/* Arm ELF linker hash entry. */
|
/* Arm ELF linker hash entry. */
|
||||||
|
@ -2478,8 +2458,8 @@ struct elf32_arm_link_hash_entry
|
||||||
{
|
{
|
||||||
struct elf_link_hash_entry root;
|
struct elf_link_hash_entry root;
|
||||||
|
|
||||||
/* Number of PC relative relocs copied for this symbol. */
|
/* Track dynamic relocs copied for this symbol. */
|
||||||
struct elf32_arm_relocs_copied * relocs_copied;
|
struct elf_dyn_relocs *dyn_relocs;
|
||||||
|
|
||||||
/* We reference count Thumb references to a PLT entry separately,
|
/* We reference count Thumb references to a PLT entry separately,
|
||||||
so that we can emit the Thumb trampoline only if needed. */
|
so that we can emit the Thumb trampoline only if needed. */
|
||||||
|
@ -2686,7 +2666,7 @@ elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
|
||||||
table, string));
|
table, string));
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
{
|
{
|
||||||
ret->relocs_copied = NULL;
|
ret->dyn_relocs = NULL;
|
||||||
ret->tls_type = GOT_UNKNOWN;
|
ret->tls_type = GOT_UNKNOWN;
|
||||||
ret->plt_thumb_refcount = 0;
|
ret->plt_thumb_refcount = 0;
|
||||||
ret->plt_maybe_thumb_refcount = 0;
|
ret->plt_maybe_thumb_refcount = 0;
|
||||||
|
@ -2841,21 +2821,21 @@ elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
|
||||||
edir = (struct elf32_arm_link_hash_entry *) dir;
|
edir = (struct elf32_arm_link_hash_entry *) dir;
|
||||||
eind = (struct elf32_arm_link_hash_entry *) ind;
|
eind = (struct elf32_arm_link_hash_entry *) ind;
|
||||||
|
|
||||||
if (eind->relocs_copied != NULL)
|
if (eind->dyn_relocs != NULL)
|
||||||
{
|
{
|
||||||
if (edir->relocs_copied != NULL)
|
if (edir->dyn_relocs != NULL)
|
||||||
{
|
{
|
||||||
struct elf32_arm_relocs_copied **pp;
|
struct elf_dyn_relocs **pp;
|
||||||
struct elf32_arm_relocs_copied *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->relocs_copied; (p = *pp) != NULL; )
|
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
|
||||||
{
|
{
|
||||||
struct elf32_arm_relocs_copied *q;
|
struct elf_dyn_relocs *q;
|
||||||
|
|
||||||
for (q = edir->relocs_copied; q != NULL; q = q->next)
|
for (q = edir->dyn_relocs; q != NULL; q = q->next)
|
||||||
if (q->section == p->section)
|
if (q->sec == p->sec)
|
||||||
{
|
{
|
||||||
q->pc_count += p->pc_count;
|
q->pc_count += p->pc_count;
|
||||||
q->count += p->count;
|
q->count += p->count;
|
||||||
|
@ -2865,11 +2845,11 @@ elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
|
||||||
if (q == NULL)
|
if (q == NULL)
|
||||||
pp = &p->next;
|
pp = &p->next;
|
||||||
}
|
}
|
||||||
*pp = edir->relocs_copied;
|
*pp = edir->dyn_relocs;
|
||||||
}
|
}
|
||||||
|
|
||||||
edir->relocs_copied = eind->relocs_copied;
|
edir->dyn_relocs = eind->dyn_relocs;
|
||||||
eind->relocs_copied = NULL;
|
eind->dyn_relocs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ind->root.type == bfd_link_hash_indirect)
|
if (ind->root.type == bfd_link_hash_indirect)
|
||||||
|
@ -10710,8 +10690,8 @@ elf32_arm_gc_sweep_hook (bfd * abfd,
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
struct elf32_arm_link_hash_entry *eh;
|
struct elf32_arm_link_hash_entry *eh;
|
||||||
struct elf32_arm_relocs_copied **pp;
|
struct elf_dyn_relocs **pp;
|
||||||
struct elf32_arm_relocs_copied *p;
|
struct elf_dyn_relocs *p;
|
||||||
|
|
||||||
eh = (struct elf32_arm_link_hash_entry *) h;
|
eh = (struct elf32_arm_link_hash_entry *) h;
|
||||||
|
|
||||||
|
@ -10730,20 +10710,17 @@ elf32_arm_gc_sweep_hook (bfd * abfd,
|
||||||
|| r_type == R_ARM_REL32
|
|| r_type == R_ARM_REL32
|
||||||
|| r_type == R_ARM_ABS32_NOI
|
|| r_type == R_ARM_ABS32_NOI
|
||||||
|| r_type == R_ARM_REL32_NOI)
|
|| r_type == R_ARM_REL32_NOI)
|
||||||
{
|
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
|
||||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL;
|
if (p->sec == sec)
|
||||||
pp = &p->next)
|
|
||||||
if (p->section == sec)
|
|
||||||
{
|
{
|
||||||
p->count -= 1;
|
p->count -= 1;
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_REL32
|
if (ELF32_R_TYPE (rel->r_info) == R_ARM_REL32
|
||||||
|| ELF32_R_TYPE (rel->r_info) == R_ARM_REL32_NOI)
|
|| ELF32_R_TYPE (rel->r_info) == R_ARM_REL32_NOI)
|
||||||
p->pc_count -= 1;
|
p->pc_count -= 1;
|
||||||
if (p->count == 0)
|
if (p->count == 0)
|
||||||
*pp = p->next;
|
*pp = p->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -11001,14 +10978,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
possible that DEF_REGULAR is not set now but will be set
|
possible that DEF_REGULAR is not set now but will be set
|
||||||
later (it is never cleared). We account for that
|
later (it is never cleared). We account for that
|
||||||
possibility below by storing information in the
|
possibility below by storing information in the
|
||||||
relocs_copied field of the hash table entry. */
|
dyn_relocs field of the hash table entry. */
|
||||||
if ((info->shared || htab->root.is_relocatable_executable)
|
if ((info->shared || htab->root.is_relocatable_executable)
|
||||||
&& (sec->flags & SEC_ALLOC) != 0
|
&& (sec->flags & SEC_ALLOC) != 0
|
||||||
&& ((r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI)
|
&& ((r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI)
|
||||||
|| (h != NULL && ! h->needs_plt
|
|| (h != NULL && ! h->needs_plt
|
||||||
&& (! info->symbolic || ! h->def_regular))))
|
&& (! info->symbolic || ! h->def_regular))))
|
||||||
{
|
{
|
||||||
struct elf32_arm_relocs_copied *p, **head;
|
struct elf_dyn_relocs *p, **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
|
||||||
|
@ -11036,7 +11013,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||||
relocations we need for this symbol. */
|
relocations we need for this symbol. */
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
head = &((struct elf32_arm_link_hash_entry *) h)->relocs_copied;
|
head = &((struct elf32_arm_link_hash_entry *) h)->dyn_relocs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -11057,21 +11034,21 @@ elf32_arm_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_arm_relocs_copied **) vpp;
|
head = (struct elf_dyn_relocs **) vpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = *head;
|
p = *head;
|
||||||
if (p == NULL || p->section != sec)
|
if (p == NULL || p->sec != sec)
|
||||||
{
|
{
|
||||||
bfd_size_type amt = sizeof *p;
|
bfd_size_type amt = sizeof *p;
|
||||||
|
|
||||||
p = (struct elf32_arm_relocs_copied *)
|
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;
|
||||||
p->next = *head;
|
p->next = *head;
|
||||||
*head = p;
|
*head = p;
|
||||||
p->section = sec;
|
p->sec = sec;
|
||||||
p->count = 0;
|
p->count = 0;
|
||||||
p->pc_count = 0;
|
p->pc_count = 0;
|
||||||
}
|
}
|
||||||
|
@ -11425,7 +11402,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
struct elf32_arm_link_hash_table *htab;
|
struct elf32_arm_link_hash_table *htab;
|
||||||
struct elf32_arm_link_hash_entry *eh;
|
struct elf32_arm_link_hash_entry *eh;
|
||||||
struct elf32_arm_relocs_copied *p;
|
struct elf_dyn_relocs *p;
|
||||||
bfd_signed_vma thumb_refs;
|
bfd_signed_vma thumb_refs;
|
||||||
|
|
||||||
eh = (struct elf32_arm_link_hash_entry *) h;
|
eh = (struct elf32_arm_link_hash_entry *) h;
|
||||||
|
@ -11640,7 +11617,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
h->root.u.def.value = th->root.u.def.value & ~1;
|
h->root.u.def.value = th->root.u.def.value & ~1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eh->relocs_copied == NULL)
|
if (eh->dyn_relocs == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* In the shared -Bsymbolic case, discard space allocated for
|
/* In the shared -Bsymbolic case, discard space allocated for
|
||||||
|
@ -11659,9 +11636,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
should avoid writing assembly like ".long foo - .". */
|
should avoid writing assembly like ".long foo - .". */
|
||||||
if (SYMBOL_CALLS_LOCAL (info, h))
|
if (SYMBOL_CALLS_LOCAL (info, h))
|
||||||
{
|
{
|
||||||
struct elf32_arm_relocs_copied **pp;
|
struct elf_dyn_relocs **pp;
|
||||||
|
|
||||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL; )
|
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
|
||||||
{
|
{
|
||||||
p->count -= p->pc_count;
|
p->count -= p->pc_count;
|
||||||
p->pc_count = 0;
|
p->pc_count = 0;
|
||||||
|
@ -11674,11 +11651,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
|
|
||||||
if (htab->vxworks_p)
|
if (htab->vxworks_p)
|
||||||
{
|
{
|
||||||
struct elf32_arm_relocs_copied **pp;
|
struct elf_dyn_relocs **pp;
|
||||||
|
|
||||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL; )
|
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
|
||||||
{
|
{
|
||||||
if (strcmp (p->section->output_section->name, ".tls_vars") == 0)
|
if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
|
||||||
*pp = p->next;
|
*pp = p->next;
|
||||||
else
|
else
|
||||||
pp = &p->next;
|
pp = &p->next;
|
||||||
|
@ -11687,11 +11664,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
|
|
||||||
/* Also discard relocs on undefined weak syms with non-default
|
/* Also discard relocs on undefined weak syms with non-default
|
||||||
visibility. */
|
visibility. */
|
||||||
if (eh->relocs_copied != NULL
|
if (eh->dyn_relocs != NULL
|
||||||
&& h->root.type == bfd_link_hash_undefweak)
|
&& h->root.type == bfd_link_hash_undefweak)
|
||||||
{
|
{
|
||||||
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
|
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
|
||||||
eh->relocs_copied = NULL;
|
eh->dyn_relocs = NULL;
|
||||||
|
|
||||||
/* Make sure undefined weak symbols are output as a dynamic
|
/* Make sure undefined weak symbols are output as a dynamic
|
||||||
symbol in PIEs. */
|
symbol in PIEs. */
|
||||||
|
@ -11742,15 +11719,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||||
goto keep;
|
goto keep;
|
||||||
}
|
}
|
||||||
|
|
||||||
eh->relocs_copied = NULL;
|
eh->dyn_relocs = NULL;
|
||||||
|
|
||||||
keep: ;
|
keep: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, allocate space. */
|
/* Finally, allocate space. */
|
||||||
for (p = eh->relocs_copied; p != NULL; p = p->next)
|
for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
asection *sreloc = elf_section_data (p->section)->sreloc;
|
asection *sreloc = elf_section_data (p->sec)->sreloc;
|
||||||
sreloc->size += p->count * RELOC_SIZE (htab);
|
sreloc->size += p->count * RELOC_SIZE (htab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11763,15 +11740,15 @@ static bfd_boolean
|
||||||
elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
|
elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
|
||||||
{
|
{
|
||||||
struct elf32_arm_link_hash_entry * eh;
|
struct elf32_arm_link_hash_entry * eh;
|
||||||
struct elf32_arm_relocs_copied * p;
|
struct elf_dyn_relocs * p;
|
||||||
|
|
||||||
if (h->root.type == bfd_link_hash_warning)
|
if (h->root.type == bfd_link_hash_warning)
|
||||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||||
|
|
||||||
eh = (struct elf32_arm_link_hash_entry *) h;
|
eh = (struct elf32_arm_link_hash_entry *) h;
|
||||||
for (p = eh->relocs_copied; p != NULL; p = p->next)
|
for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
asection *s = p->section;
|
asection *s = p->sec;
|
||||||
|
|
||||||
if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
if (s != NULL && (s->flags & SEC_READONLY) != 0)
|
||||||
{
|
{
|
||||||
|
@ -11849,13 +11826,13 @@ elf32_arm_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_arm_relocs_copied *p;
|
struct elf_dyn_relocs *p;
|
||||||
|
|
||||||
for (p = (struct elf32_arm_relocs_copied *)
|
for (p = (struct elf_dyn_relocs *)
|
||||||
elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
|
elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
if (!bfd_is_abs_section (p->section)
|
if (!bfd_is_abs_section (p->sec)
|
||||||
&& bfd_is_abs_section (p->section->output_section))
|
&& bfd_is_abs_section (p->sec->output_section))
|
||||||
{
|
{
|
||||||
/* Input section has been discarded, either because
|
/* Input section has been discarded, either because
|
||||||
it is a copy of a linkonce section or due to
|
it is a copy of a linkonce section or due to
|
||||||
|
@ -11863,7 +11840,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||||
the relocs too. */
|
the relocs too. */
|
||||||
}
|
}
|
||||||
else if (is_vxworks
|
else if (is_vxworks
|
||||||
&& strcmp (p->section->output_section->name,
|
&& strcmp (p->sec->output_section->name,
|
||||||
".tls_vars") == 0)
|
".tls_vars") == 0)
|
||||||
{
|
{
|
||||||
/* Relocations in vxworks .tls_vars sections are
|
/* Relocations in vxworks .tls_vars sections are
|
||||||
|
@ -11871,9 +11848,9 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||||
}
|
}
|
||||||
else if (p->count != 0)
|
else if (p->count != 0)
|
||||||
{
|
{
|
||||||
srel = elf_section_data (p->section)->sreloc;
|
srel = elf_section_data (p->sec)->sreloc;
|
||||||
srel->size += p->count * RELOC_SIZE (htab);
|
srel->size += p->count * RELOC_SIZE (htab);
|
||||||
if ((p->section->output_section->flags & SEC_READONLY) != 0)
|
if ((p->sec->output_section->flags & SEC_READONLY) != 0)
|
||||||
info->flags |= DF_TEXTREL;
|
info->flags |= DF_TEXTREL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue