mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-26 18:53:29 +08:00
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:
parent
e884f41802
commit
ac9ed09667
@ -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
|
||||
|
@ -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)
|
||||
|
25
bfd/ecoff.c
25
bfd/ecoff.c
@ -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,
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user