mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-28 14:30:48 +00:00
Tue Sep 13 16:04:07 1994 Steve Chamberlain (sac@jonny.cygnus.com)
* cofflink.c (coff_link_input_bfd): syment_base is unsigned so can't compare -ve numbers with it. Mon Sep 12 20:31:17 1994 Steve Chamberlain (sac@jonny.cygnus.com) * configure.in (shcoff_vec): Use cofflink.o now. * coff-sh.c: Rewritten to use new fast coff backend.
This commit is contained in:
parent
a989856340
commit
cf345e3687
@ -1,3 +1,13 @@
|
||||
Tue Sep 13 16:04:07 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
||||
|
||||
* cofflink.c (coff_link_input_bfd): syment_base is unsigned
|
||||
so can't compare -ve numbers with it.
|
||||
|
||||
Mon Sep 12 20:31:17 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
||||
|
||||
* configure.in (shcoff_vec): Use cofflink.o now.
|
||||
* coff-sh.c: Rewritten to use new fast coff backend.
|
||||
|
||||
Tue Sep 13 16:23:57 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||
|
||||
* aoutx.h (NAME(aout,final_link)): Don't assume that all the input
|
||||
|
314
bfd/coff-sh.c
314
bfd/coff-sh.c
@ -28,23 +28,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "coff/internal.h"
|
||||
#include "libcoff.h"
|
||||
|
||||
static bfd_reloc_status_type sh_reloc();
|
||||
|
||||
|
||||
static reloc_howto_type r_imm32 =
|
||||
HOWTO (R_SH_IMM32, 0,2, 32, false, 0,
|
||||
complain_overflow_bitfield, 0, "r_imm32", false, 0x0, 0xffffffff,
|
||||
false);
|
||||
{R_SH_IMM32, 0, 2, 32, false, 0,
|
||||
complain_overflow_bitfield, sh_reloc,"r_imm32", true, 0xffffffff,0xffffffff, false};
|
||||
|
||||
|
||||
|
||||
/* Turn a howto into a reloc number */
|
||||
|
||||
static int
|
||||
coff_SH_select_reloc (howto)
|
||||
reloc_howto_type *howto;
|
||||
{
|
||||
return howto->type;
|
||||
}
|
||||
|
||||
#define SELECT_RELOC(x,howto) x.r_type = coff_SH_select_reloc(howto)
|
||||
/*#define SELECT_RELOC(x,y) x->howto = (&r_imm32)*/
|
||||
|
||||
|
||||
#define BADMAG(x) SHBADMAG(x)
|
||||
@ -53,14 +45,35 @@ coff_SH_select_reloc (howto)
|
||||
#define __A_MAGIC_SET__
|
||||
|
||||
/* Code to swap in the reloc */
|
||||
#if 0
|
||||
#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
|
||||
#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
|
||||
#endif
|
||||
#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
|
||||
dst->r_stuff[0] = 'S'; \
|
||||
dst->r_stuff[1] = 'C';
|
||||
|
||||
/* Code to turn a r_type into a howto ptr, uses the above howto table
|
||||
*/
|
||||
static long
|
||||
get_symbol_value (symbol)
|
||||
asymbol *symbol;
|
||||
{
|
||||
long relocation = 0;
|
||||
|
||||
if (bfd_is_com_section (symbol->section))
|
||||
{
|
||||
relocation = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
relocation = symbol->value +
|
||||
symbol->section->output_section->vma +
|
||||
symbol->section->output_offset;
|
||||
}
|
||||
|
||||
return(relocation);
|
||||
}
|
||||
|
||||
static void
|
||||
rtype2howto (internal, dst)
|
||||
@ -70,25 +83,218 @@ rtype2howto (internal, dst)
|
||||
switch (dst->r_type)
|
||||
{
|
||||
default:
|
||||
fprintf (stderr, "BAD 0x%x\n", dst->r_type);
|
||||
abort();
|
||||
case R_SH_IMM32:
|
||||
internal->howto = &r_imm32;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
|
||||
|
||||
#define RTYPE2HOWTO(x,y) ((x)->howto = &r_imm32)
|
||||
|
||||
/* Perform any necessaru magic to the addend in a reloc entry */
|
||||
|
||||
|
||||
#if 0
|
||||
#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
|
||||
cache_ptr->addend = ext_reloc.r_offset;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Compute the addend of a reloc. If the reloc is to a common symbol,
|
||||
the object file contains the value of the common symbol. By the
|
||||
time this is called, the linker may be using a different symbol
|
||||
from a different object file with a different value. Therefore, we
|
||||
hack wildly to locate the original symbol from this file so that we
|
||||
can make the correct adjustment. This macro sets coffsym to the
|
||||
symbol from the original file, and uses it to set the addend value
|
||||
correctly. If this is not a common symbol, the usual addend
|
||||
calculation is done, except that an additional tweak is needed for
|
||||
PC relative relocs.
|
||||
FIXME: This macro refers to symbols and asect; these are from the
|
||||
calling function, not the macro arguments. */
|
||||
|
||||
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
|
||||
{ \
|
||||
coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
|
||||
if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
|
||||
coffsym = (obj_symbols (abfd) \
|
||||
+ (cache_ptr->sym_ptr_ptr - symbols)); \
|
||||
else if (ptr) \
|
||||
coffsym = coff_symbol_from (abfd, ptr); \
|
||||
if (coffsym != (coff_symbol_type *) NULL \
|
||||
&& coffsym->native->u.syment.n_scnum == 0) \
|
||||
cache_ptr->addend = - coffsym->native->u.syment.n_value; \
|
||||
else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
|
||||
&& ptr->section != (asection *) NULL) \
|
||||
cache_ptr->addend = - (ptr->section->vma + ptr->value); \
|
||||
else \
|
||||
cache_ptr->addend = 0; \
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
|
||||
reloc_processing(relent, reloc, symbols, abfd, section)
|
||||
#endif
|
||||
|
||||
/* this function is in charge of performing all the 29k relocations */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
sh_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;
|
||||
{
|
||||
/* the consth relocation comes in two parts, we have to remember
|
||||
the state between calls, in these variables */
|
||||
unsigned long insn;
|
||||
unsigned long sym_value;
|
||||
unsigned short r_type;
|
||||
|
||||
unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
|
||||
bfd_byte *hit_data =addr + (bfd_byte *)(data);
|
||||
|
||||
r_type = reloc_entry->howto->type;
|
||||
|
||||
if (output_bfd) {
|
||||
/* Partial linking - do nothing */
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
if (symbol_in != NULL
|
||||
&& bfd_is_und_section (symbol_in->section))
|
||||
{
|
||||
/* Keep the state machine happy in case we're called again */
|
||||
return (bfd_reloc_undefined);
|
||||
}
|
||||
|
||||
|
||||
sym_value = get_symbol_value(symbol_in);
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_SH_IMM32:
|
||||
/* We ignore the previous contents ! */
|
||||
insn = sym_value + reloc_entry->addend;
|
||||
bfd_put_32(abfd, insn, hit_data);
|
||||
break;
|
||||
default:
|
||||
*error_message = "Unrecognized reloc";
|
||||
return (bfd_reloc_dangerous);
|
||||
}
|
||||
|
||||
|
||||
return(bfd_reloc_ok);
|
||||
}
|
||||
|
||||
/* The reloc processing routine for the optimized COFF linker. */
|
||||
|
||||
static boolean
|
||||
coff_sh_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
contents, relocs, syms, sections)
|
||||
bfd *output_bfd;
|
||||
struct bfd_link_info *info;
|
||||
bfd *input_bfd;
|
||||
asection *input_section;
|
||||
bfd_byte *contents;
|
||||
struct internal_reloc *relocs;
|
||||
struct internal_syment *syms;
|
||||
asection **sections;
|
||||
{
|
||||
struct internal_reloc *rel;
|
||||
struct internal_reloc *relend;
|
||||
|
||||
/* If we are performing a relocateable link, we don't need to do a
|
||||
thing. The caller will take care of adjusting the reloc
|
||||
addresses and symbol indices. */
|
||||
if (info->relocateable)
|
||||
return true;
|
||||
|
||||
|
||||
rel = relocs;
|
||||
relend = rel + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
long symndx;
|
||||
bfd_byte *loc;
|
||||
struct coff_link_hash_entry *h;
|
||||
struct internal_syment *sym;
|
||||
asection *sec;
|
||||
bfd_vma val;
|
||||
bfd_reloc_status_type rstat;
|
||||
|
||||
symndx = rel->r_symndx;
|
||||
loc = contents + rel->r_vaddr - input_section->vma;
|
||||
|
||||
if (symndx == -1)
|
||||
h = NULL;
|
||||
else
|
||||
h = obj_coff_sym_hashes (input_bfd)[symndx];
|
||||
|
||||
sym = NULL;
|
||||
sec = NULL;
|
||||
val = 0;
|
||||
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
if (symndx == -1)
|
||||
sec = bfd_abs_section_ptr;
|
||||
else
|
||||
{
|
||||
sym = syms + symndx;
|
||||
sec = sections[symndx];
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->n_value
|
||||
- sec->vma
|
||||
- sec->vma);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h->root.type == bfd_link_hash_defined)
|
||||
{
|
||||
sec = h->root.u.def.section;
|
||||
val = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (rel->r_type)
|
||||
{
|
||||
default:
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return false;
|
||||
|
||||
case R_SH_IMM32:
|
||||
{
|
||||
long x = bfd_get_32 (input_bfd, loc);
|
||||
x += val;
|
||||
bfd_put_32 (input_bfd, x, loc);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
reloc_processing (relent, reloc, symbols, abfd, section)
|
||||
@ -98,61 +304,34 @@ reloc_processing (relent, reloc, symbols, abfd, section)
|
||||
bfd * abfd;
|
||||
asection * section;
|
||||
{
|
||||
asymbol *ptr;
|
||||
relent->address = reloc->r_vaddr;
|
||||
rtype2howto (relent, reloc);
|
||||
relent->howto = &r_imm32;
|
||||
|
||||
if (reloc->r_symndx > 0)
|
||||
{
|
||||
relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
|
||||
}
|
||||
|
||||
relent->sym_ptr_ptr = symbols + obj_convert(abfd)[reloc->r_symndx];
|
||||
|
||||
ptr = *(relent->sym_ptr_ptr);
|
||||
|
||||
if (ptr
|
||||
&& bfd_asymbol_bfd(ptr) == abfd
|
||||
|
||||
&& ((ptr->flags & BSF_OLD_COMMON)== 0))
|
||||
{
|
||||
relent->addend = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
relent->sym_ptr_ptr = &(bfd_abs_symbol);
|
||||
}
|
||||
{
|
||||
relent->addend = 0;
|
||||
}
|
||||
relent->address-= section->vma;
|
||||
|
||||
|
||||
relent->addend = reloc->r_offset;
|
||||
relent->address -= section->vma;
|
||||
}
|
||||
|
||||
static void
|
||||
extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
|
||||
bfd *in_abfd;
|
||||
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;
|
||||
{
|
||||
switch (reloc->howto->type)
|
||||
{
|
||||
case R_SH_IMM32:
|
||||
{
|
||||
int v = bfd_coff_reloc16_get_value(reloc, link_info,
|
||||
link_order->u.indirect.section);
|
||||
bfd_put_32 (in_abfd, v, data + *dst_ptr);
|
||||
(*dst_ptr) +=4;
|
||||
(*src_ptr)+=4;;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
#define coff_reloc16_extra_cases extra_case
|
||||
#define coff_relocate_section coff_sh_relocate_section
|
||||
|
||||
#include "coffcode.h"
|
||||
|
||||
|
||||
#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_relax_section bfd_coff_reloc16_relax_section
|
||||
|
||||
const bfd_target shcoff_vec =
|
||||
{
|
||||
"coff-sh", /* name */
|
||||
@ -169,10 +348,10 @@ const bfd_target shcoff_vec =
|
||||
'/', /* ar_pad_char */
|
||||
15, /* ar_max_namelen */
|
||||
2, /* minimum section alignment */
|
||||
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
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_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
|
||||
bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
|
||||
|
||||
@ -195,3 +374,4 @@ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
|
||||
|
||||
COFF_SWAP_TABLE,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user