* 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.
This commit is contained in:
Ian Lance Taylor 1994-01-24 20:23:18 +00:00
parent 5dad4c9728
commit 4991ebb987
9 changed files with 805 additions and 375 deletions

View File

@ -1,5 +1,17 @@
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

View File

@ -4253,9 +4253,24 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
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;
}
}
@ -4539,9 +4554,24 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
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;
}
}

View File

@ -1032,7 +1032,9 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
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:
@ -1749,10 +1751,20 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
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;
}
}

View File

@ -20,13 +20,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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[] =
{
@ -178,11 +177,12 @@ DEFUN (reloc_processing, (relent, reloc, symbols, abfd, section),
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;
@ -207,8 +207,8 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
/* 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)
{
@ -227,7 +227,7 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
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;
@ -252,7 +252,7 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
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;
@ -296,9 +296,11 @@ h8300_reloc16_estimate(input_section, symbols, reloc, shrink)
*/
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;
@ -306,6 +308,7 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_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)
{
@ -313,13 +316,18 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
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);
@ -331,10 +339,15 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
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);
@ -350,13 +363,15 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
/* 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;
@ -389,7 +404,8 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
/* 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
@ -403,11 +419,12 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
/* 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 ();
@ -439,11 +456,12 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
/* 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 ();
@ -473,7 +491,7 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
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);
@ -488,7 +506,7 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_ptr, dst_ptr)
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);
@ -516,7 +534,8 @@ h8300_reloc16_extra_cases (abfd, seclet, reloc, data, src_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
@ -530,7 +549,7 @@ bfd_target h8300coff_vec =
(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 */

View File

@ -21,50 +21,48 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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 */
@ -102,7 +100,7 @@ rtype2howto(internal, dst)
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;
@ -171,20 +169,22 @@ static void reloc_processing (relent, reloc, symbols, abfd, section)
}
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;
@ -192,7 +192,8 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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;
@ -200,7 +201,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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;
@ -208,7 +209,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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;
@ -217,7 +218,8 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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;
@ -226,7 +228,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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);
@ -236,7 +238,7 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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;;
@ -246,16 +248,21 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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)++;
@ -264,16 +271,21 @@ extra_case (in_abfd, seclet, reloc, data, src_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;
@ -293,7 +305,8 @@ extra_case (in_abfd, seclet, reloc, data, src_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 h8500coff_vec =
@ -305,19 +318,19 @@ 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},

View File

@ -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];
};
unsigned long insn;
unsigned long val;
unsigned long vallo;
#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)
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;
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;
/* 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;
asect = bfd_make_section (abfd, name);
if (!asect)
return NULL;
asect->flags = flags;
asect->_raw_size = _raw_size;
asect->vma = vma;
asect->filepos = filepos;
asect->alignment_power = 4;
return asect;
insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
bfd_put_32 (input_bfd, (bfd_vma) insn,
contents + refhi->r_vaddr - input_section->vma);
}
static bfd_target *
ecoff_core_file_p (abfd)
bfd *abfd;
{
int val;
int i;
char *secname;
struct coreout coreout;
struct idesc *idg, *idf, *ids;
val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
if (val != sizeof coreout)
return 0;
if (coreout.c_magic != CORE_MAGIC
|| coreout.c_version != CORE_VERSION1)
return 0;
core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
if (!core_hdr (abfd))
return NULL;
strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
core_signal (abfd) = coreout.c_sigcause;
bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET);
for (i = 0; i < coreout.c_nvmap; i++)
{
struct vmap vmap;
val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
if (val != sizeof vmap)
break;
switch (vmap.v_type)
{
case VDATA:
secname = ".data";
break;
case VSTACK:
secname = ".stack";
break;
default:
continue;
}
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;
}
/* Make sure that the regs are contiguous within the core file. */
idg = &coreout.c_idesc[I_GPREGS];
idf = &coreout.c_idesc[I_FPREGS];
ids = &coreout.c_idesc[I_SPECREGS];
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 */
bfd_seek (abfd, idg->i_offset, SEEK_SET);
make_bfd_asection (abfd, ".reg",
SEC_ALLOC+SEC_HAS_CONTENTS,
idg->i_len + idf->i_len + ids->i_len,
0,
idg->i_offset);
/* OK, we believe you. You're a core file (sure, sure). */
return abfd->xvec;
}
static char *
ecoff_core_file_failing_command (abfd)
bfd *abfd;
{
return core_command (abfd);
}
static int
ecoff_core_file_failing_signal (abfd)
bfd *abfd;
{
return core_signal (abfd);
}
/* Relocate a section while linking a MIPS ECOFF file. */
static boolean
ecoff_core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd, *exec_bfd;
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;
{
return true; /* XXX - FIXME */
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;
}
sym_hashes = ecoff_data (input_bfd)->sym_hashes;
gp = ecoff_data (output_bfd)->gp;
if (gp == 0)
gp_undefined = true;
else
gp_undefined = false;
got_reflo = false;
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;
}
BFD_ASSERT (int_rel.r_type
< sizeof mips_howto_table / sizeof mips_howto_table[0]);
/* 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;
}
howto = &mips_howto_table[int_rel.r_type];
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];
if (s == (asection *) NULL)
abort ();
}
/* The GPREL reloc uses an addend: the difference in the GP
values. */
if (int_rel.r_type != MIPS_R_GPREL)
addend = 0;
else
{
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 (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;
/* This symbol is defined in the output. Convert
the reloc from being against the symbol to being
against the section. */
/* Clear the r_extern bit. */
int_rel.r_extern = 0;
/* Compute a new r_symndx value. */
hsec = h->root.u.def.section;
name = bfd_get_section_name (output_bfd,
hsec->output_section);
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);
}
relocation += addend;
/* 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;
}
}
/* Adjust the reloc address. */
int_rel.r_vaddr += (input_section->output_section->vma
+ input_section->output_offset
- input_section->vma);
/* 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;
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;
}
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 */

