mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-26 18:53:29 +08:00
* libbfd-in.h: Removed swapping routines declarations.
* bfd-in.h: Added swapping routine declarations, and renamed them from _do_* to bfd_*. * libbfd.c: Renamed swapping routines from _do_* to _bfd_*. * Changed all callers. * libbfd.h, bfd-in2.h: Rebuilt.
This commit is contained in:
parent
44647fcc26
commit
23f44e6f1a
@ -1,3 +1,12 @@
|
||||
Tue Sep 7 14:17:02 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
* libbfd-in.h: Removed swapping routines declarations.
|
||||
* bfd-in.h: Added swapping routine declarations, and renamed them
|
||||
from _do_* to bfd_*.
|
||||
* libbfd.c: Renamed swapping routines from _do_* to _bfd_*.
|
||||
* Changed all callers.
|
||||
* libbfd.h, bfd-in2.h: Rebuilt.
|
||||
|
||||
Mon Sep 6 15:28:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
* elf32-i386.c (elf_howto_table): Set pcrel_offset to true for
|
||||
|
@ -304,13 +304,13 @@ bfd_target a29kcoff_big_vec =
|
||||
15, /* ar_max_namelen */
|
||||
2, /* minimum section alignment */
|
||||
/* 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,
|
||||
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 */
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
|
||||
{
|
||||
|
||||
|
712
bfd/coff-mips.c
712
bfd/coff-mips.c
@ -41,8 +41,31 @@ static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
|
||||
static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
|
||||
const struct internal_reloc *,
|
||||
PTR));
|
||||
static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
|
||||
arelent *reloc,
|
||||
asymbol *symbol,
|
||||
PTR data,
|
||||
asection *section,
|
||||
bfd *output_bfd));
|
||||
static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
|
||||
arelent *reloc,
|
||||
asymbol *symbol,
|
||||
PTR data,
|
||||
asection *section,
|
||||
bfd *output_bfd));
|
||||
static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
|
||||
arelent *reloc,
|
||||
asymbol *symbol,
|
||||
PTR data,
|
||||
asection *section,
|
||||
bfd *output_bfd));
|
||||
static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
|
||||
arelent *reloc,
|
||||
asymbol *symbol,
|
||||
PTR data,
|
||||
asection *section,
|
||||
bfd *output_bfd));
|
||||
|
||||
|
||||
/* ECOFF has COFF sections, but the debugging information is stored in
|
||||
a completely different format. ECOFF targets use some of the
|
||||
swapping routines from coffswap.h, and some of the generic COFF
|
||||
@ -50,7 +73,7 @@ static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
|
||||
use coffcode.h itself.
|
||||
|
||||
Get the generic COFF swapping routines, except for the reloc,
|
||||
symbol, and lineno ones. Give them ecoff names. */
|
||||
symbol, and lineno ones. Give them ECOFF names. */
|
||||
#define MIPSECOFF
|
||||
#define NO_COFF_RELOCS
|
||||
#define NO_COFF_SYMBOLS
|
||||
@ -67,58 +90,138 @@ static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
|
||||
#define ECOFF_32
|
||||
#include "ecoffswap.h"
|
||||
|
||||
/* This is the ECOFF backend structure. The backend_data field of the
|
||||
ecoff_tdata structure is set to this when an ECOFF BFD is
|
||||
initialized. This is used by the generic ECOFF routines. */
|
||||
/* How to process the various relocs types. */
|
||||
|
||||
static const struct ecoff_backend_data mips_ecoff_backend_data =
|
||||
static reloc_howto_type mips_howto_table[] =
|
||||
{
|
||||
/* Supported architecture. */
|
||||
bfd_arch_mips,
|
||||
/* Big endian magic number. */
|
||||
MIPS_MAGIC_BIG,
|
||||
/* Little endian magic number. */
|
||||
MIPS_MAGIC_LITTLE,
|
||||
/* 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,
|
||||
/* Bitsize of constructor entries. */
|
||||
32,
|
||||
/* 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_in,
|
||||
mips_ecoff_swap_reloc_out
|
||||
/* Reloc type 0 is ignored. The reloc reading code ensures that
|
||||
this is a reference to the .abs section, which will cause
|
||||
bfd_perform_relocation to do nothing. */
|
||||
HOWTO (MIPS_R_IGNORE, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
8, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
0, /* special_function */
|
||||
"IGNORE", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* A 16 bit reference to a symbol, normally from a data section. */
|
||||
HOWTO (MIPS_R_REFHALF, /* type */
|
||||
0, /* rightshift */
|
||||
1, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
16, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
mips_generic_reloc, /* special_function */
|
||||
"REFHALF", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffff, /* src_mask */
|
||||
0xffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* A 32 bit reference to a symbol, normally from a data section. */
|
||||
HOWTO (MIPS_R_REFWORD, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
mips_generic_reloc, /* special_function */
|
||||
"REFWORD", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* A 26 bit absolute jump address. */
|
||||
HOWTO (MIPS_R_JMPADDR, /* type */
|
||||
2, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
26, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
mips_generic_reloc, /* special_function */
|
||||
"JMPADDR", /* name */
|
||||
true, /* partial_inplace */
|
||||
0x3ffffff, /* src_mask */
|
||||
0x3ffffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The high 16 bits of a symbol value. Handled by the function
|
||||
mips_refhi_reloc. */
|
||||
HOWTO (MIPS_R_REFHI, /* type */
|
||||
16, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
16, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield, /* complain_on_overflow */
|
||||
mips_refhi_reloc, /* special_function */
|
||||
"REFHI", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffff, /* src_mask */
|
||||
0xffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The low 16 bits of a symbol value. */
|
||||
HOWTO (MIPS_R_REFLO, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
16, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
mips_reflo_reloc, /* special_function */
|
||||
"REFLO", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffff, /* src_mask */
|
||||
0xffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* A reference to an offset from the gp register. Handled by the
|
||||
function mips_gprel_reloc. */
|
||||
HOWTO (MIPS_R_GPREL, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
16, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed, /* complain_on_overflow */
|
||||
mips_gprel_reloc, /* special_function */
|
||||
"GPREL", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffff, /* src_mask */
|
||||
0xffff, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* A reference to a literal using an offset from the gp register.
|
||||
Handled by the function mips_gprel_reloc. */
|
||||
HOWTO (MIPS_R_LITERAL, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
16, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed, /* complain_on_overflow */
|
||||
mips_gprel_reloc, /* special_function */
|
||||
"LITERAL", /* name */
|
||||
true, /* partial_inplace */
|
||||
0xffff, /* src_mask */
|
||||
0xffff, /* dst_mask */
|
||||
false) /* pcrel_offset */
|
||||
};
|
||||
|
||||
#define MIPS_HOWTO_COUNT \
|
||||
(sizeof mips_howto_table / sizeof mips_howto_table[0])
|
||||
|
||||
/* See whether the magic number matches. */
|
||||
|
||||
@ -135,29 +238,6 @@ mips_ecoff_bad_format_hook (abfd, filehdr)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create an ECOFF object. */
|
||||
|
||||
static boolean
|
||||
mips_ecoff_mkobject (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *)
|
||||
bfd_zalloc (abfd, sizeof (ecoff_data_type)));
|
||||
if (abfd->tdata.ecoff_obj_data == NULL)
|
||||
{
|
||||
bfd_error = no_memory;
|
||||
return false;
|
||||
}
|
||||
|
||||
ecoff_data (abfd)->backend_data = &mips_ecoff_backend_data;
|
||||
|
||||
/* Always create a .scommon section for every BFD. This is a hack so
|
||||
that the linker has something to attach scSCommon symbols to. */
|
||||
bfd_make_section (abfd, SCOMMON);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create the MIPS ECOFF backend specific information. */
|
||||
|
||||
static PTR
|
||||
@ -170,7 +250,7 @@ mips_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
|
||||
struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
|
||||
ecoff_data_type *ecoff;
|
||||
|
||||
if (mips_ecoff_mkobject (abfd) == false)
|
||||
if (ecoff_mkobject (abfd) == false)
|
||||
return NULL;
|
||||
|
||||
ecoff = ecoff_data (abfd);
|
||||
@ -265,6 +345,359 @@ mips_ecoff_swap_reloc_out (abfd, intern, dst)
|
||||
| (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish canonicalizing a reloc. Part of this is generic to all
|
||||
ECOFF targets, and that part is in ecoff.c. The rest is done in
|
||||
this backend routine. It must fill in the howto field. */
|
||||
|
||||
static void
|
||||
mips_finish_reloc (abfd, intern, rptr)
|
||||
bfd *abfd;
|
||||
struct internal_reloc *intern;
|
||||
arelent *rptr;
|
||||
{
|
||||
if (intern->r_type > MIPS_R_LITERAL)
|
||||
abort ();
|
||||
|
||||
if (! intern->r_extern
|
||||
&& (intern->r_type == MIPS_R_GPREL
|
||||
|| intern->r_type == MIPS_R_LITERAL))
|
||||
rptr->addend += ecoff_data (abfd)->gp;
|
||||
|
||||
/* If the type is MIPS_R_IGNORE, make sure this is a reference to
|
||||
the absolute section so that the reloc is ignored. */
|
||||
if (intern->r_type == MIPS_R_IGNORE)
|
||||
rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
|
||||
|
||||
rptr->howto = &mips_howto_table[intern->r_type];
|
||||
}
|
||||
|
||||
/* ECOFF relocs are either against external symbols, or against
|
||||
sections. If we are producing relocateable output, and the reloc
|
||||
is against an external symbol, and nothing has given us any
|
||||
additional addend, the resulting reloc will also be against the
|
||||
same symbol. In such a case, we don't want to change anything
|
||||
about the way the reloc is handled, since it will all be done at
|
||||
final link time. Rather than put special case code into
|
||||
bfd_perform_relocation, all the reloc types use this howto
|
||||
function. It just short circuits the reloc if producing
|
||||
relocateable output against an external symbol. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
mips_generic_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
{
|
||||
if (output_bfd != (bfd *) NULL
|
||||
&& (symbol->flags & BSF_SECTION_SYM) == 0
|
||||
&& reloc_entry->addend == 0)
|
||||
{
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
return bfd_reloc_continue;
|
||||
}
|
||||
|
||||
/* Do a REFHI relocation. This has to be done in combination with a
|
||||
REFLO reloc, because there is a carry from the REFLO to the REFHI.
|
||||
Here we just save the information we need; we do the actual
|
||||
relocation when we see the REFLO. MIPS ECOFF requires that the
|
||||
REFLO immediately follow the REFHI, so this ought to work. */
|
||||
|
||||
static bfd_byte *mips_refhi_addr;
|
||||
static bfd_vma mips_refhi_addend;
|
||||
|
||||
static bfd_reloc_status_type
|
||||
mips_refhi_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
{
|
||||
bfd_reloc_status_type ret;
|
||||
bfd_vma relocation;
|
||||
|
||||
/* If we're relocating, and this an external symbol, we don't want
|
||||
to change anything. */
|
||||
if (output_bfd != (bfd *) NULL
|
||||
&& (symbol->flags & BSF_SECTION_SYM) == 0
|
||||
&& reloc_entry->addend == 0)
|
||||
{
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
ret = bfd_reloc_ok;
|
||||
if (symbol->section == &bfd_und_section
|
||||
&& output_bfd == (bfd *) NULL)
|
||||
ret = bfd_reloc_undefined;
|
||||
|
||||
if (bfd_is_com_section (symbol->section))
|
||||
relocation = 0;
|
||||
else
|
||||
relocation = symbol->value;
|
||||
|
||||
relocation += symbol->section->output_section->vma;
|
||||
relocation += symbol->section->output_offset;
|
||||
relocation += reloc_entry->addend;
|
||||
|
||||
if (reloc_entry->address > input_section->_cooked_size)
|
||||
return bfd_reloc_outofrange;
|
||||
|
||||
/* Save the information, and let REFLO do the actual relocation. */
|
||||
mips_refhi_addr = (bfd_byte *) data + reloc_entry->address;
|
||||
mips_refhi_addend = relocation;
|
||||
|
||||
if (output_bfd != (bfd *) NULL)
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Do a REFLO relocation. This is a straightforward 16 bit inplace
|
||||
relocation; this function exists in order to do the REFHI
|
||||
relocation described above. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
mips_reflo_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
{
|
||||
if (mips_refhi_addr != (bfd_byte *) NULL)
|
||||
{
|
||||
unsigned long insn;
|
||||
unsigned long val;
|
||||
unsigned long vallo;
|
||||
|
||||
/* Do the REFHI relocation. Note that we actually don't need to
|
||||
know anything about the REFLO itself, except where to find
|
||||
the low 16 bits of the addend needed by the REFHI. */
|
||||
insn = bfd_get_32 (abfd, mips_refhi_addr);
|
||||
vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
|
||||
& 0xffff);
|
||||
val = ((insn & 0xffff) << 16) + vallo;
|
||||
val += mips_refhi_addend;
|
||||
|
||||
/* 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;
|
||||
|
||||
insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
|
||||
bfd_put_32 (abfd, insn, mips_refhi_addr);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Do a GPREL relocation. This is a 16 bit value which must become
|
||||
the offset from the gp register. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
mips_gprel_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
{
|
||||
boolean relocateable;
|
||||
bfd_vma relocation;
|
||||
unsigned long val;
|
||||
unsigned long insn;
|
||||
|
||||
/* If we're relocating, and this is an external symbol with no
|
||||
addend, we don't want to change anything. We will only have an
|
||||
addend if this is a newly created reloc, not read from an ECOFF
|
||||
file. */
|
||||
if (output_bfd != (bfd *) NULL
|
||||
&& (symbol->flags & BSF_SECTION_SYM) == 0
|
||||
&& reloc_entry->addend == 0)
|
||||
{
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
if (output_bfd != (bfd *) NULL)
|
||||
relocateable = true;
|
||||
else
|
||||
{
|
||||
relocateable = false;
|
||||
output_bfd = symbol->section->output_section->owner;
|
||||
}
|
||||
|
||||
if (symbol->section == &bfd_und_section
|
||||
&& relocateable == false)
|
||||
return bfd_reloc_undefined;
|
||||
|
||||
/* We have to figure out the gp value, so that we can adjust the
|
||||
symbol value correctly. We look up the symbol _gp in the output
|
||||
BFD. If we can't find it, we're stuck. We cache it in the ECOFF
|
||||
target data. We don't need to adjust the symbol value for an
|
||||
external symbol if we are producing relocateable output. */
|
||||
if (ecoff_data (output_bfd)->gp == 0
|
||||
&& (relocateable == false
|
||||
|| (symbol->flags & BSF_SECTION_SYM) != 0))
|
||||
{
|
||||
if (relocateable != false)
|
||||
{
|
||||
/* Make up a value. */
|
||||
ecoff_data (output_bfd)->gp =
|
||||
symbol->section->output_section->vma + 0x4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int count;
|
||||
asymbol **sym;
|
||||
unsigned int i;
|
||||
|
||||
count = bfd_get_symcount (output_bfd);
|
||||
sym = bfd_get_outsymbols (output_bfd);
|
||||
|
||||
if (sym == (asymbol **) NULL)
|
||||
i = count;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < count; i++, sym++)
|
||||
{
|
||||
register CONST char *name;
|
||||
|
||||
name = bfd_asymbol_name (*sym);
|
||||
if (*name == '_' && strcmp (name, "_gp") == 0)
|
||||
{
|
||||
ecoff_data (output_bfd)->gp = bfd_asymbol_value (*sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= count)
|
||||
{
|
||||
/* 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");
|
||||
return bfd_reloc_dangerous;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bfd_is_com_section (symbol->section))
|
||||
relocation = 0;
|
||||
else
|
||||
relocation = symbol->value;
|
||||
|
||||
relocation += symbol->section->output_section->vma;
|
||||
relocation += symbol->section->output_offset;
|
||||
|
||||
if (reloc_entry->address > input_section->_cooked_size)
|
||||
return bfd_reloc_outofrange;
|
||||
|
||||
insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
|
||||
|
||||
/* Set val to the offset into the section or symbol. */
|
||||
val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
|
||||
if (val & 0x8000)
|
||||
val -= 0x10000;
|
||||
|
||||
/* Adjust val for the final section location and GP value. If we
|
||||
are producing relocateable output, we don't want to do this for
|
||||
an external symbol. */
|
||||
if (relocateable == false
|
||||
|| (symbol->flags & BSF_SECTION_SYM) != 0)
|
||||
val += relocation - ecoff_data (output_bfd)->gp;
|
||||
|
||||
insn = (insn &~ 0xffff) | (val & 0xffff);
|
||||
bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
|
||||
|
||||
if (relocateable != false)
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
|
||||
/* Make sure it fit in 16 bits. */
|
||||
if (val >= 0x8000 && val < 0xffff8000)
|
||||
return bfd_reloc_outofrange;
|
||||
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
/* Get the howto structure for a generic reloc type. */
|
||||
|
||||
static CONST struct reloc_howto_struct *
|
||||
mips_bfd_reloc_type_lookup (abfd, code)
|
||||
bfd *abfd;
|
||||
bfd_reloc_code_real_type code;
|
||||
{
|
||||
int mips_type;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case BFD_RELOC_16:
|
||||
mips_type = MIPS_R_REFHALF;
|
||||
break;
|
||||
case BFD_RELOC_32:
|
||||
mips_type = MIPS_R_REFWORD;
|
||||
break;
|
||||
case BFD_RELOC_MIPS_JMP:
|
||||
mips_type = MIPS_R_JMPADDR;
|
||||
break;
|
||||
case BFD_RELOC_HI16_S:
|
||||
mips_type = MIPS_R_REFHI;
|
||||
break;
|
||||
case BFD_RELOC_LO16:
|
||||
mips_type = MIPS_R_REFLO;
|
||||
break;
|
||||
case BFD_RELOC_MIPS_GPREL:
|
||||
mips_type = MIPS_R_GPREL;
|
||||
break;
|
||||
default:
|
||||
return (CONST struct reloc_howto_struct *) NULL;
|
||||
}
|
||||
|
||||
return &mips_howto_table[mips_type];
|
||||
}
|
||||
|
||||
#ifdef HOST_IRIX4
|
||||
|
||||
@ -411,28 +844,87 @@ ecoff_core_file_matches_executable_p (core_bfd, exec_bfd)
|
||||
_bfd_dummy_core_file_matches_executable_p
|
||||
#endif
|
||||
|
||||
/* This is the COFF backend structure. The backend_data field of the
|
||||
bfd_target structure is set to this. The section reading code in
|
||||
coffgen.c uses this structure. */
|
||||
/* This is the ECOFF backend structure. The backend field of the
|
||||
target vector points to this. */
|
||||
|
||||
static CONST bfd_coff_backend_data mips_ecoff_std_swap_table = {
|
||||
(void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
|
||||
(void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
|
||||
(void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
|
||||
mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
|
||||
mips_ecoff_swap_scnhdr_out,
|
||||
FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
|
||||
mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
|
||||
mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
|
||||
ecoff_set_arch_mach_hook, mips_ecoff_mkobject_hook,
|
||||
ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
|
||||
ecoff_slurp_symbol_table
|
||||
static const struct ecoff_backend_data mips_ecoff_backend_data =
|
||||
{
|
||||
/* COFF backend structure. */
|
||||
{
|
||||
(void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
|
||||
(void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
|
||||
(void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
|
||||
(unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
|
||||
mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
|
||||
mips_ecoff_swap_scnhdr_out,
|
||||
FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
|
||||
mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
|
||||
mips_ecoff_swap_scnhdr_in, mips_ecoff_bad_format_hook,
|
||||
ecoff_set_arch_mach_hook, mips_ecoff_mkobject_hook,
|
||||
ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
|
||||
ecoff_slurp_symbol_table, NULL, NULL
|
||||
},
|
||||
/* Supported architecture. */
|
||||
bfd_arch_mips,
|
||||
/* Big endian magic number. */
|
||||
MIPS_MAGIC_BIG,
|
||||
/* Little endian magic number. */
|
||||
MIPS_MAGIC_LITTLE,
|
||||
/* 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,
|
||||
/* Bitsize of constructor entries. */
|
||||
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,
|
||||
/* External reloc size. */
|
||||
RELSZ,
|
||||
/* Reloc swapping functions. */
|
||||
mips_ecoff_swap_reloc_in,
|
||||
mips_ecoff_swap_reloc_out,
|
||||
/* Backend reloc tweaking. */
|
||||
mips_finish_reloc
|
||||
};
|
||||
|
||||
/* Looking up a reloc type is MIPS specific. */
|
||||
#define ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
|
||||
|
||||
bfd_target ecoff_little_vec =
|
||||
{
|
||||
"ecoff-littlemips", /* name */
|
||||
@ -450,21 +942,21 @@ bfd_target ecoff_little_vec =
|
||||
' ', /* ar_pad_char */
|
||||
15, /* ar_max_namelen */
|
||||
4, /* minimum alignment power */
|
||||
_do_getl64, _do_getl_signed_64, _do_putl64,
|
||||
_do_getl32, _do_getl_signed_32, _do_putl32,
|
||||
_do_getl16, _do_getl_signed_16, _do_putl16, /* data */
|
||||
_do_getl64, _do_getl_signed_64, _do_putl64,
|
||||
_do_getl32, _do_getl_signed_32, _do_putl32,
|
||||
_do_getl16, _do_getl_signed_16, _do_putl16, /* hdrs */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
|
||||
|
||||
{_bfd_dummy_target, coff_object_p, /* bfd_check_format */
|
||||
ecoff_archive_p, _bfd_dummy_target},
|
||||
{bfd_false, mips_ecoff_mkobject, /* bfd_set_format */
|
||||
{bfd_false, ecoff_mkobject, /* bfd_set_format */
|
||||
_bfd_generic_mkarchive, bfd_false},
|
||||
{bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
|
||||
_bfd_write_archive_contents, bfd_false},
|
||||
JUMP_TABLE (ecoff),
|
||||
(PTR) &mips_ecoff_std_swap_table
|
||||
(PTR) &mips_ecoff_backend_data
|
||||
};
|
||||
|
||||
bfd_target ecoff_big_vec =
|
||||
@ -483,20 +975,20 @@ bfd_target ecoff_big_vec =
|
||||
' ', /* ar_pad_char */
|
||||
15, /* ar_max_namelen */
|
||||
4, /* minimum alignment power */
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
{_bfd_dummy_target, coff_object_p, /* bfd_check_format */
|
||||
ecoff_archive_p, ecoff_core_file_p},
|
||||
{bfd_false, mips_ecoff_mkobject, /* bfd_set_format */
|
||||
{bfd_false, ecoff_mkobject, /* bfd_set_format */
|
||||
_bfd_generic_mkarchive, bfd_false},
|
||||
{bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
|
||||
_bfd_write_archive_contents, bfd_false},
|
||||
JUMP_TABLE(ecoff),
|
||||
(PTR) &mips_ecoff_std_swap_table
|
||||
(PTR) &mips_ecoff_backend_data
|
||||
/* Note that there is another bfd_target just above this one. If
|
||||
you are adding initializers here, you should be adding them there
|
||||
as well. */
|
||||
|
@ -142,14 +142,14 @@ bfd_target TARGET_BIG_SYM =
|
||||
3,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the data sections */
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the file headers */
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
|
||||
/* bfd_check_format: check the format of a file being read */
|
||||
{ _bfd_dummy_target, /* unknown format */
|
||||
@ -224,14 +224,14 @@ bfd_target TARGET_LITTLE_SYM =
|
||||
3,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the data sections */
|
||||
_do_getl64, _do_getl_signed_64, _do_putl64,
|
||||
_do_getl32, _do_getl_signed_32, _do_putl32,
|
||||
_do_getl16, _do_getl_signed_16, _do_putl16,
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the file headers */
|
||||
_do_getl64, _do_getl_signed_64, _do_putl64,
|
||||
_do_getl32, _do_getl_signed_32, _do_putl32,
|
||||
_do_getl16, _do_getl_signed_16, _do_putl16,
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
|
||||
|
||||
/* bfd_check_format: check the format of a file being read */
|
||||
{ _bfd_dummy_target, /* unknown format */
|
||||
|
@ -120,14 +120,14 @@ bfd_target TARGET_BIG_SYM =
|
||||
3,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the data sections */
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the file headers */
|
||||
_do_getb64, _do_getb_signed_64, _do_putb64,
|
||||
_do_getb32, _do_getb_signed_32, _do_putb32,
|
||||
_do_getb16, _do_getb_signed_16, _do_putb16,
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16,
|
||||
|
||||
/* bfd_check_format: check the format of a file being read */
|
||||
{ _bfd_dummy_target, /* unknown format */
|
||||
@ -202,14 +202,14 @@ bfd_target TARGET_LITTLE_SYM =
|
||||
3,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the data sections */
|
||||
_do_getl64, _do_getl_signed_64, _do_putl64,
|
||||
_do_getl32, _do_getl_signed_32, _do_putl32,
|
||||
_do_getl16, _do_getl_signed_16, _do_putl16,
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
|
||||
|
||||
/* Routines to byte-swap various sized integers from the file headers */
|
||||
_do_getl64, _do_getl_signed_64, _do_putl64,
|
||||
_do_getl32, _do_getl_signed_32, _do_putl32,
|
||||
_do_getl16, _do_getl_signed_16, _do_putl16,
|
||||
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
|
||||
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
|
||||
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
|
||||
|
||||
/* bfd_check_format: check the format of a file being read */
|
||||
{ _bfd_dummy_target, /* unknown format */
|
||||
|
Loading…
Reference in New Issue
Block a user