ppc64 constify
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index 89c069b3c51f4a1c1f46978ff9af4f5f9e59e4c4..66265ef6009ef69d2450449ea1b9ac861baa58b7 100644 (file)
@@ -2212,9 +2212,6 @@ struct ppc_elf_link_hash_table
   int plt_slot_size;
   /* The size of the first PLT entry.  */
   int plt_initial_entry_size;
-
-  /* Small local sym cache.  */
-  struct sym_cache sym_cache;
 };
 
 /* Rename some of the generic section flags to better document how they
@@ -2233,8 +2230,9 @@ struct ppc_elf_link_hash_table
 /* Get the PPC ELF linker hash table from a link_info structure.  */
 
 #define ppc_elf_hash_table(p) \
-  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
-  == PPC32_ELF_DATA ? ((struct ppc_elf_link_hash_table *) ((p)->hash)) : NULL)
+  ((is_elf_hash_table ((p)->hash)                                      \
+    && elf_hash_table_id (elf_hash_table (p)) == PPC32_ELF_DATA)       \
+   ? (struct ppc_elf_link_hash_table *) (p)->hash : NULL)
 
 /* Create an entry in a PPC ELF linker hash table.  */
 
@@ -2632,7 +2630,7 @@ ppc_elf_add_symbol_hook (bfd *abfd,
       htab = ppc_elf_hash_table (info);
       if (htab->sbss == NULL)
        {
-         flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
+         flagword flags = SEC_IS_COMMON | SEC_SMALL_DATA | SEC_LINKER_CREATED;
 
          if (!htab->elf.dynobj)
            htab->elf.dynobj = abfd;
@@ -2952,7 +2950,7 @@ ppc_elf_check_relocs (bfd *abfd,
       ifunc = NULL;
       if (h == NULL && htab->elf.target_os != is_vxworks)
        {
-         Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+         Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
                                                          abfd, r_symndx);
          if (isym == NULL)
            return FALSE;
@@ -3304,12 +3302,14 @@ ppc_elf_check_relocs (bfd *abfd,
            return FALSE;
          break;
 
+       case R_PPC_TPREL16_HI:
+       case R_PPC_TPREL16_HA:
+         sec->has_tls_reloc = 1;
+         /* Fall through.  */
          /* We shouldn't really be seeing TPREL32.  */
        case R_PPC_TPREL32:
        case R_PPC_TPREL16:
        case R_PPC_TPREL16_LO:
-       case R_PPC_TPREL16_HI:
-       case R_PPC_TPREL16_HA:
          if (bfd_link_dll (info))
            info->flags |= DF_STATIC_TLS;
          goto dodyn;
@@ -3335,7 +3335,7 @@ ppc_elf_check_relocs (bfd *abfd,
              asection *s;
              Elf_Internal_Sym *isym;
 
-             isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+             isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
                                            abfd, r_symndx);
              if (isym == NULL)
                return FALSE;
@@ -3495,7 +3495,7 @@ ppc_elf_check_relocs (bfd *abfd,
                  void *vpp;
                  Elf_Internal_Sym *isym;
 
-                 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+                 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
                                                abfd, r_symndx);
                  if (isym == NULL)
                    return FALSE;
@@ -4419,6 +4419,8 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
   if (htab == NULL)
     return FALSE;
 
+  htab->do_tls_opt = 1;
+
   /* Make two passes through the relocs.  First time check that tls
      relocs involved in setting up a tls_get_addr call are indeed
      followed by such a call.  If they are not, don't do any tls
@@ -4584,6 +4586,37 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
                      tls_clear = 0;
                      break;
 
+                   case R_PPC_TPREL16_HA:
+                     if (pass == 0)
+                       {
+                         unsigned char buf[4];
+                         unsigned int insn;
+                         bfd_vma off = rel->r_offset & ~3;
+                         if (!bfd_get_section_contents (ibfd, sec, buf,
+                                                        off, 4))
+                           {
+                             if (elf_section_data (sec)->relocs != relstart)
+                               free (relstart);
+                             return FALSE;
+                           }
+                         insn = bfd_get_32 (ibfd, buf);
+                         /* addis rt,2,imm */
+                         if ((insn & ((0x3fu << 26) | 0x1f << 16))
+                             != ((15u << 26) | (2 << 16)))
+                           {
+                             /* xgettext:c-format */
+                             info->callbacks->minfo
+                               (_("%H: warning: %s unexpected insn %#x.\n"),
+                                ibfd, sec, off, "R_PPC_TPREL16_HA", insn);
+                             htab->do_tls_opt = 0;
+                           }
+                       }
+                     continue;
+
+                   case R_PPC_TPREL16_HI:
+                     htab->do_tls_opt = 0;
+                     continue;
+
                    default:
                      continue;
                    }
@@ -4678,7 +4711,6 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
                free (relstart);
            }
       }
