/* Motorola 68k series support for 32-bit ELF
- Copyright (C) 1993-2020 Free Software Foundation, Inc.
+ Copyright (C) 1993-2021 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
{
struct elf_link_hash_table root;
- /* Small local sym cache. */
- struct sym_cache sym_cache;
-
/* The PLT format used by this link, or NULL if the format has not
yet been chosen. */
const struct elf_m68k_plt_info *plt_info;
/* Get the m68k ELF linker hash table from a link_info structure. */
#define elf_m68k_hash_table(p) \
- (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == M68K_ELF_DATA ? ((struct elf_m68k_link_hash_table *) ((p)->hash)) : NULL)
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == M68K_ELF_DATA) \
+ ? (struct elf_m68k_link_hash_table *) (p)->hash : NULL)
/* Shortcut to multi-GOT data. */
#define elf_m68k_multi_got(INFO) (&elf_m68k_hash_table (INFO)->multi_got_)
return TRUE;
}
+/* Merge object attributes from IBFD into OBFD. Warn if
+ there are conflicting attributes. */
+static bfd_boolean
+m68k_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
+{
+ bfd *obfd = info->output_bfd;
+ obj_attribute *in_attr, *in_attrs;
+ obj_attribute *out_attr, *out_attrs;
+ bfd_boolean ret = TRUE;
+
+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+
+ in_attr = &in_attrs[Tag_GNU_M68K_ABI_FP];
+ out_attr = &out_attrs[Tag_GNU_M68K_ABI_FP];
+
+ if (in_attr->i != out_attr->i)
+ {
+ int in_fp = in_attr->i & 3;
+ int out_fp = out_attr->i & 3;
+ static bfd *last_fp;
+
+ if (in_fp == 0)
+ ;
+ else if (out_fp == 0)
+ {
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
+ out_attr->i ^= in_fp;
+ last_fp = ibfd;
+ }
+ else if (out_fp == 1 && in_fp == 2)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB uses hard float, %pB uses soft float"),
+ last_fp, ibfd);
+ ret = FALSE;
+ }
+ else if (out_fp == 2 && in_fp == 1)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB uses hard float, %pB uses soft float"),
+ ibfd, last_fp);
+ ret = FALSE;
+ }
+ }
+
+ if (!ret)
+ {
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ return _bfd_elf_merge_object_attributes (ibfd, info);
+}
+
/* Merge backend specific data from an object file to the output
object file when linking. */
static bfd_boolean
bfd_set_arch_mach (obfd, bfd_arch_m68k, arch_info->mach);
+ if (!m68k_elf_merge_obj_attributes (ibfd, info))
+ return FALSE;
+
in_flags = elf_elfheader (ibfd)->e_flags;
if (!elf_flags_init (obfd))
{
void *vpp;
Elf_Internal_Sym *isym;
- isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->sym_cache,
+ isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->root.sym_cache,
abfd, r_symndx);
if (isym == NULL)
return FALSE;
{
bfd *dynobj;
asection *s;
- bfd_boolean plt;
bfd_boolean relocs;
dynobj = elf_hash_table (info)->dynobj;
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
- plt = FALSE;
relocs = FALSE;
for (s = dynobj->sections; s != NULL; s = s->next)
{
if (strcmp (name, ".plt") == 0)
{
/* Remember whether there is a PLT. */
- plt = s->size != 0;
+ ;
}
else if (CONST_STRNEQ (name, ".rela"))
{
return FALSE;
}
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- /* Add some entries to the .dynamic section. We fill in the
- values later, in elf_m68k_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 (plt)
- {
- 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))
- return FALSE;
- }
-
- if (relocs)
- {
- 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 ((info->flags & DF_TEXTREL) != 0)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
- }
-#undef add_dynamic_entry
-
- return TRUE;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
}
/* This function is called via elf_link_hash_traverse if we are
strncpy ((char *) p + 4, targetsec->output_section->name, 8);
}
- if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
- if (internal_relocs != NULL
- && elf_section_data (datasec)->relocs != internal_relocs)
+ if (elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
return TRUE;
-error_return:
- if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ error_return:
+ if (symtab_hdr->contents != (unsigned char *) isymbuf)
free (isymbuf);
- if (internal_relocs != NULL
- && elf_section_data (datasec)->relocs != internal_relocs)
+ if (elf_section_data (datasec)->relocs != internal_relocs)
free (internal_relocs);
return FALSE;
}