/* BFD back-end for ALPHA Extended-Coff files.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
Ian Lance Taylor <ian@cygnus.com>.
-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, Inc., 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, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "coff/internal.h"
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 relocateable, asymbol **symbols));
+ 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 *));
bfd_size_type size;
size = sec->line_filepos * 8;
- BFD_ASSERT (size == bfd_section_size (abfd, sec)
- || size + 8 == bfd_section_size (abfd, sec));
+ BFD_ASSERT (size == sec->size
+ || size + 8 == sec->size);
if (! bfd_set_section_size (abfd, sec, size))
return NULL;
}
{
struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
- if (ALPHA_ECOFF_BADMAG (*internal_f))
- return FALSE;
+ if (! ALPHA_ECOFF_BADMAG (*internal_f))
+ return TRUE;
- return TRUE;
+ if (ALPHA_ECOFF_COMPRESSEDMAG (*internal_f))
+ (*_bfd_error_handler)
+ (_("%B: Cannot handle compressed Alpha binaries.\n"
+ " Use compiler flags, or objZ, to generate uncompressed binaries."),
+ abfd);
+
+ return FALSE;
}
/* This is a hook called by coff_real_object_p to create any backend
size = intern->r_size;
}
+ /* XXX FIXME: The maximum symndx value used to be 14 but this
+ fails with object files produced by DEC's C++ compiler.
+ Where does the value 14 (or 15) come from anyway ? */
BFD_ASSERT (intern->r_extern
- || (intern->r_symndx >= 0 && intern->r_symndx <= 14));
+ || (intern->r_symndx >= 0 && intern->r_symndx <= 15));
H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr);
H_PUT_32 (abfd, symndx, ext->r_symndx);
arelent *rptr;
{
if (intern->r_type > ALPHA_R_GPVALUE)
- abort ();
+ {
+ (*_bfd_error_handler)
+ (_("%B: unknown/unsupported relocation type %d"),
+ abfd, intern->r_type);
+ bfd_set_error (bfd_error_bad_value);
+ rptr->addend = 0;
+ rptr->howto = NULL;
+ return;
+ }
switch (intern->r_type)
{
case ALPHA_R_OP_STORE:
/* The STORE reloc needs the size and offset fields. We store
them in the addend. */
- BFD_ASSERT (intern->r_offset <= 256 && intern->r_size <= 256);
+ BFD_ASSERT (intern->r_offset <= 256);
rptr->addend = (intern->r_offset << 8) + intern->r_size;
break;
static bfd_byte *
alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
- data, relocateable, symbols)
+ data, relocatable, symbols)
bfd *abfd;
struct bfd_link_info *link_info;
struct bfd_link_order *link_order;
bfd_byte *data;
- bfd_boolean relocateable;
+ bfd_boolean relocatable;
asymbol **symbols;
{
bfd *input_bfd = link_order->u.indirect.section->owner;
long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
arelent **reloc_vector = NULL;
long reloc_count;
- bfd *output_bfd = relocateable ? abfd : (bfd *) NULL;
+ bfd *output_bfd = relocatable ? abfd : (bfd *) NULL;
bfd_vma gp;
+ bfd_size_type sz;
bfd_boolean gp_undefined;
bfd_vma stack[RELOC_STACKSIZE];
int tos = 0;
if (reloc_vector == NULL && reloc_size != 0)
goto error_return;
- if (! bfd_get_section_contents (input_bfd, input_section, data,
- (file_ptr) 0, input_section->_raw_size))
+ sz = input_section->rawsize ? input_section->rawsize : input_section->size;
+ if (! bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
goto error_return;
- /* The section size is not going to change. */
- input_section->_cooked_size = input_section->_raw_size;
- input_section->reloc_done = TRUE;
-
reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
reloc_vector, symbols);
if (reloc_count < 0)
gp = _bfd_get_gp_value (abfd);
if (gp == 0)
{
- if (relocateable)
+ if (relocatable)
{
asection *sec;
bfd_vma lo;
case ALPHA_R_SREL16:
case ALPHA_R_SREL32:
case ALPHA_R_SREL64:
- if (relocateable
+ if (relocatable
&& ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
{
rel->address += input_section->output_offset;
asymbol *symbol;
bfd_vma relocation;
- if (relocateable)
+ if (relocatable)
{
rel->address += input_section->output_offset;
break;
bfd_vma val;
int offset, size;
- if (relocateable)
+ if (relocatable)
{
rel->address += input_section->output_offset;
break;
asymbol *symbol;
bfd_vma relocation;
- if (relocateable)
+ if (relocatable)
{
rel->address += input_section->output_offset;
break;
asymbol *symbol;
bfd_vma relocation;
- if (relocateable)
+ if (relocatable)
{
rel->address += input_section->output_offset;
break;
abort ();
}
- if (relocateable)
+ if (relocatable)
{
asection *os = input_section->output_section;
break;
case bfd_reloc_overflow:
if (! ((*link_info->callbacks->reloc_overflow)
- (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
+ (link_info, NULL,
+ bfd_asymbol_name (*rel->sym_ptr_ptr),
rel->howto->name, rel->addend, input_bfd,
input_section, rel->address)))
goto error_return;
case BFD_RELOC_64_PCREL:
alpha_type = ALPHA_R_SREL64;
break;
-#if 0
- case ???:
- alpha_type = ALPHA_R_OP_PUSH;
- break;
- case ???:
- alpha_type = ALPHA_R_OP_STORE;
- break;
- case ???:
- alpha_type = ALPHA_R_OP_PSUB;
- break;
- case ???:
- alpha_type = ALPHA_R_OP_PRSHIFT;
- break;
- case ???:
- alpha_type = ALPHA_R_GPVALUE;
- break;
-#endif
default:
return (reloc_howto_type *) NULL;
}
return &alpha_howto_table[alpha_type];
}
+
+static reloc_howto_type *
+alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
+ i++)
+ if (alpha_howto_table[i].name != NULL
+ && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
+ return &alpha_howto_table[i];
+
+ return NULL;
+}
\f
/* A helper routine for alpha_relocate_section which converts an
- external reloc when generating relocateable output. Returns the
+ external reloc when generating relocatable output. Returns the
relocation amount. */
static bfd_vma
unsigned long r_symndx;
bfd_vma relocation;
- BFD_ASSERT (info->relocateable);
+ BFD_ASSERT (info->relocatable);
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
lita_sec = symndx_to_section[RELOC_SECTION_LITA];
gp = _bfd_get_gp_value (output_bfd);
- if (! info->relocateable && lita_sec != NULL)
+ if (! info->relocatable && lita_sec != NULL)
{
struct ecoff_section_tdata *lita_sec_data;
amt = sizeof (struct ecoff_section_tdata);
lita_sec_data = ((struct ecoff_section_tdata *)
bfd_zalloc (input_bfd, amt));
- ecoff_section_data (input_bfd, lita_sec) = lita_sec_data;
+ lita_sec->used_by_bfd = lita_sec_data;
}
if (lita_sec_data->gp != 0)
bfd_size_type lita_size;
lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
- lita_size = lita_sec->_cooked_size;
- if (lita_size == 0)
- lita_size = lita_sec->_raw_size;
+ lita_size = lita_sec->size;
if (gp == 0
|| lita_vma < gp - 0x8000
switch (r_type)
{
+ case ALPHA_R_GPRELHIGH:
+ (*_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)
+ (_("%B: unsupported relocation: ALPHA_R_GPRELLOW"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ continue;
+
default:
- abort ();
+ (*_bfd_error_handler)
+ (_("%B: unknown relocation type %d"),
+ input_bfd, (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ continue;
case ALPHA_R_IGNORE:
/* This reloc appears after a GPDISP reloc. On earlier
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->relocateable)
+ if (info->relocatable)
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->relocateable)
+ if (! info->relocatable)
{
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
addend += r_vaddr;
- if (info->relocateable)
+ if (info->relocatable)
{
/* Adjust r_vaddr by the addend. */
H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr);
case ALPHA_R_OP_STORE:
/* Store a value from the reloc stack into a bitfield. If
- we are generating relocateable output, all we do is
+ we are generating relocatable output, all we do is
adjust the address of the reloc. */
- if (! info->relocateable)
+ if (! info->relocatable)
{
bfd_vma mask;
bfd_vma val;
abort ();
}
- if (info->relocateable)
+ if (info->relocatable)
{
- /* We are generating relocateable output, and must
+ /* We are generating relocatable output, and must
convert the existing reloc. */
if (r_extern)
{
name = bfd_section_name (input_bfd,
symndx_to_section[r_symndx]);
if (! ((*info->callbacks->reloc_overflow)
- (info, name, alpha_howto_table[r_type].name,
+ (info, NULL, name,
+ alpha_howto_table[r_type].name,
(bfd_vma) 0, input_bfd, input_section,
r_vaddr - input_section->vma)))
return FALSE;
}
}
- if (info->relocateable && adjust_addrp)
+ if (info->relocatable && adjust_addrp)
{
/* Change the address of the relocation. */
H_PUT_64 (input_bfd,
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) 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, FALSE, 4, FALSE, 2,
+ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE,
+ ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2,
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,
alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL
+ NULL, NULL, NULL, NULL
},
/* Supported architecture. */
bfd_arch_alpha,
/* Looking up a reloc type is Alpha specific. */
#define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
+#define _bfd_ecoff_bfd_reloc_name_lookup \
+ alpha_bfd_reloc_name_lookup
/* So is getting relocated section contents. */
#define _bfd_ecoff_bfd_get_relocated_section_contents \
#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
#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
const bfd_target ecoffalpha_little_vec =
{
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
{_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
- _bfd_ecoff_archive_p, _bfd_dummy_target},
+ bfd_generic_archive_p, _bfd_dummy_target},
{bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
_bfd_generic_mkarchive, bfd_false},
{bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */