/* Xtensa-specific support for 32-bit ELF.
- Copyright 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
/* Local helper functions. */
-static bfd_boolean add_extra_plt_sections (bfd *, int);
+static bfd_boolean add_extra_plt_sections (struct bfd_link_info *, int);
static char *vsprint_msg (const char *, const char *, int, ...) ATTRIBUTE_PRINTF(2,4);
static bfd_reloc_status_type bfd_elf_xtensa_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
/* Miscellaneous utility functions. */
-static asection *elf_xtensa_get_plt_section (bfd *, int);
-static asection *elf_xtensa_get_gotplt_section (bfd *, int);
+static asection *elf_xtensa_get_plt_section (struct bfd_link_info *, int);
+static asection *elf_xtensa_get_gotplt_section (struct bfd_link_info *, int);
static asection *get_elf_r_symndx_section (bfd *, unsigned long);
static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry
(bfd *, unsigned long);
typedef struct xtensa_relax_info_struct xtensa_relax_info;
-/* Total count of PLT relocations seen during check_relocs.
- The actual PLT code must be split into multiple sections and all
- the sections have to be created before size_dynamic_sections,
- where we figure out the exact number of PLT entries that will be
- needed. It is OK if this count is an overestimate, e.g., some
- relocations may be removed by GC. */
-
-static int plt_reloc_count = 0;
-
-
/* The GNU tools do not easily allow extending interfaces to pass around
the pointer to the Xtensa ISA information, so instead we add a global
variable here (in BFD) that can be used by any of the tools that need
{
HOWTO (R_XTENSA_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_NONE",
- FALSE, 0x00000000, 0x00000000, FALSE),
+ FALSE, 0, 0, FALSE),
HOWTO (R_XTENSA_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_32",
TRUE, 0xffffffff, 0xffffffff, FALSE),
+
/* Replace a 32-bit value with a value from the runtime linker (only
used by linker-generated stub functions). The r_addend value is
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,
- NULL, "R_XTENSA_RTLD",
- FALSE, 0x00000000, 0x00000000, FALSE),
+ NULL, "R_XTENSA_RTLD", FALSE, 0, 0, FALSE),
+
HOWTO (R_XTENSA_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_XTENSA_GLOB_DAT",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ FALSE, 0, 0xffffffff, FALSE),
HOWTO (R_XTENSA_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_XTENSA_JMP_SLOT",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ FALSE, 0, 0xffffffff, FALSE),
HOWTO (R_XTENSA_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_XTENSA_RELATIVE",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ FALSE, 0, 0xffffffff, FALSE),
HOWTO (R_XTENSA_PLT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
bfd_elf_xtensa_reloc, "R_XTENSA_PLT",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ FALSE, 0, 0xffffffff, FALSE),
+
EMPTY_HOWTO (7),
+
+ /* Old relocations for backward compatibility. */
HOWTO (R_XTENSA_OP0, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_OP0",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_OP0", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_OP1, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_OP1",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_OP1", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_OP2, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_OP2",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_OP2", FALSE, 0, 0, TRUE),
+
/* Assembly auto-expansion. */
HOWTO (R_XTENSA_ASM_EXPAND, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_ASM_EXPAND",
- FALSE, 0x00000000, 0x00000000, FALSE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_ASM_EXPAND", FALSE, 0, 0, TRUE),
/* Relax assembly auto-expansion. */
HOWTO (R_XTENSA_ASM_SIMPLIFY, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_ASM_SIMPLIFY",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_ASM_SIMPLIFY", FALSE, 0, 0, TRUE),
+
EMPTY_HOWTO (13),
EMPTY_HOWTO (14),
+
/* 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",
- FALSE, 0x00000000, 0x00000000, FALSE),
+ 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",
- FALSE, 0x00000000, 0x00000000, FALSE),
+ FALSE, 0, 0, FALSE),
/* Relocations for supporting difference of symbols. */
HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
- bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE),
HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
- bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE),
HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
- bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32",
- FALSE, 0xffffffff, 0xffffffff, FALSE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE),
/* General immediate operand relocations. */
HOWTO (R_XTENSA_SLOT0_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT1_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT2_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT3_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT4_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT5_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT6_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT7_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT8_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT9_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT10_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT11_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT12_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT13_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_OP", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT14_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_OP",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_OP", FALSE, 0, 0, TRUE),
/* "Alternate" relocations. The meaning of these is opcode-specific. */
HOWTO (R_XTENSA_SLOT0_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT1_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT2_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT3_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT4_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT5_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT6_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT7_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT8_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT9_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT10_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT11_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT12_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT13_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE),
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_ALT", FALSE, 0, 0, TRUE),
HOWTO (R_XTENSA_SLOT14_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
- bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT",
- FALSE, 0x00000000, 0x00000000, TRUE)
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT", FALSE, 0, 0, TRUE),
};
#if DEBUG_GEN_RELOC
0 /* unused */
};
+/* Xtensa ELF linker hash table. */
+
+struct elf_xtensa_link_hash_table
+{
+ 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;
+
+ /* Total count of PLT relocations seen during check_relocs.
+ The actual PLT code must be split into multiple sections and all
+ the sections have to be created before size_dynamic_sections,
+ where we figure out the exact number of PLT entries that will be
+ needed. It is OK if this count is an overestimate, e.g., some
+ relocations may be removed by GC. */
+ int plt_reloc_count;
+};
+
+/* Get the Xtensa ELF linker hash table from a link_info structure. */
+
+#define elf_xtensa_hash_table(p) \
+ ((struct elf_xtensa_link_hash_table *) ((p)->hash))
+
+/* Create an Xtensa ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_xtensa_link_hash_table_create (bfd *abfd)
+{
+ struct elf_xtensa_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_xtensa_link_hash_table);
+
+ ret = bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ _bfd_elf_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->sgot = NULL;
+ ret->sgotplt = NULL;
+ ret->srelgot = NULL;
+ ret->splt = NULL;
+ ret->srelplt = NULL;
+ ret->sgotloc = NULL;
+ ret->spltlittbl = NULL;
+
+ ret->plt_reloc_count = 0;
+
+ return &ret->elf.root;
+}
static inline bfd_boolean
-xtensa_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
+elf_xtensa_dynamic_symbol_p (struct elf_link_hash_entry *h,
struct bfd_link_info *info)
{
/* Check if we should do dynamic things to this symbol. The
asection *sec,
const Elf_Internal_Rela *relocs)
{
+ struct elf_xtensa_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel;
if (info->relocatable)
return TRUE;
+ htab = elf_xtensa_hash_table (info);
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
/* Keep track of the total PLT relocation count even if we
don't yet know whether the dynamic sections will be
created. */
- plt_reloc_count += 1;
+ htab->plt_reloc_count += 1;
if (elf_hash_table (info)->dynamic_sections_created)
{
- if (!add_extra_plt_sections (elf_hash_table (info)->dynobj,
- plt_reloc_count))
+ if (! add_extra_plt_sections (info, htab->plt_reloc_count))
return FALSE;
}
}
}
-static void
-elf_xtensa_make_sym_local (struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
-{
- if (info->shared)
- {
- if (h->plt.refcount > 0)
- {
- /* Will 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;
- }
- }
- else
- {
- /* Don't need any dynamic relocations at all. */
- h->plt.refcount = 0;
- h->got.refcount = 0;
- }
-}
-
-
-static void
-elf_xtensa_hide_symbol (struct bfd_link_info *info,
- 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. */
- elf_xtensa_make_sym_local (info, h);
-
- _bfd_elf_link_hash_hide_symbol (info, h, force_local);
-}
-
-
/* Return the section that should be marked against GC for a given
relocation. */
static bfd_boolean
elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
{
+ struct elf_xtensa_link_hash_table *htab;
flagword flags, noalloc_flags;
- asection *s;
+
+ htab = elf_xtensa_hash_table (info);
/* First do all the standard stuff. */
if (! _bfd_elf_create_dynamic_sections (dynobj, info))
return FALSE;
+ htab->splt = bfd_get_section_by_name (dynobj, ".plt");
+ htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
+ htab->sgot = bfd_get_section_by_name (dynobj, ".got");
+ htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
/* Create any extra PLT sections in case check_relocs has already
been called on all the non-dynamic input files. */
- if (!add_extra_plt_sections (dynobj, plt_reloc_count))
+ if (! add_extra_plt_sections (info, htab->plt_reloc_count))
return FALSE;
noalloc_flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
flags = noalloc_flags | SEC_ALLOC | SEC_LOAD;
/* Mark the ".got.plt" section READONLY. */
- s = bfd_get_section_by_name (dynobj, ".got.plt");
- if (s == NULL
- || ! bfd_set_section_flags (dynobj, s, flags))
+ if (htab->sgotplt == NULL
+ || ! bfd_set_section_flags (dynobj, htab->sgotplt, flags))
return FALSE;
/* Create ".rela.got". */
- s = bfd_make_section_with_flags (dynobj, ".rela.got", flags);
- if (s == NULL
- || ! bfd_set_section_alignment (dynobj, s, 2))
+ htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got", flags);
+ if (htab->srelgot == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
return FALSE;
/* Create ".got.loc" (literal tables for use by dynamic linker). */
- s = bfd_make_section_with_flags (dynobj, ".got.loc", flags);
- if (s == NULL
- || ! bfd_set_section_alignment (dynobj, s, 2))
+ htab->sgotloc = bfd_make_section_with_flags (dynobj, ".got.loc", flags);
+ if (htab->sgotloc == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->sgotloc, 2))
return FALSE;
/* Create ".xt.lit.plt" (literal table for ".got.plt*"). */
- s = bfd_make_section_with_flags (dynobj, ".xt.lit.plt",
- noalloc_flags);
- if (s == NULL
- || ! bfd_set_section_alignment (dynobj, s, 2))
+ htab->spltlittbl = bfd_make_section_with_flags (dynobj, ".xt.lit.plt",
+ noalloc_flags);
+ if (htab->spltlittbl == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->spltlittbl, 2))
return FALSE;
return TRUE;
static bfd_boolean
-add_extra_plt_sections (bfd *dynobj, int count)
+add_extra_plt_sections (struct bfd_link_info *info, int count)
{
+ bfd *dynobj = elf_hash_table (info)->dynobj;
int chunk;
/* Iterate over all chunks except 0 which uses the standard ".plt" and
asection *s;
/* Stop when we find a section has already been created. */
- if (elf_xtensa_get_plt_section (dynobj, chunk))
+ if (elf_xtensa_get_plt_section (info, chunk))
break;
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
static bfd_boolean
-elf_xtensa_fix_refcounts (struct elf_link_hash_entry *h, void *arg)
+elf_xtensa_allocate_dynrelocs (struct elf_link_hash_entry *h, void *arg)
{
- struct bfd_link_info *info = (struct bfd_link_info *) arg;
-
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
- if (! xtensa_elf_dynamic_symbol_p (h, info))
- elf_xtensa_make_sym_local (info, h);
+ struct bfd_link_info *info;
+ struct elf_xtensa_link_hash_table *htab;
+ bfd_boolean is_dynamic;
- return TRUE;
-}
-
-
-static bfd_boolean
-elf_xtensa_allocate_plt_size (struct elf_link_hash_entry *h, void *arg)
-{
- asection *srelplt = (asection *) arg;
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
- if (h->plt.refcount > 0)
- srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
-
- return TRUE;
-}
+ info = (struct bfd_link_info *) arg;
+ htab = elf_xtensa_hash_table (info);
+ is_dynamic = elf_xtensa_dynamic_symbol_p (h, info);
-static bfd_boolean
-elf_xtensa_allocate_got_size (struct elf_link_hash_entry *h, void *arg)
-{
- asection *srelgot = (asection *) arg;
+ if (! is_dynamic)
+ {
+ if (info->shared)
+ {
+ /* For shared objects, there's no need for PLT entries for local
+ symbols (use RELATIVE relocs instead of JMP_SLOT relocs). */
+ if (h->plt.refcount > 0)
+ {
+ if (h->got.refcount < 0)
+ h->got.refcount = 0;
+ h->got.refcount += h->plt.refcount;
+ h->plt.refcount = 0;
+ }
+ }
+ else
+ {
+ /* Don't need any dynamic relocations at all. */
+ h->plt.refcount = 0;
+ h->got.refcount = 0;
+ }
+ }
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->plt.refcount > 0)
+ htab->srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
if (h->got.refcount > 0)
- srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
+ htab->srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
return TRUE;
}
static void
-elf_xtensa_allocate_local_got_size (struct bfd_link_info *info,
- asection *srelgot)
+elf_xtensa_allocate_local_got_size (struct bfd_link_info *info)
{
+ struct elf_xtensa_link_hash_table *htab;
bfd *i;
+ htab = elf_xtensa_hash_table (info);
+
for (i = info->input_bfds; i; i = i->link_next)
{
bfd_signed_vma *local_got_refcounts;
for (j = 0; j < cnt; ++j)
{
if (local_got_refcounts[j] > 0)
- srelgot->size += (local_got_refcounts[j]
- * sizeof (Elf32_External_Rela));
+ htab->srelgot->size += (local_got_refcounts[j]
+ * sizeof (Elf32_External_Rela));
}
}
}
elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info)
{
+ struct elf_xtensa_link_hash_table *htab;
bfd *dynobj, *abfd;
asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc;
bfd_boolean relplt, relgot;
plt_entries = 0;
plt_chunks = 0;
- srelgot = 0;
+ htab = elf_xtensa_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
if (dynobj == NULL)
abort ();
+ srelgot = htab->srelgot;
+ srelplt = htab->srelplt;
if (elf_hash_table (info)->dynamic_sections_created)
{
+ BFD_ASSERT (htab->srelgot != NULL
+ && htab->srelplt != NULL
+ && htab->sgot != NULL
+ && htab->spltlittbl != NULL
+ && htab->sgotloc != NULL);
+
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
}
/* Allocate room for one word in ".got". */
- s = bfd_get_section_by_name (dynobj, ".got");
- if (s == NULL)
- abort ();
- s->size = 4;
+ htab->sgot->size = 4;
- /* Adjust refcounts for symbols that we now know are not "dynamic". */
+ /* Allocate space in ".rela.got" for literals that reference global
+ symbols and space in ".rela.plt" for literals that have PLT
+ entries. */
elf_link_hash_traverse (elf_hash_table (info),
- elf_xtensa_fix_refcounts,
+ elf_xtensa_allocate_dynrelocs,
(void *) info);
- /* Allocate space in ".rela.got" for literals that reference
- global symbols. */
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
- if (srelgot == NULL)
- abort ();
- elf_link_hash_traverse (elf_hash_table (info),
- elf_xtensa_allocate_got_size,
- (void *) srelgot);
-
/* If we are generating a shared object, we also need space in
".rela.got" for R_XTENSA_RELATIVE relocs for literals that
reference local symbols. */
if (info->shared)
- elf_xtensa_allocate_local_got_size (info, srelgot);
-
- /* Allocate space in ".rela.plt" for literals that have PLT entries. */
- srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
- if (srelplt == NULL)
- abort ();
- elf_link_hash_traverse (elf_hash_table (info),
- elf_xtensa_allocate_plt_size,
- (void *) srelplt);
+ elf_xtensa_allocate_local_got_size (info);
/* Allocate space in ".plt" to match the size of ".rela.plt". For
each PLT entry, we need the PLT code plus a 4-byte literal.
For each chunk of ".plt", we also need two more 4-byte
literals, two corresponding entries in ".rela.got", and an
8-byte entry in ".xt.lit.plt". */
- spltlittbl = bfd_get_section_by_name (dynobj, ".xt.lit.plt");
- if (spltlittbl == NULL)
- abort ();
-
+ spltlittbl = htab->spltlittbl;
plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
plt_chunks =
(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
created earlier because the initial count of PLT relocations
was an overestimate. */
for (chunk = 0;
- (splt = elf_xtensa_get_plt_section (dynobj, chunk)) != NULL;
+ (splt = elf_xtensa_get_plt_section (info, chunk)) != NULL;
chunk++)
{
int chunk_entries;
- sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
- if (sgotplt == NULL)
- abort ();
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
+ BFD_ASSERT (sgotplt != NULL);
if (chunk < plt_chunks - 1)
chunk_entries = PLT_ENTRIES_PER_CHUNK;
/* Allocate space in ".got.loc" to match the total size of all the
literal tables. */
- sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
- if (sgotloc == NULL)
- abort ();
+ sgotloc = htab->sgotloc;
sgotloc->size = spltlittbl->size;
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
{
/* Add the special XTENSA_RTLD relocations now. The offsets won't be
known until finish_dynamic_sections, but we need to get the relocs
in place before they are sorted. */
- if (srelgot == NULL)
- abort ();
for (chunk = 0; chunk < plt_chunks; chunk++)
{
Elf_Internal_Rela irela;
/* Set up an entry in the procedure linkage table. */
static bfd_vma
-elf_xtensa_create_plt_entry (bfd *dynobj,
+elf_xtensa_create_plt_entry (struct bfd_link_info *info,
bfd *output_bfd,
unsigned reloc_index)
{
int chunk;
chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
- splt = elf_xtensa_get_plt_section (dynobj, chunk);
- sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
+ splt = elf_xtensa_get_plt_section (info, chunk);
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
BFD_ASSERT (splt != NULL && sgotplt != NULL);
plt_base = splt->output_section->vma + splt->output_offset;
Elf_Internal_Sym *local_syms,
asection **local_sections)
{
+ struct elf_xtensa_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
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)
xtensa_default_isa = xtensa_isa_init (0, 0);
- dynobj = elf_hash_table (info)->dynobj;
+ htab = elf_xtensa_hash_table (info);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
- srelgot = NULL;
- srelplt = NULL;
- if (dynobj)
- {
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");;
- 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,
/* Generate dynamic relocations. */
if (elf_hash_table (info)->dynamic_sections_created)
{
- bfd_boolean dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info);
+ bfd_boolean dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
if (dynamic_symbol && is_operand_relocation (r_type))
{
asection *srel;
if (dynamic_symbol && r_type == R_XTENSA_PLT)
- srel = srelplt;
+ srel = htab->srelplt;
else
- srel = srelgot;
+ srel = htab->srelgot;
BFD_ASSERT (srel != NULL);
contents of the literal entry to the address of
the PLT entry. */
relocation =
- elf_xtensa_create_plt_entry (dynobj, output_bfd,
+ elf_xtensa_create_plt_entry (info, output_bfd,
srel->reloc_count);
}
unresolved_reloc = FALSE;
if (unresolved_reloc
&& !((input_section->flags & SEC_DEBUGGING) != 0
&& h->def_dynamic))
- (*_bfd_error_handler)
- (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
- input_bfd,
- input_section,
- (long) rel->r_offset,
- howto->name,
- h->root.root.string);
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+
+ if (r_symndx == 0)
+ {
+ /* r_symndx will be zero only for relocs against symbols from
+ removed linkonce sections, or sections discarded by a linker
+ script. For these relocs, we just want the section contents
+ zeroed. Avoid any special processing. */
+ _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+ continue;
+ }
/* There's no point in calling bfd_perform_relocation here.
Just go directly to our "special function". */
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
- if (h->needs_plt
- && !h->def_regular)
+ if (h->needs_plt && !h->def_regular)
{
/* Mark the symbol as undefined, rather than as defined in
the .plt section. Leave the value alone. */
sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
}
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
+ struct elf_xtensa_link_hash_table *htab;
bfd *dynobj;
asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc;
Elf32_External_Dyn *dyncon, *dynconend;
if (! elf_hash_table (info)->dynamic_sections_created)
return TRUE;
+ htab = elf_xtensa_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
BFD_ASSERT (sdyn != NULL);
/* Set the first entry in the global offset table to the address of
the dynamic section. */
- sgot = bfd_get_section_by_name (dynobj, ".got");
+ sgot = htab->sgot;
if (sgot)
{
BFD_ASSERT (sgot->size == 4);
sgot->contents);
}
- srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
+ srelplt = htab->srelplt;
if (srelplt && srelplt->size != 0)
{
asection *sgotplt, *srelgot, *spltlittbl;
bfd_byte *loc;
unsigned rtld_reloc;
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");;
- BFD_ASSERT (srelgot != NULL);
-
- spltlittbl = bfd_get_section_by_name (dynobj, ".xt.lit.plt");
- BFD_ASSERT (spltlittbl != NULL);
+ srelgot = htab->srelgot;
+ spltlittbl = htab->spltlittbl;
+ BFD_ASSERT (srelgot != NULL && spltlittbl != NULL);
/* Find the first XTENSA_RTLD relocation. Presumably the rest
of them follow immediately after.... */
{
int chunk_entries = 0;
- sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
BFD_ASSERT (sgotplt != NULL);
/* Emit special RTLD relocations for the first two entries in
/* Combine adjacent literal table entries. */
BFD_ASSERT (! info->relocatable);
sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit");
- sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
+ sgotloc = htab->sgotloc;
BFD_ASSERT (sxtlit && sgotloc);
num_xtlit_entries =
elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
- const char *name;
- asection *s;
bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
break;
case DT_XTENSA_GOT_LOC_OFF:
- name = ".got.loc";
- goto get_vma;
+ dyn.d_un.d_ptr = htab->sgotloc->vma;
+ break;
+
case DT_PLTGOT:
- name = ".got";
- goto get_vma;
+ dyn.d_un.d_ptr = htab->sgot->vma;
+ break;
+
case DT_JMPREL:
- name = ".rela.plt";
- get_vma:
- s = bfd_get_section_by_name (output_bfd, name);
- BFD_ASSERT (s);
- dyn.d_un.d_ptr = s->vma;
+ dyn.d_un.d_ptr = htab->srelplt->vma;
break;
case DT_PLTRELSZ:
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
- BFD_ASSERT (s);
- dyn.d_un.d_val = s->size;
+ dyn.d_un.d_val = htab->srelplt->size;
break;
case DT_RELASZ:
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. */
- s = bfd_get_section_by_name (output_bfd, ".rela.plt");
- if (s)
- dyn.d_un.d_val -= s->size;
+ if (htab->srelplt)
+ dyn.d_un.d_val -= htab->srelplt->size;
break;
}
if (xtensa_is_littable_section (sec))
{
- bfd *dynobj = elf_hash_table (info)->dynobj;
- if (dynobj)
- {
- asection *sgotloc =
- bfd_get_section_by_name (dynobj, ".got.loc");
- if (sgotloc)
- sgotloc->size -= removed_bytes;
- }
+ asection *sgotloc = elf_xtensa_hash_table (info)->sgotloc;
+ if (sgotloc)
+ sgotloc->size -= removed_bytes;
}
}
else
return xtensa_is_property_section (sec);
}
+
+static unsigned int
+elf_xtensa_action_discarded (asection *sec)
+{
+ if (strcmp (".xt_except_table", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".xt_except_desc", sec->name) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
+
\f
/* Support for core dump NOTE sections. */
asection *input_section,
Elf_Internal_Rela *rel)
{
+ struct elf_xtensa_link_hash_table *htab;
Elf_Internal_Shdr *symtab_hdr;
struct elf_link_hash_entry **sym_hashes;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
bfd_boolean dynamic_symbol;
+ htab = elf_xtensa_hash_table (info);
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info);
+ dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
&& (input_section->flags & SEC_ALLOC) != 0
&& (dynamic_symbol || info->shared))
{
- bfd *dynobj;
- const char *srel_name;
asection *srel;
bfd_boolean is_plt = FALSE;
- dynobj = elf_hash_table (info)->dynobj;
- BFD_ASSERT (dynobj != NULL);
-
if (dynamic_symbol && r_type == R_XTENSA_PLT)
{
- srel_name = ".rela.plt";
+ srel = htab->srelplt;
is_plt = TRUE;
}
else
- srel_name = ".rela.got";
+ srel = htab->srelgot;
/* Reduce size of the .rela.* section by one reloc. */
- srel = bfd_get_section_by_name (dynobj, srel_name);
BFD_ASSERT (srel != NULL);
BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela));
srel->size -= sizeof (Elf32_External_Rela);
reloc_index = srel->size / sizeof (Elf32_External_Rela);
chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
- splt = elf_xtensa_get_plt_section (dynobj, chunk);
- sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
+ splt = elf_xtensa_get_plt_section (info, chunk);
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
BFD_ASSERT (splt != NULL && sgotplt != NULL);
/* Check if an entire PLT chunk has just been eliminated. */
if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0)
{
/* The two magic GOT entries for that chunk can go away. */
- srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ srelgot = htab->srelgot;
BFD_ASSERT (srelgot != NULL);
srelgot->reloc_count -= 2;
srelgot->size -= 2 * sizeof (Elf32_External_Rela);
if (xtensa_is_littable_section (sec))
{
- bfd *dynobj = elf_hash_table (link_info)->dynobj;
- if (dynobj)
- {
- asection *sgotloc =
- bfd_get_section_by_name (dynobj, ".got.loc");
- if (sgotloc)
- sgotloc->size -= removed_bytes;
- }
+ asection *sgotloc = elf_xtensa_hash_table (link_info)->sgotloc;
+ if (sgotloc)
+ sgotloc->size -= removed_bytes;
}
}
}
/* Miscellaneous utility functions.... */
static asection *
-elf_xtensa_get_plt_section (bfd *dynobj, int chunk)
+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];
if (chunk == 0)
- return bfd_get_section_by_name (dynobj, ".plt");
+ {
+ htab = elf_xtensa_hash_table (info);
+ return htab->splt;
+ }
+ dynobj = elf_hash_table (info)->dynobj;
sprintf (plt_name, ".plt.%u", chunk);
return bfd_get_section_by_name (dynobj, plt_name);
}
static asection *
-elf_xtensa_get_gotplt_section (bfd *dynobj, int chunk)
+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];
if (chunk == 0)
- return bfd_get_section_by_name (dynobj, ".got.plt");
+ {
+ htab = elf_xtensa_hash_table (info);
+ return htab->sgotplt;
+ }
+ dynobj = elf_hash_table (info)->dynobj;
sprintf (got_name, ".got.plt.%u", chunk);
return bfd_get_section_by_name (dynobj, got_name);
}
{ 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 }
};
\f
#define bfd_elf32_bfd_relax_section elf_xtensa_relax_section
#define bfd_elf32_bfd_reloc_type_lookup elf_xtensa_reloc_type_lookup
#define bfd_elf32_bfd_set_private_flags elf_xtensa_set_private_flags
+#define bfd_elf32_bfd_link_hash_table_create elf_xtensa_link_hash_table_create
#define elf_backend_adjust_dynamic_symbol elf_xtensa_adjust_dynamic_symbol
#define elf_backend_check_relocs elf_xtensa_check_relocs
#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_object_p elf_xtensa_object_p
#define elf_backend_reloc_type_class elf_xtensa_reloc_type_class
#define elf_backend_relocate_section elf_xtensa_relocate_section
#define elf_backend_size_dynamic_sections elf_xtensa_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
#define elf_backend_special_sections elf_xtensa_special_sections
+#define elf_backend_action_discarded elf_xtensa_action_discarded
#include "elf32-target.h"