Fix powerpc comment typo
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index a5d819386ae7be8ecd505836dde9ded7de8260fe..eb8ba62557bcdf85c783311f894d30eeb7a9f4cb 100644 (file)
@@ -1656,6 +1656,21 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         0x3e007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  /* e_li split20 format.  */
+  HOWTO (R_PPC_VLE_ADDR20,     /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        20,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_PPC_VLE_ADDR20",    /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x1f07ff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   HOWTO (R_PPC_IRELATIVE,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -3345,6 +3360,9 @@ struct ppc_elf_link_hash_table
   unsigned int local_ifunc_resolver:1;
   unsigned int maybe_local_ifunc_resolver:1;
 
+  /* Set if tls optimization is enabled.  */
+  unsigned int do_tls_opt:1;
+
   /* The size of PLT entries.  */
   int plt_entry_size;
   /* The distance between adjacent PLT slots.  */
@@ -4265,6 +4283,7 @@ ppc_elf_check_relocs (bfd *abfd,
        case R_PPC_VLE_HI16D:
        case R_PPC_VLE_HA16A:
        case R_PPC_VLE_HA16D:
+       case R_PPC_VLE_ADDR20:
          break;
 
        case R_PPC_EMB_SDA2REL:
@@ -4983,6 +5002,23 @@ ppc_elf_vle_split16 (bfd *input_bfd,
   insn |= value & 0x7ff;
   bfd_put_32 (input_bfd, insn, loc);
 }
+
+static void
+ppc_elf_vle_split20 (bfd *output_bfd, bfd_byte *loc, bfd_vma value)
+{
+  unsigned int insn;
+
+  insn = bfd_get_32 (output_bfd, loc);
+  /* We have an li20 field, bits 17..20, 11..15, 21..31.  */
+  /* Top 4 bits of value to 17..20.  */
+  insn |= (value & 0xf0000) >> 5;
+  /* Next 5 bits of the value to 11..15.  */
+  insn |= (value & 0xf800) << 5;
+  /* And the final 11 bits of the value to bits 21 to 31.  */
+  insn |= value & 0x7ff;
+  bfd_put_32 (output_bfd, insn, loc);
+}
+
 \f
 /* Choose which PLT scheme to use, and set .plt flags appropriately.
    Returns -1 on error, 0 for old PLT, 1 for new PLT.  */
@@ -5631,6 +5667,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
              symtab_hdr->contents = (unsigned char *) locsyms;
          }
       }
+  htab->do_tls_opt = 1;
   return TRUE;
 }
 \f
@@ -7914,7 +7951,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
          wrel->r_addend = 0;
 
          /* For ld -r, remove relocations in debug sections against
-            sections defined in discarded sections.  Not done for
+            symbols defined in discarded sections.  Not done for
             non-debug to preserve relocs in .eh_frame which the
             eh_frame editing code expects to be present.  */
          if (bfd_link_relocatable (info)
@@ -8426,10 +8463,44 @@ ppc_elf_relocate_section (bfd *output_bfd,
        }
 
       addend = rel->r_addend;
-      tls_type = 0;
       howto = NULL;
       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 & ((0x3f << 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)
        {
        default:
@@ -9474,6 +9545,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
          }
          goto copy_reloc;
 
+       case R_PPC_VLE_ADDR20:
+         ppc_elf_vle_split20 (output_bfd, contents + rel->r_offset, relocation);
+         continue;
+
          /* Relocate against the beginning of the section.  */
        case R_PPC_SECTOFF:
        case R_PPC_SECTOFF_LO:
This page took 0.0258890000000001 seconds and 4 git commands to generate.