For PR 4865.

* libecoff.h (struct ecoff_link_hash_entry): Change type of
	written from boolean to char.  Add new field small.
	* ecoff.c (ecoff_link_hash_newfunc): Initialize written to 0
	rather than false.  Initialize small to 0.
	(ecoff_link_add_externals): If ECOFF type is scSUndefined, set
	small.  If small is set, and hash table type is common, force the
	symbol into a section named SCOMMON and change the ECOFF type from
	scCommon to scSCommon.
	(ecoff_link_write_external): Set written to 1 rather than true.
	* coff-mips.c (mips_relocate_section): Correct JMPADDR reloc
	overflow check to consider section VMA of input file.
This commit is contained in:
Ian Lance Taylor 1994-06-14 17:06:08 +00:00
parent e884f41802
commit ac9ed09667
4 changed files with 96 additions and 2 deletions

View file

@ -1,3 +1,17 @@
Tue Jun 14 13:00:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* libecoff.h (struct ecoff_link_hash_entry): Change type of
written from boolean to char. Add new field small.
* ecoff.c (ecoff_link_hash_newfunc): Initialize written to 0
rather than false. Initialize small to 0.
(ecoff_link_add_externals): If ECOFF type is scSUndefined, set
small. If small is set, and hash table type is common, force the
symbol into a section named SCOMMON and change the ECOFF type from
scCommon to scSCommon.
(ecoff_link_write_external): Set written to 1 rather than true.
* coff-mips.c (mips_relocate_section): Correct JMPADDR reloc
overflow check to consider section VMA of input file.
Mon Jun 13 14:20:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* aoutf1.h (aout_32_sunos4_write_object_contents): Handle a

View file

@ -1444,6 +1444,43 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
}
}
/* If we are relaxing, and this is a reloc against the .text
segment, we may need to adjust it if some branches have been
expanded. The reloc types which are likely to occur in the
.text section are handled efficiently by mips_relax_section,
and thus do not need to be handled here. */
if (ecoff_data (input_bfd)->debug_info.adjust != NULL
&& ! int_rel.r_extern
&& int_rel.r_symndx == RELOC_SECTION_TEXT
&& (strcmp (bfd_get_section_name (input_bfd, input_section),
".text") != 0
|| (int_rel.r_type != MIPS_R_PCREL16
&& int_rel.r_type != MIPS_R_SWITCH
&& int_rel.r_type != MIPS_R_RELHI
&& int_rel.r_type != MIPS_R_RELLO)))
{
bfd_vma adr;
struct ecoff_value_adjust *a;
/* We need to get the addend so that we know whether we need
to adjust the address. */
BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
adr = bfd_get_32 (input_bfd,
(contents
+ adjust
+ int_rel.r_vaddr
- input_section->vma));
for (a = ecoff_data (input_bfd)->debug_info.adjust;
a != (struct ecoff_value_adjust *) NULL;
a = a->next)
{
if (adr >= a->start && adr < a->end)
addend += a->adjust;
}
}
if (info->relocateable)
{
/* We are generating relocateable output, and must convert
@ -1587,6 +1624,7 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
}
relocation += addend;
addend = 0;
/* Adjust a PC relative relocation by removing the reference
to the original address in the section and including the
@ -1697,6 +1735,23 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
}
}
/* MIPS_R_JMPADDR requires peculiar overflow detection. The
instruction provides a 28 bit address (the two lower bits are
implicit zeroes) which is combined with the upper four bits
of the instruction address. */
if (r == bfd_reloc_ok
&& int_rel.r_type == MIPS_R_JMPADDR
&& (((relocation
+ addend
+ (int_rel.r_extern ? 0 : s->vma))
& 0xf0000000)
!= ((input_section->output_section->vma
+ input_section->output_offset
+ (int_rel.r_vaddr - input_section->vma)
+ adjust)
& 0xf0000000)))
r = bfd_reloc_overflow;
if (r != bfd_reloc_ok)
{
switch (r)

View file

@ -3575,6 +3575,8 @@ ecoff_link_hash_newfunc (entry, table, string)
/* Set local fields. */
ret->indx = -1;
ret->abfd = NULL;
ret->written = 0;
ret->small = 0;
}
memset ((PTR) &ret->esym, 0, sizeof ret->esym);
@ -4171,6 +4173,25 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext)
h->abfd = abfd;
h->esym = esym;
}
/* Remember whether this symbol was small undefined. */
if (esym.asym.sc == scSUndefined)
h->small = 1;
/* If this symbol was ever small undefined, it needs to wind
up in a GP relative section. We can't control the
section of a defined symbol, but we can control the
section of a common symbol. This case is actually needed
on Ultrix 4.2 to handle the symbol cred in -lckrb. */
if (h->small
&& h->root.type == bfd_link_hash_common
&& strcmp (h->root.u.c.section->name, SCOMMON) != 0)
{
h->root.u.c.section = bfd_make_section_old_way (abfd, SCOMMON);
h->root.u.c.section->flags = SEC_ALLOC;
if (h->esym.asym.sc == scCommon)
h->esym.asym.sc = scSCommon;
}
}
}
@ -4506,7 +4527,7 @@ ecoff_link_write_external (h, data)
/* FIXME: We should check if this symbol is being stripped. */
if (h->root.written)
if (h->written)
return true;
if (h->abfd == (bfd *) NULL)
@ -4607,7 +4628,7 @@ ecoff_link_write_external (h, data)
/* bfd_ecoff_debug_one_external uses iextMax to keep track of the
symbol number. */
h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax;
h->root.written = true;
h->written = 1;
return (bfd_ecoff_debug_one_external
(output_bfd, &ecoff_data (output_bfd)->debug_info,

View file

@ -206,6 +206,10 @@ struct ecoff_link_hash_entry
bfd *abfd;
/* ECOFF external symbol information. */
EXTR esym;
/* Nonzero if this symbol has been written out. */
char written;
/* Nonzero if this symbol was referred to as small undefined. */
char small;
};
/* ECOFF linker hash table. */