-/* BFD back-end for Motorolla MCore COFF/PE
- Copyright 1999
- Free Software Foundation, Inc.
+/* BFD back-end for Motorola MCore COFF/PE
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "libbfd.h"
#include "coff/mcore.h"
#include "coff/internal.h"
/* This file is compiled more than once, but we only compile the
final_link routine once. */
-extern boolean mcore_bfd_coff_final_link
- PARAMS ((bfd *, struct bfd_link_info *));
-
-static struct bfd_link_hash_table * coff_mcore_link_hash_table_create
- PARAMS ((bfd *));
-static bfd_reloc_status_type mcore_coff_unsupported_reloc
- PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static boolean in_reloc_p
- PARAMS ((bfd *, reloc_howto_type *));
-static boolean coff_mcore_relocate_section
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
- struct internal_reloc *, struct internal_syment *, asection **));
-static reloc_howto_type * mcore_coff_reloc_type_lookup
- PARAMS ((bfd *, bfd_reloc_code_real_type));
-static reloc_howto_type * coff_mcore_rtype_to_howto
- PARAMS ((bfd *, asection *, struct internal_reloc *,
- struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
-static const bfd_target * pe_object_p
- PARAMS ((bfd *));
-
+extern bfd_boolean mcore_bfd_coff_final_link
+ (bfd *, struct bfd_link_info *);
+static bfd_reloc_status_type mcore_coff_unsupported_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
\f
/* The NT loader points the toc register to &toc + 32768, in order to
#define TOC_SECTION_NAME ".private.toc"
/* The main body of code is in coffcode.h. */
-#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
from smaller values. Start with zero, widen, *then* decrement. */
#define MINUS_ONE (((bfd_vma)0) - 1)
-
\f
static reloc_howto_type mcore_coff_howto_table[] =
{
/* Unused: */
- HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */
- 0, /* rightshift */
- 0, /* size (0 = byte, 1 = short, 2 = long) */
- 0, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
+ HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
complain_overflow_dont, /* dont complain_on_overflow */
- 0, /* special_function */
- "ABSOLUTE", /* name */
- false, /* partial_inplace */
- 0x00, /* src_mask */
- 0x00, /* dst_mask */
- false), /* pcrel_offset */
-
+ NULL, /* special_function */
+ "ABSOLUTE", /* name */
+ FALSE, /* partial_inplace */
+ 0x00, /* src_mask */
+ 0x00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
HOWTO (IMAGE_REL_MCORE_ADDR32,/* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- 0, /* special_function */
- "ADDR32", /* name */
- true, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- false), /* pcrel_offset */
-
+ NULL, /* special_function */
+ "ADDR32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
/* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
- Should not appear in object files. */
+ Should not appear in object files. */
HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4, /* type */
2, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
8, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- mcore_coff_unsupported_reloc, /* special_function */
- "IMM8BY4", /* name */
- false, /* partial_inplace */
+ mcore_coff_unsupported_reloc, /* special_function */
+ "IMM8BY4", /* name */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
- /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
+ /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
Span 2k instructions == 4k bytes.
Only useful pieces at the relocated address are the opcode (5 bits) */
HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2,/* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
11, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
- NULL, /* special_function */
- "IMM11BY2", /* name */
- false, /* partial_inplace */
+ NULL, /* special_function */
+ "IMM11BY2", /* name */
+ FALSE, /* partial_inplace */
0x0, /* src_mask */
0x7ff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
- /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
+ /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2, /* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
4, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- mcore_coff_unsupported_reloc,/* special_function */
- "IMM4BY2", /* name */
- false, /* partial_inplace */
+ mcore_coff_unsupported_reloc, /* special_function */
+ "IMM4BY2", /* name */
+ FALSE, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
- /* 32-bit pc-relative. Eventually this will help support PIC code. */
+ /* 32-bit pc-relative. Eventually this will help support PIC code. */
HOWTO (IMAGE_REL_MCORE_PCREL_32,/* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
- NULL, /* special_function */
- "PCREL_32", /* name */
- false, /* partial_inplace */
+ NULL, /* special_function */
+ "PCREL_32", /* name */
+ FALSE, /* partial_inplace */
0x0, /* src_mask */
0xffffffff, /* dst_mask */
- true), /* pcrel_offset */
+ TRUE), /* pcrel_offset */
/* Like PCREL_IMM11BY2, this relocation indicates that there is a
'jsri' at the specified address. There is a separate relocation
- entry for the literal pool entry that it references, but we
+ entry for the literal pool entry that it references, but we
might be able to change the jsri to a bsr if the target turns out
to be close enough [even though we won't reclaim the literal pool
entry, we'll get some runtime efficiency back]. Note that this
- is a relocation that we are allowed to safely ignore. */
+ is a relocation that we are allowed to safely ignore. */
HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2,/* type */
1, /* rightshift */
1, /* size (0 = byte, 1 = short, 2 = long) */
11, /* bitsize */
- true, /* pc_relative */
+ TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
- NULL, /* special_function */
- "JSR_IMM11BY2", /* name */
- false, /* partial_inplace */
+ NULL, /* special_function */
+ "JSR_IMM11BY2", /* name */
+ FALSE, /* partial_inplace */
0x0, /* src_mask */
0x7ff, /* dst_mask */
- true) /* pcrel_offset */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (IMAGE_REL_MCORE_RVA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ NULL, /* special_function */
+ "MCORE_RVA", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
};
\f
/* Extend the coff_link_hash_table structure with a few M*Core specific fields.
/* The original coff_link_hash_table structure. MUST be first field. */
struct coff_link_hash_table root;
- bfd * bfd_of_toc_owner;
- long int global_toc_size;
- long int import_table_size;
- long int first_thunk_address;
- long int thunk_size;
+ bfd * bfd_of_toc_owner;
+ long int global_toc_size;
+ long int import_table_size;
+ long int first_thunk_address;
+ long int thunk_size;
}
mcore_hash_table;
#define coff_mcore_hash_table(info) \
((mcore_hash_table *) ((info)->hash))
-/* Create an MCore coff linker hash table. */
-static struct bfd_link_hash_table *
-coff_mcore_link_hash_table_create (abfd)
- bfd * abfd;
+\f
+/* Add an entry to the base file. */
+
+static bfd_boolean
+mcore_emit_base_file_entry (struct bfd_link_info *info,
+ bfd *output_bfd,
+ asection *input_section,
+ bfd_vma reloc_offset)
{
- mcore_hash_table * ret;
+ bfd_vma addr = reloc_offset
+ - input_section->vma
+ + input_section->output_offset
+ + input_section->output_section->vma;
- ret = ((mcore_hash_table *) bfd_alloc (abfd, sizeof (* ret)));
- if (ret == (mcore_hash_table *) NULL)
- return NULL;
+ if (coff_data (output_bfd)->pe)
+ addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
- if (! _bfd_coff_link_hash_table_init
- (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
- {
- bfd_release (abfd, ret);
- return (struct bfd_link_hash_table *) NULL;
- }
-
- ret->bfd_of_toc_owner = NULL;
- ret->global_toc_size = 0;
- ret->import_table_size = 0;
- ret->first_thunk_address = 0;
- ret->thunk_size = 0;
+ if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+ return TRUE;
- return & ret->root.root;
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
}
\f
-/*ARGSUSED*/
static bfd_reloc_status_type
-mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
- output_bfd, error_message)
- bfd * abfd;
- arelent * reloc_entry;
- asymbol * symbol;
- PTR data;
- asection * input_section;
- bfd * output_bfd;
- char ** error_message;
+mcore_coff_unsupported_reloc (bfd * abfd,
+ arelent * reloc_entry,
+ asymbol * symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection * input_section ATTRIBUTE_UNUSED,
+ bfd * output_bfd ATTRIBUTE_UNUSED,
+ char ** error_message ATTRIBUTE_UNUSED)
{
BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
-
- _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
- bfd_get_filename (abfd),
+
+ /* xgettext: c-format */
+ _bfd_error_handler (_("%pB: Relocation %s (%d) is not currently supported.\n"),
+ abfd,
reloc_entry->howto->name,
reloc_entry->howto->type);
-
+
return bfd_reloc_notsupported;
}
-
\f
-/* A cheesy little macro to make the code a little more readable. */
+/* A cheesy little macro to make the code a little more readable. */
#define HOW2MAP(bfd_rtype, mcore_rtype) \
case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
static reloc_howto_type *
-mcore_coff_reloc_type_lookup (abfd, code)
- bfd * abfd;
- bfd_reloc_code_real_type code;
+mcore_coff_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
switch (code)
- {
- HOW2MAP (BFD_RELOC_32, IMAGE_REL_MCORE_ADDR32);
- HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4, IMAGE_REL_MCORE_PCREL_IMM8BY4);
- HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2, IMAGE_REL_MCORE_PCREL_IMM11BY2);
- HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2, IMAGE_REL_MCORE_PCREL_IMM4BY2);
- HOW2MAP (BFD_RELOC_32_PCREL, IMAGE_REL_MCORE_PCREL_32);
+ {
+ HOW2MAP (BFD_RELOC_32, IMAGE_REL_MCORE_ADDR32);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4, IMAGE_REL_MCORE_PCREL_IMM8BY4);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2, IMAGE_REL_MCORE_PCREL_IMM11BY2);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2, IMAGE_REL_MCORE_PCREL_IMM4BY2);
+ HOW2MAP (BFD_RELOC_32_PCREL, IMAGE_REL_MCORE_PCREL_32);
HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2);
- default:
+ HOW2MAP (BFD_RELOC_RVA, IMAGE_REL_MCORE_RVA);
+ default:
return NULL;
}
/*NOTREACHED*/
}
-
#undef HOW2MAP
-#define RTYPE2HOWTO(cache_ptr, dst) \
- (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
+#define NUM_HOWTOS NUM_ELEM (mcore_coff_howto_table)
static reloc_howto_type *
-coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
- bfd * abfd;
- asection * sec;
- struct internal_reloc * rel;
- struct coff_link_hash_entry * h;
- struct internal_syment * sym;
- bfd_vma * addendp;
+mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
{
- reloc_howto_type * howto;
+ unsigned int i;
+
+ for (i = 0; i < NUM_HOWTOS; i++)
+ if (mcore_coff_howto_table[i].name != NULL
+ && strcasecmp (mcore_coff_howto_table[i].name, r_name) == 0)
+ return &mcore_coff_howto_table[i];
+
+ return NULL;
+}
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < NUM_HOWTOS \
+ ? mcore_coff_howto_table + (dst)->r_type \
+ : NULL))
- if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
+static reloc_howto_type *
+coff_mcore_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ asection * sec,
+ struct internal_reloc * rel,
+ struct coff_link_hash_entry * h ATTRIBUTE_UNUSED,
+ struct internal_syment * sym,
+ bfd_vma * addendp)
+{
+ reloc_howto_type * howto;
+
+ if (rel->r_type >= NUM_HOWTOS)
return NULL;
-
+
howto = mcore_coff_howto_table + rel->r_type;
-
- if (howto->pc_relative)
+
+ if (rel->r_type == IMAGE_REL_MCORE_RVA)
+ * addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+ else if (howto->pc_relative)
{
* addendp = sec->vma - 2; /* XXX guess - is this right ? */
-
+
/* If the symbol is defined, then the generic code is going to
- add back the symbol value in order to cancel out an
- adjustment it made to the addend. However, we set the addend
- to 0 at the start of this function. We need to adjust here,
- to avoid the adjustment the generic code will make. FIXME:
- This is getting a bit hackish. */
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
if (sym != NULL && sym->n_scnum != 0)
* addendp -= sym->n_value;
}
else
* addendp = 0;
-
+
return howto;
}
-\f
-/* Return true if this relocation should
- appear in the output .reloc section. */
-static boolean in_reloc_p (abfd, howto)
- bfd * abfd;
- reloc_howto_type * howto;
-{
- return ! howto->pc_relative;
-}
+/* Return TRUE if this relocation should appear in the output .reloc section.
+ This function is referenced in pe_mkobject in peicode.h. */
+
+static bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, reloc_howto_type * howto)
+{
+ return ! howto->pc_relative && howto->type != IMAGE_REL_MCORE_RVA;
+}
+\f
/* The reloc processing routine for the optimized COFF linker. */
-static boolean
-coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section,
- contents, relocs, syms, sections)
- bfd * output_bfd;
- struct bfd_link_info * info;
- bfd * input_bfd;
- asection * input_section;
- bfd_byte * contents;
- struct internal_reloc * relocs;
- struct internal_syment * syms;
- asection ** sections;
+static bfd_boolean
+coff_mcore_relocate_section (bfd * output_bfd,
+ struct bfd_link_info * info,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ struct internal_reloc * relocs,
+ struct internal_syment * syms,
+ asection ** sections)
{
struct internal_reloc * rel;
struct internal_reloc * relend;
- boolean hihalf;
- bfd_vma hihalf_val;
-
- /* If we are performing a relocateable link, we don't need to do a
+
+ /* If we are performing a relocatable link, we don't need to do a
thing. The caller will take care of adjusting the reloc
addresses and symbol indices. */
- if (info->relocateable)
- return true;
-
- BFD_ASSERT (input_bfd->xvec->byteorder
- == output_bfd->xvec->byteorder);
+ if (bfd_link_relocatable (info))
+ return TRUE;
- hihalf = false;
- hihalf_val = 0;
+ /* Check if we have the same endianness */
+ if ( input_bfd->xvec->byteorder != output_bfd->xvec->byteorder
+ && output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ _bfd_error_handler
+ /* xgettext: c-format */
+ (_("%pB: compiled for a %s system and target is %s.\n"),
+ input_bfd,
+ bfd_big_endian (input_bfd) ? _("big endian") : _("little endian"),
+ bfd_big_endian (output_bfd) ? _("big endian") : _("little endian"));
+
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
rel = relocs;
relend = rel + input_section->reloc_count;
-
+
for (; rel < relend; rel++)
{
- asection * toc_section = NULL;
- bfd_vma relocation;
- long symndx;
- struct internal_syment * sym;
- bfd_vma val;
- bfd_vma addend;
- bfd_reloc_status_type rstat;
- bfd_byte * loc;
- unsigned short r_type = rel->r_type;
- reloc_howto_type * howto = NULL;
+ long symndx;
+ struct internal_syment * sym;
+ bfd_vma val;
+ bfd_vma addend;
+ bfd_reloc_status_type rstat;
+ bfd_byte * loc;
+ unsigned short r_type = rel->r_type;
+ reloc_howto_type * howto = NULL;
struct coff_link_hash_entry * h;
- const char * my_name;
-
+ const char * my_name;
+
symndx = rel->r_symndx;
loc = contents + rel->r_vaddr - input_section->vma;
sym = syms + symndx;
}
+ addend = 0;
+
/* Get the howto and initialise the addend. */
howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
sym, & addend);
if (howto == NULL)
- return false;
+ return FALSE;
val = 0;
-
+
if (h == NULL)
{
if (symndx == -1)
else
{
asection * sec = sections[symndx];
-
- val = (sym->n_value
+
+ val = (sym->n_value
+ sec->output_section->vma
+ sec->output_offset);
else if ( sym->_n._n_n._n_zeroes == 0
&& sym->_n._n_n._n_offset != 0)
my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
- else
+ else
{
static char buf [SYMNMLEN + 1];
-
+
strncpy (buf, sym->_n._n_name, SYMNMLEN);
buf[SYMNMLEN] = '\0';
my_name = buf;
|| h->root.type == bfd_link_hash_defweak)
{
asection * sec = h->root.u.def.section;
-
+
val = (h->root.u.def.value
+ sec->output_section->vma
+ sec->output_offset);
}
else
- {
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd, input_section,
- rel->r_vaddr - input_section->vma)))
- return false;
- }
-
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE);
+
my_name = h->root.root.string;
- }
+ }
rstat = bfd_reloc_ok;
-
+
/* Each case must do its own relocation, setting rstat appropriately. */
switch (r_type)
{
default:
- _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
- bfd_get_filename (input_bfd), r_type);
+ /* xgettext: c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ input_bfd, r_type);
bfd_set_error (bfd_error_bad_value);
- return false;
-
+ return FALSE;
+
case IMAGE_REL_MCORE_ABSOLUTE:
- fprintf (stderr,
- _("Warning: unsupported reloc %s <file %s, section %s>\n"),
- howto->name,
- bfd_get_filename (input_bfd),
- input_section->name);
-
- fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
- rel->r_symndx, my_name, (long) rel->r_vaddr,
- (unsigned long) rel->r_vaddr);
+ _bfd_error_handler
+ /* xgettext: c-format */
+ (_("warning: unsupported reloc %s <file %pB, section %pA>\n"
+ "sym %ld (%s), r_vaddr %" PRId64 " (%#" PRIx64 ")"),
+ howto->name, input_bfd, input_section,
+ rel->r_symndx, my_name, (int64_t) rel->r_vaddr,
+ (uint64_t) rel->r_vaddr);
break;
-
+
case IMAGE_REL_MCORE_PCREL_IMM8BY4:
case IMAGE_REL_MCORE_PCREL_IMM11BY2:
case IMAGE_REL_MCORE_PCREL_IMM4BY2:
case IMAGE_REL_MCORE_PCREL_32:
case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2:
case IMAGE_REL_MCORE_ADDR32:
+ /* XXX fixme - shouldn't this be like the code for the RVA reloc ? */
rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
break;
+
+ case IMAGE_REL_MCORE_RVA:
+ rstat = _bfd_final_link_relocate
+ (howto, input_bfd,
+ input_section, contents, rel->r_vaddr - input_section->vma,
+ val, addend);
+ break;
}
-
+
+ /* Emit a reloc if the backend thinks it needs it. */
+ if (info->base_file
+ && sym
+ && pe_data (output_bfd)->in_reloc_p (output_bfd, howto)
+ && !mcore_emit_base_file_entry (info, output_bfd, input_section,
+ rel->r_vaddr))
+ return FALSE;
+
switch (rstat)
{
default:
abort ();
-
+
case bfd_reloc_ok:
break;
-
+
case bfd_reloc_overflow:
- if (! ((*info->callbacks->reloc_overflow)
- (info, my_name, howto->name,
- (bfd_vma) 0, input_bfd,
- input_section, rel->r_vaddr - input_section->vma)))
- return false;
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), my_name, howto->name,
+ (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma);
}
- }
+ }
- return true;
+ return TRUE;
}
-
\f
-/* Tailor coffcode.h -- macro heaven. */
+/* Tailor coffcode.h -- macro heaven. */
/* We use the special COFF backend linker, with our own special touch. */
#define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
-#define coff_relocate_section coff_mcore_relocate_section
-#define coff_rtype_to_howto coff_mcore_rtype_to_howto
+#define coff_bfd_reloc_name_lookup mcore_coff_reloc_name_lookup
+#define coff_relocate_section coff_mcore_relocate_section
+#define coff_rtype_to_howto coff_mcore_rtype_to_howto
#define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
-#define COFF_PAGE_SIZE 0x1000
+/* Make sure that the 'r_offset' field is copied properly
+ so that identical binaries will compare the same. */
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET H_PUT_32
-#include "coffcode.h"
-\f
-static const bfd_target *
-pe_object_p (abfd)
- bfd * abfd;
-{
-#ifdef COFF_IMAGE_WITH_PE
- /* We need to hack badly to handle a PE image correctly. In PE
- images created by the GNU linker, the offset to the COFF header
- is always the size. However, this is not the case in images
- generated by other PE linkers. The PE format stores a four byte
- offset to the PE signature just before the COFF header at
- location 0x3c of the file. We pick up that offset, verify that
- the PE signature is there, and then set ourselves up to read in
- the COFF header. */
- {
- bfd_byte ext_offset[4];
- file_ptr offset;
- bfd_byte ext_signature[4];
- unsigned long signature;
-
- if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
- || bfd_read (ext_offset, 1, 4, abfd) != 4)
- {
- if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
-
- offset = bfd_h_get_32 (abfd, ext_offset);
-
- if (bfd_seek (abfd, offset, SEEK_SET) != 0
- || bfd_read (ext_signature, 1, 4, abfd) != 4)
- {
- if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_wrong_format);
-
- return NULL;
- }
-
- signature = bfd_h_get_32 (abfd, ext_signature);
-
- if (signature != 0x4550)
- {
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
-
- /* Here is the hack. coff_object_p wants to read filhsz bytes to
- pick up the COFF header. We adjust so that that will work. 20
- is the size of the mips COFF filehdr. */
- if (bfd_seek (abfd, (bfd_tell (abfd) - bfd_coff_filhsz (abfd) + 20),
- SEEK_SET) != 0)
- {
- if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_wrong_format);
-
- return NULL;
- }
- }
-#endif
+#define COFF_PAGE_SIZE 0x1000
- return coff_object_p (abfd);
-}
+#include "coffcode.h"
\f
-/* The transfer vectors that lead the outside world to all of the above. */
-
-const bfd_target
-TARGET_BIG_SYM =
-{
- TARGET_BIG_NAME,
- bfd_target_coff_flavour,
- BFD_ENDIAN_BIG, /* data byte order is big */
- BFD_ENDIAN_BIG, /* header byte order is big */
-
- (HAS_RELOC | EXEC_P | /* object flags */
- HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
-
- (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
- | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
-
- 0, /* leading char */
- '/', /* ar_pad_char */
- 15, /* ar_max_namelen */
-
- bfd_getb64, bfd_getb_signed_64, bfd_putb64,
- bfd_getb32, bfd_getb_signed_32, bfd_putb32,
- bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
-
- bfd_getb64, bfd_getb_signed_64, bfd_putb64,
- bfd_getb32, bfd_getb_signed_32, bfd_putb32,
- bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
-
- { _bfd_dummy_target,
- pe_object_p, /* bfd_check_format */
- bfd_generic_archive_p, /* _bfd_dummy_target */
- pe_object_p
- },
- { bfd_false,
- coff_mkobject,
- _bfd_generic_mkarchive, /* bfd_set_format */
- bfd_false
- },
- { bfd_false,
- coff_write_object_contents, /* bfd_write_contents */
- _bfd_write_archive_contents,
- bfd_false
- },
-
- BFD_JUMP_TABLE_GENERIC (coff),
- BFD_JUMP_TABLE_COPY (coff),
- BFD_JUMP_TABLE_CORE (_bfd_nocore),
- BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
- BFD_JUMP_TABLE_SYMBOLS (coff),
- BFD_JUMP_TABLE_RELOCS (coff),
- BFD_JUMP_TABLE_WRITE (coff),
- BFD_JUMP_TABLE_LINK (coff),
- BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
-
- COFF_SWAP_TABLE,
-};
-
-const bfd_target
-TARGET_LITTLE_SYM =
-{
- TARGET_LITTLE_NAME,
- bfd_target_coff_flavour,
- BFD_ENDIAN_LITTLE, /* data byte order is little */
- BFD_ENDIAN_LITTLE, /* header byte order is little */
-
- (HAS_RELOC | EXEC_P | /* object flags */
- HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
-
- (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
- | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
-
- 0, /* leading underscore */
- '/', /* ar_pad_char */
- 15, /* ar_max_namelen */
-
- bfd_getl64, bfd_getl_signed_64, bfd_putl64,
- bfd_getl32, bfd_getl_signed_32, bfd_putl32,
- bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
-
- bfd_getl64, bfd_getl_signed_64, bfd_putl64,
- bfd_getl32, bfd_getl_signed_32, bfd_putl32,
- bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
-
-/* Note that we allow an object file to be treated as a core file as well. */
- {
- _bfd_dummy_target,
- pe_object_p, /* bfd_check_format */
- bfd_generic_archive_p,
- pe_object_p
- },
- {
- bfd_false,
- coff_mkobject,
- _bfd_generic_mkarchive, /* bfd_set_format */
- bfd_false
- },
- {
- bfd_false,
- coff_write_object_contents, /* bfd_write_contents */
- _bfd_write_archive_contents,
- bfd_false
- },
-
- BFD_JUMP_TABLE_GENERIC (coff),
- BFD_JUMP_TABLE_COPY (coff),
- BFD_JUMP_TABLE_CORE (_bfd_nocore),
- BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
- BFD_JUMP_TABLE_SYMBOLS (coff),
- BFD_JUMP_TABLE_RELOCS (coff),
- BFD_JUMP_TABLE_WRITE (coff),
- BFD_JUMP_TABLE_LINK (coff),
- BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
-
- COFF_SWAP_TABLE,
-};
-
+/* Forward declaration to initialise alternative_target field. */
+extern const bfd_target TARGET_LITTLE_SYM;
+
+/* The transfer vectors that lead the outside world to all of the above. */
+CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED,
+ (SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_READONLY | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+ 0, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
+CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED,
+ (SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_READONLY | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+ 0, & TARGET_BIG_SYM, COFF_SWAP_TABLE)