* cofflink.c (coff_link_input_bfd): If r_symndx is -1, don't
change it. (_bfd_coff_generic_relocate_section): If r_symndx is -1, it is an absolute reloc. Don't dump core using r_symndx as an array index. * cf-m68klynx.c (coff_bfd_link_add_symbols): Define. (lynx_link_add_symbols): New static function (copy of function in coff-i386.c). (coff_m68k_lynxrtype_to_howto): sym argument may be NULL. * coff-i386.c (coff_i386_rtype_to_howto): Likewise. * coff-a29k.c (coff_a29k_relocate_section): Handle an r_symndx value of -1, meaning an absolute reloc.
This commit is contained in:
parent
3cd942de1e
commit
2a89559527
|
@ -1,5 +1,17 @@
|
|||
Mon Sep 12 11:43:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||
|
||||
* cofflink.c (coff_link_input_bfd): If r_symndx is -1, don't
|
||||
change it.
|
||||
(_bfd_coff_generic_relocate_section): If r_symndx is -1, it is an
|
||||
absolute reloc. Don't dump core using r_symndx as an array index.
|
||||
* cf-m68klynx.c (coff_bfd_link_add_symbols): Define.
|
||||
(lynx_link_add_symbols): New static function (copy of function in
|
||||
coff-i386.c).
|
||||
(coff_m68k_lynxrtype_to_howto): sym argument may be NULL.
|
||||
* coff-i386.c (coff_i386_rtype_to_howto): Likewise.
|
||||
* coff-a29k.c (coff_a29k_relocate_section): Handle an r_symndx
|
||||
value of -1, meaning an absolute reloc.
|
||||
|
||||
* ctor.c: Remove; obsolete.
|
||||
* Makefile.in: Rebuild dependencies.
|
||||
(BFD_LIBS): Remove ctor.o.
|
||||
|
|
|
@ -43,6 +43,7 @@ struct internal_syment;
|
|||
|
||||
static bfd_reloc_status_type _bfd_m68klynx_special_fn
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
static boolean lynx_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static const struct reloc_howto_struct *coff_m68k_lynx_rtype_to_howto
|
||||
PARAMS ((bfd *, asection *, struct internal_reloc *,
|
||||
struct coff_link_hash_entry *, struct internal_syment *,
|
||||
|
@ -175,14 +176,44 @@ _bfd_m68klynx_special_fn (abfd, reloc_entry, symbol, data, input_section,
|
|||
cache_ptr->addend += asect->vma; \
|
||||
}
|
||||
|
||||
#define coff_bfd_link_add_symbols lynx_link_add_symbols
|
||||
#define coff_rtype_to_howto coff_m68k_lynx_rtype_to_howto
|
||||
|
||||
#include "coff-m68k.c"
|
||||
|
||||
/* On Lynx, we may have a COFF archive which contains a.out elements.
|
||||
This screws up the COFF linker, which expects that any archive it
|
||||
gets contains COFF elements. We override the add_symbols function
|
||||
to check for this case. */
|
||||
|
||||
static boolean
|
||||
lynx_link_add_symbols (abfd, info)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
if (bfd_get_format (abfd) == bfd_archive)
|
||||
{
|
||||
bfd *first;
|
||||
|
||||
first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
|
||||
if (first == NULL)
|
||||
return false;
|
||||
if (! bfd_check_format (first, bfd_object))
|
||||
return false;
|
||||
if (bfd_get_flavour (first) != bfd_target_coff_flavour)
|
||||
{
|
||||
/* Treat the archive as though it were actually of the
|
||||
flavour of its first element. This ought to work,
|
||||
since the archive support is fairly generic. */
|
||||
return (*first->xvec->_bfd_link_add_symbols) (abfd, info);
|
||||
}
|
||||
}
|
||||
|
||||
return _bfd_coff_link_add_symbols (abfd, info);
|
||||
}
|
||||
|
||||
/* coff-m68k.c uses the special COFF backend linker. We need to
|
||||
adjust common symbols. FIXME: We may able to get rid of
|
||||
CALC_ADDEND and _bfd_m68klynx_special_fn. However, they may still
|
||||
be used by gas.
|
||||
adjust common symbols.
|
||||
|
||||
We can't define this function until after we have included
|
||||
coff-m68k.c, because it uses RTYPE2HOWTO. */
|
||||
|
@ -204,7 +235,7 @@ coff_m68k_lynx_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
|
|||
|
||||
howto = relent.howto;
|
||||
|
||||
if (sym->n_scnum == 0 && sym->n_value != 0)
|
||||
if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
|
||||
{
|
||||
/* This is a common symbol. The section contents include the
|
||||
size (sym->n_value) as an addend. The relocate_section
|
||||
|
|
|
@ -353,7 +353,10 @@ coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
symndx = rel->r_symndx;
|
||||
loc = contents + rel->r_vaddr - input_section->vma;
|
||||
|
||||
h = obj_coff_sym_hashes (input_bfd)[symndx];
|
||||
if (symndx == -1)
|
||||
h = NULL;
|
||||
else
|
||||
h = obj_coff_sym_hashes (input_bfd)[symndx];
|
||||
|
||||
sym = NULL;
|
||||
sec = NULL;
|
||||
|
@ -366,12 +369,17 @@ coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
{
|
||||
if (h == NULL)
|
||||
{
|
||||
sym = syms + symndx;
|
||||
sec = sections[symndx];
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->n_value
|
||||
- sec->vma);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -497,7 +505,9 @@ coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
|
||||
if (h != NULL)
|
||||
if (symndx == -1)
|
||||
name = "*ABS*";
|
||||
else if (h != NULL)
|
||||
name = h->root.root.string;
|
||||
else if (sym == NULL)
|
||||
name = "*unknown*";
|
||||
|
|
162
bfd/cofflink.c
162
bfd/cofflink.c
|
@ -695,15 +695,17 @@ _bfd_coff_final_link (abfd, info)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
/* We use section_count + 1, rather than section_count, because
|
||||
the target_index fields are 1 based. */
|
||||
finfo.section_info = ((struct coff_link_section_info *)
|
||||
malloc (abfd->section_count
|
||||
malloc ((abfd->section_count + 1)
|
||||
* sizeof (struct coff_link_section_info)));
|
||||
if (finfo.section_info == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
goto error_return;
|
||||
}
|
||||
for (i = 0; i < abfd->section_count; i++)
|
||||
for (i = 0; i <= abfd->section_count; i++)
|
||||
{
|
||||
finfo.section_info[i].relocs = NULL;
|
||||
finfo.section_info[i].rel_hashes = NULL;
|
||||
|
@ -1122,7 +1124,16 @@ coff_link_input_bfd (finfo, input_bfd)
|
|||
the symbol. */
|
||||
isym = *isymp;
|
||||
|
||||
*secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
|
||||
if (isym.n_scnum != 0)
|
||||
*secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
|
||||
else
|
||||
{
|
||||
if (isym.n_value == 0)
|
||||
*secpp = bfd_und_section_ptr;
|
||||
else
|
||||
*secpp = bfd_com_section_ptr;
|
||||
}
|
||||
|
||||
*indexp = -1;
|
||||
|
||||
skip = false;
|
||||
|
@ -1647,7 +1658,8 @@ coff_link_input_bfd (finfo, input_bfd)
|
|||
|
||||
irel = internal_relocs;
|
||||
irelend = irel + o->reloc_count;
|
||||
rel_hash = finfo->section_info[target_index].rel_hashes;
|
||||
rel_hash = (finfo->section_info[target_index].rel_hashes
|
||||
+ o->output_section->reloc_count);
|
||||
for (; irel < irelend; irel++, rel_hash++)
|
||||
{
|
||||
struct coff_link_hash_entry *h;
|
||||
|
@ -1658,6 +1670,9 @@ coff_link_input_bfd (finfo, input_bfd)
|
|||
|
||||
irel->r_vaddr += offset;
|
||||
|
||||
if (irel->r_symndx == -1)
|
||||
continue;
|
||||
|
||||
h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx];
|
||||
if (h != NULL)
|
||||
{
|
||||
|
@ -2004,3 +2019,142 @@ coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* A basic reloc handling routine which may be used by processors with
|
||||
simple relocs. */
|
||||
|
||||
boolean
|
||||
_bfd_coff_generic_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;
|
||||
|
||||
rel = relocs;
|
||||
relend = rel + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
long symndx;
|
||||
struct coff_link_hash_entry *h;
|
||||
struct internal_syment *sym;
|
||||
bfd_vma addend;
|
||||
bfd_vma val;
|
||||
const reloc_howto_type *howto;
|
||||
bfd_reloc_status_type rstat;
|
||||
|
||||
symndx = rel->r_symndx;
|
||||
|
||||
if (symndx == -1)
|
||||
{
|
||||
h = NULL;
|
||||
sym = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = obj_coff_sym_hashes (input_bfd)[symndx];
|
||||
sym = syms + symndx;
|
||||
}
|
||||
|
||||
/* COFF treats common symbols in one of two ways. Either the
|
||||
size of the symbol is included in the section contents, or it
|
||||
is not. We assume that the size is not included, and force
|
||||
the rtype_to_howto function to adjust the addend as needed. */
|
||||
if (sym != NULL && sym->n_scnum != 0)
|
||||
addend = - sym->n_value;
|
||||
else
|
||||
addend = 0;
|
||||
|
||||
howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
|
||||
sym, &addend);
|
||||
if (howto == NULL)
|
||||
return false;
|
||||
|
||||
val = 0;
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
asection *sec;
|
||||
|
||||
if (symndx == -1)
|
||||
{
|
||||
sec = bfd_abs_section_ptr;
|
||||
val = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sec = sections[symndx];
|
||||
val = (sec->output_section->vma
|
||||
+ sec->output_offset
|
||||
+ sym->n_value
|
||||
- sec->vma);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h->root.type == bfd_link_hash_defined)
|
||||
{
|
||||
asection *sec;
|
||||
|
||||
sec = h->root.u.def.section;
|
||||
val = (h->root.u.def.value
|
||||
+ sec->output_section->vma
|
||||
+ sec->output_offset);
|
||||
}
|
||||
else if (! info->relocateable)
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
(info, h->root.root.string, input_bfd, input_section,
|
||||
rel->r_vaddr - input_section->vma)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents,
|
||||
rel->r_vaddr - input_section->vma,
|
||||
val, addend);
|
||||
|
||||
switch (rstat)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
case bfd_reloc_ok:
|
||||
break;
|
||||
case bfd_reloc_overflow:
|
||||
{
|
||||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
|
||||
if (symndx == -1)
|
||||
name = "*ABS*";
|
||||
else if (h != NULL)
|
||||
name = h->root.root.string;
|
||||
else if (sym->_n._n_n._n_zeroes == 0
|
||||
&& sym->_n._n_n._n_offset != 0)
|
||||
name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
|
||||
else
|
||||
{
|
||||
strncpy (buf, sym->_n._n_name, SYMNMLEN);
|
||||
buf[SYMNMLEN] = '\0';
|
||||
name = buf;
|
||||
}
|
||||
|
||||
if (! ((*info->callbacks->reloc_overflow)
|
||||
(info, name, howto->name, (bfd_vma) 0, input_bfd,
|
||||
input_section, rel->r_vaddr - input_section->vma)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue