ChangeLog:
[deliverable/binutils-gdb.git] / bfd / elf-m10200.c
index 025e3ad92af6bbf9a761cab23f53b94375d538c0..099722e134757aa32bac2bc823c038c2c1769420 100644 (file)
@@ -1,53 +1,50 @@
 /* Matsushita 10200 specific support for 32-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
    Free Software Foundation, Inc.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
 static void mn10200_info_to_howto
-  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
-static boolean mn10200_elf_relax_delete_bytes
+  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static bfd_boolean mn10200_elf_relax_delete_bytes
   PARAMS ((bfd *, asection *, bfd_vma, int));
-static boolean mn10200_elf_symbol_address_p
+static bfd_boolean mn10200_elf_symbol_address_p
   PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
 static bfd_reloc_status_type mn10200_elf_final_link_relocate
   PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
           bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
           struct bfd_link_info *, asection *, int));
-static boolean mn10200_elf_relocate_section
-PARAMS (( bfd *, struct bfd_link_info *, bfd *, asection *,
-         bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
-         asection **));
-static boolean mn10200_elf_relax_section
-  PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+static bfd_boolean mn10200_elf_relocate_section
+  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
+          bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
+          asection **));
+static bfd_boolean mn10200_elf_relax_section
+  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
 static bfd_byte * mn10200_elf_get_relocated_section_contents
   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
-          bfd_byte *, boolean, asymbol **));
-
-/* We have to use RELA instructions since md_apply_fix3 in the assembler
-   does absolutely nothing.  */
-#define USE_RELA
+          bfd_byte *, bfd_boolean, asymbol **));
 
 enum reloc_type {
   R_MN10200_NONE = 0,
@@ -67,114 +64,114 @@ static reloc_howto_type elf_mn10200_howto_table[] = {
         0,
         2,
         16,
-        false,
+        FALSE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_NONE",
-        false,
+        FALSE,
         0,
         0,
-        false),
+        FALSE),
   /* Standard 32 bit reloc.  */
   HOWTO (R_MN10200_32,
         0,
         2,
         32,
-        false,
+        FALSE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_32",
-        false,
+        FALSE,
         0xffffffff,
         0xffffffff,
-        false),
+        FALSE),
   /* Standard 16 bit reloc.  */
   HOWTO (R_MN10200_16,
         0,
         1,
         16,
-        false,
+        FALSE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_16",
-        false,
+        FALSE,
         0xffff,
         0xffff,
-        false),
+        FALSE),
   /* Standard 8 bit reloc.  */
   HOWTO (R_MN10200_8,
         0,
         0,
         8,
-        false,
+        FALSE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_8",
-        false,
+        FALSE,
         0xff,
         0xff,
-        false),
+        FALSE),
   /* Standard 24 bit reloc.  */
   HOWTO (R_MN10200_24,
         0,
         2,
         24,
-        false,
+        FALSE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_24",
-        false,
+        FALSE,
         0xffffff,
         0xffffff,
-        false),
+        FALSE),
   /* Simple 8 pc-relative reloc.  */
   HOWTO (R_MN10200_PCREL8,
         0,
         0,
         8,
-        true,
+        TRUE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_PCREL8",
-        false,
+        FALSE,
         0xff,
         0xff,
-        true),
+        TRUE),
   /* Simple 16 pc-relative reloc.  */
   HOWTO (R_MN10200_PCREL16,
         0,
         1,
         16,
-        true,
+        TRUE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_PCREL16",
-        false,
+        FALSE,
         0xffff,
         0xffff,
-        true),
+        TRUE),
   /* Simple 32bit pc-relative reloc with a 1 byte adjustment
      to get the pc-relative offset correct.  */
   HOWTO (R_MN10200_PCREL24,
         0,
         2,
         24,
-        true,
+        TRUE,
         0,
         complain_overflow_bitfield,
         bfd_elf_generic_reloc,
         "R_MN10200_PCREL24",
-        false,
+        FALSE,
         0xffffff,
         0xffffff,
-        true),
+        TRUE),
 };
 
 struct mn10200_reloc_map {
@@ -211,13 +208,30 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
   return NULL;
 }
 
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < (sizeof (elf_mn10200_howto_table)
+           / sizeof (elf_mn10200_howto_table[0]));
+       i++)
+    if (elf_mn10200_howto_table[i].name != NULL
+       && strcasecmp (elf_mn10200_howto_table[i].name, r_name) == 0)
+      return &elf_mn10200_howto_table[i];
+
+  return NULL;
+}
+
 /* Set the howto pointer for an MN10200 ELF reloc.  */
 
 static void
 mn10200_info_to_howto (abfd, cache_ptr, dst)
      bfd *abfd ATTRIBUTE_UNUSED;
      arelent *cache_ptr;
