Handle R_X86_64_64 properly for x32
[deliverable/binutils-gdb.git] / bfd / elf32-lm32.c
index 6184f49fcdab76f4d13262a1d8788f317780ebd6..b18f08f459f8ae8700b0ae86410e24b36cc9007e 100644 (file)
@@ -1,5 +1,5 @@
 /* Lattice Mico32-specific support for 32-bit ELF
-   Copyright 2008, 2009  Free Software Foundation, Inc.
+   Copyright 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
    Contributed by Jon Beniston <jon@beniston.com>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -102,7 +102,8 @@ struct elf_lm32_link_hash_table
 /* Get the lm32 ELF linker hash table from a link_info structure.  */
 
 #define lm32_elf_hash_table(p) \
-  ((struct elf_lm32_link_hash_table *) ((p)->hash))
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+  == LM32_ELF_DATA ? ((struct elf_lm32_link_hash_table *) ((p)->hash)) : NULL)
 
 #define lm32fdpic_got_section(info) \
   (lm32_elf_hash_table (info)->sgot)
@@ -164,7 +165,8 @@ lm32_elf_link_hash_table_create (bfd *abfd)
 
   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
                                      lm32_elf_link_hash_newfunc,
-                                     sizeof (struct elf_lm32_link_hash_entry)))
+                                     sizeof (struct elf_lm32_link_hash_entry),
+                                     LM32_ELF_DATA))
     {
       free (ret);
       return NULL;
@@ -219,10 +221,13 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
   if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
     return TRUE;
 
+  htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   if (! _bfd_elf_create_got_section (dynobj, info))
     return FALSE;
 
-  htab = lm32_elf_hash_table (info);
   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
   htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
   htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
@@ -241,7 +246,10 @@ create_rofixup_section (bfd *dynobj, struct bfd_link_info *info)
   struct elf_lm32_link_hash_table *htab;
   htab = lm32_elf_hash_table (info);
 
-  /* Fixup section for R_LM32_32 relocs */
+  if (htab == NULL)
+    return FALSE;
+
+  /* Fixup section for R_LM32_32 relocs.  */
   lm32fdpic_fixup32_section (info) = bfd_make_section_with_flags (dynobj,
                                                                    ".rofixup",
                                                                   (SEC_ALLOC
@@ -818,18 +826,18 @@ lm32_elf_relocate_section (bfd *output_bfd,
   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
   Elf_Internal_Rela *rel, *relend;
-
   struct elf_lm32_link_hash_table *htab = lm32_elf_hash_table (info);
   bfd *dynobj;
   bfd_vma *local_got_offsets;
-  asection *sgot, *splt, *sreloc;
+  asection *sgot;
+
+  if (htab == NULL)
+    return FALSE;
 
   dynobj = htab->root.dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
   sgot = htab->sgot;
-  splt = htab->splt;
-  sreloc = NULL;
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -848,7 +856,6 @@ lm32_elf_relocate_section (bfd *output_bfd,
       bfd_vma gp;
       bfd_reloc_status_type r;
       const char *name = NULL;
-      asection *osec;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -867,7 +874,7 @@ lm32_elf_relocate_section (bfd *output_bfd,
         {
           /* It's a local symbol.  */
           sym = local_syms + r_symndx;
-          osec = sec = local_sections[r_symndx];
+          sec = local_sections[r_symndx];
           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
           name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
@@ -883,20 +890,12 @@ lm32_elf_relocate_section (bfd *output_bfd,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
                                   unresolved_reloc, warned);
-         osec = sec;
          name = h->root.root.string;
         }
 
-      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 (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
         {
@@ -1281,14 +1280,10 @@ lm32_elf_check_relocs (bfd *abfd,
   const Elf_Internal_Rela *rel_end;
   struct elf_lm32_link_hash_table *htab;
   bfd *dynobj;
-  bfd_vma *local_got_offsets;
-  asection *sgot, *srelgot, *sreloc;
 
   if (info->relocatable)
     return TRUE;
 
-  sgot = srelgot = sreloc = NULL;
-
   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);
@@ -1296,8 +1291,10 @@ lm32_elf_check_relocs (bfd *abfd,
     sym_hashes_end -= symtab_hdr->sh_info;
 
   htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   dynobj = htab->root.dynobj;
-  local_got_offsets = elf_local_got_offsets (abfd);
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -1424,6 +1421,9 @@ lm32_elf_finish_dynamic_sections (bfd *output_bfd,
   asection *sgot;
 
   htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   dynobj = htab->root.dynobj;
 
   sgot = htab->sgotplt;
@@ -1442,7 +1442,6 @@ lm32_elf_finish_dynamic_sections (bfd *output_bfd,
       for (; dyncon < dynconend; dyncon++)
         {
           Elf_Internal_Dyn dyn;
-          const char *name;
           asection *s;
 
           bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
@@ -1453,11 +1452,9 @@ lm32_elf_finish_dynamic_sections (bfd *output_bfd,
               break;
 
             case DT_PLTGOT:
-              name = ".got";
               s = htab->sgot->output_section;
               goto get_vma;
             case DT_JMPREL:
-              name = ".rela.plt";
               s = htab->srelplt->output_section;
             get_vma:
               BFD_ASSERT (s != NULL);
@@ -1599,11 +1596,11 @@ lm32_elf_finish_dynamic_symbol (bfd *output_bfd,
                                Elf_Internal_Sym *sym)
 {
   struct elf_lm32_link_hash_table *htab;
-  bfd *dynobj;
   bfd_byte *loc;
 
   htab = lm32_elf_hash_table (info);
-  dynobj = htab->root.dynobj;
+  if (htab == NULL)
+    return FALSE;
 
   if (h->plt.offset != (bfd_vma) -1)
     {
@@ -1866,13 +1863,6 @@ lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
-  if (h->size == 0)
-    {
-      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
-                            h->root.root.string);
-      return TRUE;
-    }
-
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
      an entry for this symbol in the .dynsym section.  The dynamic
@@ -1884,6 +1874,9 @@ lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      same memory location for the variable.  */
 
   htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   s = htab->sdynbss;
   BFD_ASSERT (s != NULL);
 
@@ -1891,7 +1884,7 @@ lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
       asection *srel;
 
@@ -1918,14 +1911,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
-  if (h->root.type == bfd_link_hash_warning)
-    /* When warning symbols are created, they **replace** the "real"
-       entry in the hash table, thus we never get to see the real
-       symbol in a hash traversal.  So look at it now.  */
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   info = (struct bfd_link_info *) inf;
   htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   eh = (struct elf_lm32_link_hash_entry *) h;
 
@@ -2108,9 +2097,6 @@ readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   struct elf_lm32_link_hash_entry *eh;
   struct elf_lm32_dyn_relocs *p;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   eh = (struct elf_lm32_link_hash_entry *) h;
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
@@ -2142,6 +2128,9 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
   bfd *ibfd;
 
   htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   dynobj = htab->root.dynobj;
   BFD_ASSERT (dynobj != NULL);
 
@@ -2376,7 +2365,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
                           /* Don't generate entries for weak symbols.  */
                           if (!h || (h && h->root.type != bfd_link_hash_undefweak))
                             {
-                              if (!elf_discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0))
+                              if (!discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0))
                                 {
                                   switch (ELF32_R_TYPE (internal_relocs->r_info))
                                     {
@@ -2398,7 +2387,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
                                   if (!strcmp (current->name, h->root.root.string))
                                     break;
                                 }
-                              if (!current && !elf_discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC))
+                              if (!current && !discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC))
                                 {
                                   /* Will this have an entry in the GOT.  */
                                   if (ELF32_R_TYPE (internal_relocs->r_info) == R_LM32_16_GOT)
@@ -2469,6 +2458,8 @@ lm32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   int ptralign = 2; /* 32bit */
 
   htab = lm32_elf_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   /* Make sure we have a GOT - For the case where we have a dynamic object
      but none of the relocs in check_relocs */
@@ -2839,6 +2830,7 @@ lm32_elf_fdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 
 
 #define ELF_ARCH                bfd_arch_lm32
+#define ELF_TARGET_ID          LM32_ELF_DATA
 #define ELF_MACHINE_CODE        EM_LATTICEMICO32
 #define ELF_MAXPAGESIZE         0x1000
 
This page took 0.027721 seconds and 4 git commands to generate.