* elf32-mips.c (mips_elf_local_relocation_p): New static
authorIan Lance Taylor <ian@airs.com>
Fri, 16 Jul 1999 19:09:22 +0000 (19:09 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 16 Jul 1999 19:09:22 +0000 (19:09 +0000)
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
bfd/elf32-mips.c

index a4314d84208b01b3a694d01c001d1cd2e63e23aa..5f5dcad421432c110ccaef3b94153c11727be880 100644 (file)
@@ -1,3 +1,16 @@
+1999-07-16  Ian Lance Taylor  <ian@zembu.com>
+
+       * 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  <schwab@suse.de>
 
        * elflink.h (elf_link_record_local_dynamic_symbol): Remove unused
index 0d61c02628cfdf64f31d2eae32bdb2c4c8d64bf4..a9d3acf6e70bf21a69431b368a9ba3479d4019fc 100644 (file)
@@ -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: