/* 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
#include "sysdep.h"
#include "bfd.h"
-#include "bfd_stdint.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/rx.h"
/* 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)
{
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;
}
\f
static bfd_vma
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
{
/* 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,
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);
}
idx = (int) (entry_vma - table_start_cache) / 4;
/* This will look like $tableentry$<N>$<name> */
- 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);
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
&& 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)
+ 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;
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,
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;
}
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,
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;
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. */
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;
}
}
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));
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;
}
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;
+}
\f
#ifdef DEBUG
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);
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 *
char * cloc = (char *) location;
swapped_data = (char *) bfd_alloc (abfd, count);
+ if (swapped_data == NULL)
+ return FALSE;
for (i = 0; i < count; i += 4)
{
}
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;
#endif
}
- return TRUE;
+ return _bfd_elf_modify_headers (abfd, info);
}
/* The default literal sections should always be marked as "code" (i.e.,
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);
&& 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;
}
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;
+ 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);
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 ++)
{
#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
#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"