From 6387d6028b60ff3c825d17674bddf83d12b30261 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 16 Jul 1999 19:09:22 +0000 Subject: * elf32-mips.c (mips_elf_local_relocation_p): New static function. (mips_elf_next_lo16_addend): Call bfd_set_error on failure. (mips_elf_calculate_relocation): Use mips_elf_local_relocation_p. Always set *require_jalxp. (mips_elf_stub_section_p): Mark abfd parameter as unused. (_bfd_mips_elf_relocate_section): Only look for LO16 following GOT16 if the GOT16 is against a local symbol. Don't return false for an undefined symbol. If there is an overflow, assert that we have a name. --- bfd/ChangeLog | 13 ++++++++++ bfd/elf32-mips.c | 76 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a4314d8..5f5dcad 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +1999-07-16 Ian Lance Taylor + + * elf32-mips.c (mips_elf_local_relocation_p): New static + function. + (mips_elf_next_lo16_addend): Call bfd_set_error on failure. + (mips_elf_calculate_relocation): Use mips_elf_local_relocation_p. + Always set *require_jalxp. + (mips_elf_stub_section_p): Mark abfd parameter as unused. + (_bfd_mips_elf_relocate_section): Only look for LO16 following + GOT16 if the GOT16 is against a local symbol. Don't return false + for an undefined symbol. If there is an overflow, assert that we + have a name. + 1999-07-16 Andreas Schwab * elflink.h (elf_link_record_local_dynamic_symbol): Remove unused diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 0d61c02..a9d3acf 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -184,6 +184,8 @@ static boolean mips_elf_sort_hash_table static asection * mips_elf_got_section PARAMS ((bfd *)); static struct mips_got_info *mips_elf_got_info PARAMS ((bfd *, asection **)); +static boolean mips_elf_local_relocation_p + PARAMS ((bfd *, const Elf_Internal_Rela *, asection **)); static bfd_vma mips_elf_create_local_got_entry PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma)); static bfd_vma mips_elf_got16_entry @@ -5150,6 +5152,29 @@ mips_elf_got_info (abfd, sgotp) return g; } +/* Return whether a relocation is against a local symbol. */ + +static boolean +mips_elf_local_relocation_p (input_bfd, relocation, local_sections) + bfd *input_bfd; + const Elf_Internal_Rela *relocation; + asection **local_sections; +{ + unsigned long r_symndx; + Elf_Internal_Shdr *symtab_hdr; + + r_symndx = ELF32_R_SYM (relocation->r_info); + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + if (! elf_bad_symtab (input_bfd)) + return r_symndx < symtab_hdr->sh_info; + else + { + /* The symbol table does not follow the rule that local symbols + must come before globals. */ + return local_sections[r_symndx] != NULL; + } +} + /* Sign-extend VALUE, which has the indicated number of BITS. */ static bfd_vma @@ -5554,6 +5579,7 @@ mips_elf_next_lo16_addend (relocation, relend, addendp) } /* We didn't find it. */ + bfd_set_error (bfd_error_bad_value); return false; } @@ -5754,19 +5780,18 @@ mips_elf_calculate_relocation (abfd, /* Assume that there will be no overflow. */ overflowed_p = false; - /* Figure out whether or not the symbol is local. */ + /* Figure out whether or not the symbol is local, and get the offset + used in the array of hash table entries. */ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (elf_bad_symtab (input_bfd)) + local_p = mips_elf_local_relocation_p (input_bfd, relocation, + local_sections); + if (! elf_bad_symtab (input_bfd)) + extsymoff = symtab_hdr->sh_info; + else { /* The symbol table does not follow the rule that local symbols must come before globals. */ extsymoff = 0; - local_p = local_sections[r_symndx] != NULL; - } - else - { - extsymoff = symtab_hdr->sh_info; - local_p = r_symndx < extsymoff; } /* Figure out the value of the symbol. */ @@ -5905,9 +5930,8 @@ mips_elf_calculate_relocation (abfd, /* Calls from 16-bit code to 32-bit code and vice versa require the special jalx instruction. */ - if (!info->relocateable - && ((r_type == R_MIPS16_26) != target_is_16_bit_code_p)) - *require_jalxp = true; + *require_jalxp = (!info->relocateable + && ((r_type == R_MIPS16_26) != target_is_16_bit_code_p)); /* If we haven't already determined the GOT offset, or the GP value, and we're going to need it, get it now. */ @@ -6381,7 +6405,7 @@ mips_elf_perform_relocation (info, howto, relocation, value, static boolean mips_elf_stub_section_p (abfd, section) - bfd *abfd; + bfd *abfd ATTRIBUTE_UNUSED; asection *section; { const char *name = bfd_get_section_name (abfd, section); @@ -6463,7 +6487,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* For some kinds of relocations, the ADDEND is a combination of the addend stored in two different relocations. */ - if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16) + if (r_type == R_MIPS_HI16 + || (r_type == R_MIPS_GOT16 + && mips_elf_local_relocation_p (input_bfd, rel, + local_sections))) { /* Scan ahead to find a matching R_MIPS_LO16 relocation. */ @@ -6486,7 +6513,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, { /* Used the saved HI16 addend. */ if (!last_hi16_addend_valid_p) - return false; + { + bfd_set_error (bfd_error_bad_value); + return false; + } addend |= last_hi16_addend; } else if (r_type == R_MIPS16_GPREL) @@ -6533,7 +6563,9 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; case bfd_reloc_undefined: - return false; + /* mips_elf_calculate_relocation already called the + undefined_symbol callback. */ + break; case bfd_reloc_notsupported: abort (); @@ -6544,12 +6576,14 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* Ignore overflow until we reach the last relocation for a given location. */ ; - else if (!name - || ! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - + else + { + BFD_ASSERT (name != NULL); + if (! ((*info->callbacks->reloc_overflow) + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset))) + return false; + } break; case bfd_reloc_ok: -- cgit v1.1