-     Elf32_Internal_Rela *dst;
+     Elf_Internal_Rela *dst;
 {
   unsigned int r_type;
 
@@ -331,7 +345,7 @@ mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
 }
 \f
 /* Relocate an MN10200 ELF section.  */
-static boolean
+static bfd_boolean
 mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                              contents, relocs, local_syms, local_sections)
      bfd *output_bfd;
@@ -347,9 +361,6 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocateable)
-    return true;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -377,34 +388,32 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        {
          sym = local_syms + r_symndx;
          sec = local_sections[r_symndx];
-         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
        }
       else
        {
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-         if (h->root.type == bfd_link_hash_defined
-             || h->root.type == bfd_link_hash_defweak)
-           {
-             sec = h->root.u.def.section;
-             relocation = (h->root.u.def.value
-                           + sec->output_section->vma
-                           + sec->output_offset);
-           }
-         else if (h->root.type == bfd_link_hash_undefweak)
-           relocation = 0;
-         else
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset, true)))
-               return false;
-             relocation = 0;
-           }
+         bfd_boolean unresolved_reloc, warned;
+
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned);
+       }
+
+      if (sec != NULL && elf_discarded_section (sec))
+       {
+         /* For relocs against symbols from removed linkonce sections,
+            or sections discarded by a linker script, we just want the
+            section contents zeroed.  Avoid any special processing.  */
+         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+         rel->r_info = 0;
+         rel->r_addend = 0;
+         continue;
        }
 
+      if (info->relocatable)
+       continue;
+
       r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                           input_section,
                                           contents, rel->r_offset,
@@ -430,16 +439,17 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            {
            case bfd_reloc_overflow:
              if (! ((*info->callbacks->reloc_overflow)
-                    (info, name, howto->name, (bfd_vma) 0,
-                     input_bfd, input_section, rel->r_offset)))
-               return false;
+                    (info, (h ? &h->root : NULL), name, howto->name,
+                     (bfd_vma) 0, input_bfd, input_section,
+                     rel->r_offset)))
+               return FALSE;
              break;
 
            case bfd_reloc_undefined:
              if (! ((*info->callbacks->undefined_symbol)
                     (info, name, input_bfd, input_section,
-                     rel->r_offset, true)))
-               return false;
+                     rel->r_offset, TRUE)))
+               return FALSE;
              break;
 
            case bfd_reloc_outofrange:
@@ -462,18 +472,18 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              if (!((*info->callbacks->warning)
                    (info, msg, name, input_bfd, input_section,
                     rel->r_offset)))
-               return false;
+               return FALSE;
              break;
            }
        }
     }
 
-  return true;
+  return TRUE;
 }
 
 /* This function handles relaxing for the mn10200.
 
-   There's quite a few relaxing opportunites available on the mn10200:
+   There are quite a few relaxing opportunities available on the mn10200:
 
        * jsr:24 -> jsr:16                                         2 bytes
 
@@ -500,12 +510,12 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        We don't handle imm16->imm8 or d16->d8 as they're very rare
        and somewhat more difficult to support.  */
 
-static boolean
+static bfd_boolean
 mn10200_elf_relax_section (abfd, sec, link_info, again)
      bfd *abfd;
      asection *sec;
      struct bfd_link_info *link_info;
-     boolean *again;
+     bfd_boolean *again;
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *internal_relocs;
@@ -514,26 +524,21 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
   Elf_Internal_Sym *isymbuf = NULL;
 
   /* Assume nothing changes.  */
-  *again = false;
+  *again = FALSE;
 
-  /* We don't have to do anything for a relocateable link, if
+  /* We don't have to do anything for a relocatable link, if
      this section does not have relocs, or if this is not a
      code section.  */
-  if (link_info->relocateable
+  if (link_info->relocatable
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
-    return true;
-
-  /* If this is the first time we have been called for this section,
-     initialize the cooked size.  */
-  if (sec->_cooked_size == 0)
-    sec->_cooked_size = sec->_raw_size;
+    return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
   /* Get a copy of the native relocations.  */
-  internal_relocs = (_bfd_elf32_link_read_relocs
+  internal_relocs = (_bfd_elf_link_read_relocs
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
                      link_info->keep_memory));
   if (internal_relocs == NULL)
@@ -561,12 +566,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
          else
            {
              /* Go get them off disk.  */
-             contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
-             if (contents == NULL)
-               goto error_return;
-
-             if (! bfd_get_section_contents (abfd, sec, contents,
-                                             (file_ptr) 0, sec->_raw_size))
+             if (!bfd_malloc_and_get_section (abfd, sec, &contents))
                goto error_return;
            }
        }
@@ -683,7 +683,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
              /* That will change things, so, we should relax again.
                 Note that this is not required, and it may be slow.  */
-             *again = true;
+             *again = TRUE;
            }
        }
 
@@ -730,7 +730,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
              /* That will change things, so, we should relax again.
                 Note that this is not required, and it may be slow.  */
-             *again = true;
+             *again = TRUE;
            }
        }
 
@@ -757,7 +757,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
          value += irel->r_addend;
 
          /* Do nothing if this reloc is the last byte in the section.  */
-         if (irel->r_offset == sec->_cooked_size)
+         if (irel->r_offset == sec->size)
            continue;
 
          /* See if the next instruction is an unconditional pc-relative
@@ -883,7 +883,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
          /* That will change things, so, we should relax again.
             Note that this is not required, and it may be slow.  */
-         *again = true;
+         *again = TRUE;
        }
 
       /* Try to turn a 24bit immediate, displacement or absolute address
@@ -922,7 +922,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
                  if (value & 0x8000)
                    continue;
 
-                 /* Note that we've changed the reldection contents, etc.  */
+                 /* Note that we've changed the relocation contents, etc.  */
                  elf_section_data (sec)->relocs = internal_relocs;
                  elf_section_data (sec)->this_hdr.contents = contents;
                  symtab_hdr->contents = (unsigned char *) isymbuf;
@@ -946,7 +946,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
                  /* That will change things, so, we should relax again.
                     Note that this is not required, and it may be slow.  */
-                 *again = true;
+                 *again = TRUE;
                  break;
 
                /* mov imm24,an -> mov imm16,an
@@ -961,7 +961,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
                case 0x40:
                case 0x44:
                case 0xc8:
-                 /* Note that we've changed the reldection contents, etc.  */
+                 /* Note that we've changed the relocation contents, etc.  */
                  elf_section_data (sec)->relocs = internal_relocs;
                  elf_section_data (sec)->this_hdr.contents = contents;
                  symtab_hdr->contents = (unsigned char *) isymbuf;
@@ -997,7 +997,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
                  /* That will change things, so, we should relax again.
                     Note that this is not required, and it may be slow.  */
-                 *again = true;
+                 *again = TRUE;
                  break;
 
                /* cmp imm24,dn -> cmp imm16,dn
@@ -1044,7 +1044,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
                      && (value & 0x8000) != 0)
                    continue;
 
-                 /* Note that we've changed the reldection contents, etc.  */
+                 /* Note that we've changed the relocation contents, etc.  */
                  elf_section_data (sec)->relocs = internal_relocs;
                  elf_section_data (sec)->this_hdr.contents = contents;
                  symtab_hdr->contents = (unsigned char *) isymbuf;
