* 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:
parent
5dad4c9728
commit
4991ebb987
@ -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
|
||||
|
42
bfd/aoutx.h
42
bfd/aoutx.h
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,7 +207,7 @@ 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 */
|
||||
|
105
bfd/coff-h8500.c
105
bfd/coff-h8500.c
@ -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},
|
||||
|
700
bfd/coff-mips.c
700
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];
|
||||
};
|
||||
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 */
|
||||
|
124
bfd/coff-z8k.c
124
bfd/coff-z8k.c
@ -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,
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user