From ac9ed09667f63fe7bad504e039e50a84cc860d9c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 14 Jun 1994 17:06:08 +0000 Subject: 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. --- bfd/coff-mips.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'bfd/coff-mips.c') diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index 3ad2f0a..d013bc1 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -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) -- cgit v1.1