/* BFD back-end for MIPS Extended-Coff files.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2017 Free Software Foundation, Inc.
Original version by Per Bothner.
Full support added by Ian Lance Taylor, ian@cygnus.com.
#include "libecoff.h"
\f
/* Prototypes for static functions. */
+static bfd_reloc_status_type
+mips_generic_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+mips_refhi_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+mips_reflo_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+mips_gprel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_boolean mips_ecoff_bad_format_hook
- PARAMS ((bfd *abfd, PTR filehdr));
-static void mips_ecoff_swap_reloc_in
- PARAMS ((bfd *, PTR, struct internal_reloc *));
-static void mips_ecoff_swap_reloc_out
- PARAMS ((bfd *, const struct internal_reloc *, PTR));
-static void mips_adjust_reloc_in
- PARAMS ((bfd *, const struct internal_reloc *, arelent *));
-static void mips_adjust_reloc_out
- PARAMS ((bfd *, const arelent *, struct internal_reloc *));
-static bfd_reloc_status_type mips_generic_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
-static bfd_reloc_status_type mips_refhi_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
-static bfd_reloc_status_type mips_reflo_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
-static bfd_reloc_status_type mips_gprel_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
-static void mips_relocate_hi
- PARAMS ((struct internal_reloc *refhi, struct internal_reloc *reflo,
- bfd *input_bfd, asection *input_section, bfd_byte *contents,
- bfd_vma relocation));
-static bfd_boolean mips_relocate_section
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
-static reloc_howto_type *mips_bfd_reloc_type_lookup
- PARAMS ((bfd *, bfd_reloc_code_real_type));
\f
/* ECOFF has COFF sections, but the debugging information is stored in
a completely different format. ECOFF targets use some of the
#define NO_COFF_RELOCS
#define NO_COFF_SYMBOLS
#define NO_COFF_LINENOS
-#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
+#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
-#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
+#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
-#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
-#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
+#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
+#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
#include "coffswap.h"
/* See whether the magic number matches. */
static bfd_boolean
-mips_ecoff_bad_format_hook (abfd, filehdr)
- bfd *abfd;
- PTR filehdr;
+mips_ecoff_bad_format_hook (bfd * abfd, void * filehdr)
{
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
/* Swap a reloc in. */
static void
-mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
- bfd *abfd;
- PTR ext_ptr;
- struct internal_reloc *intern;
+mips_ecoff_swap_reloc_in (bfd * abfd,
+ void * ext_ptr,
+ struct internal_reloc *intern)
{
const RELOC *ext = (RELOC *) ext_ptr;
/* Swap a reloc out. */
static void
-mips_ecoff_swap_reloc_out (abfd, intern, dst)
- bfd *abfd;
- const struct internal_reloc *intern;
- PTR dst;
+mips_ecoff_swap_reloc_out (bfd * abfd,
+ const struct internal_reloc * intern,
+ void * dst)
{
RELOC *ext = (RELOC *) dst;
long r_symndx;
this backend routine. It must fill in the howto field. */
static void
-mips_adjust_reloc_in (abfd, intern, rptr)
- bfd *abfd;
- const struct internal_reloc *intern;
- arelent *rptr;
+mips_adjust_reloc_in (bfd *abfd,
+ const struct internal_reloc *intern,
+ arelent *rptr)
{
if (intern->r_type > MIPS_R_PCREL16)
abort ();
are needed for MIPS. */
static void
-mips_adjust_reloc_out (abfd, rel, intern)
- bfd *abfd ATTRIBUTE_UNUSED;
- const arelent *rel ATTRIBUTE_UNUSED;
- struct internal_reloc *intern ATTRIBUTE_UNUSED;
+mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
+ const arelent *rel ATTRIBUTE_UNUSED,
+ struct internal_reloc *intern ATTRIBUTE_UNUSED)
{
}
relocatable output against an external symbol. */
static bfd_reloc_status_type
-mips_generic_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data ATTRIBUTE_UNUSED;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
+mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
static struct mips_hi *mips_refhi_list;
static bfd_reloc_status_type
-mips_refhi_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
+mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
bfd_reloc_status_type ret;
bfd_vma relocation;
relocation described above. */
static bfd_reloc_status_type
-mips_reflo_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;
+mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
if (mips_refhi_list != NULL)
{
the offset from the gp register. */
static bfd_reloc_status_type
-mips_gprel_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;
+mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
{
bfd_boolean relocatable;
bfd_vma gp;
/* Get the howto structure for a generic reloc type. */
static reloc_howto_type *
-mips_bfd_reloc_type_lookup (abfd, code)
- bfd *abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
int mips_type;
instructions. */
static void
-mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents,
- relocation)
- struct internal_reloc *refhi;
- struct internal_reloc *reflo;
- bfd *input_bfd;
- asection *input_section;
- bfd_byte *contents;
- bfd_vma relocation;
+mips_relocate_hi (struct internal_reloc *refhi,
+ struct internal_reloc *reflo,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma relocation)
{
unsigned long insn;
unsigned long val;
/* Relocate a section while linking a MIPS ECOFF file. */
static bfd_boolean
-mips_relocate_section (output_bfd, info, input_bfd, input_section,
- contents, external_relocs)
- bfd *output_bfd;
- struct bfd_link_info *info;
- bfd *input_bfd;
- asection *input_section;
- bfd_byte *contents;
- PTR external_relocs;
+mips_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ void * external_relocs)
{
asection **symndx_to_section;
struct ecoff_link_hash_entry **sym_hashes;
bfd_reloc_status_type r;
if (! got_lo)
- mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
+ mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel);
else
{
int_rel = lo_int_rel;
lo_ext_rel < ext_rel_end;
lo_ext_rel++)
{
- mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
+ mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel,
&lo_int_rel);
if (lo_int_rel.r_type != int_rel.r_type)
break;
{
if (gp_undefined)
{
- if (! ((*info->callbacks->reloc_dangerous)
- (info, _("GP relative relocation used when GP not defined"),
- input_bfd, input_section,
- int_rel.r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->reloc_dangerous)
+ (info, _("GP relative relocation used when GP not defined"),
+ input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma);
/* Only give the error once per link. */
gp = 4;
_bfd_set_gp_value (output_bfd, gp);
and the GP value of OUTPUT_BFD (which is in GP). */
addend = ecoff_data (input_bfd)->gp - gp;
}
- else if (! info->relocatable
+ else if (! bfd_link_relocatable (info)
|| h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
}
}
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
/* We are generating relocatable output, and must convert
the existing reloc. */
if (int_rel.r_symndx == -1)
{
/* This symbol is not being written out. */
- if (! ((*info->callbacks->unattached_reloc)
- (info, h->root.root.string, input_bfd,
- input_section,
- int_rel.r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->unattached_reloc)
+ (info, h->root.root.string, input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma);
int_rel.r_symndx = 0;
}
relocation = 0;
- input_section->vma);
/* Save the changed reloc information. */
- mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
+ mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel);
}
else
{
}
else
{
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section,
- int_rel.r_vaddr - input_section->vma, TRUE)))
- return FALSE;
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma, TRUE);
relocation = 0;
}
}
name = NULL;
else
name = bfd_section_name (input_bfd, s);
- if (! ((*info->callbacks->reloc_overflow)
- (info, (h ? &h->root : NULL), name, howto->name,
- (bfd_vma) 0, input_bfd, input_section,
- int_rel.r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma);
}
break;
}
{
/* COFF backend structure. */
{
- (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
- (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
- (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
- (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
- (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
- (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
- (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
+ (void (*) (bfd *,void *,int,int,int,int,void *)) bfd_void, /* aux_in */
+ (void (*) (bfd *,void *,void *)) bfd_void, /* sym_in */
+ (void (*) (bfd *,void *,void *)) bfd_void, /* lineno_in */
+ (unsigned (*) (bfd *,void *,int,int,int,int,void *)) bfd_void,/*aux_out*/
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* sym_out */
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* lineno_out */
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* reloc_out */
mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
mips_ecoff_swap_scnhdr_out,
- FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE, FALSE, 4, FALSE, 2,
+ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
+ ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768,
mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
mips_ecoff_swap_scnhdr_in, NULL,
mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
/* GC of sections is not done. */
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
+/* Input section flags is not implemented. */
+#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+
/* Merging of sections is not done. */
#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
#define _bfd_ecoff_section_already_linked \
- _bfd_generic_section_already_linked
+ _bfd_coff_section_already_linked
+#define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
-extern const bfd_target ecoff_big_vec;
+extern const bfd_target mips_ecoff_be_vec;
-const bfd_target ecoff_little_vec =
+const bfd_target mips_ecoff_le_vec =
{
"ecoff-littlemips", /* name */
bfd_target_ecoff_flavour,
0, /* leading underscore */
' ', /* ar_pad_char */
15, /* ar_max_namelen */
+ 0, /* match priority. */
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_JUMP_TABLE_LINK (_bfd_ecoff),
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
- & ecoff_big_vec,
+ & mips_ecoff_be_vec,
- (PTR) &mips_ecoff_backend_data
+ & mips_ecoff_backend_data
};
-const bfd_target ecoff_big_vec =
+const bfd_target mips_ecoff_be_vec =
{
"ecoff-bigmips", /* name */
bfd_target_ecoff_flavour,
0, /* leading underscore */
' ', /* ar_pad_char */
15, /* ar_max_namelen */
+ 0, /* match priority. */
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
BFD_JUMP_TABLE_LINK (_bfd_ecoff),
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
- & ecoff_little_vec,
+ & mips_ecoff_le_vec,
- (PTR) &mips_ecoff_backend_data
+ & mips_ecoff_backend_data
};
-const bfd_target ecoff_biglittle_vec =
+const bfd_target mips_ecoff_bele_vec =
{
"ecoff-biglittlemips", /* name */
bfd_target_ecoff_flavour,
0, /* leading underscore */
' ', /* ar_pad_char */
15, /* ar_max_namelen */
+ 0, /* match priority. */
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 */
NULL,
- (PTR) &mips_ecoff_backend_data
+ & mips_ecoff_backend_data
};