/* BFD back-end for ALPHA Extended-Coff files.
- Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
Ian Lance Taylor <ian@cygnus.com>.
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, boolean relocateable, asymbol **symbols));
case ALPHA_R_SREL16:
case ALPHA_R_SREL32:
case ALPHA_R_SREL64:
- /* The PC relative relocs do not seem to use the section VMA as
- a negative addend. */
- rptr->addend = 0;
+ /* This relocs appear to be fully resolved when they are against
+ internal symbols. Against external symbols, BRADDR at least
+ appears to be resolved against the next instruction. */
+ if (! intern->r_extern)
+ rptr->addend = 0;
+ else
+ rptr->addend = - (intern->r_vaddr + 4);
break;
case ALPHA_R_GPREL32:
bfd *output_bfd = relocateable ? abfd : (bfd *) NULL;
bfd_vma gp;
boolean gp_undefined;
- bfd_vma gp;
bfd_vma stack[RELOC_STACKSIZE];
int tos = 0;
if (r == bfd_reloc_ok && gp_undefined)
{
r = bfd_reloc_dangerous;
- err = (char *) "GP relative relocation used when GP not defined";
+ err = (char *) _("GP relative relocation used when GP not defined");
}
break;
{
r = bfd_reloc_dangerous;
err =
- (char *) "GP relative relocation used when GP not defined";
+ (char *) _("GP relative relocation used when GP not defined");
}
}
break;
does not cause anything to happen, itself. */
rel->address += input_section->output_offset;
break;
-
+
case ALPHA_R_GPDISP:
/* This marks the ldah of an ldah/lda pair which loads the
gp register with the difference of the gp value and the
rel->address += input_section->output_offset;
}
break;
-
+
case ALPHA_R_OP_PUSH:
/* Push a value on the reloc evaluation stack. */
{
stack[tos - 1] >>= relocation;
}
break;
-
+
case ALPHA_R_GPVALUE:
/* I really don't know if this does the right thing. */
gp = rel->addend;
os->reloc_count++;
}
- if (r != bfd_reloc_ok)
+ if (r != bfd_reloc_ok)
{
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)))
+ input_bfd, input_section, rel->address, true)))
goto error_return;
break;
- case bfd_reloc_dangerous:
+ case bfd_reloc_dangerous:
if (! ((*link_info->callbacks->reloc_dangerous)
(link_info, err, input_bfd, input_section,
rel->address)))
r_symndx = RELOC_SECTION_XDATA;
break;
}
-
+
if (r_symndx == -1)
abort ();
pointer. To support large programs, we need to allow multiple
global pointers. This works as long as each input .lita section
is <64KB big. This implies that when producing relocatable
- output, the .lita section is limited to 64KB. . */
+ output, the .lita section is limited to 64KB. . */
lita_sec = symndx_to_section[RELOC_SECTION_LITA];
gp = _bfd_get_gp_value (output_bfd);
/* Either gp hasn't been set at all or the current gp
cannot address this .lita section. In both cases we
reset the gp to point into the "middle" of the
- current input .lita section. For now, we issue a
- warning when redefining the gp value (probably should
- be made optional). */
+ current input .lita section. */
if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
{
- (*_bfd_error_handler)
- ("%s: warning: using multiple gp values",
- bfd_get_filename (output_bfd));
+ (*info->callbacks->warning) (info,
+ _("using multiple gp values"),
+ (char *) NULL, output_bfd,
+ (asection *) NULL, (bfd_vma) 0);
ecoff_data (output_bfd)->issued_multiple_gp_warning = true;
}
if (lita_vma < gp - 0x8000)
case ALPHA_R_REFLONG:
case ALPHA_R_REFQUAD:
- case ALPHA_R_BRADDR:
case ALPHA_R_HINT:
+ relocatep = true;
+ break;
+
+ case ALPHA_R_BRADDR:
case ALPHA_R_SREL16:
case ALPHA_R_SREL32:
case ALPHA_R_SREL64:
+ if (r_extern)
+ addend += - (r_vaddr + 4);
relocatep = true;
break;
/* See ALPHA_R_LITERAL above for the uses of this reloc. It
does not cause anything to happen, itself. */
break;
-
+
case ALPHA_R_GPDISP:
/* This marks the ldah of an ldah/lda pair which loads the
gp register with the difference of the gp value and the
gp_usedp = true;
}
break;
-
+
case ALPHA_R_OP_PUSH:
case ALPHA_R_OP_PSUB:
case ALPHA_R_OP_PRSHIFT:
relocated. */
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
- input_section, (bfd_vma) 0)))
+ input_section, (bfd_vma) 0, true)))
return false;
addend = 0;
}
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
input_section,
- r_vaddr - input_section->vma)))
+ r_vaddr - input_section->vma, true)))
return false;
relocation = 0;
}
if (gp_usedp && gp_undefined)
{
if (! ((*info->callbacks->reloc_dangerous)
- (info, "GP relative relocation when GP not defined",
+ (info, _("GP relative relocation when GP not defined"),
input_bfd, input_section, r_vaddr - input_section->vma)))
return false;
/* Only give the error once per link. */
/* Do final adjustments to the filehdr and the aouthdr. This routine
sets the dynamic bits in the file header. */
-/*ARGSUSED*/
static boolean
alpha_adjust_headers (abfd, fhdr, ahdr)
bfd *abfd;
left = size;
- /* I don't know what the next eight bytes are for. */
+ /* I don't know what the next eight bytes are for. */
if (bfd_read (ab, 1, 8, nbfd) != 8)
goto error_return;
error_return:
if (nbfd != NULL)
bfd_close (nbfd);
- return NULL;
+ return NULL;
}
/* Open the next archived file. */
/* 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. */
+ BSD-4.4-style element with a long odd size. */
filestart = last_file->origin + size;
filestart += filestart % 2;
}
(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, true,
+ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true, false, 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, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL
},
/* Supported architecture. */
bfd_arch_alpha,
/* Relaxing sections is generic. */
#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
+#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
const bfd_target ecoffalpha_little_vec =
{
BFD_JUMP_TABLE_LINK (_bfd_ecoff),
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+ NULL,
+
(PTR) &alpha_ecoff_backend_data
};