X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf32-nios2.c;h=5d787eb2f4010692fe23121eb8f73e6d60cd8278;hb=49455d8bbd8eac5b7ce7e26c691af27998647584;hp=450eeed86adf5344023d15fe2f39a41aae8b6023;hpb=2dcf00ce6c001c42c89e6f6baace708b706994f2;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c index 450eeed86a..5d787eb2f4 100644 --- a/bfd/elf32-nios2.c +++ b/bfd/elf32-nios2.c @@ -1,5 +1,5 @@ /* 32-bit ELF support for Nios II. - Copyright (C) 2012-2018 Free Software Foundation, Inc. + Copyright (C) 2012-2019 Free Software Foundation, Inc. Contributed by Nigel Gray (ngray@altera.com). Contributed by Mentor Graphics, Inc. @@ -31,6 +31,7 @@ #include "elf/nios2.h" #include "opcode/nios2.h" #include "elf32-nios2.h" +#include "libiberty.h" /* Use RELA relocations. */ #ifndef USE_RELA @@ -1578,10 +1579,8 @@ lookup_howto (unsigned int rtype, bfd *abfd) 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) { @@ -1597,18 +1596,19 @@ lookup_howto (unsigned int rtype, bfd *abfd) } } - 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; } } @@ -1620,7 +1620,8 @@ struct elf_reloc_map 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}, @@ -2926,7 +2927,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 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; } @@ -2942,7 +2943,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 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; @@ -2954,18 +2955,16 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 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; @@ -2973,6 +2972,7 @@ nios2_elf32_bfd_reloc_type_lookup (bfd *abfd, /* 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) @@ -2984,32 +2984,40 @@ nios2_elf32_bfd_reloc_name_lookup (bfd *abfd, 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 @@ -3712,8 +3720,8 @@ nios2_elf32_relocate_section (bfd *output_bfd, 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; @@ -3812,8 +3820,10 @@ nios2_elf32_relocate_section (bfd *output_bfd, 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; } @@ -3830,13 +3840,23 @@ nios2_elf32_relocate_section (bfd *output_bfd, { 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 (input_bfd, 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; } @@ -4507,6 +4527,8 @@ nios2_elf32_relocate_section (bfd *output_bfd, { (*info->callbacks->warning) (info, msg, name, input_bfd, input_section, rel->r_offset); + if (msgbuf) + free (msgbuf); return FALSE; } }