Line 1828... |
Line 1828... |
}
|
}
|
|
|
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
|
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
|
}
|
}
|
|
|
|
static Elf_Internal_Rela *
|
|
sparc_elf_find_reloc_at_ofs (Elf_Internal_Rela *rel,
|
|
Elf_Internal_Rela *relend,
|
|
bfd_vma offset)
|
|
{
|
|
while (rel < relend)
|
|
{
|
|
if (rel->r_offset == offset)
|
|
return rel;
|
|
rel++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
/* Update the got entry reference counts for the section being removed. */
|
/* Update the got entry reference counts for the section being removed. */
|
bfd_boolean
|
bfd_boolean
|
_bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
_bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
|
asection *sec, const Elf_Internal_Rela *relocs)
|
asection *sec, const Elf_Internal_Rela *relocs)
|
{
|
{
|
Line 3674... |
Line 3688... |
else if (h != NULL)
|
else if (h != NULL)
|
tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
|
tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
|
if (! info->shared
|
if (! info->shared
|
|| (r_type == R_SPARC_TLS_GD_CALL && tls_type == GOT_TLS_IE))
|
|| (r_type == R_SPARC_TLS_GD_CALL && tls_type == GOT_TLS_IE))
|
{
|
{
|
|
Elf_Internal_Rela *rel2;
|
bfd_vma insn;
|
bfd_vma insn;
|
|
|
if (!info->shared && (h == NULL || h->dynindx == -1))
|
if (!info->shared && (h == NULL || h->dynindx == -1))
|
{
|
{
|
/* GD -> LE */
|
/* GD -> LE */
|
Line 3709... |
Line 3724... |
contents + rel->r_offset + 4);
|
contents + rel->r_offset + 4);
|
rel++;
|
rel++;
|
continue;
|
continue;
|
}
|
}
|
|
|
bfd_put_32 (output_bfd, 0x9001c008, contents + rel->r_offset);
|
/* We cannot just overwrite the delay slot instruction,
|
|
as it might be what puts the %o0 argument to
|
|
__tls_get_addr into place. So we have to transpose
|
|
the delay slot with the add we patch in. */
|
|
insn = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
|
|
bfd_put_32 (output_bfd, insn,
|
|
contents + rel->r_offset);
|
|
bfd_put_32 (output_bfd, 0x9001c008,
|
|
contents + rel->r_offset + 4);
|
|
|
|
rel2 = rel;
|
|
while ((rel2 = sparc_elf_find_reloc_at_ofs (rel2 + 1, relend,
|
|
rel->r_offset + 4))
|
|
!= NULL)
|
|
{
|
|
/* If the instruction we moved has a relocation attached to
|
|
it, adjust the offset so that it will apply to the correct
|
|
instruction. */
|
|
rel2->r_offset -= 4;
|
|
}
|
continue;
|
continue;
|
}
|
}
|
|
|
h = (struct elf_link_hash_entry *)
|
h = (struct elf_link_hash_entry *)
|
bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
|
bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
|
Line 3792... |
Line 3826... |
/* Dynamic relocs are not propagated for SEC_DEBUGGING sections
|
/* Dynamic relocs are not propagated for SEC_DEBUGGING sections
|
because such sections are not SEC_ALLOC and thus ld.so will
|
because such sections are not SEC_ALLOC and thus ld.so will
|
not process them. */
|
not process them. */
|
if (unresolved_reloc
|
if (unresolved_reloc
|
&& !((input_section->flags & SEC_DEBUGGING) != 0
|
&& !((input_section->flags & SEC_DEBUGGING) != 0
|
&& h->def_dynamic))
|
&& h->def_dynamic)
|
|
&& _bfd_elf_section_offset (output_bfd, info, input_section,
|
|
rel->r_offset) != (bfd_vma) -1)
|
(*_bfd_error_handler)
|
(*_bfd_error_handler)
|
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
|
(_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
|
input_bfd,
|
input_bfd,
|
input_section,
|
input_section,
|
(long) rel->r_offset,
|
(long) rel->r_offset,
|
Line 4753... |
Line 4789... |
}
|
}
|
else
|
else
|
return rel->address;
|
return rel->address;
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|
|
/* Merge backend specific data from an object file to the output
|
|
object file when linking. */
|
|
|
|
bfd_boolean
|
|
_bfd_sparc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|
{
|
|
obj_attribute *in_attr, *in_attrs;
|
|
obj_attribute *out_attr, *out_attrs;
|
|
|
|
if (!elf_known_obj_attributes_proc (obfd)[0].i)
|
|
{
|
|
/* This is the first object. Copy the attributes. */
|
|
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
|
|
|
/* Use the Tag_null value to indicate the attributes have been
|
|
initialized. */
|
|
elf_known_obj_attributes_proc (obfd)[0].i = 1;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
|
|
out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
|
|
|
|
in_attr = &in_attrs[Tag_GNU_Sparc_HWCAPS];
|
|
out_attr = &out_attrs[Tag_GNU_Sparc_HWCAPS];
|
|
|
|
out_attr->i |= in_attr->i;
|
|
|
|
/* Merge Tag_compatibility attributes and any common GNU ones. */
|
|
_bfd_elf_merge_object_attributes (ibfd, obfd);
|
|
|
|
return TRUE;
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|