/* Xtensa-specific support for 32-bit ELF.
- Copyright (C) 2003-2021 Free Software Foundation, Inc.
+ Copyright (C) 2003-2023 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#include "elf/xtensa.h"
#include "splay-tree.h"
#include "xtensa-isa.h"
-#include "xtensa-config.h"
+#include "xtensa-dynconfig.h"
/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
#define OCTETS_PER_BYTE(ABFD, SEC) 1
#define XTENSA_NO_NOP_REMOVAL 0
-#ifndef XSHAL_ABI
-#define XSHAL_ABI 0
-#endif
-
#ifndef XTHAL_ABI_UNDEFINED
#define XTHAL_ABI_UNDEFINED -1
#endif
-#ifndef XTHAL_ABI_WINDOWED
-#define XTHAL_ABI_WINDOWED 0
-#endif
-
-#ifndef XTHAL_ABI_CALL0
-#define XTHAL_ABI_CALL0 1
-#endif
-
/* Local helper functions. */
static bool add_extra_plt_sections (struct bfd_link_info *, int);
\f
static reloc_howto_type elf_howto_table[] =
{
- HOWTO (R_XTENSA_NONE, 0, 3, 0, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_NONE, 0, 0, 0, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_NONE",
false, 0, 0, false),
- HOWTO (R_XTENSA_32, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_32, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_32",
true, 0xffffffff, 0xffffffff, false),
special: 1 means to substitute a pointer to the runtime linker's
dynamic resolver function; 2 means to substitute the link map for
the shared object. */
- HOWTO (R_XTENSA_RTLD, 0, 2, 32, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_RTLD, 0, 4, 32, false, 0, complain_overflow_dont,
NULL, "R_XTENSA_RTLD", false, 0, 0, false),
- HOWTO (R_XTENSA_GLOB_DAT, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_GLOB_DAT, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_XTENSA_GLOB_DAT",
false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_JMP_SLOT, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_JMP_SLOT, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_XTENSA_JMP_SLOT",
false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_RELATIVE, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_RELATIVE, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_XTENSA_RELATIVE",
false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_PLT, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_PLT, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_PLT",
false, 0, 0xffffffff, false),
EMPTY_HOWTO (13),
- HOWTO (R_XTENSA_32_PCREL, 0, 2, 32, true, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_32_PCREL, 0, 4, 32, true, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_32_PCREL",
false, 0, 0xffffffff, true),
/* GNU extension to record C++ vtable hierarchy. */
- HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 2, 0, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 4, 0, false, 0, complain_overflow_dont,
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,
+ HOWTO (R_XTENSA_GNU_VTENTRY, 0, 4, 0, false, 0, complain_overflow_dont,
_bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY",
false, 0, 0, false),
/* Relocations for supporting difference of symbols. */
- HOWTO (R_XTENSA_DIFF8, 0, 0, 8, false, 0, complain_overflow_signed,
+ HOWTO (R_XTENSA_DIFF8, 0, 1, 8, false, 0, complain_overflow_signed,
bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", false, 0, 0xff, false),
- HOWTO (R_XTENSA_DIFF16, 0, 1, 16, false, 0, complain_overflow_signed,
+ HOWTO (R_XTENSA_DIFF16, 0, 2, 16, false, 0, complain_overflow_signed,
bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", false, 0, 0xffff, false),
- HOWTO (R_XTENSA_DIFF32, 0, 2, 32, false, 0, complain_overflow_signed,
+ HOWTO (R_XTENSA_DIFF32, 0, 4, 32, false, 0, complain_overflow_signed,
bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", false, 0, 0xffffffff, false),
/* General immediate operand relocations. */
bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT", false, 0, 0, true),
/* TLS relocations. */
- HOWTO (R_XTENSA_TLSDESC_FN, 0, 2, 32, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_TLSDESC_FN, 0, 4, 32, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_TLSDESC_FN",
false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_TLSDESC_ARG, 0, 2, 32, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_TLSDESC_ARG, 0, 4, 32, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_TLSDESC_ARG",
false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_TLS_DTPOFF, 0, 2, 32, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_TLS_DTPOFF, 0, 4, 32, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_TLS_DTPOFF",
false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_TLS_TPOFF, 0, 2, 32, false, 0, complain_overflow_dont,
+ HOWTO (R_XTENSA_TLS_TPOFF, 0, 4, 32, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_TLS_TPOFF",
false, 0, 0xffffffff, false),
HOWTO (R_XTENSA_TLS_FUNC, 0, 0, 0, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_TLS_CALL",
false, 0, 0, false),
- HOWTO (R_XTENSA_PDIFF8, 0, 0, 8, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_PDIFF8, 0, 1, 8, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF8", false, 0, 0xff, false),
- HOWTO (R_XTENSA_PDIFF16, 0, 1, 16, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_PDIFF16, 0, 2, 16, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF16", false, 0, 0xffff, false),
- HOWTO (R_XTENSA_PDIFF32, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_PDIFF32, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF32", false, 0, 0xffffffff, false),
- HOWTO (R_XTENSA_NDIFF8, 0, 0, 8, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_NDIFF8, 0, 1, 8, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF8", false, 0, 0xff, false),
- HOWTO (R_XTENSA_NDIFF16, 0, 1, 16, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_NDIFF16, 0, 2, 16, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF16", false, 0, 0xffff, false),
- HOWTO (R_XTENSA_NDIFF32, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO (R_XTENSA_NDIFF32, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF32", false, 0, 0xffffffff, false),
};
flagword predef_flags;
bfd_size_type table_entry_size, section_limit;
- if (!section
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
+ || !section
|| !(section->flags & SEC_ALLOC)
|| (section->flags & SEC_DEBUGGING))
{
table_entry_size -= 4;
num_records = table_size / table_entry_size;
+
table_data = retrieve_contents (abfd, table_section, true);
+ if (table_data == NULL)
+ {
+ *table_p = NULL;
+ return 0;
+ }
+
blocks = (property_table_entry *)
bfd_malloc (num_records * sizeof (property_table_entry));
block_count = 0;
switch (r_type)
{
case R_XTENSA_TLSDESC_FN:
- if (bfd_link_pic (info))
+ if (bfd_link_dll (info))
{
tls_type = GOT_TLS_GD;
is_got = true;
break;
case R_XTENSA_TLSDESC_ARG:
- if (bfd_link_pic (info))
+ if (bfd_link_dll (info))
{
tls_type = GOT_TLS_GD;
is_got = true;
else
{
tls_type = GOT_TLS_IE;
- if (h && elf_xtensa_hash_entry (h) != htab->tlsbase)
+ if (h && elf_xtensa_hash_entry (h) != htab->tlsbase
+ && elf_xtensa_dynamic_symbol_p (h, info))
is_got = true;
}
break;
case R_XTENSA_TLS_DTPOFF:
- if (bfd_link_pic (info))
+ if (bfd_link_dll (info))
tls_type = GOT_TLS_GD;
else
tls_type = GOT_TLS_IE;
tls_type = GOT_TLS_IE;
if (bfd_link_pic (info))
info->flags |= DF_STATIC_TLS;
- if (bfd_link_pic (info) || h)
+ if (bfd_link_dll (info) || elf_xtensa_dynamic_symbol_p (h, info))
is_got = true;
break;
return bfd_reloc_dangerous;
}
+ if (input_size <= address)
+ return bfd_reloc_outofrange;
/* Read the instruction into a buffer and decode the opcode. */
xtensa_insnbuf_from_chars (isa, ibuff, contents + address,
input_size - address);
case R_XTENSA_TLS_TPOFF:
/* Switch to LE model for local symbols in an executable. */
- if (! bfd_link_pic (info) && ! dynamic_symbol)
+ if (! bfd_link_dll (info) && ! dynamic_symbol)
{
relocation = tpoff (info, relocation);
break;
{
if (r_type == R_XTENSA_TLSDESC_FN)
{
- if (! bfd_link_pic (info) || (tls_type & GOT_TLS_IE) != 0)
+ if (! bfd_link_dll (info) || (tls_type & GOT_TLS_IE) != 0)
r_type = R_XTENSA_NONE;
}
else if (r_type == R_XTENSA_TLSDESC_ARG)
{
- if (bfd_link_pic (info))
+ if (bfd_link_dll (info))
{
if ((tls_type & GOT_TLS_IE) != 0)
r_type = R_XTENSA_TLS_TPOFF;
break;
case R_XTENSA_TLS_DTPOFF:
- if (! bfd_link_pic (info))
+ if (! bfd_link_dll (info))
/* Switch from LD model to LE model. */
relocation = tpoff (info, relocation);
else
int offset;
unsigned int size;
+ if (elf_tdata (abfd) == NULL
+ || elf_tdata (abfd)->core == NULL)
+ return false;
+
/* The size for Xtensa is variable, so don't try to recognize the format
based on the size. Just assume this is GNU/Linux. */
+ if (note == NULL || note->descsz < 28)
+ return false;
/* pr_cursig */
elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
size, note->descpos + offset);
}
-
static bool
elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
else
fprintf (fp, " ?? + ");
- fprintf_vma (fp, r_rel->target_offset);
+ fprintf (fp, "%" PRIx64, (uint64_t) r_rel->target_offset);
if (r_rel->virtual_offset)
- {
- fprintf (fp, " + ");
- fprintf_vma (fp, r_rel->virtual_offset);
- }
+ fprintf (fp, " + %" PRIx64, (uint64_t) r_rel->virtual_offset);
fprintf (fp, ")");
}
(if undefined or weak). */
h1 = r_reloc_get_hash_entry (&src1->r_rel);
h2 = r_reloc_get_hash_entry (&src2->r_rel);
+
+ /* Keep start_stop literals always unique to avoid dropping it due to them
+ having late initialization.
+ Now they are equal because initialized with zeroed values. */
+ if (h2 && h2->start_stop)
+ return false;
+
if (r_reloc_is_defined (&src1->r_rel)
&& (final_static_link
|| ((!h1 || h1->root.type != bfd_link_hash_defweak)