/* Xilinx MicroBlaze-specific support for 32-bit ELF
- Copyright (C) 2009-2020 Free Software Foundation, Inc.
+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
Boston, MA 02110-1301, USA. */
-int dbg = 0;
-
#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
{
struct elf_link_hash_table elf;
- /* Small local sym to section mapping cache. */
- struct sym_cache sym_sec;
-
/* TLS Local Dynamic GOT Entry */
union {
bfd_signed_vma refcount;
/* Get the ELF linker hash table from a link_info structure. */
-#define elf32_mb_hash_table(p) \
- (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
+#define elf32_mb_hash_table(p) \
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
+ ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
/* Create an entry in a microblaze ELF linker hash table. */
Elf_Internal_Sym *isym;
void *vpp;
- isym = bfd_sym_from_r_symndx (&htab->sym_sec,
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
abfd, r_symndx);
if (isym == NULL)
return FALSE;
edir = (struct elf32_mb_link_hash_entry *) dir;
eind = (struct elf32_mb_link_hash_entry *) ind;
- if (ind->dyn_relocs != NULL)
- {
- if (dir->dyn_relocs != NULL)
- {
- struct elf_dyn_relocs **pp;
- struct elf_dyn_relocs *p;
-
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
- list. Merge any entries against the same section. */
- for (pp = &ind->dyn_relocs; (p = *pp) != NULL; )
- {
- struct elf_dyn_relocs *q;
-
- for (q = dir->dyn_relocs; q != NULL; q = q->next)
- if (q->sec == p->sec)
- {
- q->pc_count += p->pc_count;
- q->count += p->count;
- *pp = p->next;
- break;
- }
- if (q == NULL)
- pp = &p->next;
- }
- *pp = dir->dyn_relocs;
- }
-
- dir->dyn_relocs = ind->dyn_relocs;
- ind->dyn_relocs = NULL;
- }
-
edir->tls_mask |= eind->tls_mask;
_bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
-/* Find dynamic relocs for H that apply to read-only sections. */
-
-static asection *
-readonly_dynrelocs (struct elf_link_hash_entry *h)
-{
- struct elf_dyn_relocs *p;
-
- for (p = h->dyn_relocs; p != NULL; p = p->next)
- {
- asection *s = p->sec->output_section;
-
- if (s != NULL && (s->flags & SEC_READONLY) != 0)
- return p->sec;
- }
- return NULL;
-}
-
static bfd_boolean
microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h)
/* If we don't find any dynamic relocs in read-only sections, then
we'll be keeping the dynamic relocs and avoiding the copy reloc. */
- if (!readonly_dynrelocs (h))
+ if (!_bfd_elf_readonly_dynrelocs (h))
{
h->non_got_ref = 0;
return TRUE;
return FALSE;
}
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- /* Add some entries to the .dynamic section. We fill in the
- values later, in microblaze_elf_finish_dynamic_sections, but we
- must add the entries now so that we get the correct size for
- the .dynamic section. The DT_DEBUG entry is filled in by the
- dynamic linker and used by the debugger. */
-#define add_dynamic_entry(TAG, VAL) \
- _bfd_elf_add_dynamic_entry (info, TAG, VAL)
-
- if (bfd_link_executable (info))
- {
- if (!add_dynamic_entry (DT_DEBUG, 0))
- return FALSE;
- }
-
- if (!add_dynamic_entry (DT_RELA, 0)
- || !add_dynamic_entry (DT_RELASZ, 0)
- || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
- return FALSE;
-
- if (htab->elf.splt->size != 0)
- {
- if (!add_dynamic_entry (DT_PLTGOT, 0)
- || !add_dynamic_entry (DT_PLTRELSZ, 0)
- || !add_dynamic_entry (DT_PLTREL, DT_RELA)
- || !add_dynamic_entry (DT_JMPREL, 0)
- || !add_dynamic_entry (DT_BIND_NOW, 1))
- return FALSE;
- }
-
- if (info->flags & DF_TEXTREL)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
- }
-#undef add_dynamic_entry
- return TRUE;
+ /* ??? Force DF_BIND_NOW? */
+ info->flags |= DF_BIND_NOW;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE);
}
/* Finish up dynamic symbol handling. We set the contents of various
put into .sbss. */
*secp = bfd_make_section_old_way (abfd, ".sbss");
if (*secp == NULL
- || !bfd_set_section_flags (*secp, SEC_IS_COMMON))
+ || !bfd_set_section_flags (*secp, SEC_IS_COMMON | SEC_SMALL_DATA))
return FALSE;
*valp = sym->st_size;