View File

@ -1,5 +1,5 @@
/* 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>.
@ -21,70 +21,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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 */
@ -122,11 +87,11 @@ DEFUN (rtype2howto, (internal, dst),
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:
@ -180,25 +145,30 @@ DEFUN (reloc_processing, (relent, reloc, symbols, abfd, section),
}
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;
@ -206,15 +176,18 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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;
@ -222,10 +195,11 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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 */
@ -234,7 +208,11 @@ extra_case (in_abfd, seclet, reloc, data, src_ptr, dst_ptr)
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)++;
@ -253,7 +231,8 @@ extra_case (in_abfd, seclet, reloc, data, src_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 =
@ -265,15 +244,19 @@ 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},
@ -283,6 +266,5 @@ bfd_target z8kcoff_vec =
_bfd_write_archive_contents, bfd_false},
JUMP_TABLE (coff),
0, 0,
COFF_SWAP_TABLE,
};

View File

@ -1,5 +1,5 @@
/* 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
@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "sysdep.h"
#include "libbfd.h"
#include "obstack.h"
#include "bfdlink.h"
#include "libelf.h"
/* ELF32/HPPA relocation support
@ -43,7 +44,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* 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] =
{
@ -1184,13 +1186,15 @@ static asymbol *global_symbol;
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;
@ -1698,9 +1702,7 @@ hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
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;
}
@ -1913,6 +1915,7 @@ typedef struct elf32_hppa_stub_description_struct
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;
@ -1937,9 +1940,10 @@ find_stubs (abfd, stub_sec)
}
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);
@ -1955,6 +1959,7 @@ new_stub (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;
@ -1993,16 +1998,17 @@ find_stub_by_name (abfd, stub_sec, name)
/* 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)
{
@ -2146,7 +2152,6 @@ void
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. */
@ -2183,27 +2188,46 @@ hppa_elf_stub_finish (output_bfd)
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_overflow:
{
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:
case bfd_reloc_overflow:
bfd_error_vector.reloc_value_truncated (*parent, NULL);
break;
default:
abort ();
break;
@ -2325,10 +2349,11 @@ elf32_hppa_reloc_type type;
}
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;
@ -2372,12 +2397,12 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
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?!? */
@ -2429,7 +2454,7 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
= (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
@ -2567,6 +2592,8 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
{
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);
@ -2732,9 +2759,11 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types, caller_ar)
}
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;
@ -2817,11 +2846,11 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, 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? */
@ -2915,7 +2944,7 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
= (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.
@ -3051,13 +3080,14 @@ hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
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];
@ -3145,7 +3175,8 @@ hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
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;
}
@ -3166,7 +3197,7 @@ hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
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;
@ -3225,7 +3256,8 @@ hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
}
}
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;
}

View File

@ -1646,7 +1646,9 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data,
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: