Fix extracting from AIX big archives.
[deliverable/binutils-gdb.git] / bfd / elf32-d10v.c
index 07f120ec8920a4775c727d3ab0b00f1ba3691474..cd0624477eb99663a8d853166017742ff23852bc 100644 (file)
@@ -1,5 +1,5 @@
 /* D10V-specific support for 32-bit ELF
-   Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
+   Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Martin Hunt (hunt@cygnus.com).
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -22,196 +22,193 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "sysdep.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
-/* #include "elf/d10v.h" */
+#include "elf/d10v.h"
 
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
 static void d10v_info_to_howto_rel
   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
-
-
-/* Use REL instead of RELA to save space */
+static asection * elf32_d10v_gc_mark_hook
+  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+          struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static boolean elf32_d10v_gc_sweep_hook
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          const Elf_Internal_Rela *));
+static boolean elf32_d10v_check_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          const Elf_Internal_Rela *));
+static boolean elf32_d10v_relocate_section
+  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
+          bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
+          asection **));
+
+/* Use REL instead of RELA to save space.  */
 #define USE_REL
 
-enum reloc_type
-{
-  R_D10V_NONE = 0,
-  R_D10V_10_PCREL_R,
-  R_D10V_10_PCREL_L,
-  R_D10V_16,
-  R_D10V_18,
-  R_D10V_18_PCREL,
-  R_D10V_32,
-  R_D10V_GNU_VTINHERIT,
-  R_D10V_GNU_VTENTRY,
-  R_D10V_max
-};
-
 static reloc_howto_type elf_d10v_howto_table[] =
-{
-  /* This reloc does nothing.  */
-  HOWTO (R_D10V_NONE,          /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        false,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_NONE",         /* name */
-        false,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        false),                /* pcrel_offset */
-
-  /* An PC Relative 10-bit relocation, shifted by 2  */
-  /* right container */
-  HOWTO (R_D10V_10_PCREL_R,    /* type */
-        2,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        10,                    /* bitsize */
-        true,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_10_PCREL_R",   /* name */
-        false,                 /* partial_inplace */
-        0xff,                  /* src_mask */
-        0xff,                  /* dst_mask */
-        true),                 /* pcrel_offset */
-
-  /* An PC Relative 10-bit relocation, shifted by 2  */
-  /* left container */
-  HOWTO (R_D10V_10_PCREL_L,    /* type */
-        2,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        10,                    /* bitsize */
-        true,                  /* pc_relative */
-        15,                    /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_10_PCREL_L",   /* name */
-        false,                 /* partial_inplace */
-        0x07f8000,                     /* src_mask */
-        0x07f8000,             /* dst_mask */
-        true),                 /* pcrel_offset */
-
-  /* A 16 bit absolute relocation */
-  HOWTO (R_D10V_16,            /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        false,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_16",           /* name */
-        false,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        false),                /* pcrel_offset */
-
-  /* An 18 bit absolute relocation, right shifted 2 */
-  HOWTO (R_D10V_18,            /* type */
-        2,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        18,                    /* bitsize */
-        false,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_18",           /* name */
-        false,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        false),                /* pcrel_offset */
-
-  /* A relative 18 bit relocation, right shifted by 2  */
-  HOWTO (R_D10V_18_PCREL,      /* type */
-        2,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        18,                    /* bitsize */
-        true,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_18_PCREL",     /* name */
-        false,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        true),                 /* pcrel_offset */
-
-  /* A 32 bit absolute relocation */
-  HOWTO (R_D10V_32,            /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        false,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_D10V_32",           /* name */
-        false,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
-        0xffffffff,            /* dst_mask */
-        false),                /* pcrel_offset */
-
-  /* GNU extension to record C++ vtable hierarchy */
-  HOWTO (R_D10V_GNU_VTINHERIT, /* type */
-         0,                     /* rightshift */
-         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-         0,                     /* bitsize */
-         false,                 /* pc_relative */
-         0,                     /* bitpos */
-         complain_overflow_dont, /* complain_on_overflow */
-         NULL,                  /* special_function */
-         "R_D10V_GNU_VTINHERIT", /* name */
-         false,                 /* partial_inplace */
-         0,                     /* src_mask */
-         0,                     /* dst_mask */
-         false),                /* pcrel_offset */
-
-  /* GNU extension to record C++ vtable member usage */
-  HOWTO (R_D10V_GNU_VTENTRY,     /* type */
-         0,                     /* rightshift */
-         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-         0,                     /* bitsize */
-         false,                 /* pc_relative */
-         0,                     /* bitpos */
-         complain_overflow_dont, /* complain_on_overflow */
-         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
-         "R_D10V_GNU_VTENTRY",   /* name */
-         false,                 /* partial_inplace */
-         0,                     /* src_mask */
-         0,                     /* dst_mask */
-         false),                /* pcrel_offset */
-};
+  {
+    /* This reloc does nothing.  */
+    HOWTO (R_D10V_NONE,                /* type */
+          0,                   /* rightshift */
+          2,                   /* size (0 = byte, 1 = short, 2 = long) */
+          32,                  /* bitsize */
+          false,               /* pc_relative */
+          0,                   /* bitpos */
+          complain_overflow_dont, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_NONE",       /* name */
+          false,               /* partial_inplace */
+          0,                   /* src_mask */
+          0,                   /* dst_mask */
+          false),              /* pcrel_offset */
+
+    /* An PC Relative 10-bit relocation, shifted by 2  */
+    /* right container */
+    HOWTO (R_D10V_10_PCREL_R,  /* type */
+          2,                   /* rightshift */
+          2,                   /* size (0 = byte, 1 = short, 2 = long) */
+          8,                   /* bitsize */
+          true,                /* pc_relative */
+          0,                   /* bitpos */
+          complain_overflow_signed, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_10_PCREL_R", /* name */
+          false,               /* partial_inplace */
+          0xff,                /* src_mask */
+          0xff,                /* dst_mask */
+          true),               /* pcrel_offset */
+
+    /* An PC Relative 10-bit relocation, shifted by 2  */
+    /* left container */
+    HOWTO (R_D10V_10_PCREL_L,  /* type */
+          2,                   /* rightshift */
+          2,                   /* size (0 = byte, 1 = short, 2 = long) */
+          8,                   /* bitsize */
+          true,                /* pc_relative */
+          15,                  /* bitpos */
+          complain_overflow_signed, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_10_PCREL_L", /* name */
+          false,               /* partial_inplace */
+          0x07f8000,           /* src_mask */
+          0x07f8000,           /* dst_mask */
+          true),               /* pcrel_offset */
+
+    /* A 16 bit absolute relocation */
+    HOWTO (R_D10V_16,          /* type */
+          0,                   /* rightshift */
+          1,                   /* size (0 = byte, 1 = short, 2 = long) */
+          16,                  /* bitsize */
+          false,               /* pc_relative */
+          0,                   /* bitpos */
+          complain_overflow_dont, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_16",         /* name */
+          false,               /* partial_inplace */
+          0xffff,              /* src_mask */
+          0xffff,              /* dst_mask */
+          false),              /* pcrel_offset */
+
+    /* An 18 bit absolute relocation, right shifted 2 */
+    HOWTO (R_D10V_18,          /* type */
+          2,                   /* rightshift */
+          1,                   /* size (0 = byte, 1 = short, 2 = long) */
+          16,                  /* bitsize */
+          false,               /* pc_relative */
+          0,                   /* bitpos */
+          complain_overflow_dont, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_18",         /* name */
+          false,               /* partial_inplace */
+          0xffff,              /* src_mask */
+          0xffff,              /* dst_mask */
+          false),              /* pcrel_offset */
+
+    /* A relative 18 bit relocation, right shifted by 2  */
+    HOWTO (R_D10V_18_PCREL,    /* type */
+          2,                   /* rightshift */
+          2,                   /* size (0 = byte, 1 = short, 2 = long) */
+          16,                  /* bitsize */
+          true,                /* pc_relative */
+          0,                   /* bitpos */
+          complain_overflow_signed, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_18_PCREL",   /* name */
+          false,               /* partial_inplace */
+          0xffff,              /* src_mask */
+          0xffff,              /* dst_mask */
+          true),                       /* pcrel_offset */
+
+    /* A 32 bit absolute relocation */
+    HOWTO (R_D10V_32,          /* type */
+          0,                   /* rightshift */
+          2,                   /* size (0 = byte, 1 = short, 2 = long) */
+          32,                  /* bitsize */
+          false,               /* pc_relative */
+          0,                   /* bitpos */
+          complain_overflow_dont, /* complain_on_overflow */
+          bfd_elf_generic_reloc, /* special_function */
+          "R_D10V_32",         /* name */
+          false,               /* partial_inplace */
+          0xffffffff,          /* src_mask */
+          0xffffffff,          /* dst_mask */
+          false),              /* pcrel_offset */
+
+    /* GNU extension to record C++ vtable hierarchy */
+    HOWTO (R_D10V_GNU_VTINHERIT, /* type */
+          0,                     /* rightshift */
+          2,                     /* size (0 = byte, 1 = short, 2 = long) */
+          0,                     /* bitsize */
+          false,                 /* pc_relative */
+          0,                     /* bitpos */
+          complain_overflow_dont, /* complain_on_overflow */
+          NULL,                  /* special_function */
+          "R_D10V_GNU_VTINHERIT", /* name */
+          false,                 /* partial_inplace */
+          0,                     /* src_mask */
+          0,                     /* dst_mask */
+          false),                /* pcrel_offset */
+
+    /* GNU extension to record C++ vtable member usage */
+    HOWTO (R_D10V_GNU_VTENTRY,     /* type */
+          0,                     /* rightshift */
+          2,                     /* size (0 = byte, 1 = short, 2 = long) */
+          0,                     /* bitsize */
+          false,                 /* pc_relative */
+          0,                     /* bitpos */
+          complain_overflow_dont, /* complain_on_overflow */
+          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
+          "R_D10V_GNU_VTENTRY",   /* name */
+          false,                 /* partial_inplace */
+          0,                     /* src_mask */
+          0,                     /* dst_mask */
+          false),                /* pcrel_offset */
+  };
 
 /* Map BFD reloc types to D10V ELF reloc types.  */
 
 struct d10v_reloc_map
-{
-  bfd_reloc_code_real_type bfd_reloc_val;
-  unsigned char elf_reloc_val;
-};
-
- static const struct d10v_reloc_map d10v_reloc_map[] =
-{
-  { BFD_RELOC_NONE, R_D10V_NONE, },
-  { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
-  { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
-  { BFD_RELOC_16, R_D10V_16 },
-  { BFD_RELOC_D10V_18, R_D10V_18 },
-  { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
-  { BFD_RELOC_32, R_D10V_32 },
-  { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
-  { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
-};
+  {
+    bfd_reloc_code_real_type bfd_reloc_val;
+    unsigned char elf_reloc_val;
+  };
+
+static const struct d10v_reloc_map d10v_reloc_map[] =
+  {
+    { BFD_RELOC_NONE, R_D10V_NONE, },
+    { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
+    { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
+    { BFD_RELOC_16, R_D10V_16 },
+    { BFD_RELOC_D10V_18, R_D10V_18 },
+    { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
+    { BFD_RELOC_32, R_D10V_32 },
+    { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
+    { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
+  };
 
 static reloc_howto_type *
 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      bfd_reloc_code_real_type code;
 {
   unsigned int i;
@@ -231,7 +228,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
 
 static void
 d10v_info_to_howto_rel (abfd, cache_ptr, dst)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      arelent *cache_ptr;
      Elf32_Internal_Rel *dst;
 {
@@ -245,7 +242,7 @@ d10v_info_to_howto_rel (abfd, cache_ptr, dst)
 static asection *
 elf32_d10v_gc_mark_hook (abfd, info, rel, h, sym)
        bfd *abfd;
-       struct bfd_link_info *info;
+       struct bfd_link_info *info ATTRIBUTE_UNUSED;
        Elf_Internal_Rela *rel;
        struct elf_link_hash_entry *h;
        Elf_Internal_Sym *sym;
@@ -275,23 +272,17 @@ elf32_d10v_gc_mark_hook (abfd, info, rel, h, sym)
      }
    else
      {
-       if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-                && sym->st_shndx != SHN_COMMON))
-          {
-            return bfd_section_from_elf_index (abfd, sym->st_shndx);
-          }
-      }
+       return bfd_section_from_elf_index (abfd, sym->st_shndx);
+     }
   return NULL;
 }
 
 static boolean
 elf32_d10v_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+     asection *sec ATTRIBUTE_UNUSED;
+     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
 {
   /* we don't use got and plt entries for d10v */
   return true;
@@ -300,7 +291,7 @@ elf32_d10v_gc_sweep_hook (abfd, info, sec, relocs)
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.  */
+
 static boolean
 elf32_d10v_check_relocs (abfd, info, sec, relocs)
      bfd *abfd;
@@ -312,28 +303,28 @@ elf32_d10v_check_relocs (abfd, info, sec, relocs)
   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
+
   if (info->relocateable)
     return true;
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
   if (!elf_bad_symtab (abfd))
     sym_hashes_end -= symtab_hdr->sh_info;
+
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
+
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
         h = NULL;
       else
         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
       switch (ELF32_R_TYPE (rel->r_info))
         {
         /* This relocation describes the C++ object vtable hierarchy.
@@ -342,7 +333,7 @@ elf32_d10v_check_relocs (abfd, info, sec, relocs)
           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
             return false;
           break;
+
         /* This relocation describes which C++ vtable entries are actually
            used.  Record for later use during GC.  */
         case R_D10V_GNU_VTENTRY:
@@ -351,7 +342,7 @@ elf32_d10v_check_relocs (abfd, info, sec, relocs)
           break;
         }
     }
+
   return true;
 }
 
@@ -425,9 +416,7 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
        {
          sym = local_syms + r_symndx;
          sec = local_sections[r_symndx];
-         relocation = (sec->output_section->vma
-                       + sec->output_offset
-                       + sym->st_value);
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
        }
       else
        {
@@ -449,7 +438,7 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
            {
              if (!((*info->callbacks->undefined_symbol)
                    (info, h->root.root.string, input_bfd,
-                    input_section, rel->r_offset)))
+                    input_section, rel->r_offset, true)))
                return false;
              relocation = 0;
            }
@@ -464,7 +453,7 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
          if (name == NULL || *name == '\0')
            name = bfd_section_name (input_bfd, sec);
        }
-      
+
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                     contents, rel->r_offset,
                                     relocation, rel->r_addend);
@@ -485,24 +474,24 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
            case bfd_reloc_undefined:
              if (!((*info->callbacks->undefined_symbol)
                    (info, name, input_bfd, input_section,
-                    rel->r_offset)))
+                    rel->r_offset, true)))
                return false;
              break;
 
            case bfd_reloc_outofrange:
-             msg = _ ("internal error: out of range error");
+             msg = _("internal error: out of range error");
              goto common_error;
 
            case bfd_reloc_notsupported:
-             msg = _ ("internal error: unsupported relocation error");
+             msg = _("internal error: unsupported relocation error");
              goto common_error;
 
            case bfd_reloc_dangerous:
-             msg = _ ("internal error: dangerous error");
+             msg = _("internal error: dangerous error");
              goto common_error;
 
            default:
-             msg = _ ("internal error: unknown error");
+             msg = _("internal error: unknown error");
              /* fall through */
 
            common_error:
@@ -518,7 +507,8 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
   return true;
 }
 #define ELF_ARCH               bfd_arch_d10v
-#define ELF_MACHINE_CODE       EM_CYGNUS_D10V
+#define ELF_MACHINE_CODE       EM_D10V
+#define ELF_MACHINE_ALT1       EM_CYGNUS_D10V
 #define ELF_MAXPAGESIZE                0x1000
 
 #define TARGET_BIG_SYM          bfd_elf32_d10v_vec
This page took 0.034781 seconds and 4 git commands to generate.