/* Xtensa-specific support for 32-bit ELF.
- Copyright 2003, 2004 Free Software Foundation, Inc.
+ Copyright 2003 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
struct elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
+ property_table_entry *lit_table;
+ int ltblsize;
if (info->relocatable)
return TRUE;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
+ ltblsize = xtensa_read_table_entries (abfd, sec, &lit_table,
+ XTENSA_LIT_SEC_NAME);
+ if (ltblsize < 0)
+ return FALSE;
+
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
if ((sec->flags & SEC_ALLOC) != 0)
{
+ if ((sec->flags & SEC_READONLY) != 0
+ && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ sec->vma + rel->r_offset))
+ h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+
if (h->got.refcount <= 0)
h->got.refcount = 1;
else
if ((sec->flags & SEC_ALLOC) != 0)
{
+ if ((sec->flags & SEC_READONLY) != 0
+ && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ sec->vma + rel->r_offset))
+ h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+
if (h->plt.refcount <= 0)
{
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_got_refcounts[r_symndx] += 1;
+
+ /* If the relocation is not inside the GOT, the DF_TEXTREL
+ flag needs to be set. */
+ if (info->shared
+ && (sec->flags & SEC_READONLY) != 0
+ && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ sec->vma + rel->r_offset))
+ info->flags |= DF_TEXTREL;
}
break;
}
}
+ free (lit_table);
return TRUE;
}
else
{
/* Don't need any dynamic relocations at all. */
+ h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
h->plt.refcount = 0;
h->got.refcount = 0;
}
if (! xtensa_elf_dynamic_symbol_p (h, info))
elf_xtensa_make_sym_local (info, h);
+ /* If the symbol has a relocation outside the GOT, set the
+ DF_TEXTREL flag. */
+ if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) != 0)
+ info->flags |= DF_TEXTREL;
+
return TRUE;
}
return FALSE;
}
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+
if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
|| !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
return FALSE;
struct elf_link_hash_entry **sym_hashes;
asection *srelgot, *srelplt;
bfd *dynobj;
- property_table_entry *lit_table = 0;
- int ltblsize = 0;
char *error_message = NULL;
if (xtensa_default_isa == NULL)
srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
}
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- ltblsize = xtensa_read_table_entries (input_bfd, input_section,
- &lit_table, XTENSA_LIT_SEC_NAME);
- if (ltblsize < 0)
- return FALSE;
- }
-
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
}
else
{
- RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
- r_symndx, symtab_hdr, sym_hashes,
- h, sec, relocation,
- unresolved_reloc, warned);
+ RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
+ symtab_hdr, relocation, sec,
+ unresolved_reloc, info,
+ warned);
if (relocation == 0
&& !unresolved_reloc
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
- /* Complain if the relocation is in a read-only section
- and not in a literal pool. */
- if ((input_section->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- input_section->vma
- + rel->r_offset))
- {
- error_message =
- _("dynamic relocation in read-only section");
- if (!((*info->callbacks->reloc_dangerous)
- (info, error_message, input_bfd, input_section,
- rel->r_offset)))
- return FALSE;
- }
-
if (dynamic_symbol)
{
outrel.r_addend = rel->r_addend;
}
}
- if (lit_table)
- free (lit_table);
-
return TRUE;
}