X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-rx.c;h=3f03ab21f09cf4f7a149232e131a4e60a8886e13;hb=9e790a80160676e7fd3fb8be6cf3c1c77d9ded81;hp=efdf72a4528b76d9381be81fe436533ae651ddc5;hpb=863f7a5f4811c24d9a5863ffb541ff3da1511450;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c index efdf72a452..3f03ab21f0 100644 --- a/bfd/elf32-rx.c +++ b/bfd/elf32-rx.c @@ -1,5 +1,5 @@ /* Renesas RX specific support for 32-bit ELF. - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2020 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -20,7 +20,6 @@ #include "sysdep.h" #include "bfd.h" -#include "bfd_stdint.h" #include "libbfd.h" #include "elf-bfd.h" #include "elf/rx.h" @@ -300,8 +299,8 @@ rx_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name) /* Set the howto pointer for an RX ELF reloc. */ -static void -rx_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, +static bfd_boolean +rx_info_to_howto_rela (bfd * abfd, arelent * cache_ptr, Elf_Internal_Rela * dst) { @@ -311,10 +310,21 @@ rx_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, if (r_type >= (unsigned int) R_RX_max) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: invalid RX reloc number: %d"), abfd, r_type); - r_type = 0; + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + bfd_set_error (bfd_error_bad_value); + return FALSE; } cache_ptr->howto = rx_elf_howto_table + r_type; + if (cache_ptr->howto->name == 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; } static bfd_vma @@ -533,7 +543,7 @@ rx_elf_relocate_section name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); - name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name; + name = sym->st_name == 0 ? bfd_section_name (sec) : name; } else { @@ -566,7 +576,9 @@ rx_elf_relocate_section /* We have already done error checking in rx_table_find(). */ - buf = (char *) malloc (13 + strlen (name + 20)); + buf = (char *) bfd_malloc (13 + strlen (name + 20)); + if (buf == NULL) + return FALSE; sprintf (buf, "$tablestart$%s", name + 20); table_start_cache = get_symbol_value (buf, @@ -592,14 +604,14 @@ rx_elf_relocate_section if (table_end_cache <= entry_vma || entry_vma < table_start_cache) { /* xgettext:c-format */ - _bfd_error_handler (_("%B:%A: table entry %s outside table"), + _bfd_error_handler (_("%pB:%pA: table entry %s outside table"), input_bfd, input_section, name); } else if ((int) (entry_vma - table_start_cache) % 4) { /* xgettext:c-format */ - _bfd_error_handler (_("%B:%A: table entry %s not word-aligned within table"), + _bfd_error_handler (_("%pB:%pA: table entry %s not word-aligned within table"), input_bfd, input_section, name); } @@ -608,7 +620,10 @@ rx_elf_relocate_section idx = (int) (entry_vma - table_start_cache) / 4; /* This will look like $tableentry$$ */ - buf = (char *) malloc (12 + 20 + strlen (name + 20)); + buf = (char *) bfd_malloc (12 + 20 + strlen (name + 20)); + if (buf == NULL) + return FALSE; + sprintf (buf, "$tableentry$%d$%s", idx, name + 20); h = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, buf, FALSE, FALSE, TRUE); @@ -660,13 +675,20 @@ rx_elf_relocate_section r = bfd_reloc_ok; -#define RANGE(a,b) if (a > (long) relocation || (long) relocation > b) r = bfd_reloc_overflow -#define ALIGN(m) if (relocation & m) r = bfd_reloc_other; -#define OP(i) (contents[rel->r_offset + (i)]) +#define RANGE(a,b) \ + if (a > (long) relocation || (long) relocation > b) \ + r = bfd_reloc_overflow +#define ALIGN(m) \ + if (relocation & m) \ + r = bfd_reloc_other +#define OP(i) \ + (contents[rel->r_offset + (i)]) #define WARN_REDHAT(type) \ - /* xgettext:c-format */ \ - _bfd_error_handler (_("%B:%A: Warning: deprecated Red Hat reloc " type " detected against: %s."), \ - input_bfd, input_section, name) + /* xgettext:c-format */ \ + _bfd_error_handler \ + (_("%pB:%pA: warning: deprecated Red Hat reloc " \ + "%s detected against: %s"), \ + input_bfd, input_section, #type, name) /* Check for unsafe relocs in PID mode. These are any relocs where an absolute address is being computed. There are special cases @@ -684,9 +706,12 @@ rx_elf_relocate_section && strcmp (name, "__romdatastart") != 0 \ && !saw_subtract) \ /* xgettext:c-format */ \ - _bfd_error_handler (_("%B(%A): unsafe PID relocation %s at %#Lx (against %s in %s)"), \ + _bfd_error_handler (_("%pB(%pA): unsafe PID relocation %s " \ + "at %#" PRIx64 " (against %s in %s)"), \ input_bfd, input_section, howto->name, \ - input_section->output_section->vma + input_section->output_offset + rel->r_offset, \ + (uint64_t) (input_section->output_section->vma \ + + input_section->output_offset \ + + rel->r_offset), \ name, sec->name); \ } \ while (0) @@ -1264,7 +1289,8 @@ rx_elf_relocate_section + sec->output_offset + rel->r_addend); else - _bfd_error_handler (_("Warning: RX_SYM reloc with an unknown symbol")); + _bfd_error_handler + (_("warning: RX_SYM reloc with an unknown symbol")); } break; @@ -1432,7 +1458,7 @@ rx_elf_relocate_section and emit a more helpful error message. */ if (r_type == R_RX_DIR24S_PCREL) /* xgettext:c-format */ - msg = _("%B(%A): error: call to undefined function '%s'"); + msg = _("%pB(%pA): error: call to undefined function '%s'"); else (*info->callbacks->reloc_overflow) (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, @@ -1446,27 +1472,27 @@ rx_elf_relocate_section case bfd_reloc_other: /* xgettext:c-format */ - msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area"); + msg = _("%pB(%pA): warning: unaligned access to symbol '%s' in the small data area"); break; case bfd_reloc_outofrange: /* xgettext:c-format */ - msg = _("%B(%A): internal error: out of range error"); + msg = _("%pB(%pA): internal error: out of range error"); break; case bfd_reloc_notsupported: /* xgettext:c-format */ - msg = _("%B(%A): internal error: unsupported relocation error"); + msg = _("%pB(%pA): internal error: unsupported relocation error"); break; case bfd_reloc_dangerous: /* xgettext:c-format */ - msg = _("%B(%A): internal error: dangerous relocation"); + msg = _("%pB(%pA): internal error: dangerous relocation"); break; default: /* xgettext:c-format */ - msg = _("%B(%A): internal error: unknown error"); + msg = _("%pB(%pA): internal error: unknown error"); break; } @@ -1717,7 +1743,7 @@ static bfd_vma rx_offset_for_reloc (bfd * abfd, Elf_Internal_Rela * rel, Elf_Internal_Shdr * symtab_hdr, - Elf_External_Sym_Shndx * shndx_buf ATTRIBUTE_UNUSED, + bfd_byte * shndx_buf ATTRIBUTE_UNUSED, Elf_Internal_Sym * intsyms, Elf_Internal_Rela ** lrel, bfd * input_bfd, @@ -1984,7 +2010,7 @@ elf32_rx_relax_section (bfd * abfd, bfd_byte * free_contents = NULL; Elf_Internal_Sym * intsyms = NULL; Elf_Internal_Sym * free_intsyms = NULL; - Elf_External_Sym_Shndx * shndx_buf = NULL; + bfd_byte * shndx_buf = NULL; bfd_vma pc; bfd_vma sec_start; bfd_vma symval = 0; @@ -2037,17 +2063,20 @@ elf32_rx_relax_section (bfd * abfd, if (shndx_hdr && shndx_hdr->sh_size != 0) { - bfd_size_type amt; + size_t amt; - amt = symtab_hdr->sh_info; - amt *= sizeof (Elf_External_Sym_Shndx); - shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt); - if (shndx_buf == NULL) + if (_bfd_mul_overflow (symtab_hdr->sh_info, + sizeof (Elf_External_Sym_Shndx), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + goto error_return; + } + if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0) goto error_return; - if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread (shndx_buf, amt, abfd) != amt) + shndx_buf = _bfd_malloc_and_read (abfd, amt, amt); + if (shndx_buf == NULL) goto error_return; - shndx_hdr->contents = (bfd_byte *) shndx_buf; + shndx_hdr->contents = shndx_buf; } /* Get a copy of the native relocations. */ @@ -2911,9 +2940,9 @@ elf32_rx_relax_section (bfd * abfd, break; case 0: #if RX_OPCODE_BIG_ENDIAN - imm_val = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | ip[3]; + imm_val = ((unsigned) ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | ip[3]; #else - imm_val = (ip[3] << 24) | (ip[2] << 16) | (ip[1] << 8) | ip[0]; + imm_val = ((unsigned) ip[3] << 24) | (ip[2] << 16) | (ip[1] << 8) | ip[0]; #endif break; } @@ -3008,8 +3037,7 @@ elf32_rx_relax_section (bfd * abfd, return TRUE; error_return: - if (free_contents != NULL) - free (free_contents); + free (free_contents); if (shndx_buf != NULL) { @@ -3017,8 +3045,7 @@ elf32_rx_relax_section (bfd * abfd, free (shndx_buf); } - if (free_intsyms != NULL) - free (free_intsyms); + free (free_intsyms); return FALSE; } @@ -3143,8 +3170,8 @@ rx_elf_merge_private_bfd_data (bfd * ibfd, struct bfd_link_info *info) } else { - _bfd_error_handler (_("There is a conflict merging the" - " ELF header flags from %B"), + _bfd_error_handler (_("there is a conflict merging the" + " ELF header flags from %pB"), ibfd); _bfd_error_handler (_(" the input file's flags: %s"), describe_flags (new_flags)); @@ -3191,7 +3218,12 @@ elf32_rx_machine (bfd * abfd ATTRIBUTE_UNUSED) For now we assume that the flags are OK. */ if ((elf_elfheader (abfd)->e_flags & EF_RX_CPU_MASK) == EF_RX_CPU_RX) #endif - return bfd_mach_rx; + if ((elf_elfheader (abfd)->e_flags & E_FLAG_RX_V2)) + return bfd_mach_rx_v2; + else if ((elf_elfheader (abfd)->e_flags & E_FLAG_RX_V3)) + return bfd_mach_rx_v3; + else + return bfd_mach_rx; return 0; } @@ -3288,6 +3320,13 @@ rx_elf_object_p (bfd * abfd) return TRUE; } + +static bfd_boolean +rx_linux_object_p (bfd * abfd) +{ + bfd_default_set_arch_mach (abfd, bfd_arch_rx, elf32_rx_machine (abfd)); + return TRUE; +} #ifdef DEBUG @@ -3299,26 +3338,14 @@ rx_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms) Elf_Internal_Sym * isymend; Elf_Internal_Sym * isym; Elf_Internal_Shdr * symtab_hdr; - bfd_boolean free_internal = FALSE, free_external = FALSE; char * st_info_str; char * st_info_stb_str; char * st_other_str; char * st_shndx_str; - if (! internal_syms) - { - internal_syms = bfd_malloc (1000); - free_internal = 1; - } - if (! external_syms) - { - external_syms = bfd_malloc (1000); - free_external = 1; - } - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; locsymcount = symtab_hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - if (free_internal) + if (!internal_syms) isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, internal_syms, external_syms, NULL); @@ -3370,10 +3397,6 @@ rx_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms) isym->st_other, st_other_str, isym->st_shndx, st_shndx_str); } - if (free_internal) - free (internal_syms); - if (free_external) - free (external_syms); } char * @@ -3582,6 +3605,8 @@ rx_set_section_contents (bfd * abfd, char * cloc = (char *) location; swapped_data = (char *) bfd_alloc (abfd, count); + if (swapped_data == NULL) + return FALSE; for (i = 0; i < count; i += 4) { @@ -3651,8 +3676,7 @@ rx_final_link (bfd * abfd, struct bfd_link_info * info) } static bfd_boolean -elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED, - struct bfd_link_info * info ATTRIBUTE_UNUSED) +elf32_rx_modify_headers (bfd *abfd, struct bfd_link_info *info) { const struct elf_backend_data * bed; struct elf_obj_tdata * tdata; @@ -3684,7 +3708,7 @@ elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED, #endif } - return TRUE; + return _bfd_elf_modify_headers (abfd, info); } /* The default literal sections should always be marked as "code" (i.e., @@ -3747,7 +3771,9 @@ rx_table_find (struct bfd_hash_entry *vent, void *vinfo) find all the related symbols and mark their sections as SEC_KEEP so we don't garbage collect them. */ - buf = (char *) malloc (12 + 10 + strlen (tname)); + buf = (char *) bfd_malloc (12 + 10 + strlen (tname)); + if (buf == NULL) + return FALSE; sprintf (buf, "$tableend$%s", tname); h = bfd_link_hash_lookup (info->info->hash, buf, FALSE, FALSE, TRUE); @@ -3755,7 +3781,7 @@ rx_table_find (struct bfd_hash_entry *vent, void *vinfo) && h->type != bfd_link_hash_defweak)) { /* xgettext:c-format */ - _bfd_error_handler (_("%B:%A: table %s missing corresponding %s"), + _bfd_error_handler (_("%pB:%pA: table %s missing corresponding %s"), abfd, sec, name, buf); return TRUE; } @@ -3763,7 +3789,7 @@ rx_table_find (struct bfd_hash_entry *vent, void *vinfo) if (h->u.def.section != ent->u.def.section) { /* xgettext:c-format */ - _bfd_error_handler (_("%B:%A: %s and %s must be in the same input section"), + _bfd_error_handler (_("%pB:%pA: %s and %s must be in the same input section"), h->u.def.section->owner, h->u.def.section, name, buf); return TRUE; @@ -3876,7 +3902,9 @@ rx_table_map (struct bfd_hash_entry *vent, void *vinfo) + ent->u.def.section->output_section->vma + ent->u.def.section->output_offset); - buf = (char *) malloc (12 + 10 + strlen (tname)); + buf = (char *) bfd_malloc (12 + 10 + strlen (tname)); + if (buf == NULL) + return FALSE; sprintf (buf, "$tableend$%s", tname); end_addr = get_symbol_value_maybe (buf, info->info); @@ -3896,8 +3924,21 @@ rx_table_map (struct bfd_hash_entry *vent, void *vinfo) info->table_start = start_addr; info->table_size = (int) (end_addr - start_addr) / 4; - info->table_handlers = (bfd_vma *) malloc (info->table_size * sizeof (bfd_vma)); - info->table_entries = (struct bfd_link_hash_entry **) malloc (info->table_size * sizeof (struct bfd_link_hash_entry)); + info->table_handlers = (bfd_vma *) + bfd_malloc (info->table_size * sizeof (bfd_vma)); + if (info->table_handlers == NULL) + { + free (buf); + return FALSE; + } + info->table_entries = (struct bfd_link_hash_entry **) + bfd_malloc (info->table_size * sizeof (struct bfd_link_hash_entry)); + if (info->table_entries == NULL) + { + free (info->table_handlers); + free (buf); + return FALSE; + } for (idx = 0; idx < (int) (end_addr - start_addr) / 4; idx ++) { @@ -4004,7 +4045,7 @@ rx_additional_link_map_text (bfd *obfd, struct bfd_link_info *info, FILE *mapfil #define elf_backend_relocate_section rx_elf_relocate_section #define elf_symbol_leading_char ('_') #define elf_backend_can_gc_sections 1 -#define elf_backend_modify_program_headers elf32_rx_modify_program_headers +#define elf_backend_modify_headers elf32_rx_modify_headers #define bfd_elf32_bfd_reloc_type_lookup rx_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup rx_reloc_name_lookup @@ -4037,3 +4078,18 @@ rx_additional_link_map_text (bfd *obfd, struct bfd_link_info *info, FILE *mapfil #define elf32_bed elf32_rx_be_ns_bed #include "elf32-target.h" + +#undef TARGET_LITTLE_SYM +#define TARGET_LITTLE_SYM rx_elf32_linux_le_vec +#undef TARGET_LITTLE_NAME +#define TARGET_LITTLE_NAME "elf32-rx-linux" +#undef TARGET_BIG_SYM +#undef TARGET_BIG_NAME + +#undef elf_backend_object_p +#define elf_backend_object_p rx_linux_object_p +#undef elf_symbol_leading_char +#undef elf32_bed +#define elf32_bed elf32_rx_le_linux_bed + +#include "elf32-target.h"