@@ -1098,7 +1098,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
                  /* That will change things, so, we should relax again.
                     Note that this is not required, and it may be slow.  */
-                 *again = true;
+                 *again = TRUE;
                  break;
 
                /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
@@ -1129,7 +1129,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
 
                  /* That will change things, so, we should relax again.
                     Note that this is not required, and it may be slow.  */
-                 *again = true;
+                 *again = TRUE;
                  break;
                }
            }
@@ -1164,7 +1164,7 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
       && elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
-  return true;
+  return TRUE;
 
  error_return:
   if (isymbuf != NULL
@@ -1177,12 +1177,12 @@ mn10200_elf_relax_section (abfd, sec, link_info, again)
       && elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
-  return false;
+  return FALSE;
 }
 
 /* Delete some bytes from a section while relaxing.  */
 
-static boolean
+static bfd_boolean
 mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
      bfd *abfd;
      asection *sec;
@@ -1209,7 +1209,7 @@ mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
      power larger than the number of bytes we are deleting.  */
 
   irelalign = NULL;
-  toaddr = sec->_cooked_size;
+  toaddr = sec->size;
 
   irel = elf_section_data (sec)->relocs;
   irelend = irel + sec->reloc_count;
@@ -1217,7 +1217,7 @@ mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
   /* Actually delete the bytes.  */
   memmove (contents + addr, contents + addr + count,
           (size_t) (toaddr - addr - count));
-  sec->_cooked_size -= count;
+  sec->size -= count;
 
   /* Adjust all the relocs.  */
   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
@@ -1257,12 +1257,12 @@ mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
        }
     }
 
-  return true;
+  return TRUE;
 }
 
-/* Return true if a symbol exists at the given address, else return
-   false.  */
-static boolean
+/* Return TRUE if a symbol exists at the given address, else return
+   FALSE.  */
+static bfd_boolean
 mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
      bfd *abfd;
      asection *sec;
@@ -1284,7 +1284,7 @@ mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
     {
       if (isym->st_shndx == sec_shndx
          && isym->st_value == addr)
-       return true;
+       return TRUE;
     }
 
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
@@ -1298,10 +1298,10 @@ mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec
          && sym_hash->root.u.def.value == addr)
-       return true;
+       return TRUE;
     }
 
-  return false;
+  return FALSE;
 }
 
 /* This is a version of bfd_generic_get_relocated_section_contents
@@ -1309,12 +1309,12 @@ mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
 
 static bfd_byte *
 mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
-                                           data, relocateable, symbols)
+                                           data, relocatable, symbols)
      bfd *output_bfd;
      struct bfd_link_info *link_info;
      struct bfd_link_order *link_order;
      bfd_byte *data;
-     boolean relocateable;
+     bfd_boolean relocatable;
      asymbol **symbols;
 {
   Elf_Internal_Shdr *symtab_hdr;
@@ -1326,17 +1326,17 @@ mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
 
   /* We only need to handle the case of relaxing, or of having a
      particular set of section contents, specially.  */
-  if (relocateable
+  if (relocatable
       || elf_section_data (input_section)->this_hdr.contents == NULL)
     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
                                                       link_order, data,
-                                                      relocateable,
+                                                      relocatable,
                                                       symbols);
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
-         (size_t) input_section->_raw_size);
+         (size_t) input_section->size);
 
   if ((input_section->flags & SEC_RELOC) != 0
       && input_section->reloc_count > 0)
@@ -1346,9 +1346,9 @@ mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
       asection **secpp;
       bfd_size_type amt;
 
-      internal_relocs = (_bfd_elf32_link_read_relocs
+      internal_relocs = (_bfd_elf_link_read_relocs
                         (input_bfd, input_section, (PTR) NULL,
-                         (Elf_Internal_Rela *) NULL, false));
+                         (Elf_Internal_Rela *) NULL, FALSE));
       if (internal_relocs == NULL)
        goto error_return;
 
This page took 0.044003 seconds and 4 git commands to generate.