/* BFD back-end for Hitachi H8/300 COFF binaries.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
Free Software Foundation, Inc.
Written by Steve Chamberlain, <sac@cygnus.com>.
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
/* We derive a hash table from the basic BFD hash table to
- hold entries in the function vector. Aside from the
+ hold entries in the function vector. Aside from the
info stored by the basic hash table, we need the offset
of a particular entry within the hash table as well as
the offset where we'll add the next entry. */
struct funcvec_hash_entry
-{
- /* The basic hash table entry. */
- struct bfd_hash_entry root;
+ {
+ /* The basic hash table entry. */
+ struct bfd_hash_entry root;
- /* The offset within the vectors section where
- this entry lives. */
- bfd_vma offset;
-};
+ /* The offset within the vectors section where
+ this entry lives. */
+ bfd_vma offset;
+ };
struct funcvec_hash_table
-{
- /* The basic hash table. */
- struct bfd_hash_table root;
+ {
+ /* The basic hash table. */
+ struct bfd_hash_table root;
- bfd *abfd;
+ bfd *abfd;
- /* Offset at which we'll add the next entry. */
- unsigned int offset;
-};
+ /* Offset at which we'll add the next entry. */
+ unsigned int offset;
+ };
static struct bfd_hash_entry *
funcvec_hash_newfunc
struct bfd_hash_table *,
const char *))));
+static bfd_reloc_status_type special PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static int select_reloc PARAMS ((reloc_howto_type *));
+static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
+static void reloc_processing PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
+static boolean h8300_symbol_address_p PARAMS ((bfd *, asection *, bfd_vma));
+static int h8300_reloc16_estimate PARAMS ((bfd *, asection *, arelent *, unsigned int, struct bfd_link_info *));
+static void h8300_reloc16_extra_cases PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *));
+static boolean h8300_bfd_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
+
/* To lookup a value in the function vector hash table. */
#define funcvec_hash_lookup(table, string, create, copy) \
((struct funcvec_hash_entry *) \
bfd *abfd;
{
struct h8300_coff_link_hash_table *ret;
- ret = ((struct h8300_coff_link_hash_table *)
- bfd_alloc (abfd, sizeof (struct h8300_coff_link_hash_table)));
+ bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table);
+
+ ret = (struct h8300_coff_link_hash_table *) bfd_alloc (abfd, amt);
if (ret == NULL)
return NULL;
- if (!_bfd_link_hash_table_init (&ret->root.root, abfd, _bfd_generic_link_hash_newfunc))
+ if (!_bfd_link_hash_table_init (&ret->root.root, abfd,
+ _bfd_generic_link_hash_newfunc))
{
bfd_release (abfd, ret);
return NULL;
We only come here for pcrel stuff and return normally if not an -r link.
When doing -r, we can't do any arithmetic for the pcrel stuff, because
the code in reloc.c assumes that we can manipulate the targets of
- the pcrel branches. This isn't so, since the H8/300 can do relaxing,
+ the pcrel branches. This isn't so, since the H8/300 can do relaxing,
which means that the gap after the instruction may not be enough to
contain the offset required for the branch, so we have to use only
the addend until the final link. */
#define __A_MAGIC_SET__
/* Code to swap in the reloc. */
-#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
-#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET H_PUT_32
#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
dst->r_stuff[0] = 'S'; \
dst->r_stuff[1] = 'C';
static asection *last_input_section = NULL;
static arelent *last_reloc = NULL;
- /* The address of the thing to be relocated will have moved back by
+ /* The address of the thing to be relocated will have moved back by
the size of the shrink - but we don't change reloc->address here,
since we need it to know where the relocation lives in the source
uncooked section. */
/* Only examine the relocs which might be relaxable. */
switch (reloc->howto->type)
- {
+ {
/* This is the 16/24 bit absolute branch which could become an 8 bit
pc-relative branch. */
case R_JMP1:
this jump. +128 is valid since the target will move two bytes
closer if we do relax this branch. */
if ((int)gap >= -128 && (int)gap <= 128 )
- {
+ {
/* It's possible we may be able to eliminate this branch entirely;
if the previous instruction is a branch around this instruction,
and there's no label at this instruction, then we can reverse
bCC lab1 bCC' lab2
jmp lab2
lab1: lab1:
-
+
This saves 4 bytes instead of two, and should be relatively
common. */
this jump. +128 is valid since the target will move two bytes
closer if we do relax this branch. */
if ((int)gap >= -128 && (int)gap <= 128 )
- {
+ {
/* Change the reloc type. */
reloc->howto = howto_table + 15;
value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
/* Get the address of the instruction (not the reloc). */
- dot = (link_order->offset
- + dst_address
+ dot = (link_order->offset
+ + dst_address
+ link_order->u.indirect.section->output_section->vma + 1);
gap = value - dot;
/* Everything looks OK. Apply the relocation and update the
src/dst address appropriately. */
- bfd_put_16 (abfd, gap, data + dst_address);
+ bfd_put_16 (abfd, (bfd_vma) gap, data + dst_address);
dst_address += 2;
src_address += 2;
src_address += 2;
break;
-
+
/* Similarly for a 24bit absolute that is now 8 bits. */
case R_JMPL2:
/* Get the address of the target of this branch. */
/* We need to find the symbol so we can determine it's
address in the function vector table. */
asymbol *symbol;
- bfd_vma value;
const char *name;
+ struct funcvec_hash_table *ftab;
struct funcvec_hash_entry *h;
asection *vectors_sec = h8300_coff_hash_table (link_info)->vectors_sec;
}
/* This is a jump/call through a function vector, and we're
- expected to create the function vector ourselves.
+ expected to create the function vector ourselves.
First look up this symbol in the linker hash table -- we need
the derived linker symbol which holds this symbol's index
name = symbol->name;
if (symbol->flags & BSF_LOCAL)
{
- char *new_name = bfd_malloc (strlen (name) + 9);
+ char *new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9);
if (new_name == NULL)
abort ();
name = new_name;
}
- h = funcvec_hash_lookup (h8300_coff_hash_table (link_info)->funcvec_hash_table,
- name, false, false);
+ ftab = h8300_coff_hash_table (link_info)->funcvec_hash_table;
+ h = funcvec_hash_lookup (ftab, name, false, false);
/* This shouldn't ever happen. If it does that means we've got
data corruption of some kind. Aborting seems like a reasonable
bfd_set_section_contents (vectors_sec->output_section->owner,
vectors_sec->output_section,
vectors_sec->contents,
- vectors_sec->output_offset,
+ (file_ptr) vectors_sec->output_offset,
vectors_sec->_raw_size);
break;
}
{
asection *sec;
struct funcvec_hash_table *funcvec_hash_table;
+ bfd_size_type amt;
/* If we haven't created a vectors section, do so now. */
if (!h8300_coff_hash_table (info)->vectors_sec)
return false;
/* Also create the vector hash table. */
- funcvec_hash_table = ((struct funcvec_hash_table *)
- bfd_alloc (abfd, sizeof (struct funcvec_hash_table)));
+ amt = sizeof (struct funcvec_hash_table);
+ funcvec_hash_table = (struct funcvec_hash_table *) bfd_alloc (abfd, amt);
if (!funcvec_hash_table)
return false;
if (reloc_size <= 0)
continue;
- relocs = (arelent **) bfd_malloc ((size_t) reloc_size);
+ relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
if (!relocs)
return false;
&& symbol != bfd_abs_section_ptr->symbol)
{
+ struct funcvec_hash_table *ftab;
struct funcvec_hash_entry *h;
name = symbol->name;
if (symbol->flags & BSF_LOCAL)
{
- char *new_name = bfd_malloc (strlen (name) + 9);
+ char *new_name;
+ new_name = bfd_malloc ((bfd_size_type) strlen (name) + 9);
if (new_name == NULL)
abort ();
}
/* Look this symbol up in the function vector hash table. */
- h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
- name, false, false);
-
+ ftab = h8300_coff_hash_table (info)->funcvec_hash_table;
+ h = funcvec_hash_lookup (ftab, name, false, false);
/* If this symbol isn't already in the hash table, add
it and bump up the size of the hash table. */
if (h == NULL)
{
- h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
- name, true, true);
+ h = funcvec_hash_lookup (ftab, name, true, true);
if (h == NULL)
{
free (relocs);
/* Now actually allocate some space for the function vector. It's
wasteful to do this more than once, but this is easier. */
- if (h8300_coff_hash_table (info)->vectors_sec->_raw_size != 0)
+ sec = h8300_coff_hash_table (info)->vectors_sec;
+ if (sec->_raw_size != 0)
{
/* Free the old contents. */
- if (h8300_coff_hash_table (info)->vectors_sec->contents)
- free (h8300_coff_hash_table (info)->vectors_sec->contents);
+ if (sec->contents)
+ free (sec->contents);
/* Allocate new contents. */
- h8300_coff_hash_table (info)->vectors_sec->contents
- = bfd_malloc (h8300_coff_hash_table (info)->vectors_sec->_raw_size);
+ sec->contents = bfd_malloc (sec->_raw_size);
}
return true;