/* Xtensa-specific support for 32-bit ELF.
- Copyright (C) 2003-2016 Free Software Foundation, Inc.
+ Copyright (C) 2003-2018 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
static int internal_reloc_compare (const void *, const void *);
static int internal_reloc_matches (const void *, const void *);
static asection *xtensa_get_property_section (asection *, const char *);
-extern asection *xtensa_make_property_section (asection *, const char *);
static flagword xtensa_get_property_predef_flags (asection *);
/* Other functions called directly by the linker. */
/* GNU extension to record C++ vtable hierarchy. */
HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 2, 0, FALSE, 0, complain_overflow_dont,
- NULL, "R_XTENSA_GNU_VTINHERIT",
+ NULL, "R_XTENSA_GNU_VTINHERIT",
FALSE, 0, 0, FALSE),
/* GNU extension to record C++ vtable member usage. */
HOWTO (R_XTENSA_GNU_VTENTRY, 0, 2, 0, FALSE, 0, complain_overflow_dont,
- _bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY",
+ _bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY",
FALSE, 0, 0, FALSE),
/* Relocations for supporting difference of symbols. */
break;
}
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
+ bfd_set_error (bfd_error_bad_value);
TRACE ("Unknown");
return NULL;
}
/* Given an ELF "rela" relocation, find the corresponding howto and record
it in the BFD internal arelent representation of the relocation. */
-static void
-elf_xtensa_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+static bfd_boolean
+elf_xtensa_info_to_howto_rela (bfd *abfd,
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
if (r_type >= (unsigned int) R_XTENSA_max)
{
- _bfd_error_handler (_("%B: invalid XTENSA reloc number: %d"), abfd, r_type);
- r_type = 0;
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
}
cache_ptr->howto = &elf_howto_table[r_type];
+ return TRUE;
}
\f
invoked. Note: the 32-byte frame size used here cannot be changed
without a corresponding change in the runtime linker. */
-static const bfd_byte elf_xtensa_be_plt_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_xtensa_be_plt_entry[][PLT_ENTRY_SIZE] =
{
-#if XSHAL_ABI == XTHAL_ABI_WINDOWED
- 0x6c, 0x10, 0x04, /* entry sp, 32 */
-#endif
- 0x18, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
- 0x1a, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
- 0x1b, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
- 0x0a, 0x80, 0x00, /* jx a8 */
- 0 /* unused */
+ {
+ 0x6c, 0x10, 0x04, /* entry sp, 32 */
+ 0x18, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
+ 0x1a, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
+ 0x1b, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
+ 0x0a, 0x80, 0x00, /* jx a8 */
+ 0 /* unused */
+ },
+ {
+ 0x18, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
+ 0x1a, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
+ 0x1b, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
+ 0x0a, 0x80, 0x00, /* jx a8 */
+ 0 /* unused */
+ }
};
-static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_xtensa_le_plt_entry[][PLT_ENTRY_SIZE] =
{
-#if XSHAL_ABI == XTHAL_ABI_WINDOWED
- 0x36, 0x41, 0x00, /* entry sp, 32 */
-#endif
- 0x81, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
- 0xa1, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
- 0xb1, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
- 0xa0, 0x08, 0x00, /* jx a8 */
- 0 /* unused */
+ {
+ 0x36, 0x41, 0x00, /* entry sp, 32 */
+ 0x81, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
+ 0xa1, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
+ 0xb1, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
+ 0xa0, 0x08, 0x00, /* jx a8 */
+ 0 /* unused */
+ },
+ {
+ 0x81, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
+ 0xa1, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
+ 0xb1, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
+ 0xa0, 0x08, 0x00, /* jx a8 */
+ 0 /* unused */
+ }
};
/* The size of the thread control block. */
struct elf_link_hash_table elf;
/* Short-cuts to get to dynamic linker sections. */
- asection *sgot;
- asection *sgotplt;
- asection *srelgot;
- asection *splt;
- asection *srelplt;
asection *sgotloc;
asection *spltlittbl;
property_table_compare);
/* Check that the table contents are valid. Problems may occur,
- for example, if an unrelocated object file is stripped. */
+ for example, if an unrelocated object file is stripped. */
for (blk = 1; blk < block_count; blk++)
{
/* The only circumstance where two entries may legitimately
if (blocks[blk - 1].address == blocks[blk].address &&
blocks[blk - 1].size != 0)
{
- (*_bfd_error_handler) (_("%B(%A): invalid property table"),
- abfd, section);
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB(%pA): invalid property table"),
+ abfd, section);
bfd_set_error (bfd_error_bad_value);
free (blocks);
return -1;
for (rel = relocs; rel < rel_end; rel++)
{
unsigned int r_type;
- unsigned long r_symndx;
+ unsigned r_symndx;
struct elf_link_hash_entry *h = NULL;
struct elf_xtensa_link_hash_entry *eh;
int tls_type, old_tls_type;
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
- (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
- abfd, r_symndx);
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: bad symbol index: %d"),
+ abfd, r_symndx);
return FALSE;
}
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 = 1;
}
eh = elf_xtensa_hash_entry (h);
tls_type |= old_tls_type;
else
{
- (*_bfd_error_handler)
- (_("%B: `%s' accessed both as normal and thread local symbol"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' accessed both as normal and thread local symbol"),
abfd,
h ? h->root.root.string : "<local>");
return FALSE;
static void
elf_xtensa_make_sym_local (struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+ struct elf_link_hash_entry *h)
{
if (bfd_link_pic (info))
{
if (h->plt.refcount > 0)
- {
+ {
/* For shared objects, there's no need for PLT entries for local
symbols (use RELATIVE relocs instead of JMP_SLOT relocs). */
- if (h->got.refcount < 0)
- h->got.refcount = 0;
- h->got.refcount += h->plt.refcount;
- h->plt.refcount = 0;
- }
+ if (h->got.refcount < 0)
+ h->got.refcount = 0;
+ h->got.refcount += h->plt.refcount;
+ h->plt.refcount = 0;
+ }
}
else
{
static void
elf_xtensa_hide_symbol (struct bfd_link_info *info,
- struct elf_link_hash_entry *h,
- bfd_boolean force_local)
+ struct elf_link_hash_entry *h,
+ bfd_boolean force_local)
{
/* For a shared link, move the plt refcount to the got refcount to leave
space for RELATIVE relocs. */
}
-/* Update the GOT & PLT entry reference counts
- for the section being removed. */
-
-static bfd_boolean
-elf_xtensa_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;
- const Elf_Internal_Rela *rel, *relend;
- struct elf_xtensa_link_hash_table *htab;
-
- htab = elf_xtensa_hash_table (info);
- if (htab == NULL)
- return FALSE;
-
- if (bfd_link_relocatable (info))
- return TRUE;
-
- if ((sec->flags & SEC_ALLOC) == 0)
- return TRUE;
-
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- sym_hashes = elf_sym_hashes (abfd);
-
- relend = relocs + sec->reloc_count;
- for (rel = relocs; rel < relend; rel++)
- {
- unsigned long r_symndx;
- unsigned int r_type;
- struct elf_link_hash_entry *h = NULL;
- struct elf_xtensa_link_hash_entry *eh;
- bfd_boolean is_got = FALSE;
- bfd_boolean is_plt = FALSE;
- bfd_boolean is_tlsfunc = FALSE;
-
- 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 = elf_xtensa_hash_entry (h);
-
- r_type = ELF32_R_TYPE (rel->r_info);
- switch (r_type)
- {
- case R_XTENSA_TLSDESC_FN:
- if (bfd_link_pic (info))
- {
- is_got = TRUE;
- is_tlsfunc = TRUE;
- }
- break;
-
- case R_XTENSA_TLSDESC_ARG:
- if (bfd_link_pic (info))
- is_got = TRUE;
- else
- {
- if (h && elf_xtensa_hash_entry (h) != htab->tlsbase)
- is_got = TRUE;
- }
- break;
-
- case R_XTENSA_TLS_TPOFF:
- if (bfd_link_pic (info) || h)
- is_got = TRUE;
- break;
-
- case R_XTENSA_32:
- is_got = TRUE;
- break;
-
- case R_XTENSA_PLT:
- is_plt = TRUE;
- break;
-
- default:
- continue;
- }
-
- if (h)
- {
- if (is_plt)
- {
- /* If the symbol has been localized its plt.refcount got moved
- to got.refcount. Handle it as GOT. */
- if (h->plt.refcount > 0)
- h->plt.refcount--;
- else
- is_got = TRUE;
- }
- if (is_got)
- {
- if (h->got.refcount > 0)
- h->got.refcount--;
- }
- if (is_tlsfunc)
- {
- if (eh->tlsfunc_refcount > 0)
- eh->tlsfunc_refcount--;
- }
- }
- else
- {
- if (is_got || is_plt)
- {
- bfd_signed_vma *got_refcount
- = &elf_local_got_refcounts (abfd) [r_symndx];
- if (*got_refcount > 0)
- *got_refcount -= 1;
- }
- if (is_tlsfunc)
- {
- bfd_signed_vma *tlsfunc_refcount
- = &elf_xtensa_local_tlsfunc_refcounts (abfd) [r_symndx];
- if (*tlsfunc_refcount > 0)
- *tlsfunc_refcount -= 1;
- }
- }
- }
-
- return TRUE;
-}
-
-
/* Create all the dynamic sections. */
static bfd_boolean
/* First do all the standard stuff. */
if (! _bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
- htab->splt = bfd_get_linker_section (dynobj, ".plt");
- htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
- htab->sgot = bfd_get_linker_section (dynobj, ".got");
- htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
- htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
/* Create any extra PLT sections in case check_relocs has already
been called on all the non-dynamic input files. */
flags = noalloc_flags | SEC_ALLOC | SEC_LOAD;
/* Mark the ".got.plt" section READONLY. */
- if (htab->sgotplt == NULL
- || ! bfd_set_section_flags (dynobj, htab->sgotplt, flags))
+ if (htab->elf.sgotplt == NULL
+ || ! bfd_set_section_flags (dynobj, htab->elf.sgotplt, flags))
return FALSE;
/* Create ".got.loc" (literal tables for use by dynamic linker). */
/* 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)
+ 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;
}
elf_xtensa_make_sym_local (info, h);
if (h->plt.refcount > 0)
- htab->srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
+ htab->elf.srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
if (h->got.refcount > 0)
- htab->srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
+ htab->elf.srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
return TRUE;
}
}
if (local_got_refcounts[j] > 0)
- htab->srelgot->size += (local_got_refcounts[j]
- * sizeof (Elf32_External_Rela));
+ htab->elf.srelgot->size += (local_got_refcounts[j]
+ * sizeof (Elf32_External_Rela));
}
}
}
dynobj = elf_hash_table (info)->dynobj;
if (dynobj == NULL)
abort ();
- srelgot = htab->srelgot;
- srelplt = htab->srelplt;
+ srelgot = htab->elf.srelgot;
+ srelplt = htab->elf.srelplt;
if (elf_hash_table (info)->dynamic_sections_created)
{
- BFD_ASSERT (htab->srelgot != NULL
- && htab->srelplt != NULL
- && htab->sgot != NULL
+ BFD_ASSERT (htab->elf.srelgot != NULL
+ && htab->elf.srelplt != NULL
+ && htab->elf.sgot != NULL
&& htab->spltlittbl != NULL
&& htab->sgotloc != NULL);
}
/* Allocate room for one word in ".got". */
- htab->sgot->size = 4;
+ htab->elf.sgot->size = 4;
/* Allocate space in ".rela.got" for literals that reference global
symbols and space in ".rela.plt" for literals that have PLT
case R_XTENSA_ASM_SIMPLIFY:
{
- /* Convert the L32R/CALLX to CALL. */
+ /* Convert the L32R/CALLX to CALL. */
bfd_reloc_status_type retval =
elf_xtensa_do_asm_simplify (contents, address, input_size,
error_message);
/* Fill in the entry in the procedure linkage table. */
memcpy (splt->contents + code_offset,
(bfd_big_endian (output_bfd)
- ? elf_xtensa_be_plt_entry
- : elf_xtensa_le_plt_entry),
+ ? elf_xtensa_be_plt_entry[XSHAL_ABI != XTHAL_ABI_WINDOWED]
+ : elf_xtensa_le_plt_entry[XSHAL_ABI != XTHAL_ABI_WINDOWED]),
PLT_ENTRY_SIZE);
abi_offset = XSHAL_ABI == XTHAL_ABI_WINDOWED ? 3 : 0;
bfd_put_16 (output_bfd, l32r_offset (got_base + 0,
xtensa_format_set_slot (isa, fmt, 0, ibuff, sbuff);
xtensa_insnbuf_to_chars (isa, ibuff, contents + rel->r_offset,
- input_size - rel->r_offset);
+ input_size - rel->r_offset);
return TRUE;
}
if (rel->r_offset >= input_size
&& ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): relocation offset out of range (size=0x%x)"),
- input_bfd, input_section, rel->r_offset, input_size);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "relocation offset out of range (size=%#" PRIx64 ")"),
+ input_bfd, input_section, (uint64_t) rel->r_offset,
+ (uint64_t) input_size);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
|| h->root.type == bfd_link_hash_defweak)
&& IS_XTENSA_TLS_RELOC (r_type) != (sym_type == STT_TLS))
{
- (*_bfd_error_handler)
+ _bfd_error_handler
((sym_type == STT_TLS
- ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
- : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+ /* xgettext:c-format */
+ ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
+ /* xgettext:c-format */
+ : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
input_bfd,
input_section,
- (long) rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
name);
}
asection *srel;
if (dynamic_symbol && r_type == R_XTENSA_PLT)
- srel = htab->srelplt;
+ srel = htab->elf.srelplt;
else
- srel = htab->srelgot;
+ srel = htab->elf.srelgot;
BFD_ASSERT (srel != NULL);
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
- asection *srel = htab->srelgot;
+ asection *srel = htab->elf.srelgot;
int indx;
outrel.r_offset = (input_section->output_section->vma
&& _bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset) != (bfd_vma) -1)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): "
+ "unresolvable %s relocation against symbol `%s'"),
input_bfd,
input_section,
- (long) rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
name);
return FALSE;
sgotloc_size = sgotloc->size;
if (sgotloc_size != section_size)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("internal inconsistency in size of .got.loc section"));
return -1;
}
/* Set the first entry in the global offset table to the address of
the dynamic section. */
- sgot = htab->sgot;
+ sgot = htab->elf.sgot;
if (sgot)
{
BFD_ASSERT (sgot->size == 4);
sgot->contents);
}
- srelplt = htab->srelplt;
+ srelplt = htab->elf.srelplt;
if (srelplt && srelplt->size != 0)
{
asection *sgotplt, *srelgot, *spltlittbl;
bfd_byte *loc;
unsigned rtld_reloc;
- srelgot = htab->srelgot;
+ srelgot = htab->elf.srelgot;
spltlittbl = htab->spltlittbl;
BFD_ASSERT (srelgot != NULL && spltlittbl != NULL);
break;
case DT_PLTGOT:
- dyn.d_un.d_ptr = (htab->sgot->output_section->vma
- + htab->sgot->output_offset);
+ dyn.d_un.d_ptr = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset);
break;
case DT_JMPREL:
- dyn.d_un.d_ptr = (htab->srelplt->output_section->vma
- + htab->srelplt->output_offset);
+ dyn.d_un.d_ptr = (htab->elf.srelplt->output_section->vma
+ + htab->elf.srelplt->output_offset);
break;
case DT_PLTRELSZ:
- dyn.d_un.d_val = htab->srelplt->size;
- break;
-
- case DT_RELASZ:
- /* Adjust RELASZ to not include JMPREL. This matches what
- glibc expects and what is done for several other ELF
- targets (e.g., i386, alpha), but the "correct" behavior
- seems to be unresolved. Since the linker script arranges
- for .rela.plt to follow all other relocation sections, we
- don't have to worry about changing the DT_RELA entry. */
- if (htab->srelplt)
- dyn.d_un.d_val -= htab->srelplt->size;
+ dyn.d_un.d_val = htab->elf.srelplt->size;
break;
}
object file when linking. */
static bfd_boolean
-elf_xtensa_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf_xtensa_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
unsigned out_mach, in_mach;
flagword out_flag, in_flag;
/* Check if we have the same endianness. */
- if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ if (!_bfd_generic_verify_endian_match (ibfd, info))
return FALSE;
/* Don't even pretend to support mixed-format linking. */
in_mach = in_flag & EF_XTENSA_MACH;
if (out_mach != in_mach)
{
- (*_bfd_error_handler)
- (_("%B: incompatible machine type. Output is 0x%x. Input is 0x%x"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: incompatible machine type; output is 0x%x; input is 0x%x"),
ibfd, out_mach, in_mach);
bfd_set_error (bfd_error_wrong_format);
return FALSE;
if (content_length < address)
{
- *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+ *error_message = _("attempt to convert L32R/CALLX to CALL failed");
return bfd_reloc_other;
}
direct_call_opcode = swap_callx_for_call_opcode (opcode);
if (direct_call_opcode == XTENSA_UNDEFINED)
{
- *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+ *error_message = _("attempt to convert L32R/CALLX to CALL failed");
return bfd_reloc_other;
}
/* The following text actions are generated:
- "ta_remove_insn" remove an instruction or instructions
- "ta_remove_longcall" convert longcall to call
+ "ta_remove_insn" remove an instruction or instructions
+ "ta_remove_longcall" convert longcall to call
"ta_convert_longcall" convert longcall to nop/call
- "ta_narrow_insn" narrow a wide instruction
- "ta_widen" widen a narrow instruction
- "ta_fill" add fill or remove fill
+ "ta_narrow_insn" narrow a wide instruction
+ "ta_widen" widen a narrow instruction
+ "ta_fill" add fill or remove fill
removed < 0 is a fill; branches to the fill address will be
changed to address + fill size (e.g., address - removed)
removed >= 0 branches to the fill address will stay unchanged
- "ta_remove_literal" remove a literal; this action is
+ "ta_remove_literal" remove a literal; this action is
indicated when a literal is removed
- or replaced.
- "ta_add_literal" insert a new literal; this action is
- indicated when a literal has been moved.
- It may use a virtual_offset because
+ or replaced.
+ "ta_add_literal" insert a new literal; this action is
+ indicated when a literal has been moved.
+ It may use a virtual_offset because
multiple literals can be placed at the
- same location.
+ same location.
For each of these text actions, we also record the number of bytes
removed by performing the text action. In the case of a "ta_widen"
enum text_action_enum_t
{
ta_none,
- ta_remove_insn, /* removed = -size */
- ta_remove_longcall, /* removed = -size */
- ta_convert_longcall, /* removed = 0 */
- ta_narrow_insn, /* removed = -1 */
- ta_widen_insn, /* removed = +1 */
- ta_fill, /* removed = +size */
+ ta_remove_insn, /* removed = -size */
+ ta_remove_longcall, /* removed = -size */
+ ta_convert_longcall, /* removed = 0 */
+ ta_narrow_insn, /* removed = -1 */
+ ta_widen_insn, /* removed = +1 */
+ ta_fill, /* removed = +size */
ta_remove_literal,
ta_add_literal
};
entry_end - ebb->end_offset);
if (insn_block_len != (entry_end - ebb->end_offset))
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
- ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
+ "possible configuration mismatch"),
+ ebb->sec->owner, ebb->sec,
+ (uint64_t) (ebb->end_offset + insn_block_len));
return FALSE;
}
ebb->end_offset += insn_block_len;
ebb->start_offset - block_begin);
if (insn_block_len != ebb->start_offset - block_begin)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
- ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
+ "possible configuration mismatch"),
+ ebb->sec->owner, ebb->sec,
+ (uint64_t) (ebb->end_offset + insn_block_len));
return FALSE;
}
ebb->start_offset -= insn_block_len;
continue;
/* Count PC-relative operand relocations against the target section.
- Note: The conditions tested here must match the conditions under
+ Note: The conditions tested here must match the conditions under
which init_source_reloc is called in collect_source_relocs(). */
is_l32r_reloc = FALSE;
if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
reloc[i].irel = irel;
/* Every relocation won't possibly be checked in the optimized version of
- check_section_ebb_pcrels_fit, so this needs to be done here. */
+ check_section_ebb_pcrels_fit, so this needs to be done here. */
if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
{
/* None of the current alternate relocs are PC-relative,
simplify_size = get_asm_simplify_size (contents, sec_size, r_offset);
if (simplify_size == 0)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"),
- sec->owner, sec, r_offset);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction for "
+ "XTENSA_ASM_SIMPLIFY relocation; "
+ "possible configuration mismatch"),
+ sec->owner, sec, (uint64_t) r_offset);
continue;
}
return TRUE;
decode_error:
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
- ebb->sec->owner, ebb->sec, offset);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
+ "possible configuration mismatch"),
+ ebb->sec->owner, ebb->sec, (uint64_t) offset);
return FALSE;
}
continue;
/* The original and new output section for these must be the same
- in order to coalesce. */
+ in order to coalesce. */
if (r_reloc_get_section (&reloc[i].r_rel)->output_section
!= sec->output_section)
return FALSE;
/* Update the action so that the code that moves
the contents will do the right thing. */
/* ta_remove_longcall and ta_remove_insn actions are
- grouped together in the tree as well as
+ grouped together in the tree as well as
ta_convert_longcall and ta_none, so that changes below
can be done w/o removing and reinserting action into
the tree. */
if (dynamic_symbol && r_type == R_XTENSA_PLT)
{
- srel = htab->srelplt;
+ srel = htab->elf.srelplt;
is_plt = TRUE;
}
else
- srel = htab->srelgot;
+ srel = htab->elf.srelgot;
/* Reduce size of the .rela.* section by one reloc. */
BFD_ASSERT (srel != NULL);
if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0)
{
/* The two magic GOT entries for that chunk can go away. */
- srelgot = htab->srelgot;
+ srelgot = htab->elf.srelgot;
BFD_ASSERT (srelgot != NULL);
srelgot->reloc_count -= 2;
srelgot->size -= 2 * sizeof (Elf32_External_Rela);
predef_flags = xtensa_get_property_predef_flags (sec);
/* Walk over memory and relocations at the same time.
- This REQUIRES that the internal_relocs be sorted by offset. */
+ This REQUIRES that the internal_relocs be sorted by offset. */
qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
internal_reloc_compare);
{
if (r_type != R_XTENSA_ASM_EXPAND)
{
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): unexpected fix for %s relocation"),
- input_bfd, input_section, rel->r_offset,
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB(%pA+%#" PRIx64 "): unexpected fix for %s relocation"),
+ input_bfd, input_section, (uint64_t) rel->r_offset,
elf_howto_table[r_type].name);
return FALSE;
}
static asection *
elf_xtensa_get_plt_section (struct bfd_link_info *info, int chunk)
{
- struct elf_xtensa_link_hash_table *htab;
bfd *dynobj;
- char plt_name[10];
+ char plt_name[17];
if (chunk == 0)
- {
- htab = elf_xtensa_hash_table (info);
- if (htab == NULL)
- return NULL;
-
- return htab->splt;
- }
+ return elf_hash_table (info)->splt;
dynobj = elf_hash_table (info)->dynobj;
sprintf (plt_name, ".plt.%u", chunk);
static asection *
elf_xtensa_get_gotplt_section (struct bfd_link_info *info, int chunk)
{
- struct elf_xtensa_link_hash_table *htab;
bfd *dynobj;
- char got_name[14];
+ char got_name[21];
if (chunk == 0)
- {
- htab = elf_xtensa_hash_table (info);
- if (htab == NULL)
- return NULL;
- return htab->sgotplt;
- }
+ return elf_hash_table (info)->sgotplt;
dynobj = elf_hash_table (info)->dynobj;
sprintf (got_name, ".got.plt.%u", chunk);
struct elf_link_hash_entry *h = elf_sym_hashes (abfd)[indx];
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;
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
switch (h->root.type)
{
elf_sym_hashes (abfd)[indx];
while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
+ || h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
if (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
+ || h->root.type == bfd_link_hash_defweak)
offset = h->root.u.def.value;
}
return offset;
suffix = sec->name + linkonce_len;
/* For backward compatibility, replace "t." instead of inserting
- the new linkonce_kind (but not for "prop" sections). */
+ the new linkonce_kind (but not for "prop" sections). */
if (CONST_STRNEQ (suffix, "t.") && linkonce_kind[1] == '.')
- suffix += 2;
+ suffix += 2;
strcat (prop_sec_name + linkonce_len, suffix);
}
else
/* Find the corresponding ".got.plt*" section. */
if (sec->name[4] == '\0')
- sgotplt = bfd_get_linker_section (sec->owner, ".got.plt");
+ sgotplt = elf_hash_table (link_info)->sgotplt;
else
{
char got_name[14];
{
{ STRING_COMMA_LEN (".fini.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
{ STRING_COMMA_LEN (".init.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
- { STRING_COMMA_LEN (".literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
- { STRING_COMMA_LEN (".xtensa.info"), 0, SHT_NOTE, 0 },
- { NULL, 0, 0, 0, 0 }
+ { STRING_COMMA_LEN (".literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".xtensa.info"), 0, SHT_NOTE, 0 },
+ { NULL, 0, 0, 0, 0 }
};
\f
#define ELF_TARGET_ID XTENSA_ELF_DATA
#define ELF_MACHINE_CODE EM_XTENSA
#define ELF_MACHINE_ALT1 EM_XTENSA_OLD
-#if XCHAL_HAVE_MMU
-#define ELF_MAXPAGESIZE (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
-#else /* !XCHAL_HAVE_MMU */
-#define ELF_MAXPAGESIZE 1
-#endif /* !XCHAL_HAVE_MMU */
+#define ELF_MAXPAGESIZE 0x1000
#endif /* ELF_ARCH */
#define elf_backend_can_gc_sections 1
#define elf_backend_got_header_size 4
#define elf_backend_want_dynbss 0
#define elf_backend_want_got_plt 1
+#define elf_backend_dtrel_excludes_plt 1
#define elf_info_to_howto elf_xtensa_info_to_howto_rela
#define elf_backend_finish_dynamic_sections elf_xtensa_finish_dynamic_sections
#define elf_backend_finish_dynamic_symbol elf_xtensa_finish_dynamic_symbol
#define elf_backend_gc_mark_hook elf_xtensa_gc_mark_hook
-#define elf_backend_gc_sweep_hook elf_xtensa_gc_sweep_hook
#define elf_backend_grok_prstatus elf_xtensa_grok_prstatus
#define elf_backend_grok_psinfo elf_xtensa_grok_psinfo
#define elf_backend_hide_symbol elf_xtensa_hide_symbol
#define elf_backend_relocate_section elf_xtensa_relocate_section
#define elf_backend_size_dynamic_sections elf_xtensa_size_dynamic_sections
#define elf_backend_always_size_sections elf_xtensa_always_size_sections
-#define elf_backend_omit_section_dynsym \
- ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
#define elf_backend_special_sections elf_xtensa_special_sections
#define elf_backend_action_discarded elf_xtensa_action_discarded
#define elf_backend_copy_indirect_symbol elf_xtensa_copy_indirect_symbol