/* IA-64 support for 64-bit ELF
- Copyright (C) 1998-2019 Free Software Foundation, Inc.
+ Copyright (C) 1998-2021 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of BFD, the Binary File Descriptor library.
#define LOG_SECTION_ALIGN 2
#endif
+#define is_ia64_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_object_id (bfd) == IA64_ELF_DATA)
+
typedef struct bfd_hash_entry *(*new_hash_entry_func)
(struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
asection *rel_pltoff_sec; /* Dynamic relocation section for same. */
bfd_size_type minplt_entries; /* Number of minplt entries. */
- unsigned reltext : 1; /* Are there relocs against readonly sections? */
unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished? */
bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry. */
/* There are maybe R_IA64_GPREL22 relocations, including those
};
#define elfNN_ia64_hash_table(p) \
- (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == IA64_ELF_DATA) \
+ ? (struct elfNN_ia64_link_hash_table *) (p)->hash : NULL)
static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
(struct elfNN_ia64_link_hash_table *ia64_info,
return TRUE;
error_return:
- if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+ if ((unsigned char *) isymbuf != symtab_hdr->contents)
free (isymbuf);
- if (contents != NULL
- && elf_section_data (sec)->this_hdr.contents != contents)
+ if (elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
- if (internal_relocs != NULL
- && elf_section_data (sec)->relocs != internal_relocs)
+ if (elf_section_data (sec)->relocs != internal_relocs)
free (internal_relocs);
return FALSE;
}
flag. */
static bfd_boolean
-elfNN_ia64_section_flags (flagword *flags,
- const Elf_Internal_Shdr *hdr)
+elfNN_ia64_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_IA_64_SHORT)
- *flags |= SEC_SMALL_DATA;
+ hdr->bfd_section->flags |= SEC_SMALL_DATA;
return TRUE;
}
scomm = bfd_make_section_with_flags (abfd, ".scommon",
(SEC_ALLOC
| SEC_IS_COMMON
+ | SEC_SMALL_DATA
| SEC_LINKER_CREATED));
if (scomm == NULL)
return FALSE;
struct elfNN_ia64_dyn_sym_info *dyn_i;
unsigned int count;
- if (dir->info)
- free (dir->info);
+ free (dir->info);
dir->info = ind->info;
dir->count = ind->count;
struct elfNN_ia64_link_hash_entry *entry
= (struct elfNN_ia64_link_hash_entry *) xentry;
- if (entry->info)
- {
- free (entry->info);
- entry->info = NULL;
- entry->count = 0;
- entry->sorted_count = 0;
- entry->size = 0;
- }
+ free (entry->info);
+ entry->info = NULL;
+ entry->count = 0;
+ entry->sorted_count = 0;
+ entry->size = 0;
return TRUE;
}
struct elfNN_ia64_local_hash_entry *entry
= (struct elfNN_ia64_local_hash_entry *) *slot;
- if (entry->info)
- {
- free (entry->info);
- entry->info = NULL;
- entry->count = 0;
- entry->sorted_count = 0;
- entry->size = 0;
- }
+ free (entry->info);
+ entry->info = NULL;
+ entry->count = 0;
+ entry->sorted_count = 0;
+ entry->size = 0;
return TRUE;
}
return NULL;
}
ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free;
+ ret->root.dt_pltgot_required = TRUE;
return &ret->root.root;
}
key.addend = addend;
dyn_i = bsearch (&key, info, sorted_count,
sizeof (*info), addend_compare);
-
if (dyn_i)
- {
- return dyn_i;
- }
+ return dyn_i;
}
- /* Do a quick check for the last inserted entry. */
- dyn_i = info + count - 1;
- if (dyn_i->addend == addend)
+ if (count != 0)
{
- return dyn_i;
+ /* Do a quick check for the last inserted entry. */
+ dyn_i = info + count - 1;
+ if (dyn_i->addend == addend)
+ return dyn_i;
}
}
*size_p = size;
*info_p = info;
-has_space:
+ has_space:
/* Append the new one to the array. */
dyn_i = info + count;
memset (dyn_i, 0, sizeof (*dyn_i));
if (size != count)
{
amt = count * sizeof (*info);
- info = bfd_malloc (amt);
- if (info != NULL)
- {
- memcpy (info, *info_p, amt);
- free (*info_p);
- *size_p = count;
- *info_p = info;
- }
+ info = bfd_realloc (info, amt);
+ *size_p = count;
+ if (info == NULL && count != 0)
+ /* realloc should never fail since we are reducing size here,
+ but if it does use the old array. */
+ info = *info_p;
+ else
+ *info_p = info;
}
- key.addend = addend;
- dyn_i = bsearch (&key, info, count,
- sizeof (*info), addend_compare);
+ if (count == 0)
+ dyn_i = NULL;
+ else
+ {
+ key.addend = addend;
+ dyn_i = bsearch (&key, info, count, sizeof (*info), addend_compare);
+ }
}
return dyn_i;
abort ();
}
if (rent->reltext)
- ia64_info->reltext = 1;
+ x->info->flags |= DF_TEXTREL;
rent->srel->size += sizeof (ElfNN_External_Rela) * count;
}
struct elfNN_ia64_link_hash_table *ia64_info;
asection *sec;
bfd *dynobj;
- bfd_boolean relplt = FALSE;
ia64_info = elfNN_ia64_hash_table (info);
if (ia64_info == NULL)
ia64_info->rel_pltoff_sec = NULL;
else
{
- relplt = TRUE;
+ ia64_info->root.dt_jmprel_required = TRUE;
/* We use the reloc_count field as a counter if we need to
copy relocs into the output file. */
sec->reloc_count = 0;
later (in finish_dynamic_sections) but we must add the entries now
so that we get the correct size for the .dynamic section. */
- if (bfd_link_executable (info))
- {
- /* 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 (!add_dynamic_entry (DT_DEBUG, 0))
- return FALSE;
- }
-
- if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
- return FALSE;
- if (!add_dynamic_entry (DT_PLTGOT, 0))
+ if (!_bfd_elf_add_dynamic_tags (output_bfd, info, TRUE))
return FALSE;
- if (relplt)
- {
- if (!add_dynamic_entry (DT_PLTRELSZ, 0)
- || !add_dynamic_entry (DT_PLTREL, DT_RELA)
- || !add_dynamic_entry (DT_JMPREL, 0))
- return FALSE;
- }
-
- if (!add_dynamic_entry (DT_RELA, 0)
- || !add_dynamic_entry (DT_RELASZ, 0)
- || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
+ if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
return FALSE;
-
- if (ia64_info->reltext)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- info->flags |= DF_TEXTREL;
- }
}
/* ??? Perhaps force __gp local. */
{
if (max_short_vma - min_short_vma >= 0x400000)
{
-overflow:
+ overflow:
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: short data segment overflowed (%#" PRIx64 " >= 0x400000)"),
case bfd_reloc_outofrange:
case bfd_reloc_overflow:
default:
-missing_tls_sec:
+ missing_tls_sec:
{
const char *name;
/* Merge backend specific data from an object file to the output
object file when linking. */
+
static bfd_boolean
elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
flagword in_flags;
bfd_boolean ok = TRUE;
- /* Don't even pretend to support mixed-format linking. */
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
- || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
- return FALSE;
+ /* FIXME: What should be checked when linking shared libraries? */
+ if ((ibfd->flags & DYNAMIC) != 0)
+ return TRUE;
+
+ if (!is_ia64_elf (ibfd) || !is_ia64_elf (obfd))
+ return TRUE;
in_flags = elf_elfheader (ibfd)->e_flags;
out_flags = elf_elfheader (obfd)->e_flags;
flagword flags;
const char *name;
char *unwi_name, *unw_name;
- bfd_size_type amt;
+ size_t amt;
if (abfd->flags & DYNAMIC)
return TRUE;
break;
}
}
+
+static void
+ignore_errors (const char *fmt ATTRIBUTE_UNUSED, ...)
+{
+}
\f
#define TARGET_LITTLE_SYM ia64_elfNN_le_vec
#define TARGET_LITTLE_NAME "elfNN-ia64-little"
We don't want to flood users with so many error messages. We turn
off the warning for now. It will be turned on later when the Intel
compiler is fixed. */
-#define elf_backend_link_order_error_handler NULL
+#define elf_backend_link_order_error_handler ignore_errors
#include "elfNN-target.h"