#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/v850.h"
+#include "libiberty.h"
-/* sign-extend a 24-bit number */
+/* Sign-extend a 24-bit number. */
#define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
static reloc_howto_type *v850_elf_reloc_type_lookup
Elf_Internal_Sym *, asection *));
static boolean v850_elf_section_from_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
-
-/* Note: It is REQUIRED that the 'type' value of each entry in this array
- match the index of the entry in the array. */
+static boolean v850_elf_gc_sweep_hook
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static asection * v850_elf_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *,
+ Elf_Internal_Rela *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+
+/* Note: It is REQUIRED that the 'type' value of each entry
+ in this array match the index of the entry in the array. */
static reloc_howto_type v850_elf_howto_table[] =
{
/* This reloc does nothing. */
};
\f
-/* Map a bfd relocation into the appropriate howto structure */
+/* Map a bfd relocation into the appropriate howto structure. */
+
static reloc_howto_type *
v850_elf_reloc_type_lookup (abfd, code)
bfd * abfd ATTRIBUTE_UNUSED;
{
unsigned int i;
- for (i = 0;
- i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
- i++)
- {
- if (v850_elf_reloc_map[i].bfd_reloc_val == code)
- {
- BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
+ for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;)
+ if (v850_elf_reloc_map[i].bfd_reloc_val == code)
+ {
+ BFD_ASSERT (v850_elf_howto_table[code].type == v850_elf_reloc_map[i].elf_reloc_val);
- return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
- }
- }
+ return v850_elf_howto_table + code;
+ }
return NULL;
}
\f
/* Set the howto pointer for an V850 ELF reloc. */
+
static void
v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
bfd * abfd ATTRIBUTE_UNUSED;
return false;
break;
- /* This relocation describes which C++ vtable entries are actually
- used. Record for later use during GC. */
+ /* This relocation describes which C++ vtable entries
+ are actually used. Record for later use during GC. */
case R_V850_GNU_VTENTRY:
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return false;
small_data_common:
if (h)
{
- h->other |= other; /* flag which type of relocation was used */
+ /* Flag which type of relocation was used. */
+ h->other |= other;
if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
&& (h->other & V850_OTHER_ERROR) == 0)
{
&& h->root.u.c.p
&& !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
{
- asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
+ asection * section;
+
+ section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
section->flags |= SEC_IS_COMMON;
}
return ret;
}
-/*
- * In the old version, when an entry was checked out from the table,
- * it was deleted. This produced an error if the entry was needed
- * more than once, as the second attempted retry failed.
- *
- * In the current version, the entry is not deleted, instead we set
- * the field 'found' to true. If a second lookup matches the same
- * entry, then we know that the hi16s reloc has already been updated
- * and does not need to be updated a second time.
- *
- * TODO - TOFIX: If it is possible that we need to restore 2 different
- * addresses from the same table entry, where the first generates an
- * overflow, whilst the second do not, then this code will fail.
- */
+/* In the old version, when an entry was checked out from the table,
+ it was deleted. This produced an error if the entry was needed
+ more than once, as the second attempted retry failed.
+
+ In the current version, the entry is not deleted, instead we set
+ the field 'found' to true. If a second lookup matches the same
+ entry, then we know that the hi16s reloc has already been updated
+ and does not need to be updated a second time.
+
+ TODO - TOFIX: If it is possible that we need to restore 2 different
+ addresses from the same table entry, where the first generates an
+ overflow, whilst the second do not, then this code will fail. */
typedef struct hi16s_location
{
/* FIXME: The code here probably ought to be removed and the code in reloc.c
allowed to do its stuff instead. At least for most of the relocs, anwyay. */
+
static bfd_reloc_status_type
v850_elf_perform_relocation (abfd, r_type, addend, address)
bfd * abfd;
0x00000000
+ 0x00006fff (bit 15 not set, so the top half is zero)
------------
- 0x00006fff which is wrong (assuming that fred is at 0xffff)
- */
-
+ 0x00006fff which is wrong (assuming that fred is at 0xffff). */
{
long result;
}
\f
/* Insert the addend into the instruction. */
+
static bfd_reloc_status_type
v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
bfd * abfd ATTRIBUTE_UNUSED;
/* If there is an output BFD,
and the symbol is not a section name (which is only defined at final link time),
and either we are not putting the addend into the instruction
- or the addend is zero, so there is nothing to add into the instruction
+ or the addend is zero, so there is nothing to add into the instruction
then just fixup the address and return. */
if (obfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
}
#if 0
else if (obfd != NULL)
- {
- return bfd_reloc_continue;
- }
+ return bfd_reloc_continue;
#endif
/* Catch relocs involving undefined symbols. */
.section ".foo","ax"
nop
foo:
- nop
- */
+ nop */
if (reloc->howto->pc_relative == true)
{
/* Here the variable relocation holds the final address of the
symbol we are relocating against, plus any addend. */
relocation -= isection->output_section->vma + isection->output_offset;
- /* Deal with pcrel_offset */
+ /* Deal with pcrel_offset. */
relocation -= reloc->address;
}
#endif
}
\f
/* Perform a relocation as part of a final link. */
+
static bfd_reloc_status_type
v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
input_section, contents, offset, value,
if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000))
return bfd_reloc_overflow;
- value = SEXT24 (value); /* Only the bottom 24 bits of the PC are valid */
+ /* Only the bottom 24 bits of the PC are valid */
+ value = SEXT24 (value);
break;
case R_V850_HI16_S:
h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
if (h == (struct bfd_link_hash_entry *) NULL
|| h->type != bfd_link_hash_defined)
- return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
+ /* Actually this indicates that __ep could not be found. */
+ return bfd_reloc_continue;
ep = (h->u.def.value
+ h->u.def.section->output_section->vma
h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
if (h == (struct bfd_link_hash_entry *) NULL
|| h->type != bfd_link_hash_defined)
- return (bfd_reloc_dangerous + 1); /* Actually this indicates that __ctbp could not be found. */
+ /* Actually this indicates that __ctbp could not be found. */
+ return bfd_reloc_dangerous + 1;
ctbp = (h->u.def.value
+ h->u.def.section->output_section->vma
}
\f
/* Relocate an V850 ELF section. */
+
static boolean
v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
contents, relocs, local_syms, local_sections)
#if 0
{
char * name;
+
name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
name = (name == NULL) ? "<none>" : name;
-fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
- sec->name, name, sym->st_name,
- sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
+ fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ sec->name, name, sym->st_name,
+ sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
}
#endif
}
+ sec->output_section->vma
+ sec->output_offset);
#if 0
-fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
- sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
+ fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
+ sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
#endif
}
else if (h->root.type == bfd_link_hash_undefweak)
{
#if 0
-fprintf (stderr, "undefined: sec: %s, name: %s\n",
- sec->name, h->root.root.string);
+ fprintf (stderr, "undefined: sec: %s, name: %s\n",
+ sec->name, h->root.root.string);
#endif
relocation = 0;
}
input_section, rel->r_offset, true)))
return false;
#if 0
-fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
+ fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
#endif
relocation = 0;
}
}
- /* FIXME: We should use the addend, but the COFF relocations
- don't. */
+ /* FIXME: We should use the addend, but the COFF relocations don't. */
r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
input_section,
contents, rel->r_offset,
asection *sec ATTRIBUTE_UNUSED;
const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
{
- /* No got and plt entries for v850-elf */
+ /* No got and plt entries for v850-elf. */
return true;
}
}
return NULL;
}
+
/* Set the right machine number. */
+
static boolean
v850_elf_object_p (abfd)
bfd *abfd;
}
/* Store the machine number in the flags field. */
+
static void
v850_elf_final_write_processing (abfd, linker)
bfd * abfd;
}
/* Function to keep V850 specific file flags. */
+
static boolean
v850_elf_set_private_flags (abfd, flags)
bfd * abfd;
return true;
}
-/* Copy backend specific data from one object module to another */
+/* Copy backend specific data from one object module to another. */
+
static boolean
v850_elf_copy_private_bfd_data (ibfd, obfd)
bfd * ibfd;
elf_gp (obfd) = elf_gp (ibfd);
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
elf_flags_init (obfd) = true;
+
return true;
}
-/* Merge backend specific data from an object file to the output
- object file when linking. */
+/* Merge backend specific data from an object file
+ to the output object file when linking. */
static boolean
v850_elf_merge_private_bfd_data (ibfd, obfd)
bfd * ibfd;
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
&& bfd_get_arch_info (obfd)->the_default)
- {
- return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
- }
+ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
return true;
}
return true;
}
-/* Display the flags field */
+
+/* Display the flags field. */
static boolean
v850_elf_print_private_bfd_data (abfd, ptr)
static asymbol v850_elf_zcom_symbol;
static asymbol * v850_elf_zcom_symbol_ptr;
-/* Given a BFD section, try to locate the corresponding ELF section
- index. */
+/* Given a BFD section, try to locate the
+ corresponding ELF section index. */
static boolean
v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
return true;
}
-/*ARGSIGNORED*/
static boolean
v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
bfd * abfd ATTRIBUTE_UNUSED;
return true;
}
-/* Set the correct type for a V850 ELF section. We do this by the
- section name, which is a hack, but ought to work. */
+/* Set the correct type for a V850 ELF section. We do this
+ by the section name, which is a hack, but ought to work. */
+
static boolean
v850_elf_fake_sections (abfd, hdr, sec)
bfd * abfd ATTRIBUTE_UNUSED;