aboutsummaryrefslogtreecommitdiff
path: root/bfd/coff-mips.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-01-24 20:23:18 +0000
committerIan Lance Taylor <ian@airs.com>1994-01-24 20:23:18 +0000
commit4991ebb9873c7965b6a70f47ef9ed5c0149b5ae4 (patch)
tree68fd14f3d82d9a8b76892d47d49561184d4b5ccb /bfd/coff-mips.c
parent5dad4c97286ccff467bb6c96203056106a19e551 (diff)
downloadgdb-4991ebb9873c7965b6a70f47ef9ed5c0149b5ae4.zip
gdb-4991ebb9873c7965b6a70f47ef9ed5c0149b5ae4.tar.gz
gdb-4991ebb9873c7965b6a70f47ef9ed5c0149b5ae4.tar.bz2
* 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.
Diffstat (limited to 'bfd/coff-mips.c')
-rw-r--r--bfd/coff-mips.c664
1 files changed, 496 insertions, 168 deletions
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
index e641b60..c4a793a 100644
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -21,8 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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"
@@ -49,25 +49,38 @@ static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
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));
/* ECOFF has COFF sections, but the debugging information is stored in
a completely different format. ECOFF targets use some of the
@@ -364,7 +377,7 @@ mips_adjust_reloc_in (abfd, intern, rptr)
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;
@@ -388,13 +401,15 @@ mips_generic_reloc (abfd,
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
@@ -422,13 +437,15 @@ mips_refhi_reloc (abfd,
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;
@@ -480,13 +497,15 @@ mips_reflo_reloc (abfd,
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)
{
@@ -522,7 +541,7 @@ mips_reflo_reloc (abfd,
/* 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
@@ -530,17 +549,19 @@ mips_reflo_reloc (abfd,
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;
@@ -616,9 +637,8 @@ mips_gprel_reloc (abfd,
{
/* 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;
}
}
@@ -657,7 +677,7 @@ mips_gprel_reloc (abfd,
/* Make sure it fit in 16 bits. */
if (val >= 0x8000 && val < 0xffff8000)
- return bfd_reloc_outofrange;
+ return bfd_reloc_overflow;
return bfd_reloc_ok;
}
@@ -691,6 +711,9 @@ mips_bfd_reloc_type_lookup (abfd, code)
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;
}
@@ -698,150 +721,443 @@ mips_bfd_reloc_type_lookup (abfd, code)
return &mips_howto_table[mips_type];
}
-#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
/* This is the ECOFF backend structure. The backend field of the
target vector points to this. */
@@ -868,12 +1184,8 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
},
/* 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,
@@ -885,33 +1197,39 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
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. */
@@ -919,7 +1237,9 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
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. */
@@ -929,6 +1249,14 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
#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 */
@@ -938,7 +1266,7 @@ bfd_target ecoff_little_vec =
(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 */
@@ -972,7 +1300,7 @@ bfd_target ecoff_big_vec =
(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 */