/* 32-bit ELF support for Nios II.
- Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Copyright (C) 2012-2020 Free Software Foundation, Inc.
Contributed by Nigel Gray (ngray@altera.com).
Contributed by Mentor Graphics, Inc.
#include "elf/nios2.h"
#include "opcode/nios2.h"
#include "elf32-nios2.h"
+#include "libiberty.h"
/* Use RELA relocations. */
#ifndef USE_RELA
int i;
/* R2 relocations are a superset of R1, so use that for the lookup
table. */
- int r1_howto_tbl_size = (int) (sizeof (elf_nios2_r1_howto_table_rel)
- / sizeof (elf_nios2_r1_howto_table_rel[0]));
- int r2_howto_tbl_size = (int) (sizeof (elf_nios2_r2_howto_table_rel)
- / sizeof (elf_nios2_r2_howto_table_rel[0]));
+ int r1_howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r1_howto_table_rel);
+ int r2_howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r2_howto_table_rel);
if (!initialized)
{
}
}
- BFD_ASSERT (rtype <= R_NIOS2_ILLEGAL);
+ if (rtype > R_NIOS2_ILLEGAL)
+ return NULL;
i = elf_code_to_howto_index[rtype];
if (BFD_IS_R2 (abfd))
{
if (i >= r2_howto_tbl_size)
- return 0;
+ return NULL;
return elf_nios2_r2_howto_table_rel + i;
}
else
{
if (i >= r1_howto_tbl_size)
- return 0;
+ return NULL;
return elf_nios2_r1_howto_table_rel + i;
}
}
enum elf_nios2_reloc_type elf_val;
};
-static const struct elf_reloc_map nios2_reloc_map[] = {
+static const struct elf_reloc_map nios2_reloc_map[] =
+{
{BFD_RELOC_NONE, R_NIOS2_NONE},
{BFD_RELOC_NIOS2_S16, R_NIOS2_S16},
{BFD_RELOC_NIOS2_U16, R_NIOS2_U16},
unsigned int top_id, top_index;
asection *section;
asection **input_list, **list;
- bfd_size_type amt;
+ size_t amt;
struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
/* Count the number of input BFDs and find the top input section id. */
= (struct elf32_nios2_stub_hash_entry *) gen_entry;
asection *stub_sec = hsh->stub_sec;
bfd_vma sym_value;
+ struct bfd_link_info *info;
+
+ info = (struct bfd_link_info *) in_arg;
+
+ /* Fail if the target section could not be assigned to an output
+ section. The user should fix his linker script. */
+ if (hsh->target_section->output_section == NULL
+ && info->non_contiguous_regions)
+ info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output section. "
+ "Retry without --enable-non-contiguous-regions.\n"),
+ hsh->target_section);
/* Make a note of the offset within the stubs for this entry. */
hsh->stub_offset = stub_sec->size;
/* We want to read in symbol extension records only once. To do this
we need to read in the local symbols in parallel and save them for
later use; so hold pointers to the local symbols in an array. */
- bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ size_t amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
all_local_syms = bfd_zmalloc (amt);
htab->all_local_syms = all_local_syms;
if (all_local_syms == NULL)
if (bfd_big_endian (ibfd))
{
_bfd_error_handler
- (_("error: %pB: Big-endian R2 is not supported."), ibfd);
+ (_("error: %pB: big-endian R2 is not supported"), ibfd);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
architectures. */
_bfd_error_handler
/* xgettext:c-format */
- (_("error: %pB: Conflicting CPU architectures %d/%d"),
+ (_("error: %pB: conflicting CPU architectures %d/%d"),
ibfd, new_flags, old_flags);
bfd_set_error (bfd_error_bad_value);
return FALSE;
return TRUE;
}
-
/* Implement bfd_elf32_bfd_reloc_type_lookup:
Given a BFD reloc type, return a howto structure. */
+
static reloc_howto_type *
nios2_elf32_bfd_reloc_type_lookup (bfd *abfd,
bfd_reloc_code_real_type code)
{
int i;
- for (i = 0;
- i < (int) (sizeof (nios2_reloc_map) / sizeof (struct elf_reloc_map));
- ++i)
+ for (i = 0; i < (int) ARRAY_SIZE (nios2_reloc_map); ++i)
if (nios2_reloc_map[i].bfd_val == code)
return lookup_howto (nios2_reloc_map[i].elf_val, abfd);
return NULL;
/* Implement bfd_elf32_bfd_reloc_name_lookup:
Given a reloc name, return a howto structure. */
+
static reloc_howto_type *
nios2_elf32_bfd_reloc_name_lookup (bfd *abfd,
const char *r_name)
if (BFD_IS_R2 (abfd))
{
howto_tbl = elf_nios2_r2_howto_table_rel;
- howto_tbl_size = (int) (sizeof (elf_nios2_r2_howto_table_rel)
- / sizeof (elf_nios2_r2_howto_table_rel[0]));
+ howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r2_howto_table_rel);
}
else
{
howto_tbl = elf_nios2_r1_howto_table_rel;
- howto_tbl_size = (int) (sizeof (elf_nios2_r1_howto_table_rel)
- / sizeof (elf_nios2_r1_howto_table_rel[0]));
+ howto_tbl_size = (int) ARRAY_SIZE (elf_nios2_r1_howto_table_rel);
}
for (i = 0; i < howto_tbl_size; i++)
if (howto_tbl[i].name && strcasecmp (howto_tbl[i].name, r_name) == 0)
return howto_tbl + i;
+
return NULL;
}
/* Implement elf_info_to_howto:
Given a ELF32 relocation, fill in a arelent structure. */
-static void
+
+static bfd_boolean
nios2_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
unsigned int r_type;
r_type = ELF32_R_TYPE (dst->r_info);
- cache_ptr->howto = lookup_howto (r_type, abfd);
+ if ((cache_ptr->howto = lookup_howto (r_type, abfd)) == NULL)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ return TRUE;
}
/* Return the base VMA address which should be subtracted from real addresses
h = bfd_hash_lookup (&info->hash->table, "_gp", FALSE, FALSE);
lh = (struct bfd_link_hash_entry *) h;
-lookup:
+ lookup:
if (lh)
{
switch (lh->type)
const char *name = NULL;
int r_type;
const char *format;
- char msgbuf[256];
- const char* msg = (const char*) NULL;
+ char *msgbuf = NULL;
+ char *msg = NULL;
bfd_boolean unresolved_reloc;
bfd_vma off;
int use_plt;
reloc_address = 0;
format = _("global pointer relative relocation at address "
- "0x%08x when _gp not defined\n");
- sprintf (msgbuf, format, reloc_address);
+ "%#" PRIx64 " when _gp not defined\n");
+ if (asprintf (&msgbuf, format,
+ (uint64_t) reloc_address) == -1)
+ msgbuf = NULL;
msg = msgbuf;
r = bfd_reloc_dangerous;
}
{
if (h)
name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link,
+ sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (sec);
+ }
/* xgettext:c-format */
- format = _("Unable to reach %s (at 0x%08x) from the "
- "global pointer (at 0x%08x) because the "
- "offset (%d) is out of the allowed range, "
- "-32678 to 32767.\n" );
- sprintf (msgbuf, format, name, symbol_address, gp,
- (signed)relocation);
+ format = _("unable to reach %s (at %#" PRIx64 ") from "
+ "the global pointer (at %#" PRIx64 ") "
+ "because the offset (%" PRId64 ") is out of "
+ "the allowed range, -32678 to 32767\n" );
+ if (asprintf (&msgbuf, format, name,
+ (uint64_t) symbol_address, (uint64_t) gp,
+ (int64_t) relocation) == -1)
+ msgbuf = NULL;
msg = msgbuf;
r = bfd_reloc_outofrange;
}
symtab_hdr->sh_link,
sym->st_name);
if (name == NULL || *name == '\0')
- name = bfd_section_name (input_bfd, sec);
+ name = bfd_section_name (sec);
}
switch (r)
{
(*info->callbacks->warning) (info, msg, name, input_bfd,
input_section, rel->r_offset);
+ if (msgbuf)
+ free (msgbuf);
return FALSE;
}
}
/* Implement elf-backend_section_flags:
Convert NIOS2 specific section flags to bfd internal section flags. */
static bfd_boolean
-nios2_elf32_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
+nios2_elf32_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_NIOS2_GPREL)
- *flags |= SEC_SMALL_DATA;
+ hdr->bfd_section->flags |= SEC_SMALL_DATA;
return TRUE;
}
nios2_elf32_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
Elf_Internal_Shdr *hdr, asection *sec)
{
- register const char *name = bfd_get_section_name (abfd, sec);
+ const char *name = bfd_section_name (sec);
if ((sec->flags & SEC_SMALL_DATA)
|| strcmp (name, ".sdata") == 0
/* In order for the two loads in .PLTresolve to share the same %hiadj,
_GLOBAL_OFFSET_TABLE_ must be aligned to a 16-byte boundary. */
- if (!bfd_set_section_alignment (dynobj, htab->root.sgotplt, 4))
+ if (!bfd_set_section_alignment (htab->root.sgotplt, 4))
return FALSE;
/* The Nios II ABI specifies that GOT-relative relocations are relative
same %hiadj, the start of the PLT (as well as the GOT) must be aligned
to a 16-byte boundary. This is because the addresses for these loads
include the -(.plt+4) PIC correction. */
- return bfd_set_section_alignment (dynobj, htab->root.splt, 4);
+ return bfd_set_section_alignment (htab->root.splt, 4);
}
/* Implement elf_backend_copy_indirect_symbol:
p = *head;
if (p == NULL || p->sec != sec)
{
- bfd_size_type amt = sizeof *p;
+ size_t amt = sizeof *p;
p = ((struct elf_dyn_relocs *)
bfd_alloc (htab->root.dynobj, amt));
if (p == NULL)
/* Align dynbss. */
s->size = BFD_ALIGN (s->size, (bfd_size_type)1 << align2);
- if (align2 > bfd_get_section_alignment (dynobj, s)
- && !bfd_set_section_alignment (dynobj, s, align2))
+ if (align2 > bfd_section_alignment (s)
+ && !bfd_set_section_alignment (s, align2))
return FALSE;
/* Define the symbol as being at this point in the section. */
/* It's OK to base decisions on the section name, because none
of the dynobj section names depend upon the input files. */
- name = bfd_get_section_name (dynobj, s);
+ name = bfd_section_name (s);
if (CONST_STRNEQ (name, ".rela"))
{
nios2_elf32_link_hash_table_create (bfd *abfd)
{
struct elf32_nios2_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct elf32_nios2_link_hash_table);
+ size_t amt = sizeof (struct elf32_nios2_link_hash_table);
ret = bfd_zmalloc (amt);
if (ret == NULL)