bfd_vma plt_offset;
bfd_vma gotplt_offset;
bfd_boolean has_iplt_entry;
+ bfd_boolean resolved_to_zero;
globals = elf32_arm_hash_table (info);
if (globals == NULL)
gotplt_offset = (bfd_vma) -1;
}
+ resolved_to_zero = (h != NULL
+ && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+
switch (r_type)
{
case R_ARM_NONE:
&& !(input_bfd == globals->stub_bfd
&& strstr (input_section->name, STUB_SUFFIX))
&& (h == NULL
- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !resolved_to_zero)
|| h->root.type != bfd_link_hash_undefweak)
&& r_type != R_ARM_PC24
&& r_type != R_ARM_CALL
if ((bfd_link_pic (info) || indx != 0)
&& (h == NULL
- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !resolved_to_zero)
|| h->root.type != bfd_link_hash_undefweak))
{
need_relocs = TRUE;
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}
-/* Update the got entry reference counts for the section being removed. */
-
-static bfd_boolean
-elf32_arm_gc_sweep_hook (bfd * abfd,
- struct bfd_link_info * info,
- asection * sec,
- const Elf_Internal_Rela * relocs)
-{
- Elf_Internal_Shdr *symtab_hdr;
- struct elf_link_hash_entry **sym_hashes;
- bfd_signed_vma *local_got_refcounts;
- const Elf_Internal_Rela *rel, *relend;
- struct elf32_arm_link_hash_table * globals;
-
- if (bfd_link_relocatable (info))
- return TRUE;
-
- globals = elf32_arm_hash_table (info);
- if (globals == NULL)
- return FALSE;
-
- elf_section_data (sec)->local_dynrel = NULL;
-
- symtab_hdr = & elf_symtab_hdr (abfd);
- sym_hashes = elf_sym_hashes (abfd);
- local_got_refcounts = elf_local_got_refcounts (abfd);
-
- check_use_blx (globals);
-
- relend = relocs + sec->reloc_count;
- for (rel = relocs; rel < relend; rel++)
- {
- unsigned long r_symndx;
- struct elf_link_hash_entry *h = NULL;
- struct elf32_arm_link_hash_entry *eh;
- int r_type;
- bfd_boolean call_reloc_p;
- bfd_boolean may_become_dynamic_p;
- bfd_boolean may_need_local_target_p;
- union gotplt_union *root_plt;
- struct arm_plt_info *arm_plt;
-
- r_symndx = ELF32_R_SYM (rel->r_info);
- if (r_symndx >= symtab_hdr->sh_info)
- {
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
- }
- eh = (struct elf32_arm_link_hash_entry *) h;
-
- call_reloc_p = FALSE;
- may_become_dynamic_p = FALSE;
- may_need_local_target_p = FALSE;
-
- r_type = ELF32_R_TYPE (rel->r_info);
- r_type = arm_real_reloc_type (globals, r_type);
- switch (r_type)
- {
- case R_ARM_GOT32:
- case R_ARM_GOT_PREL:
- case R_ARM_TLS_GD32:
- case R_ARM_TLS_IE32:
- if (h != NULL)
- {
- if (h->got.refcount > 0)
- h->got.refcount -= 1;
- }
- else if (local_got_refcounts != NULL)
- {
- if (local_got_refcounts[r_symndx] > 0)
- local_got_refcounts[r_symndx] -= 1;
- }
- break;
-
- case R_ARM_TLS_LDM32:
- globals->tls_ldm_got.refcount -= 1;
- break;
-
- case R_ARM_PC24:
- case R_ARM_PLT32:
- case R_ARM_CALL:
- case R_ARM_JUMP24:
- case R_ARM_PREL31:
- case R_ARM_THM_CALL:
- case R_ARM_THM_JUMP24:
- case R_ARM_THM_JUMP19:
- call_reloc_p = TRUE;
- may_need_local_target_p = TRUE;
- break;
-
- case R_ARM_ABS12:
- if (!globals->vxworks_p)
- {
- may_need_local_target_p = TRUE;
- break;
- }
- /* Fall through. */
- case R_ARM_ABS32:
- case R_ARM_ABS32_NOI:
- case R_ARM_REL32:
- case R_ARM_REL32_NOI:
- case R_ARM_MOVW_ABS_NC:
- case R_ARM_MOVT_ABS:
- case R_ARM_MOVW_PREL_NC:
- case R_ARM_MOVT_PREL:
- case R_ARM_THM_MOVW_ABS_NC:
- case R_ARM_THM_MOVT_ABS:
- case R_ARM_THM_MOVW_PREL_NC:
- case R_ARM_THM_MOVT_PREL:
- /* Should the interworking branches be here also? */
- if ((bfd_link_pic (info) || globals->root.is_relocatable_executable)
- && (sec->flags & SEC_ALLOC) != 0)
- {
- if (h == NULL
- && elf32_arm_howto_from_type (r_type)->pc_relative)
- {
- call_reloc_p = TRUE;
- may_need_local_target_p = TRUE;
- }
- else
- may_become_dynamic_p = TRUE;
- }
- else
- may_need_local_target_p = TRUE;
- break;
-
- default:
- break;
- }
-
- if (may_need_local_target_p
- && elf32_arm_get_plt_info (abfd, globals, eh, r_symndx, &root_plt,
- &arm_plt))
- {
- /* If PLT refcount book-keeping is wrong and too low, we'll
- see a zero value (going to -1) for the root PLT reference
- count. */
- if (root_plt->refcount >= 0)
- {
- BFD_ASSERT (root_plt->refcount != 0);
- root_plt->refcount -= 1;
- }
- else
- /* A value of -1 means the symbol has become local, forced
- or seeing a hidden definition. Any other negative value
- is an error. */
- BFD_ASSERT (root_plt->refcount == -1);
-
- if (!call_reloc_p)
- arm_plt->noncall_refcount--;
-
- if (r_type == R_ARM_THM_CALL)
- arm_plt->maybe_thumb_refcount--;
-
- if (r_type == R_ARM_THM_JUMP24
- || r_type == R_ARM_THM_JUMP19)
- arm_plt->thumb_refcount--;
- }
-
- if (may_become_dynamic_p)
- {
- struct elf_dyn_relocs **pp;
- struct elf_dyn_relocs *p;
-
- if (h != NULL)
- pp = &(eh->dyn_relocs);
- else
- {
- Elf_Internal_Sym *isym;
-
- isym = bfd_sym_from_r_symndx (&globals->sym_cache,
- abfd, r_symndx);
- if (isym == NULL)
- return FALSE;
- pp = elf32_arm_get_local_dynreloc_list (abfd, r_symndx, isym);
- if (pp == NULL)
- return FALSE;
- }
- for (; (p = *pp) != NULL; pp = &p->next)
- if (p->sec == sec)
- {
- /* Everything must go for SEC. */
- *pp = p->next;
- break;
- }
- }
- }
-
- return TRUE;
-}
-
/* Look through the relocs for a section during the first phase. */
static bfd_boolean
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
- /* PR15323, ref flags aren't set for references in the
- same object. */
- h->root.non_ir_ref_regular = 1;
}
}
BFD_ASSERT (dynobj != NULL
&& (h->needs_plt
|| h->type == STT_GNU_IFUNC
- || h->u.weakdef != NULL
+ || h->is_weakalias
|| (h->def_dynamic
&& h->ref_regular
&& !h->def_regular)));
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
- if (h->u.weakdef != NULL)
+ if (h->is_weakalias)
{
- BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
- || h->u.weakdef->root.type == bfd_link_hash_defweak);
- h->root.u.def.section = h->u.weakdef->root.u.def.section;
- h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ struct elf_link_hash_entry *def = weakdef (h);
+ BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+ h->root.u.def.section = def->root.u.def.section;
+ h->root.u.def.value = def->root.u.def.value;
return TRUE;
}
{
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
- if (h->dynindx == -1
- && !h->forced_local)
+ if (h->dynindx == -1 && !h->forced_local
+ && h->root.type == bfd_link_hash_undefweak)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
- if (h->dynindx == -1
- && !h->forced_local)
+ if (h->dynindx == -1 && !h->forced_local
+ && h->root.type == bfd_link_hash_undefweak)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefweak)
{
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
eh->dyn_relocs = NULL;
/* Make sure undefined weak symbols are output as a dynamic
{
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
- if (h->dynindx == -1
- && !h->forced_local)
+ if (h->dynindx == -1 && !h->forced_local
+ && h->root.type == bfd_link_hash_undefweak)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
#define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections
-#define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
#define elf_backend_check_relocs elf32_arm_check_relocs
#define elf_backend_update_relocs elf32_arm_update_relocs
#define elf_backend_relocate_section elf32_arm_relocate_section
#undef elf_backend_lookup_section_flags_hook
#define elf_backend_lookup_section_flags_hook elf32_arm_lookup_section_flags
+#define elf_backend_linux_prpsinfo32_ugid16 TRUE
+
#include "elf32-target.h"
/* Native Client targets. */