/* BFD back-end for Motorola MCore COFF/PE
- Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010, 2011, 2012
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 bfd_boolean mcore_bfd_coff_final_link
- PARAMS ((bfd *, struct bfd_link_info *));
-#if 0
-static struct bfd_link_hash_table *coff_mcore_link_hash_table_create
- PARAMS ((bfd *));
-#endif
+ (bfd *, struct bfd_link_info *);
static bfd_reloc_status_type mcore_coff_unsupported_reloc
- PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static bfd_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 void mcore_emit_base_file_entry
- PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_vma));
-static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
\f
/* The NT loader points the toc register to &toc + 32768, in order to
use the complete range of a 16-bit displacement. We have to adjust
#define coff_mcore_hash_table(info) \
((mcore_hash_table *) ((info)->hash))
-#if 0
-/* Create an MCore coff linker hash table. */
-
-static struct bfd_link_hash_table *
-coff_mcore_link_hash_table_create (abfd)
- bfd * abfd;
-{
- mcore_hash_table * ret;
-
- ret = (mcore_hash_table *) bfd_malloc ((bfd_size_type) sizeof (* ret));
- if (ret == (mcore_hash_table *) NULL)
- return NULL;
-
- if (! _bfd_coff_link_hash_table_init
- (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
- {
- free (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;
-
- return & ret->root.root;
-}
-#endif
\f
/* Add an entry to the base file. */
-static void
-mcore_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
- struct bfd_link_info * info;
- bfd * output_bfd;
- asection * input_section;
- bfd_vma reloc_offset;
+static bfd_boolean
+mcore_emit_base_file_entry (struct bfd_link_info *info,
+ bfd *output_bfd,
+ asection *input_section,
+ bfd_vma reloc_offset)
{
bfd_vma addr = reloc_offset
- input_section->vma
if (coff_data (output_bfd)->pe)
addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
- fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file);
+ if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+ return TRUE;
+
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
}
\f
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 ATTRIBUTE_UNUSED;
- PTR data ATTRIBUTE_UNUSED;
- asection * input_section ATTRIBUTE_UNUSED;
- bfd * output_bfd ATTRIBUTE_UNUSED;
- char ** error_message ATTRIBUTE_UNUSED;
+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);
case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
static reloc_howto_type *
-mcore_coff_reloc_type_lookup (abfd, code)
- bfd * abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+mcore_coff_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
switch (code)
{
}
/*NOTREACHED*/
}
-
#undef HOW2MAP
+static reloc_howto_type *
+mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (mcore_coff_howto_table)
+ / sizeof (mcore_coff_howto_table[0]));
+ 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 = mcore_coff_howto_table + (dst)->r_type;
static reloc_howto_type *
-coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
- 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;
+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;
This function is referenced in pe_mkobject in peicode.h. */
static bfd_boolean
-in_reloc_p (abfd, howto)
- bfd * abfd ATTRIBUTE_UNUSED;
- reloc_howto_type * howto;
+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 bfd_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;
+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;
- bfd_boolean hihalf;
- bfd_vma hihalf_val;
/* If we are performing a relocatable link, we don't need to do a
thing. The caller will take care of adjusting the reloc
if (info->relocatable)
return TRUE;
- /* Check if we have the same endianess */
+ /* Check if we have the same endianness */
if ( input_bfd->xvec->byteorder != output_bfd->xvec->byteorder
&& output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
{
return FALSE;
}
- hihalf = FALSE;
- hihalf_val = 0;
-
rel = relocs;
relend = rel + input_section->reloc_count;
break;
}
- if (info->base_file)
- {
- /* Emit a reloc if the backend thinks it needs it. */
- if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
- mcore_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
- }
+ /* 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)
{
case bfd_reloc_overflow:
if (! ((*info->callbacks->reloc_overflow)
- (info, my_name, howto->name,
+ (info, (h ? &h->root : NULL), my_name, howto->name,
(bfd_vma) 0, input_bfd,
input_section, rel->r_vaddr - input_section->vma)))
return FALSE;
/* 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_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