-  htab->do_tls_opt = 1;
   return TRUE;
 }
 \f
@@ -5822,20 +5854,9 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-      if (bfd_link_executable (info))
-       {
-         if (!add_dynamic_entry (DT_DEBUG, 0))
-           return FALSE;
-       }
-
-      if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
-       {
-         if (!add_dynamic_entry (DT_PLTGOT, 0)
-             || !add_dynamic_entry (DT_PLTRELSZ, 0)
-             || !add_dynamic_entry (DT_PLTREL, DT_RELA)
-             || !add_dynamic_entry (DT_JMPREL, 0))
-           return FALSE;
-       }
+      if (!_bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info,
+                                                   relocs))
+       return FALSE;
 
       if (htab->plt_type == PLT_NEW
          && htab->glink != NULL
@@ -5849,30 +5870,6 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
              && !add_dynamic_entry (DT_PPC_OPT, PPC_OPT_TLS))
            return FALSE;
        }
-
-      if (relocs)
-       {
-         if (!add_dynamic_entry (DT_RELA, 0)
-             || !add_dynamic_entry (DT_RELASZ, 0)
-             || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
-           return FALSE;
-       }
-
-      /* If any dynamic relocs apply to a read-only section, then we
-        need a DT_TEXTREL entry.  */
-      if ((info->flags & DF_TEXTREL) == 0)
-       elf_link_hash_traverse (elf_hash_table (info),
-                               _bfd_elf_maybe_set_textrel,
-                               info);
-
-      if ((info->flags & DF_TEXTREL) != 0)
-       {
-         if (!add_dynamic_entry (DT_TEXTREL, 0))
-           return FALSE;
-       }
-      if (htab->elf.target_os == is_vxworks
-         && !elf_vxworks_add_dynamic_entries (output_bfd, info))
-       return FALSE;
    }
 #undef add_dynamic_entry
 
@@ -7590,39 +7587,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
       if (r_type < R_PPC_max)
        howto = ppc_elf_howto_table[r_type];
 
-      switch (r_type)
-       {
-       default:
-         break;
-
-       case R_PPC_TPREL16_HA:
-         if (htab->do_tls_opt && relocation + addend + 0x8000 < 0x10000)
-           {
-             bfd_byte *p = contents + (rel->r_offset & ~3);
-             unsigned int insn = bfd_get_32 (input_bfd, p);
-             if ((insn & ((0x3fu << 26) | 0x1f << 16))
-                 != ((15u << 26) | (2 << 16)) /* addis rt,2,imm */)
-               /* xgettext:c-format */
-               info->callbacks->minfo
-                 (_("%H: warning: %s unexpected insn %#x.\n"),
-                  input_bfd, input_section, rel->r_offset, howto->name, insn);
-             else
-               bfd_put_32 (input_bfd, NOP, p);
-           }
-         break;
-
-       case R_PPC_TPREL16_LO:
-         if (htab->do_tls_opt && relocation + addend + 0x8000 < 0x10000)
-           {
-             bfd_byte *p = contents + (rel->r_offset & ~3);
-             unsigned int insn = bfd_get_32 (input_bfd, p);
-             insn &= ~(0x1f << 16);
-             insn |= 2 << 16;
-             bfd_put_32 (input_bfd, insn, p);
-           }
-         break;
-       }
-
       tls_type = 0;
       switch (r_type)
        {
@@ -8787,6 +8751,31 @@ ppc_elf_relocate_section (bfd *output_bfd,
          goto copy_reloc;
        }
 
+      switch (r_type)
+       {
+       default:
+         break;
+
+       case R_PPC_TPREL16_HA:
+         if (htab->do_tls_opt && relocation + addend + 0x8000 < 0x10000)
+           {
+             bfd_byte *p = contents + (rel->r_offset & ~3);
+             bfd_put_32 (input_bfd, NOP, p);
+           }
+         break;
+
+       case R_PPC_TPREL16_LO:
+         if (htab->do_tls_opt && relocation + addend + 0x8000 < 0x10000)
+           {
+             bfd_byte *p = contents + (rel->r_offset & ~3);
+             unsigned int insn = bfd_get_32 (input_bfd, p);
+             insn &= ~(0x1f << 16);
+             insn |= 2 << 16;
+             bfd_put_32 (input_bfd, insn, p);
+           }
+         break;
+       }
+
       switch (r_type)
        {
        default:
This page took 0.027657 seconds and 4 git commands to generate.