Mon Jan 24 12:38:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+ * bfd/aoutx.h (aout_link_input_section_std,
+ aout_link_input_section_ext): Pass additional arguments to
+ reloc_overflow callback.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents,
+ alpha_relocat_section): Likewise.
+ * coff-h8300.c (h8300_reloc16_extra_cases): Likewise.
+ * coff-h8500.c (extra_case): Likewise.
+ * coff-mips.c (mips_relocate_section): Likewise.
+ * coff-z8k.c (extra_case): Likewise.
+ * elf32-hppa.c (hppa_elf_stub_finish): Likewise.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
+
* bout.c (calljx_callback, callj_callback): Use get_value to get
the symbol value and check for undefined symbols.
(get_value): If the symbol is undefined, look it up in the linker
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, input_bfd, input_section, r_addr)))
- return false;
+ {
+ const char *name;
+
+ if (r_extern)
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ else
+ {
+ asection *s;
+
+ s = aout_reloc_index_to_section (input_bfd, r_index);
+ name = bfd_section_name (input_bfd, s);
+ }
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info, name, howto_table_std[howto_idx].name,
+ (bfd_vma) 0, input_bfd, input_section, r_addr)))
+ return false;
+ }
break;
}
}
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, input_bfd, input_section, r_addr)))
- return false;
+ {
+ const char *name;
+
+ if (r_extern)
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ else
+ {
+ asection *s;
+
+ s = aout_reloc_index_to_section (input_bfd, r_index);
+ name = bfd_section_name (input_bfd, s);
+ }
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info, name, howto_table_ext[r_type].name,
+ r_addend, input_bfd, input_section, r_addr)))
+ return false;
+ }
break;
}
}
break;
case bfd_reloc_overflow:
if (! ((*link_info->callbacks->reloc_overflow)
- (link_info, input_bfd, input_section, rel->address)))
+ (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
+ rel->howto->name, rel->addend, input_bfd,
+ input_section, rel->address)))
return NULL;
break;
case bfd_reloc_outofrange:
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*info->callbacks->reloc_overflow)
- (info, input_bfd, input_section,
- r_vaddr - input_section->vma)))
- return false;
+ {
+ const char *name;
+
+ if (r_extern)
+ name = sym_hashes[r_symndx]->root.root.string;
+ else
+ name = bfd_section_name (input_bfd,
+ symndx_to_section[r_symndx]);
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, alpha_howto_table[r_type].name,
+ (bfd_vma) 0, input_bfd, input_section,
+ r_vaddr - input_section->vma)))
+ return false;
+ }
break;
}
}
#include "bfd.h"
#include "sysdep.h"
-#include "libbfd.h"
#include "obstack.h"
+#include "libbfd.h"
+#include "bfdlink.h"
#include "coff/h8300.h"
#include "coff/internal.h"
-#include "seclet.h"
#include "libcoff.h"
-extern bfd_error_vector_type bfd_error_vector;
static reloc_howto_type howto_table[] =
{
static int
-h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
+h8300_reloc16_estimate(input_section, symbols, reloc, shrink, link_info)
asection *input_section;
asymbol **symbols;
arelent *reloc;
unsigned int shrink;
+ struct bfd_link_info *link_info;
{
bfd_vma value;
bfd_vma dot;
/* Thing is a move one byte */
case R_MOVB1:
- value = bfd_coff_reloc16_get_value(reloc,0);
-
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
if (value >= 0xff00)
{
actual data */
case R_JMPL1:
- value = bfd_coff_reloc16_get_value(reloc, 0);
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
dot = input_section->output_section->vma +
input_section->output_offset + address;
case R_JMP1:
- value = bfd_coff_reloc16_get_value(reloc, 0);
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
dot = input_section->output_section->vma +
input_section->output_offset + address;
*/
static void
-h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
+h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
+ dst_ptr)
bfd *abfd;
- struct bfd_seclet *seclet;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
arelent *reloc;
bfd_byte *data;
unsigned int *src_ptr;
{
unsigned int src_address = *src_ptr;
unsigned int dst_address = *dst_ptr;
+ asection *input_section = link_order->u.indirect.section;
switch (reloc->howto->type)
{
the byte before the 24bit hole, so we can treat it as a 32bit pointer */
case R_PCRBYTE:
{
- bfd_vma dot = seclet->offset
+ bfd_vma dot = link_order->offset
+ dst_address
- + seclet->u.indirect.section->output_section->vma;
- int gap = bfd_coff_reloc16_get_value (reloc, seclet) - dot;
+ + link_order->u.indirect.section->output_section->vma;
+ int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ - dot);
if (gap > 127 || gap < -128)
{
- bfd_error_vector.reloc_value_truncated (reloc, seclet);
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
}
bfd_put_8 (abfd, gap, data + dst_address);
case R_RELBYTE:
{
- unsigned int gap = bfd_coff_reloc16_get_value (reloc, seclet);
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
if (gap > 0xff && gap < ~0xff)
{
- bfd_error_vector.reloc_value_truncated (reloc, seclet);
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
}
bfd_put_8 (abfd, gap, data + dst_address);
/* A relword which would like to have been modified but
didn't make it */
case R_RELWORD:
- bfd_put_16 (abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+ bfd_put_16 (abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + dst_address);
dst_address += 2;
src_address += 2;
break;
case R_RELLONG:
- bfd_put_32 (abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+ bfd_put_32 (abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + dst_address);
dst_address += 4;
src_address += 4;
/* the offset must fit ! after all, what was all the relaxing
about ? */
- bfd_put_8 (abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+ bfd_put_8 (abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + dst_address);
/* Note the magic - src goes up by two bytes, but dst by only
/* Speciial relaxed type */
{
- bfd_vma dot = seclet->offset
+ bfd_vma dot = link_order->offset
+ dst_address
- + seclet->u.indirect.section->output_section->vma;
+ + link_order->u.indirect.section->output_section->vma;
- int gap = bfd_coff_reloc16_get_value (reloc, seclet) - dot - 1;
+ int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ - dot - 1);
if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
abort ();
/* Speciial relaxed type */
{
- bfd_vma dot = seclet->offset
+ bfd_vma dot = link_order->offset
+ dst_address
- + seclet->u.indirect.section->output_section->vma;
+ + link_order->u.indirect.section->output_section->vma;
- int gap = bfd_coff_reloc16_get_value (reloc, seclet) - dot - 2;
+ int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ - dot - 2);
if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00))
abort ();
case R_JMPL1:
{
- int v = bfd_coff_reloc16_get_value (reloc, seclet);
+ int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
int o = bfd_get_32 (abfd, data + src_address);
v = (v & 0x00ffffff) | (o & 0xff000000);
bfd_put_32 (abfd, v, data + dst_address);
the byte before the 24bit hole, so we can treat it as a 32bit pointer */
case R_MOVLB1:
{
- int v = bfd_coff_reloc16_get_value (reloc, seclet);
+ int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
int o = bfd_get_32 (abfd, data + dst_address);
v = (v & 0x00ffffff) | (o & 0xff000000);
bfd_put_32 (abfd, v, data + dst_address);
#undef coff_bfd_get_relocated_section_contents
#undef coff_bfd_relax_section
-#define coff_bfd_get_relocated_section_contents bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
'_', /* leading char */
'/', /* ar_pad_char */
#include "bfd.h"
#include "sysdep.h"
-#include "libbfd.h"
#include "obstack.h"
+#include "libbfd.h"
+#include "bfdlink.h"
#include "coff/h8500.h"
#include "coff/internal.h"
#include "libcoff.h"
-#include "seclet.h"
-
-extern bfd_error_vector_type bfd_error_vector;
static reloc_howto_type r_imm8 =
-HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0, true,
- true, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false);
+HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0,
+ complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false);
static reloc_howto_type r_imm16 =
-HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0, true,
- true, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false);
+HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0,
+ complain_overflow_bitfield, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false);
static reloc_howto_type r_imm24 =
-HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0, true,
- true, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false);
+HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0,
+ complain_overflow_bitfield, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false);
static reloc_howto_type r_imm32 =
-HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0, true,
- true, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false);
+HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0,
+ complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false);
static reloc_howto_type r_high8 =
-HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0, true,
- true, 0, "r_high8", true, 0x000000ff, 0x000000ff, false);
+HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0,
+ complain_overflow_bitfield, 0, "r_high8", true, 0x000000ff, 0x000000ff, false);
static reloc_howto_type r_low16 =
-HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0, true,
- true, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false);
+HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0,
+ complain_overflow_bitfield, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false);
static reloc_howto_type r_pcrel8 =
-HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, true, true, 0, "r_pcrel8", true, 0, 0, true);
+HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, complain_overflow_signed, 0, "r_pcrel8", true, 0, 0, true);
static reloc_howto_type r_pcrel16 =
-HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, true, true, 0, "r_pcrel16", true, 0, 0, true);
+HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, complain_overflow_signed, 0, "r_pcrel16", true, 0, 0, true);
static reloc_howto_type r_high16 =
-HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0, true,
- true, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false);
+HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0,
+ complain_overflow_bitfield, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false);
/* Turn a howto into a reloc number */
switch (dst->r_type)
{
default:
- printf ("BAD 0x%x\n", dst->r_type);
+ fprintf (stderr, "BAD 0x%x\n", dst->r_type);
case R_H8500_IMM8:
internal->howto = &r_imm8;
break;
}
static void
-extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
+extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
bfd *in_abfd;
- bfd_seclet_type *seclet;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
arelent *reloc;
bfd_byte *data;
unsigned int *src_ptr;
unsigned int *dst_ptr;
{
bfd_byte *d = data+*dst_ptr;
+ asection *input_section = link_order->u.indirect.section;
switch (reloc->howto->type)
{
case R_H8500_IMM8:
bfd_put_8 (in_abfd,
- bfd_coff_reloc16_get_value (reloc, seclet),
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
d);
(*dst_ptr) += 1;
(*src_ptr) += 1;
case R_H8500_HIGH8:
bfd_put_8 (in_abfd,
- (bfd_coff_reloc16_get_value (reloc, seclet)>>16),
+ (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ >> 16),
d );
(*dst_ptr) += 1;
(*src_ptr) += 1;
case R_H8500_IMM16:
bfd_put_16 (in_abfd,
- bfd_coff_reloc16_get_value (reloc, seclet) ,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
d );
(*dst_ptr) += 2;
(*src_ptr) += 2;
case R_H8500_LOW16:
bfd_put_16 (in_abfd,
- bfd_coff_reloc16_get_value (reloc, seclet) ,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
d);
(*dst_ptr) += 2;
case R_H8500_HIGH16:
bfd_put_16 (in_abfd,
- bfd_coff_reloc16_get_value (reloc, seclet)>>16 ,
+ (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ >>16),
d);
(*dst_ptr) += 2;
case R_H8500_IMM24:
{
- int v = bfd_coff_reloc16_get_value(reloc, seclet);
+ int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
int o = bfd_get_32(in_abfd, data+ *dst_ptr -1);
v = (v & 0x00ffffff) | (o & 0xff00000);
bfd_put_32 (in_abfd, v, data + *dst_ptr -1);
break;
case R_H8500_IMM32:
{
- int v = bfd_coff_reloc16_get_value(reloc, seclet);
+ int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
bfd_put_32 (in_abfd, v, data + *dst_ptr);
(*dst_ptr) +=4;
(*src_ptr)+=4;;
case R_H8500_PCREL8:
{
- bfd_vma dst = bfd_coff_reloc16_get_value (reloc, seclet);
- bfd_vma dot = seclet->offset
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = link_order->offset
+ *dst_ptr
- + seclet->u.indirect.section->output_section->vma;
+ + link_order->u.indirect.section->output_section->vma;
int gap = dst - dot - 1; /* -1 since were in the odd byte of the
word and the pc's been incremented */
if (gap > 128 || gap < -128)
{
- bfd_error_vector.reloc_value_truncated (reloc, seclet);
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
}
bfd_put_8 (in_abfd, gap, data + *dst_ptr);
(*dst_ptr)++;
}
case R_H8500_PCREL16:
{
- bfd_vma dst = bfd_coff_reloc16_get_value (reloc, seclet);
- bfd_vma dot = seclet->offset
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = link_order->offset
+ *dst_ptr
- + seclet->u.indirect.section->output_section->vma;
+ + link_order->u.indirect.section->output_section->vma;
int gap = dst - dot - 1; /* -1 since were in the odd byte of the
word and the pc's been incremented */
if (gap > 32767 || gap < -32768)
{
- bfd_error_vector.reloc_value_truncated (reloc, seclet);
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
}
bfd_put_16 (in_abfd, gap, data + *dst_ptr);
(*dst_ptr)+=2;
#undef coff_bfd_get_relocated_section_contents
#undef coff_bfd_relax_section
-#define coff_bfd_get_relocated_section_contents bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
bfd_target h8500coff_vec =
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
'_', /* leading symbol underscore */
'/', /* ar_pad_char */
15, /* ar_max_namelen */
1, /* minimum section alignment */
- _do_getb64, _do_getb_signed_64, _do_putb64,
- _do_getb32, _do_getb_signed_32, _do_putb32,
- _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
- _do_getb64, _do_getb_signed_64, _do_putb64,
- _do_getb32, _do_getb_signed_32, _do_putb32,
- _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
{_bfd_dummy_target, coff_object_p, /* bfd_check_format */
bfd_generic_archive_p, _bfd_dummy_target},
#include "bfd.h"
#include "sysdep.h"
+#include "bfdlink.h"
#include "libbfd.h"
-#include "seclet.h"
#include "coff/internal.h"
#include "coff/sym.h"
#include "coff/symconst.h"
asymbol *symbol,
PTR data,
asection *section,
- bfd *output_bfd));
+ 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));
+ 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));
+ 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));
+ bfd *output_bfd,
+ char **error));
+static void mips_relocate_refhi PARAMS ((struct internal_reloc *refhi,
+ struct internal_reloc *reflo,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma relocation));
+static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
+ bfd *, asection *,
+ bfd_byte *, PTR));
\f
/* ECOFF has COFF sections, but the debugging information is stored in
a completely different format. ECOFF targets use some of the
are needed for MIPS. */
static void
-mips_adjust_reloc_in (abfd, rel, intern)
+mips_adjust_reloc_out (abfd, rel, intern)
bfd *abfd;
const arelent *rel;
struct internal_reloc *intern;
symbol,
data,
input_section,
- output_bfd)
+ output_bfd,
+ error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
+ char **error_message;
{
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
symbol,
data,
input_section,
- output_bfd)
+ output_bfd,
+ error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
+ char **error_message;
{
bfd_reloc_status_type ret;
bfd_vma relocation;
symbol,
data,
input_section,
- output_bfd)
+ output_bfd,
+ error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
+ char **error_message;
{
if (mips_refhi_addr != (bfd_byte *) NULL)
{
/* Now do the REFLO reloc in the usual way. */
return mips_generic_reloc (abfd, reloc_entry, symbol, data,
- input_section, output_bfd);
+ input_section, output_bfd, error_message);
}
/* Do a GPREL relocation. This is a 16 bit value which must become
static bfd_reloc_status_type
mips_gprel_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd)
+ 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;
{
boolean relocateable;
bfd_vma relocation;
{
/* Only get the error once. */
ecoff_data (output_bfd)->gp = 4;
- /* FIXME: How can we get the program name here? */
- fprintf (stderr,
- "GP relative relocation when _gp not defined\n");
+ *error_message =
+ (char *) "GP relative relocation when _gp not defined";
return bfd_reloc_dangerous;
}
}
/* Make sure it fit in 16 bits. */
if (val >= 0x8000 && val < 0xffff8000)
- return bfd_reloc_outofrange;
+ return bfd_reloc_overflow;
return bfd_reloc_ok;
}
case BFD_RELOC_MIPS_GPREL:
mips_type = MIPS_R_GPREL;
break;
+ case BFD_RELOC_MIPS_LITERAL:
+ mips_type = MIPS_R_LITERAL;
+ break;
default:
return (CONST struct reloc_howto_struct *) NULL;
}
return &mips_howto_table[mips_type];
}
\f
-#ifdef HOST_IRIX4
+/* A helper routine for mips_relocate_section which handles the REFHI
+ relocation. The REFHI relocation must be followed by a REFLO
+ relocation, and the addend used is formed from the addends of both
+ instructions. */
-#include <core.out.h>
-
-struct sgi_core_struct
+static void
+mips_relocate_refhi (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;
{
- int sig;
- char cmd[CORE_NAMESIZE];
-};
-
-#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
-#define core_signal(bfd) (core_hdr(bfd)->sig)
-#define core_command(bfd) (core_hdr(bfd)->cmd)
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+
+ insn = bfd_get_32 (input_bfd,
+ contents + refhi->r_vaddr - input_section->vma);
+ vallo = (bfd_get_32 (input_bfd,
+ contents + reflo->r_vaddr - input_section->vma)
+ & 0xffff);
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += relocation;
+
+ /* The low order 16 bits are always treated as a signed value.
+ Therefore, a negative value in the low order bits requires an
+ adjustment in the high order bits. We need to make this
+ adjustment in two ways: once for the bits we took from the data,
+ and once for the bits we are putting back in to the data. */
+ if ((vallo & 0x8000) != 0)
+ val -= 0x10000;
+ if ((val & 0x8000) != 0)
+ val += 0x10000;
-static asection *
-make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
- bfd *abfd;
- CONST char *name;
- flagword flags;
- bfd_size_type _raw_size;
- bfd_vma vma;
- file_ptr filepos;
-{
- asection *asect;
+ insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (input_bfd, (bfd_vma) insn,
+ contents + refhi->r_vaddr - input_section->vma);
+}
- asect = bfd_make_section (abfd, name);
- if (!asect)
- return NULL;
+/* Relocate a section while linking a MIPS ECOFF file. */
- asect->flags = flags;
- asect->_raw_size = _raw_size;
- asect->vma = vma;
- asect->filepos = filepos;
- asect->alignment_power = 4;
+static 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;
+{
+ asection **symndx_to_section;
+ struct ecoff_link_hash_entry **sym_hashes;
+ bfd_vma gp;
+ boolean gp_undefined;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+ boolean got_reflo;
+
+ BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
+ == output_bfd->xvec->header_byteorder_big_p);
+
+ /* We keep a table mapping the symndx found in an internal reloc to
+ the appropriate section. This is faster than looking up the
+ section by name each time. */
+ symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
+ if (symndx_to_section == (asection **) NULL)
+ {
+ symndx_to_section = ((asection **)
+ bfd_alloc (input_bfd,
+ (NUM_RELOC_SECTIONS
+ * sizeof (asection *))));
+
+ symndx_to_section[RELOC_SECTION_NONE] = NULL;
+ symndx_to_section[RELOC_SECTION_TEXT] =
+ bfd_get_section_by_name (input_bfd, ".text");
+ symndx_to_section[RELOC_SECTION_RDATA] =
+ bfd_get_section_by_name (input_bfd, ".rdata");
+ symndx_to_section[RELOC_SECTION_DATA] =
+ bfd_get_section_by_name (input_bfd, ".data");
+ symndx_to_section[RELOC_SECTION_SDATA] =
+ bfd_get_section_by_name (input_bfd, ".sdata");
+ symndx_to_section[RELOC_SECTION_SBSS] =
+ bfd_get_section_by_name (input_bfd, ".sbss");
+ symndx_to_section[RELOC_SECTION_BSS] =
+ bfd_get_section_by_name (input_bfd, ".bss");
+ symndx_to_section[RELOC_SECTION_INIT] =
+ bfd_get_section_by_name (input_bfd, ".init");
+ symndx_to_section[RELOC_SECTION_LIT8] =
+ bfd_get_section_by_name (input_bfd, ".lit8");
+ symndx_to_section[RELOC_SECTION_LIT4] =
+ bfd_get_section_by_name (input_bfd, ".lit4");
+ symndx_to_section[RELOC_SECTION_XDATA] = NULL;
+ symndx_to_section[RELOC_SECTION_PDATA] = NULL;
+ symndx_to_section[RELOC_SECTION_FINI] =
+ bfd_get_section_by_name (input_bfd, ".fini");
+ symndx_to_section[RELOC_SECTION_LITA] = NULL;
+ symndx_to_section[RELOC_SECTION_ABS] = NULL;
+
+ ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
+ }
- return asect;
-}
+ sym_hashes = ecoff_data (input_bfd)->sym_hashes;
-static bfd_target *
-ecoff_core_file_p (abfd)
- bfd *abfd;
-{
- int val;
- int i;
- char *secname;
- struct coreout coreout;
- struct idesc *idg, *idf, *ids;
+ gp = ecoff_data (output_bfd)->gp;
+ if (gp == 0)
+ gp_undefined = true;
+ else
+ gp_undefined = false;
- val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
- if (val != sizeof coreout)
- return 0;
+ got_reflo = false;
- if (coreout.c_magic != CORE_MAGIC
- || coreout.c_version != CORE_VERSION1)
- return 0;
+ ext_rel = (struct external_reloc *) external_relocs;
+ ext_rel_end = ext_rel + input_section->reloc_count;
+ for (; ext_rel < ext_rel_end; ext_rel++)
+ {
+ struct internal_reloc int_rel;
+ struct internal_reloc reflo_int_rel;
+ bfd_vma addend;
+ reloc_howto_type *howto;
+ struct ecoff_link_hash_entry *h = NULL;
+ asection *s = NULL;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ if (! got_reflo)
+ mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
+ else
+ {
+ int_rel = reflo_int_rel;
+ got_reflo = false;
+ }
- core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
- if (!core_hdr (abfd))
- return NULL;
+ BFD_ASSERT (int_rel.r_type
+ < sizeof mips_howto_table / sizeof mips_howto_table[0]);
- strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
- core_signal (abfd) = coreout.c_sigcause;
+ /* The REFHI reloc requires special handling. It must be
+ followed by a REFLO reloc, and the addend is formed from both
+ fields. */
+ if (int_rel.r_type == MIPS_R_REFHI)
+ {
+ BFD_ASSERT ((ext_rel + 1) < ext_rel_end);
+ mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1),
+ &reflo_int_rel);
+ BFD_ASSERT (reflo_int_rel.r_type == MIPS_R_REFLO
+ && int_rel.r_extern == reflo_int_rel.r_extern
+ && int_rel.r_symndx == reflo_int_rel.r_symndx);
+ got_reflo = true;
+ }
- bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET);
+ howto = &mips_howto_table[int_rel.r_type];
- for (i = 0; i < coreout.c_nvmap; i++)
- {
- struct vmap vmap;
+ if (int_rel.r_extern)
+ {
+ h = sym_hashes[int_rel.r_symndx];
+ /* If h is NULL, that means that there is a reloc against an
+ external symbol which we thought was just a debugging
+ symbol. This should not happen. */
+ if (h == (struct ecoff_link_hash_entry *) NULL)
+ abort ();
+ }
+ else
+ {
+ if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
+ s = NULL;
+ else
+ s = symndx_to_section[int_rel.r_symndx];
- val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
- if (val != sizeof vmap)
- break;
+ if (s == (asection *) NULL)
+ abort ();
+ }
- switch (vmap.v_type)
+ /* The GPREL reloc uses an addend: the difference in the GP
+ values. */
+ if (int_rel.r_type != MIPS_R_GPREL)
+ addend = 0;
+ else
{
- case VDATA:
- secname = ".data";
- break;
- case VSTACK:
- secname = ".stack";
- break;
- default:
- continue;
+ if (gp_undefined)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info, "GP relative relocation when GP not defined",
+ input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ /* Only give the error once per link. */
+ ecoff_data (output_bfd)->gp = gp = 4;
+ gp_undefined = false;
+ }
+ if (! int_rel.r_extern)
+ {
+ /* This is a relocation against a section. The current
+ addend in the instruction is the difference between
+ INPUT_SECTION->vma and the GP value of INPUT_BFD. We
+ must change this to be the difference between the
+ final definition (which will end up in RELOCATION)
+ and the GP value of OUTPUT_BFD (which is in GP). */
+ addend = ecoff_data (input_bfd)->gp - gp;
+ }
+ else if (! info->relocateable
+ || h->root.type == bfd_link_hash_defined)
+ {
+ /* This is a relocation against an undefined or common
+ symbol. The current addend in the instruction is
+ simply the desired offset into the symbol (normally
+ zero). We are going to change this into a relocation
+ against a defined symbol, so we want the instruction
+ to hold the difference between the final definition
+ of the symbol (which will end up in RELOCATION) and
+ the GP value of OUTPUT_BFD (which is in GP). */
+ addend = - gp;
+ }
+ else
+ {
+ /* This is a relocation against an undefined or common
+ symbol. The current addend in the instruction is
+ simply the desired offset into the symbol (normally
+ zero). We are generating relocateable output, and we
+ aren't going to define this symbol, so we just leave
+ the instruction alone. */
+ addend = 0;
+ }
}
- if (!make_bfd_asection (abfd, secname,
- SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
- vmap.v_len,
- vmap.v_vaddr,
- vmap.v_offset,
- 2))
- return NULL;
- }
+ if (info->relocateable)
+ {
+ /* We are generating relocateable output, and must convert
+ the existing reloc. */
+ if (int_rel.r_extern)
+ {
+ if (h->root.type == bfd_link_hash_defined)
+ {
+ asection *hsec;
+ const char *name;
- /* Make sure that the regs are contiguous within the core file. */
+ /* This symbol is defined in the output. Convert
+ the reloc from being against the symbol to being
+ against the section. */
- idg = &coreout.c_idesc[I_GPREGS];
- idf = &coreout.c_idesc[I_FPREGS];
- ids = &coreout.c_idesc[I_SPECREGS];
+ /* Clear the r_extern bit. */
+ int_rel.r_extern = 0;
- if (idg->i_offset + idg->i_len != idf->i_offset
- || idf->i_offset + idf->i_len != ids->i_offset)
- return 0; /* Can't deal with non-contig regs */
+ /* Compute a new r_symndx value. */
+ hsec = h->root.u.def.section;
+ name = bfd_get_section_name (output_bfd,
+ hsec->output_section);
- bfd_seek (abfd, idg->i_offset, SEEK_SET);
+ int_rel.r_symndx = -1;
+ switch (name[1])
+ {
+ case 'b':
+ if (strcmp (name, ".bss") == 0)
+ int_rel.r_symndx = RELOC_SECTION_BSS;
+ break;
+ case 'd':
+ if (strcmp (name, ".data") == 0)
+ int_rel.r_symndx = RELOC_SECTION_DATA;
+ break;
+ case 'f':
+ if (strcmp (name, ".fini") == 0)
+ int_rel.r_symndx = RELOC_SECTION_FINI;
+ break;
+ case 'i':
+ if (strcmp (name, ".init") == 0)
+ int_rel.r_symndx = RELOC_SECTION_INIT;
+ break;
+ case 'l':
+ if (strcmp (name, ".lit8") == 0)
+ int_rel.r_symndx = RELOC_SECTION_LIT8;
+ else if (strcmp (name, ".lit4") == 0)
+ int_rel.r_symndx = RELOC_SECTION_LIT4;
+ break;
+ case 'r':
+ if (strcmp (name, ".rdata") == 0)
+ int_rel.r_symndx = RELOC_SECTION_RDATA;
+ break;
+ case 's':
+ if (strcmp (name, ".sdata") == 0)
+ int_rel.r_symndx = RELOC_SECTION_SDATA;
+ else if (strcmp (name, ".sbss") == 0)
+ int_rel.r_symndx = RELOC_SECTION_SBSS;
+ break;
+ case 't':
+ if (strcmp (name, ".text") == 0)
+ int_rel.r_symndx = RELOC_SECTION_TEXT;
+ break;
+ }
+
+ if (int_rel.r_symndx == -1)
+ abort ();
+
+ /* Add the section VMA and the symbol value. */
+ relocation = (h->root.u.def.value
+ + hsec->output_section->vma
+ + hsec->output_offset);
+ }
+ else
+ {
+ /* Change the symndx value to the right one for the
+ output BFD. */
+ int_rel.r_symndx = h->indx;
+ 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;
+ int_rel.r_symndx = 0;
+ }
+ relocation = 0;
+ }
+ }
+ else
+ {
+ /* This is a relocation against a section. Adjust the
+ value by the amount the section moved. */
+ relocation = (s->output_section->vma
+ + s->output_offset
+ - s->vma);
+ }
- make_bfd_asection (abfd, ".reg",
- SEC_ALLOC+SEC_HAS_CONTENTS,
- idg->i_len + idf->i_len + ids->i_len,
- 0,
- idg->i_offset);
+ relocation += addend;
- /* OK, we believe you. You're a core file (sure, sure). */
+ /* Adjust the contents. */
+ if (relocation == 0)
+ r = bfd_reloc_ok;
+ else
+ {
+ if (int_rel.r_type != MIPS_R_REFHI)
+ r = _bfd_relocate_contents (howto, input_bfd, relocation,
+ (contents
+ + int_rel.r_vaddr
+ - input_section->vma));
+ else
+ {
+ mips_relocate_refhi (&int_rel, &reflo_int_rel,
+ input_bfd, input_section, contents,
+ relocation);
+ r = bfd_reloc_ok;
+ }
+ }
- return abfd->xvec;
-}
+ /* Adjust the reloc address. */
+ int_rel.r_vaddr += (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma);
-static char *
-ecoff_core_file_failing_command (abfd)
- bfd *abfd;
-{
- return core_command (abfd);
-}
+ /* Save the changed reloc information. */
+ mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
+ }
+ else
+ {
+ /* We are producing a final executable. */
+ if (int_rel.r_extern)
+ {
+ /* This is a reloc against a symbol. */
+ if (h->root.type == bfd_link_hash_defined)
+ {
+ asection *hsec;
-static int
-ecoff_core_file_failing_signal (abfd)
- bfd *abfd;
-{
- return core_signal (abfd);
-}
+ hsec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + hsec->output_section->vma
+ + hsec->output_offset);
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ relocation = 0;
+ }
+ }
+ else
+ {
+ /* This is a reloc against a section. */
+ relocation = (s->output_section->vma
+ + s->output_offset
+ - s->vma);
+
+ /* Adjust a PC relative relocation by removing the
+ reference to the original source section. */
+ if (howto->pc_relative)
+ relocation += input_section->vma;
+ }
-static boolean
-ecoff_core_file_matches_executable_p (core_bfd, exec_bfd)
- bfd *core_bfd, *exec_bfd;
-{
- return true; /* XXX - FIXME */
+ if (int_rel.r_type != MIPS_R_REFHI)
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ int_rel.r_vaddr - input_section->vma,
+ relocation,
+ addend);
+ else
+ {
+ mips_relocate_refhi (&int_rel, &reflo_int_rel, input_bfd,
+ input_section, contents, relocation);
+ r = bfd_reloc_ok;
+ }
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (int_rel.r_extern)
+ name = h->root.root.string;
+ else
+ name = bfd_section_name (input_bfd, s);
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
}
-#else /* not def HOST_IRIX4 */
-#define ecoff_core_file_p _bfd_dummy_target
-#define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
-#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
-#define ecoff_core_file_matches_executable_p \
- _bfd_dummy_core_file_matches_executable_p
-#endif
\f
/* This is the ECOFF backend structure. The backend field of the
target vector points to this. */
},
/* Supported architecture. */
bfd_arch_mips,
- /* Symbol table magic number. */
- magicSym,
/* Initial portion of armap string. */
"__________",
- /* Alignment of debugging information. E.g., 4. */
- 4,
/* The page boundary used to align sections in a demand-paged
executable file. E.g., 0x1000. */
0x1000,
32,
/* Reloc to use for constructor entries. */
&mips_howto_table[MIPS_R_REFWORD],
- /* Sizes of external symbolic information. */
- sizeof (struct hdr_ext),
- sizeof (struct dnr_ext),
- sizeof (struct pdr_ext),
- sizeof (struct sym_ext),
- sizeof (struct opt_ext),
- sizeof (struct fdr_ext),
- sizeof (struct rfd_ext),
- sizeof (struct ext_ext),
- /* Functions to swap in external symbolic data. */
- ecoff_swap_hdr_in,
- ecoff_swap_dnr_in,
- ecoff_swap_pdr_in,
- ecoff_swap_sym_in,
- ecoff_swap_opt_in,
- ecoff_swap_fdr_in,
- ecoff_swap_rfd_in,
- ecoff_swap_ext_in,
- /* Functions to swap out external symbolic data. */
- ecoff_swap_hdr_out,
- ecoff_swap_dnr_out,
- ecoff_swap_pdr_out,
- ecoff_swap_sym_out,
- ecoff_swap_opt_out,
- ecoff_swap_fdr_out,
- ecoff_swap_rfd_out,
- ecoff_swap_ext_out,
+ {
+ /* Symbol table magic number. */
+ magicSym,
+ /* Alignment of debugging information. E.g., 4. */
+ 4,
+ /* Sizes of external symbolic information. */
+ sizeof (struct hdr_ext),
+ sizeof (struct dnr_ext),
+ sizeof (struct pdr_ext),
+ sizeof (struct sym_ext),
+ sizeof (struct opt_ext),
+ sizeof (struct fdr_ext),
+ sizeof (struct rfd_ext),
+ sizeof (struct ext_ext),
+ /* Functions to swap in external symbolic data. */
+ ecoff_swap_hdr_in,
+ ecoff_swap_dnr_in,
+ ecoff_swap_pdr_in,
+ ecoff_swap_sym_in,
+ ecoff_swap_opt_in,
+ ecoff_swap_fdr_in,
+ ecoff_swap_rfd_in,
+ ecoff_swap_ext_in,
+ /* Functions to swap out external symbolic data. */
+ ecoff_swap_hdr_out,
+ ecoff_swap_dnr_out,
+ ecoff_swap_pdr_out,
+ ecoff_swap_sym_out,
+ ecoff_swap_opt_out,
+ ecoff_swap_fdr_out,
+ ecoff_swap_rfd_out,
+ ecoff_swap_ext_out
+ },
/* External reloc size. */
RELSZ,
/* Reloc swapping functions. */
mips_ecoff_swap_reloc_out,
/* Backend reloc tweaking. */
mips_adjust_reloc_in,
- mips_adjust_reloc_out
+ mips_adjust_reloc_out,
+ /* Relocate section contents while linking. */
+ mips_relocate_section
};
/* Looking up a reloc type is MIPS specific. */
#define ecoff_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
+/* Core file support is usually traditional (but note that Irix uses
+ irix-core.c). */
+#define ecoff_core_file_p _bfd_dummy_target
+#define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
+#define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
+#define ecoff_core_file_matches_executable_p \
+ _bfd_dummy_core_file_matches_executable_p
+
bfd_target ecoff_little_vec =
{
"ecoff-littlemips", /* name */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
flags */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect flags */
0, /* leading underscore */
/* BFD back-end for Zilog Z800n COFF binaries.
- Copyright 1992 Free Software Foundation, Inc.
+ Copyright 1992, 1993 Free Software Foundation, Inc.
Contributed by Cygnus Support.
Written by Steve Chamberlain, <sac@cygnus.com>.
#include "bfd.h"
#include "sysdep.h"
-#include "libbfd.h"
#include "obstack.h"
+#include "libbfd.h"
+#include "bfdlink.h"
#include "coff/z8k.h"
#include "coff/internal.h"
#include "libcoff.h"
-#include "seclet.h"
-
-extern bfd_error_vector_type bfd_error_vector;
-
-/* Dummy for now */
-static bfd_reloc_status_type
-DEFUN (func_da, (abfd, reloc_entry, symbol, data, input_section, output_bfd),
- bfd * abfd AND
- arelent * reloc_entry AND
- struct symbol_cache_entry *symbol AND
- PTR data AND
- asection * input_section AND
- bfd * output_bfd)
-{
-}
-
-/* Dummy for now */
-static bfd_reloc_status_type
-DEFUN (func_imm8, (abfd, reloc_entry, symbol, data, input_section, output_bfd),
- bfd * abfd AND
- arelent * reloc_entry AND
- struct symbol_cache_entry *symbol AND
- PTR data AND
- asection * input_section AND
- bfd * output_bfd)
-{
-}
-
-/* Dummy for now */
-static bfd_reloc_status_type
-DEFUN (func_jr, (abfd, reloc_entry, symbol, data, input_section, output_bfd),
- bfd * abfd AND
- arelent * reloc_entry AND
- struct symbol_cache_entry *symbol AND
- PTR data AND
- asection * input_section AND
- bfd * output_bfd)
-{
-}
-
static reloc_howto_type r_imm32 =
-HOWTO (R_IMM32, 0, 1, 32, false, 0, true,
- true, func_jr, "r_imm32", true, 0xffffffff, 0xffffffff, false);
+HOWTO (R_IMM32, 0, 1, 32, false, 0,
+ complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff,
+ 0xffffffff, false);
static reloc_howto_type r_imm4l =
-HOWTO (R_IMM4L, 0, 1, 4, false, 0, true,
- true, func_jr, "r_imm4l", true, 0xf, 0xf, false);
+HOWTO (R_IMM4L, 0, 1, 4, false, 0,
+ complain_overflow_bitfield, 0, "r_imm4l", true, 0xf, 0xf, false);
static reloc_howto_type r_da =
-HOWTO (R_DA, 0, 1, 16, false, 0, true,
- true, func_da, "r_da", true, 0x0000ffff, 0x0000ffff, false);
+HOWTO (R_IMM16, 0, 1, 16, false, 0,
+ complain_overflow_bitfield, 0, "r_da", true, 0x0000ffff, 0x0000ffff,
+ false);
static reloc_howto_type r_imm8 =
-HOWTO (R_IMM8, 0, 1, 8, false, 0, true,
- true, func_imm8, "r_imm8", true, 0x000000ff, 0x000000ff, false);
+HOWTO (R_IMM8, 0, 1, 8, false, 0,
+ complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff,
+ false);
static reloc_howto_type r_jr =
-HOWTO (R_JR, 0, 1, 8, true, 0, true, true, func_jr, "r_jr", true, 0, 0, true);
+HOWTO (R_JR, 0, 1, 8, true, 0, complain_overflow_signed, 0,
+ "r_jr", true, 0, 0, true);
/* Turn a howto into a reloc number */
switch (dst->r_type)
{
default:
- printf ("BAD %x\n", dst->r_type);
+ fprintf (stderr, "BAD 0x%x\n", dst->r_type);
case R_IMM8:
internal->howto = &r_imm8;
break;
- case R_DA:
+ case R_IMM16:
internal->howto = &r_da;
break;
case R_JR:
}
static void
-extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
+extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
bfd *in_abfd;
- bfd_seclet_type *seclet;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
arelent *reloc;
bfd_byte *data;
unsigned int *src_ptr;
unsigned int *dst_ptr;
{
+ asection *input_section = link_order->u.indirect.section;
+
switch (reloc->howto->type)
{
case R_IMM8:
- bfd_put_8 (in_abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+ bfd_put_8 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + *dst_ptr);
(*dst_ptr) += 1;
(*src_ptr) += 1;
break;
case R_IMM32:
- bfd_put_32 (in_abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+ bfd_put_32 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + *dst_ptr);
(*dst_ptr) += 4;
(*src_ptr) += 4;
case R_IMM4L:
bfd_put_8 (in_abfd,
- (bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
- | (0x0f & bfd_coff_reloc16_get_value (reloc, seclet)),
+ ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
+ | (0x0f
+ & bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section))),
data + *dst_ptr);
(*dst_ptr) += 1;
(*src_ptr) += 1;
break;
- case R_DA:
- bfd_put_16 (in_abfd, bfd_coff_reloc16_get_value (reloc, seclet),
+ case R_IMM16:
+ bfd_put_16 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
data + *dst_ptr);
(*dst_ptr) += 2;
(*src_ptr) += 2;
case R_JR:
{
- bfd_vma dst = bfd_coff_reloc16_get_value (reloc, seclet);
- bfd_vma dot = seclet->offset
- + *dst_ptr
- + seclet->u.indirect.section->output_section->vma;
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (link_order->offset
+ + *dst_ptr
+ + input_section->output_section->vma);
int gap = dst - dot - 1;/* -1 since were in the odd byte of the
word and the pc's been incremented */
gap /= 2;
if (gap > 128 || gap < -128)
{
- bfd_error_vector.reloc_value_truncated (reloc, seclet);
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
}
bfd_put_8 (in_abfd, gap, data + *dst_ptr);
(*dst_ptr)++;
#undef coff_bfd_get_relocated_section_contents
#undef coff_bfd_relax_section
-#define coff_bfd_get_relocated_section_contents bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
bfd_target z8kcoff_vec =
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
- HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
'_', /* leading symbol underscore */
'/', /* ar_pad_char */
15, /* ar_max_namelen */
1, /* minimum section alignment */
- _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
- _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
{_bfd_dummy_target, coff_object_p, /* bfd_check_format */
bfd_generic_archive_p, _bfd_dummy_target},
_bfd_write_archive_contents, bfd_false},
JUMP_TABLE (coff),
- 0, 0,
COFF_SWAP_TABLE,
};
/* BFD back-end for HP PA-RISC ELF files.
- Copyright (C) 1990-1991 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by
#include "sysdep.h"
#include "libbfd.h"
#include "obstack.h"
+#include "bfdlink.h"
#include "libelf.h"
/* ELF32/HPPA relocation support
/* ELF/PA relocation howto entries */
-static bfd_reloc_status_type hppa_elf_reloc ();
+static bfd_reloc_status_type hppa_elf_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
{
static int global_sym_defined;
static bfd_reloc_status_type
-hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
+hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol_in;
PTR data;
asection *input_section;
bfd *output_bfd;
+ char **error_message;
{
unsigned long insn;
long sym_value = 0;
break;
default:
- fprintf (stderr, "Relocation problem : ");
- fprintf (stderr, "Unrecognized reloc type %d, in module %s\n",
- r_type, abfd->filename);
+ *error_message = (char *) "Unrecognized reloc";
return bfd_reloc_dangerous;
}
int *stub_secp; /* pointer to the next available location in the buffer */
char *stub_contents; /* contents of the stubs for this bfd */
elf32_hppa_stub_name_list *stub_listP;
+ struct bfd_link_info *link_info;
}
elf32_hppa_stub_description;
}
static elf32_hppa_stub_description *
-new_stub (abfd, stub_sec)
+new_stub (abfd, stub_sec, link_info)
bfd *abfd;
asection *stub_sec;
+ struct bfd_link_info *link_info;
{
elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
stub->allocated_size = 0;
stub->stub_contents = NULL;
stub->stub_secp = NULL;
+ stub->link_info = link_info;
stub->next = elf_hppa_stub_rootP;
elf_hppa_stub_rootP = stub;
/* Locate the stub by the given name. */
static elf32_hppa_stub_name_list *
-add_stub_by_name(abfd, stub_sec, sym)
+add_stub_by_name(abfd, stub_sec, sym, link_info)
bfd *abfd;
asection *stub_sec;
asymbol *sym;
+ struct bfd_link_info *link_info;
{
elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
elf32_hppa_stub_name_list *stub_entry;
if (!stub)
- stub = new_stub(abfd, stub_sec);
+ stub = new_stub(abfd, stub_sec, link_info);
if (stub)
{
hppa_elf_stub_finish (output_bfd)
bfd *output_bfd;
{
- extern bfd_error_vector_type bfd_error_vector;
elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
/* All the stubs have been built. Finish up building */
/* stub section. Apply relocations to the section. */
for (parent = reloc_vector; *parent != (arelent *) NULL;
parent++)
{
+ char *err = (char *) NULL;
bfd_reloc_status_type r =
- bfd_perform_relocation (stub_bfd,
- *parent,
- stub_list->stub_contents,
- stub_sec, 0);
+ bfd_perform_relocation (stub_bfd,
+ *parent,
+ stub_list->stub_contents,
+ stub_sec, (bfd *) NULL, &err);
if (r != bfd_reloc_ok)
{
+ struct bfd_link_info *link_info = stub_list->link_info;
+
switch (r)
{
case bfd_reloc_undefined:
- bfd_error_vector.undefined_symbol (*parent, NULL);
+ if (! ((*link_info->callbacks->undefined_symbol)
+ (link_info,
+ bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ stub_bfd, stub_sec, (*parent)->address)))
+ abort ();
break;
case bfd_reloc_dangerous:
- bfd_error_vector.reloc_dangerous (*parent, NULL);
+ if (! ((*link_info->callbacks->reloc_dangerous)
+ (link_info, err, stub_bfd, stub_sec,
+ (*parent)->address)))
+ abort ();
break;
- case bfd_reloc_outofrange:
case bfd_reloc_overflow:
- bfd_error_vector.reloc_value_truncated (*parent, NULL);
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info,
+ bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ (*parent)->howto->name,
+ (*parent)->addend,
+ stub_bfd, stub_sec,
+ (*parent)->address)))
+ abort ();
+ }
break;
+ case bfd_reloc_outofrange:
default:
abort ();
break;
}
asymbol *
-hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
+hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
stub_types, rtn_adjust, data)
bfd *abfd;
bfd *output_bfd;
+ struct bfd_link_info *link_info;
arelent *reloc_entry;
int stub_types[5];
int rtn_adjust;
stub_sec->output_section = output_text_section->output_section;
stub_sec->output_offset = 0;
bfd_set_section_alignment (abfd, stub_sec, 2);
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
}
/* Make the stub if we did not find one already. */
if (!stub_desc)
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
/* Allocate space to write the stub.
FIXME. Why using realloc?!? */
= (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
stub_sym->section = stub_sec;
stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
- stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym);
+ stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
/* Redirect the original relocation from the old symbol (a function)
to the stub (the stub calls the function). Change the type of
{
NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
}
+ else
+ NEW_INSTRUCTION (stub_entry, COPY_31_2);
/* Save the return address. */
NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
}
asymbol *
-hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
+hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
+ symbol, data)
bfd *abfd;
bfd *output_bfd;
+ struct bfd_link_info *link_info;
arelent *reloc_entry;
asymbol *symbol;
unsigned *data;
}
bfd_set_section_alignment (abfd, stub_sec, 2);
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
}
if (!stub_desc)
- stub_desc = new_stub (abfd, stub_sec);
+ stub_desc = new_stub (abfd, stub_sec, link_info);
/* Allocate memory to contain the stub. FIXME. Why isn't this using
the BFD memory allocation routines? */
= (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
stub_sym->section = stub_sec;
stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
- stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym);
+ stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
/* Change symbol associated with the original relocation to point
to the stub.
asymbol *
hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
- syms, new_sym_cnt)
+ syms, new_sym_cnt, link_info)
bfd *stub_bfd;
bfd *abfd;
bfd *output_bfd;
asection *asec;
asymbol **syms;
int *new_sym_cnt;
+ struct bfd_link_info *link_info;
{
int i;
int stub_types[5];
R_HPPA_STUB_CALL_17) it will be possible to perform
the code reorientation. */
r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
- rle, stub_types,
+ link_info, rle,
+ stub_types,
true, insn);
new_syms[new_cnt++] = *r;
}
realloc (new_syms, (new_max * sizeof (asymbol)));
}
r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
- rle,
+ link_info, rle,
rle->sym_ptr_ptr[0],
insn);
new_syms[new_cnt++] = *r;
}
}
r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
- rle, stub_types,
+ link_info, rle,
+ stub_types,
rtn_adjust, insn);
new_syms[new_cnt++] = *r;
}
break;
case bfd_reloc_overflow:
if (! ((*link_info->callbacks->reloc_overflow)
- (link_info, input_bfd, input_section, (*parent)->address)))
+ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ (*parent)->howto->name, (*parent)->addend,
+ input_bfd, input_section, (*parent)->address)))
return NULL;
break;
case bfd_reloc_outofrange: