/* BFD back-end for ALPHA Extended-Coff files.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
Ian Lance Taylor <ian@cygnus.com>.
\f
/* Prototypes for static functions. */
-static const bfd_target *alpha_ecoff_object_p
- PARAMS ((bfd *));
-static bfd_boolean alpha_ecoff_bad_format_hook
- PARAMS ((bfd *abfd, PTR filehdr));
-static PTR alpha_ecoff_mkobject_hook
- PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
-static void alpha_ecoff_swap_reloc_in
- PARAMS ((bfd *, PTR, struct internal_reloc *));
-static void alpha_ecoff_swap_reloc_out
- PARAMS ((bfd *, const struct internal_reloc *, PTR));
-static void alpha_adjust_reloc_in
- PARAMS ((bfd *, const struct internal_reloc *, arelent *));
-static void alpha_adjust_reloc_out
- PARAMS ((bfd *, const arelent *, struct internal_reloc *));
-static reloc_howto_type *alpha_bfd_reloc_type_lookup
- PARAMS ((bfd *, bfd_reloc_code_real_type));
-static bfd_byte *alpha_ecoff_get_relocated_section_contents
- PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *,
- bfd_byte *data, bfd_boolean relocatable, asymbol **symbols));
-static bfd_vma alpha_convert_external_reloc
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *,
- struct ecoff_link_hash_entry *));
-static bfd_boolean alpha_relocate_section
- PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
-static bfd_boolean alpha_adjust_headers
- PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
-static PTR alpha_ecoff_read_ar_hdr
- PARAMS ((bfd *));
-static bfd *alpha_ecoff_get_elt_at_filepos
- PARAMS ((bfd *, file_ptr));
-static bfd *alpha_ecoff_openr_next_archived_file
- PARAMS ((bfd *, bfd *));
-static bfd *alpha_ecoff_get_elt_at_index
- PARAMS ((bfd *, symindex));
+
\f
/* ECOFF has COFF sections, but the debugging information is stored in
a completely different format. ECOFF targets use some of the
\f
/* How to process the various reloc types. */
-static bfd_reloc_status_type reloc_nil
- PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-
static bfd_reloc_status_type
-reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc ATTRIBUTE_UNUSED;
- asymbol *sym ATTRIBUTE_UNUSED;
- PTR data ATTRIBUTE_UNUSED;
- asection *sec ATTRIBUTE_UNUSED;
- bfd *output_bfd ATTRIBUTE_UNUSED;
- char **error_message ATTRIBUTE_UNUSED;
+reloc_nil (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc ATTRIBUTE_UNUSED,
+ asymbol *sym ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
{
return bfd_reloc_ok;
}
/* Recognize an Alpha ECOFF file. */
static const bfd_target *
-alpha_ecoff_object_p (abfd)
- bfd *abfd;
+alpha_ecoff_object_p (bfd *abfd)
{
static const bfd_target *ret;
/* See whether the magic number matches. */
static bfd_boolean
-alpha_ecoff_bad_format_hook (abfd, filehdr)
- bfd *abfd ATTRIBUTE_UNUSED;
- PTR filehdr;
+alpha_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ void * filehdr)
{
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
return TRUE;
if (ALPHA_ECOFF_COMPRESSEDMAG (*internal_f))
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: Cannot handle compressed Alpha binaries.\n"
" Use compiler flags, or objZ, to generate uncompressed binaries."),
abfd);
/* This is a hook called by coff_real_object_p to create any backend
specific information. */
-static PTR
-alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
- bfd *abfd;
- PTR filehdr;
- PTR aouthdr;
+static void *
+alpha_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr)
{
- PTR ecoff;
+ void * ecoff;
ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
/* Swap a reloc in. */
static void
-alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
- bfd *abfd;
- PTR ext_ptr;
- struct internal_reloc *intern;
+alpha_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
-alpha_ecoff_swap_reloc_out (abfd, intern, dst)
- bfd *abfd;
- const struct internal_reloc *intern;
- PTR dst;
+alpha_ecoff_swap_reloc_out (bfd *abfd,
+ const struct internal_reloc *intern,
+ void * dst)
{
RELOC *ext = (RELOC *) dst;
long symndx;
this backend routine. It must fill in the howto field. */
static void
-alpha_adjust_reloc_in (abfd, intern, rptr)
- bfd *abfd;
- const struct internal_reloc *intern;
- arelent *rptr;
+alpha_adjust_reloc_in (bfd *abfd,
+ const struct internal_reloc *intern,
+ arelent *rptr)
{
if (intern->r_type > ALPHA_R_GPVALUE)
{
- (*_bfd_error_handler)
+ /* xgettext:c-format */
+ _bfd_error_handler
(_("%B: unknown/unsupported relocation type %d"),
abfd, intern->r_type);
bfd_set_error (bfd_error_bad_value);
not need to undo. */
static void
-alpha_adjust_reloc_out (abfd, rel, intern)
- bfd *abfd ATTRIBUTE_UNUSED;
- const arelent *rel;
- struct internal_reloc *intern;
+alpha_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED,
+ const arelent *rel,
+ struct internal_reloc *intern)
{
switch (intern->r_type)
{
assembler is going to handle this. */
static bfd_byte *
-alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
- data, relocatable, symbols)
- bfd *abfd;
- struct bfd_link_info *link_info;
- struct bfd_link_order *link_order;
- bfd_byte *data;
- bfd_boolean relocatable;
- asymbol **symbols;
+alpha_ecoff_get_relocated_section_contents (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ asymbol **symbols)
{
bfd *input_bfd = link_order->u.indirect.section->owner;
asection *input_section = link_order->u.indirect.section;
switch (r)
{
case bfd_reloc_undefined:
- if (! ((*link_info->callbacks->undefined_symbol)
- (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
- input_bfd, input_section, rel->address, TRUE)))
- goto error_return;
+ (*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
+ input_bfd, input_section, rel->address, TRUE);
break;
case bfd_reloc_dangerous:
- if (! ((*link_info->callbacks->reloc_dangerous)
- (link_info, err, input_bfd, input_section,
- rel->address)))
- goto error_return;
+ (*link_info->callbacks->reloc_dangerous)
+ (link_info, err, input_bfd, input_section, rel->address);
break;
case bfd_reloc_overflow:
- if (! ((*link_info->callbacks->reloc_overflow)
- (link_info, NULL,
- bfd_asymbol_name (*rel->sym_ptr_ptr),
- rel->howto->name, rel->addend, input_bfd,
- input_section, rel->address)))
- goto error_return;
+ (*link_info->callbacks->reloc_overflow)
+ (link_info, NULL, bfd_asymbol_name (*rel->sym_ptr_ptr),
+ rel->howto->name, rel->addend, input_bfd,
+ input_section, rel->address);
break;
case bfd_reloc_outofrange:
default:
/* Get the howto structure for a generic reloc type. */
static reloc_howto_type *
-alpha_bfd_reloc_type_lookup (abfd, code)
- bfd *abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
+alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
{
int alpha_type;
relocation amount. */
static bfd_vma
-alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h)
- bfd *output_bfd ATTRIBUTE_UNUSED;
- struct bfd_link_info *info;
- bfd *input_bfd;
- struct external_reloc *ext_rel;
- struct ecoff_link_hash_entry *h;
+alpha_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ struct external_reloc *ext_rel,
+ struct ecoff_link_hash_entry *h)
{
unsigned long r_symndx;
bfd_vma relocation;
- BFD_ASSERT (info->relocatable);
+ BFD_ASSERT (bfd_link_relocatable (info));
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
could be combined somehow. */
static bfd_boolean
-alpha_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;
+alpha_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, *lita_sec;
struct ecoff_link_hash_entry **sym_hashes;
lita_sec = symndx_to_section[RELOC_SECTION_LITA];
gp = _bfd_get_gp_value (output_bfd);
- if (! info->relocatable && lita_sec != NULL)
+ if (! bfd_link_relocatable (info) && lita_sec != NULL)
{
struct ecoff_section_tdata *lita_sec_data;
switch (r_type)
{
case ALPHA_R_GPRELHIGH:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: unsupported relocation: ALPHA_R_GPRELHIGH"),
input_bfd);
bfd_set_error (bfd_error_bad_value);
continue;
-
+
case ALPHA_R_GPRELLOW:
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("%B: unsupported relocation: ALPHA_R_GPRELLOW"),
input_bfd);
bfd_set_error (bfd_error_bad_value);
continue;
-
+
default:
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unknown relocation type %d"),
input_bfd, (int) r_type);
bfd_set_error (bfd_error_bad_value);
not otherwise used for anything. For some reason, the
address of the relocation does not appear to include the
section VMA, unlike the other relocation types. */
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr,
ext_rel->r_vaddr);
adjust_addrp = FALSE;
if (h == (struct ecoff_link_hash_entry *) NULL)
abort ();
- if (! info->relocatable)
+ if (! bfd_link_relocatable (info))
{
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
do not have a meaningful number for the
location within the section that is being
relocated. */
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, (bfd_vma) 0, TRUE)))
- return FALSE;
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, (bfd_vma) 0, TRUE);
addend = 0;
}
}
/* This symbol is not being written out. Pass
the address as 0, as with undefined_symbol,
above. */
- if (! ((*info->callbacks->unattached_reloc)
- (info, h->root.root.string, input_bfd,
- input_section, (bfd_vma) 0)))
- return FALSE;
+ (*info->callbacks->unattached_reloc)
+ (info, h->root.root.string,
+ input_bfd, input_section, (bfd_vma) 0);
}
addend = alpha_convert_external_reloc (output_bfd, info,
addend += r_vaddr;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
/* Adjust r_vaddr by the addend. */
H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr);
/* Store a value from the reloc stack into a bitfield. If
we are generating relocatable output, all we do is
adjust the address of the reloc. */
- if (! info->relocatable)
+ if (! bfd_link_relocatable (info))
{
bfd_vma mask;
bfd_vma val;
abort ();
}
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
/* We are generating relocatable output, and must
convert the existing reloc. */
&& h->indx == -1)
{
/* This symbol is not being written out. */
- if (! ((*info->callbacks->unattached_reloc)
- (info, h->root.root.string, input_bfd,
- input_section, r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->unattached_reloc)
+ (info, h->root.root.string, input_bfd,
+ input_section, r_vaddr - input_section->vma);
}
relocation = alpha_convert_external_reloc (output_bfd,
}
else
{
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section,
- r_vaddr - input_section->vma, TRUE)))
- return FALSE;
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ r_vaddr - input_section->vma, TRUE);
relocation = 0;
}
}
else
name = bfd_section_name (input_bfd,
symndx_to_section[r_symndx]);
- if (! ((*info->callbacks->reloc_overflow)
- (info, NULL, name,
- alpha_howto_table[r_type].name,
- (bfd_vma) 0, input_bfd, input_section,
- r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, NULL, name, alpha_howto_table[r_type].name,
+ (bfd_vma) 0, input_bfd, input_section,
+ r_vaddr - input_section->vma);
}
break;
}
}
}
- if (info->relocatable && adjust_addrp)
+ if (bfd_link_relocatable (info) && adjust_addrp)
{
/* Change the address of the relocation. */
H_PUT_64 (input_bfd,
if (gp_usedp && gp_undefined)
{
- if (! ((*info->callbacks->reloc_dangerous)
- (info, _("GP relative relocation used when GP not defined"),
- input_bfd, input_section, r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->reloc_dangerous)
+ (info, _("GP relative relocation used when GP not defined"),
+ input_bfd, input_section, r_vaddr - input_section->vma);
/* Only give the error once per link. */
gp = 4;
_bfd_set_gp_value (output_bfd, gp);
sets the dynamic bits in the file header. */
static bfd_boolean
-alpha_adjust_headers (abfd, fhdr, ahdr)
- bfd *abfd;
- struct internal_filehdr *fhdr;
- struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED;
+alpha_adjust_headers (bfd *abfd,
+ struct internal_filehdr *fhdr,
+ struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED)
{
if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
fhdr->f_flags |= F_ALPHA_CALL_SHARED;
/* Read an archive header. This is like the standard routine, but it
also accepts ARFZMAG. */
-static PTR
-alpha_ecoff_read_ar_hdr (abfd)
- bfd *abfd;
+static void *
+alpha_ecoff_read_ar_hdr (bfd *abfd)
{
struct areltdata *ret;
struct ar_hdr *h;
ret->parsed_size = H_GET_64 (abfd, ab);
}
- return (PTR) ret;
+ return ret;
}
/* Get an archive element at a specified file position. This is where
we uncompress the archive element if necessary. */
static bfd *
-alpha_ecoff_get_elt_at_filepos (archive, filepos)
- bfd *archive;
- file_ptr filepos;
+alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos)
{
bfd *nbfd = NULL;
struct areltdata *tdata;
nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
nbfd->flags |= BFD_IN_MEMORY;
- nbfd->iostream = (PTR) bim;
+ nbfd->iostream = bim;
+ nbfd->iovec = &_bfd_memory_iovec;
+ nbfd->origin = 0;
BFD_ASSERT (! nbfd->cacheable);
return nbfd;
/* Open the next archived file. */
static bfd *
-alpha_ecoff_openr_next_archived_file (archive, last_file)
- bfd *archive;
- bfd *last_file;
+alpha_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file)
{
- file_ptr filestart;
+ ufile_ptr filestart;
if (last_file == NULL)
filestart = bfd_ardata (archive)->first_file_filepos;
/* Pad to an even boundary...
Note that last_file->origin can be odd in the case of
BSD-4.4-style element with a long odd size. */
- filestart = last_file->origin + size;
+ filestart = last_file->proxy_origin + size;
filestart += filestart % 2;
+ if (filestart < last_file->proxy_origin)
+ {
+ /* Prevent looping. See PR19256. */
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
}
return alpha_ecoff_get_elt_at_filepos (archive, filestart);
{
/* 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 */
alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
alpha_ecoff_swap_scnhdr_out,
- FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
- ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2,
+ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
+ ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768,
alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
alpha_ecoff_swap_scnhdr_in, NULL,
alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
#define _bfd_ecoff_get_section_contents_in_window \
_bfd_generic_get_section_contents_in_window
+/* Input section flag lookup is generic. */
+#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+
/* Relaxing sections is generic. */
#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_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
+#define _bfd_ecoff_bfd_link_check_relocs _bfd_generic_link_check_relocs
+
+/* Installing internal relocations in a section is also generic. */
+#define _bfd_ecoff_set_reloc _bfd_generic_set_reloc
-const bfd_target ecoffalpha_little_vec =
+const bfd_target alpha_ecoff_le_vec =
{
"ecoff-littlealpha", /* 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) &alpha_ecoff_backend_data
+ & alpha_ecoff_backend_data
};