PowerPC VLE
[deliverable/binutils-gdb.git] / gas / config / tc-ppc.c
index 838f5223311301ff1ff53da69dd1098c1045efd2..fc2a0458288d5228ad0598cd3e6ae7b8e1826293 100644 (file)
@@ -1,7 +1,5 @@
 /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1994-2016 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of GAS, the GNU Assembler.
@@ -131,7 +129,6 @@ static void ppc_vbyte (int);
 #endif
 
 #ifdef OBJ_ELF
-static void ppc_elf_cons (int);
 static void ppc_elf_rdata (int);
 static void ppc_elf_lcomm (int);
 static void ppc_elf_localentry (int);
@@ -209,11 +206,19 @@ ppc_cpu_t sticky = 0;
 /* Value for ELF e_flags EF_PPC64_ABI.  */
 unsigned int ppc_abiversion = 0;
 
+#ifdef OBJ_ELF
 /* Flags set on encountering toc relocs.  */
-enum {
+static enum {
   has_large_toc_reloc = 1,
   has_small_toc_reloc = 2
 } toc_reloc_types;
+#endif
+
+/* Warn on emitting data to code sections.  */
+int warn_476;
+unsigned long last_insn;
+segT last_seg;
+subsegT last_subseg;
 \f
 /* The target specific pseudo-ops which we support.  */
 
@@ -259,11 +264,7 @@ const pseudo_typeS md_pseudo_table[] =
 #endif
 
 #ifdef OBJ_ELF
-  { "llong",   ppc_elf_cons,   8 },
-  { "quad",    ppc_elf_cons,   8 },
-  { "long",    ppc_elf_cons,   4 },
-  { "word",    ppc_elf_cons,   2 },
-  { "short",   ppc_elf_cons,   2 },
+  { "llong",   cons,           8 },
   { "rdata",   ppc_elf_rdata,  0 },
   { "rodata",  ppc_elf_rdata,  0 },
   { "lcomm",   ppc_elf_lcomm,  0 },
@@ -303,7 +304,7 @@ const pseudo_typeS md_pseudo_table[] =
 /* Structure to hold information about predefined registers.  */
 struct pd_reg
   {
-    char *name;
+    const char *name;
     int value;
   };
 
@@ -861,7 +862,7 @@ register_name (expressionS *expressionP)
   else if (!reg_names_p || !ISALPHA (name[0]))
     return FALSE;
 
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
 
   /* Put back the delimiting char.  */
@@ -1047,18 +1048,6 @@ static segT ppc_current_section;
 
 #ifdef OBJ_ELF
 symbolS *GOT_symbol;           /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
-#define PPC_APUINFO_ISEL       0x40
-#define PPC_APUINFO_PMR                0x41
-#define PPC_APUINFO_RFMCI      0x42
-#define PPC_APUINFO_CACHELCK   0x43
-#define PPC_APUINFO_SPE                0x100
-#define PPC_APUINFO_EFS                0x101
-#define PPC_APUINFO_BRLOCK     0x102
-#define PPC_APUINFO_VLE                0x104
-
-/*
- * We keep a list of APUinfo
- */
 unsigned long *ppc_apuinfo_list;
 unsigned int ppc_apuinfo_num;
 unsigned int ppc_apuinfo_num_alloc;
@@ -1072,12 +1061,14 @@ const char *const md_shortopts = "um:";
 #define OPTION_NOPS (OPTION_MD_BASE + 0)
 const struct option md_longopts[] = {
   {"nops", required_argument, NULL, OPTION_NOPS},
+  {"ppc476-workaround", no_argument, &warn_476, 1},
+  {"no-ppc476-workaround", no_argument, &warn_476, 0},
   {NULL, no_argument, NULL, 0}
 };
 const size_t md_longopts_size = sizeof (md_longopts);
 
 int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
 {
   ppc_cpu_t new_cpu;
 
@@ -1250,6 +1241,9 @@ md_parse_option (int c, char *arg)
       }
       break;
 
+    case 0:
+      break;
+
     default:
       return 0;
     }
@@ -1277,7 +1271,8 @@ PowerPC options:\n\
 -m476                   generate code for PowerPC 476\n\
 -m7400, -m7410, -m7450, -m7455\n\
                         generate code for PowerPC 7400/7410/7450/7455\n\
--m750cl                 generate code for PowerPC 750cl\n"));
+-m750cl                 generate code for PowerPC 750cl\n\
+-m821, -m850, -m860     generate code for PowerPC 821/850/860\n"));
   fprintf (stream, _("\
 -mppc64, -m620          generate code for PowerPC 620/625/630\n\
 -mppc64bridge           generate code for PowerPC 64, including bridge insns\n\
@@ -1289,6 +1284,7 @@ PowerPC options:\n\
 -mpower6, -mpwr6        generate code for Power6 architecture\n\
 -mpower7, -mpwr7        generate code for Power7 architecture\n\
 -mpower8, -mpwr8        generate code for Power8 architecture\n\
+-mpower9, -mpwr9        generate code for Power9 architecture\n\
 -mcell                  generate code for Cell Broadband Engine architecture\n\
 -mcom                   generate code Power/PowerPC common instructions\n\
 -many                   generate code for any architecture (PWR/PWRX/PPC)\n"));
@@ -1323,7 +1319,8 @@ PowerPC options:\n\
 -Qy, -Qn                ignored\n"));
 #endif
   fprintf (stream, _("\
--nops=count             when aligning, more than COUNT nops uses a branch\n"));
+-nops=count             when aligning, more than COUNT nops uses a branch\n\
+-ppc476-workaround      warn if emitting data to code sections\n"));
 }
 \f
 /* Set ppc_cpu if it is not already set.  */
@@ -1395,7 +1392,7 @@ ppc_mach (void)
     return bfd_mach_ppc;
 }
 
-extern char*
+extern const char*
 ppc_target_format (void)
 {
 #ifdef OBJ_COFF
@@ -1451,7 +1448,7 @@ insn_validate (const struct powerpc_opcode *op)
       else
         {
          const struct powerpc_operand *operand = &powerpc_operands[*o];
-         if (operand->shift != PPC_OPSHIFT_INV)
+         if (operand->shift != (int) PPC_OPSHIFT_INV)
            {
              unsigned long mask;
 
@@ -1554,6 +1551,18 @@ ppc_setup_opcodes (void)
                  bad_insn = TRUE;
                }
            }
+         if ((op->flags & PPC_OPCODE_VLE) != 0)
+           {
+             as_bad (_("%s is enabled by vle flag"), op->name);
+             bad_insn = TRUE;
+           }
+         if (PPC_OP (op->opcode) != 4
+             && PPC_OP (op->opcode) != 31
+             && (op->deprecated & PPC_OPCODE_VLE) == 0)
+           {
+             as_bad (_("%s not disabled by vle flag"), op->name);
+             bad_insn = TRUE;
+           }
          bad_insn |= insn_validate (op);
        }
 
@@ -1625,10 +1634,6 @@ ppc_setup_opcodes (void)
        }
     }
 
-  if ((ppc_cpu & PPC_OPCODE_VLE) != 0)
-    for (op = vle_opcodes; op < op_end; op++)
-      hash_insert (ppc_hash, op->name, (void *) op);
-
   /* Insert the macros into a hash table.  */
   ppc_macro_hash = hash_new ();
 
@@ -1727,7 +1732,7 @@ ppc_cleanup (void)
     unsigned int i;
 
     /* Create the .PPC.EMB.apuinfo section.  */
-    apuinfo_secp = subseg_new (".PPC.EMB.apuinfo", 0);
+    apuinfo_secp = subseg_new (APUINFO_SECTION_NAME, 0);
     bfd_set_section_flags (stdoutput,
                           apuinfo_secp,
                           SEC_HAS_CONTENTS | SEC_READONLY);
@@ -1742,7 +1747,7 @@ ppc_cleanup (void)
     md_number_to_chars (p, (valueT) 2, 4);
 
     p = frag_more (8);
-    strcpy (p, "APUinfo");
+    strcpy (p, APUINFO_LABEL);
 
     for (i = 0; i < ppc_apuinfo_num; i++)
       {
@@ -1767,7 +1772,7 @@ ppc_insert_operand (unsigned long insn,
                    const struct powerpc_operand *operand,
                    offsetT val,
                    ppc_cpu_t cpu,
-                   char *file,
+                   const char *file,
                    unsigned int line)
 {
   long min, max, right;
@@ -1776,10 +1781,21 @@ ppc_insert_operand (unsigned long insn,
   right = max & -max;
   min = 0;
 
-  if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+  if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0)
     {
-      if ((operand->flags & PPC_OPERAND_SIGNOPT) == 0)
-       max = (max >> 1) & -right;
+      /* Extend the allowed range for addis to [-32768, 65535].
+        Similarly for cmpli and some VLE high part insns.  For 64-bit
+        it would be good to disable this for signed fields since the
+        value is sign extended into the high 32 bits of the register.
+        If the value is, say, an address, then we might care about
+        the high bits.  However, gcc as of 2014-06 uses unsigned
+        values when loading the high part of 64-bit constants using
+        lis.  */
+      min = ~(max >> 1) & -right;
+    }
+  else if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+    {
+      max = (max >> 1) & -right;
       min = ~max & -right;
     }
 
@@ -1844,7 +1860,7 @@ static bfd_reloc_code_real_type
 ppc_elf_suffix (char **str_p, expressionS *exp_p)
 {
   struct map_bfd {
-    char *string;
+    const char *string;
     unsigned int length : 8;
     unsigned int valid32 : 1;
     unsigned int valid64 : 1;
@@ -1959,11 +1975,11 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
     MAP64 ("tprel@highera",    BFD_RELOC_PPC64_TPREL16_HIGHERA),
     MAP64 ("tprel@highest",    BFD_RELOC_PPC64_TPREL16_HIGHEST),
     MAP64 ("tprel@highesta",   BFD_RELOC_PPC64_TPREL16_HIGHESTA),
-    { (char *) 0, 0, 0, 0,     BFD_RELOC_UNUSED }
+    { (char *) 0, 0, 0, 0,     BFD_RELOC_NONE }
   };
 
   if (*str++ != '@')
-    return BFD_RELOC_UNUSED;
+    return BFD_RELOC_NONE;
 
   for (ch = *str, str2 = ident;
        (str2 < ident + sizeof (ident) - 1
@@ -2049,63 +2065,49 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
        return (bfd_reloc_code_real_type) reloc;
       }
 
-  return BFD_RELOC_UNUSED;
+  return BFD_RELOC_NONE;
 }
 
-/* Like normal .long/.short/.word, except support @got, etc.
-   Clobbers input_line_pointer, checks end-of-line.  */
-static void
-ppc_elf_cons (int nbytes /* 1=.byte, 2=.word, 4=.long, 8=.llong */)
-{
-  expressionS exp;
-  bfd_reloc_code_real_type reloc;
-
-  if (is_it_end_of_statement ())
-    {
-      demand_empty_rest_of_line ();
-      return;
-    }
+/* Support @got, etc. on constants emitted via .short, .int etc.  */
 
-  do
-    {
-      expression (&exp);
-      if (*input_line_pointer == '@'
-         && (reloc = ppc_elf_suffix (&input_line_pointer,
-                                     &exp)) != BFD_RELOC_UNUSED)
-       {
-         reloc_howto_type *reloc_howto;
-         int size;
+bfd_reloc_code_real_type
+ppc_elf_parse_cons (expressionS *exp, unsigned int nbytes)
+{
+  expression (exp);
+  if (nbytes >= 2 && *input_line_pointer == '@')
+    return ppc_elf_suffix (&input_line_pointer, exp);
+  return BFD_RELOC_NONE;
+}
 
-         reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
-         size = bfd_get_reloc_size (reloc_howto);
+/* Warn when emitting data to code sections, unless we are emitting
+   a relocation that ld --ppc476-workaround uses to recognise data
+   *and* there was an unconditional branch prior to the data.  */
 
-         if (size > nbytes)
-           {
-             as_bad (_("%s relocations do not fit in %d bytes\n"),
-                     reloc_howto->name, nbytes);
-           }
-         else
-           {
-             char *p;
-             int offset;
-
-             p = frag_more (nbytes);
-             memset (p, 0, nbytes);
-             offset = 0;
-             if (target_big_endian)
-               offset = nbytes - size;
-             fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
-                          &exp, 0, reloc);
-           }
-       }
-      else
-       emit_expr (&exp, (unsigned int) nbytes);
+void
+ppc_elf_cons_fix_check (expressionS *exp ATTRIBUTE_UNUSED,
+                       unsigned int nbytes, fixS *fix)
+{
+  if (warn_476
+      && (now_seg->flags & SEC_CODE) != 0
+      && (nbytes != 4
+         || fix == NULL
+         || !(fix->fx_r_type == BFD_RELOC_32
+              || fix->fx_r_type == BFD_RELOC_CTOR
+              || fix->fx_r_type == BFD_RELOC_32_PCREL)
+         || !(last_seg == now_seg && last_subseg == now_subseg)
+         || !((last_insn & (0x3f << 26)) == (18u << 26)
+              || ((last_insn & (0x3f << 26)) == (16u << 26)
+                  && (last_insn & (0x14 << 21)) == (0x14 << 21))
+              || ((last_insn & (0x3f << 26)) == (19u << 26)
+                  && (last_insn & (0x3ff << 1)) == (16u << 1)
+                  && (last_insn & (0x14 << 21)) == (0x14 << 21)))))
+    {
+      /* Flag that we've warned.  */
+      if (fix != NULL)
+       fix->fx_tcbit = 1;
+
+      as_warn (_("data in executable section"));
     }
-  while (*input_line_pointer++ == ',');
-
-  /* Put terminator back into stream.  */
-  input_line_pointer--;
-  demand_empty_rest_of_line ();
 }
 
 /* Solaris pseduo op to change to the .rodata section.  */
@@ -2137,13 +2139,12 @@ ppc_elf_lcomm (int xxx ATTRIBUTE_UNUSED)
   char *pfrag;
   int align2;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
 
-  /* just after name is now '\0'.  */
+  /* Just after name is now '\0'.  */
   p = input_line_pointer;
   *p = c;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   if (*input_line_pointer != ',')
     {
       as_bad (_("expected comma after symbol-name: rest of line ignored."));
@@ -2233,8 +2234,8 @@ ppc_elf_lcomm (int xxx ATTRIBUTE_UNUSED)
 static void
 ppc_elf_localentry (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name = input_line_pointer;
-  char c = get_symbol_end ();
+  char *name;
+  char c = get_symbol_name (&name);
   char *p;
   expressionS exp;
   symbolS *sym;
@@ -2243,7 +2244,7 @@ ppc_elf_localentry (int ignore ATTRIBUTE_UNUSED)
 
   p = input_line_pointer;
   *p = c;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   if (*input_line_pointer != ',')
     {
       *p = 0;
@@ -2340,8 +2341,7 @@ ppc_elf_validate_fix (fixS *fixp, segT seg)
       return;
 
     case SHLIB_MRELOCATABLE:
-      if (fixp->fx_r_type <= BFD_RELOC_UNUSED
-         && fixp->fx_r_type != BFD_RELOC_16_GOTOFF
+      if (fixp->fx_r_type != BFD_RELOC_16_GOTOFF
          && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF
          && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF
          && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
@@ -2386,7 +2386,6 @@ ppc_frob_file_before_adjust (void)
       const char *name;
       char *dotname;
       symbolS *dotsym;
-      size_t len;
 
       name = S_GET_NAME (symp);
       if (name[0] == '.')
@@ -2396,10 +2395,7 @@ ppc_frob_file_before_adjust (void)
          || S_IS_DEFINED (symp))
        continue;
 
-      len = strlen (name) + 1;
-      dotname = xmalloc (len + 1);
-      dotname[0] = '.';
-      memcpy (dotname + 1, name, len);
+      dotname = concat (".", name, (char *) NULL);
       dotsym = symbol_find_noref (dotname, 1);
       free (dotname);
       if (dotsym != NULL && (symbol_used_p (dotsym)
@@ -2487,8 +2483,7 @@ parse_toc_entry (enum toc_size_qualifier *toc_kind)
   SKIP_WHITESPACE ();
 
   /* Find the spelling of the operand.  */
-  toc_spec = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&toc_spec);
 
   if (strcmp (toc_spec, "toc") == 0)
     {
@@ -2517,7 +2512,7 @@ parse_toc_entry (enum toc_size_qualifier *toc_kind)
   /* Now find the ']'.  */
   *input_line_pointer = c;
 
-  SKIP_WHITESPACE ();       /* leading whitespace could be there.  */
+  SKIP_WHITESPACE_AFTER_NAME ();       /* leading whitespace could be there.  */
   c = *input_line_pointer++; /* input_line_pointer->past char in c.  */
 
   if (c != ']')
@@ -2532,16 +2527,25 @@ parse_toc_entry (enum toc_size_qualifier *toc_kind)
 }
 #endif
 
-#ifdef OBJ_XCOFF
+#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
 /* See whether a symbol is in the TOC section.  */
 
 static int
 ppc_is_toc_sym (symbolS *sym)
 {
+#ifdef OBJ_XCOFF
   return (symbol_get_tc (sym)->symbol_class == XMC_TC
          || symbol_get_tc (sym)->symbol_class == XMC_TC0);
-}
 #endif
+#ifdef OBJ_ELF
+  const char *sname = segment_name (S_GET_SEGMENT (sym));
+  if (ppc_obj64)
+    return strcmp (sname, ".toc") == 0;
+  else
+    return strcmp (sname, ".got") == 0;
+#endif
+}
+#endif /* defined (OBJ_XCOFF) || defined (OBJ_ELF) */
 \f
 
 #ifdef OBJ_ELF
@@ -2561,14 +2565,13 @@ ppc_apuinfo_section_add (unsigned int apu, unsigned int version)
       if (ppc_apuinfo_num_alloc == 0)
        {
          ppc_apuinfo_num_alloc = 4;
-         ppc_apuinfo_list = (unsigned long *)
-             xmalloc (sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+         ppc_apuinfo_list = XNEWVEC (unsigned long, ppc_apuinfo_num_alloc);
        }
       else
        {
          ppc_apuinfo_num_alloc += 4;
-         ppc_apuinfo_list = (unsigned long *) xrealloc (ppc_apuinfo_list,
-             sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+         ppc_apuinfo_list = XRESIZEVEC (unsigned long, ppc_apuinfo_list,
+                                        ppc_apuinfo_num_alloc);
        }
     }
   ppc_apuinfo_list[ppc_apuinfo_num++] = APUID (apu, version);
@@ -2740,12 +2743,18 @@ md_assemble (char *str)
       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
          && skip_optional)
        {
+         long val = ppc_optional_operand_value (operand);
          if (operand->insert)
            {
-             insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
+             insn = (*operand->insert) (insn, val, ppc_cpu, &errmsg);
              if (errmsg != (const char *) NULL)
                as_bad ("%s", errmsg);
            }
+         else if (operand->shift >= 0)
+           insn |= ((long) val & operand->bitm) << operand->shift;
+         else
+           insn |= ((long) val & operand->bitm) >> -operand->shift;
+
          if ((operand->flags & PPC_OPERAND_NEXT) != 0)
            next_opindex = *opindex_ptr + 1;
          continue;
@@ -2832,12 +2841,12 @@ md_assemble (char *str)
              /* FIXME: these next two specifically specify 32/64 bit
                 toc entries.  We don't support them today.  Is this
                 the right way to say that?  */
-             toc_reloc = BFD_RELOC_UNUSED;
+             toc_reloc = BFD_RELOC_NONE;
              as_bad (_("unimplemented toc32 expression modifier"));
              break;
            case must_be_64:
              /* FIXME: see above.  */
-             toc_reloc = BFD_RELOC_UNUSED;
+             toc_reloc = BFD_RELOC_NONE;
              as_bad (_("unimplemented toc64 expression modifier"));
              break;
            default:
@@ -2907,7 +2916,7 @@ md_assemble (char *str)
          bfd_reloc_code_real_type reloc;
          char *orig_str = str;
 
-         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
            switch (reloc)
              {
              default:
@@ -2993,7 +3002,7 @@ md_assemble (char *str)
        }
       else
        {
-         bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
+         bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
 #ifdef OBJ_ELF
          if (ex.X_op == O_symbol && str[0] == '(')
            {
@@ -3010,7 +3019,7 @@ md_assemble (char *str)
                  expression (&tls_exp);
                  if (tls_exp.X_op == O_symbol)
                    {
-                     reloc = BFD_RELOC_UNUSED;
+                     reloc = BFD_RELOC_NONE;
                      if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0)
                        {
                          reloc = BFD_RELOC_PPC_TLSGD;
@@ -3021,7 +3030,7 @@ md_assemble (char *str)
                          reloc = BFD_RELOC_PPC_TLSLD;
                          input_line_pointer += 7;
                        }
-                     if (reloc != BFD_RELOC_UNUSED)
+                     if (reloc != BFD_RELOC_NONE)
                        {
                          SKIP_WHITESPACE ();
                          str = input_line_pointer;
@@ -3038,7 +3047,7 @@ md_assemble (char *str)
                }
            }
 
-         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
            {
              /* Some TLS tweaks.  */
              switch (reloc)
@@ -3068,11 +3077,16 @@ md_assemble (char *str)
                  break;
                }
 
+             /* addpcis.  */
+             if (opcode->opcode == (19 << 26) + (2 << 1)
+                 && reloc == BFD_RELOC_HI16_S)
+               reloc = BFD_RELOC_PPC_REL16DX_HA;
+
              /* If VLE-mode convert LO/HI/HA relocations.  */
              if (opcode->flags & PPC_OPCODE_VLE)
                {
                  int tmp_insn = insn & opcode->mask;
-                 
+
                  int use_d_reloc = (tmp_insn == E_OR2I_INSN
                                     || tmp_insn == E_AND2I_DOT_INSN
                                     || tmp_insn == E_OR2IS_INSN
@@ -3110,7 +3124,7 @@ md_assemble (char *str)
                      else if (use_a_reloc)
                        reloc = BFD_RELOC_PPC_VLE_HI16A;
                      break;
-        
+
                    case BFD_RELOC_HI16_S:
                      if (use_d_reloc)
                        reloc = BFD_RELOC_PPC_VLE_HA16D;
@@ -3137,7 +3151,7 @@ md_assemble (char *str)
            }
 #endif /* OBJ_ELF */
 
-         if (reloc != BFD_RELOC_UNUSED)
+         if (reloc != BFD_RELOC_NONE)
            ;
          /* Determine a BFD reloc value based on the operand information.
             We are only prepared to turn a few of the operands into
@@ -3169,11 +3183,17 @@ md_assemble (char *str)
                   && operand->shift == 0)
            {
              reloc = BFD_RELOC_16;
-#ifdef OBJ_XCOFF
+#if defined OBJ_XCOFF || defined OBJ_ELF
              /* Note: the symbol may be not yet defined.  */
              if ((operand->flags & PPC_OPERAND_PARENS) != 0
                  && ppc_is_toc_sym (ex.X_add_symbol))
-               reloc = BFD_RELOC_PPC_TOC16;
+               {
+                 reloc = BFD_RELOC_PPC_TOC16;
+#ifdef OBJ_ELF
+                 as_warn (_("assuming %s on symbol"),
+                          ppc_obj64 ? "@toc" : "@xgot");
+#endif
+               }
 #endif
            }
 
@@ -3351,7 +3371,12 @@ md_assemble (char *str)
        ppc_apuinfo_section_add (PPC_APUINFO_CACHELCK, 1);
       if (opcode->flags & PPC_OPCODE_RFMCI)
        ppc_apuinfo_section_add (PPC_APUINFO_RFMCI, 1);
-      if (opcode->flags & PPC_OPCODE_VLE)
+      /* Only set the VLE flag if the instruction has been pulled via
+         the VLE instruction set.  This way the flag is guaranteed to
+         be set for VLE-only instructions or for VLE-only processors,
+         however it'll remain clear for dual-mode instructions on
+         dual-mode and, more importantly, standard-mode processors.  */
+      if ((ppc_cpu & opcode->flags) == PPC_OPCODE_VLE)
        ppc_apuinfo_section_add (PPC_APUINFO_VLE, 1);
     }
 #endif
@@ -3383,6 +3408,9 @@ md_assemble (char *str)
   frag_now->insn_addr = addr_mod;
   frag_now->has_code = 1;
   md_number_to_chars (f, insn, insn_length);
+  last_insn = insn;
+  last_seg = now_seg;
+  last_subseg = now_subseg;
 
 #ifdef OBJ_ELF
   dwarf2_emit_insn (insn_length);
@@ -3392,7 +3420,7 @@ md_assemble (char *str)
   for (i = 0; i < fc; i++)
     {
       fixS *fixP;
-      if (fixups[i].reloc != BFD_RELOC_UNUSED)
+      if (fixups[i].reloc != BFD_RELOC_NONE)
        {
          reloc_howto_type *reloc_howto;
          int size;
@@ -3405,9 +3433,6 @@ md_assemble (char *str)
          size = bfd_get_reloc_size (reloc_howto);
          offset = target_big_endian ? (insn_length - size) : 0;
 
-         if (size < 1 || size > 4)
-           abort ();
-
          fixP = fix_new_exp (frag_now,
                              f - frag_now->fr_literal + offset,
                              size,
@@ -3425,7 +3450,7 @@ md_assemble (char *str)
                              insn_length,
                              &fixups[i].exp,
                              (operand->flags & PPC_OPERAND_RELATIVE) != 0,
-                             BFD_RELOC_UNUSED);
+                             BFD_RELOC_NONE);
        }
       fixP->fx_pcrel_adjust = fixups[i].opindex;
     }
@@ -3489,7 +3514,7 @@ ppc_macro (char *str, const struct powerpc_macro *macro)
     }
 
   /* Put the string together.  */
-  complete = s = (char *) alloca (len + 1);
+  complete = s = XNEWVEC (char, len + 1);
   format = macro->format;
   while (*format != '\0')
     {
@@ -3507,6 +3532,7 @@ ppc_macro (char *str, const struct powerpc_macro *macro)
 
   /* Assemble the constructed instruction.  */
   md_assemble (complete);
+  free (complete);
 }
 \f
 #ifdef OBJ_ELF
@@ -3540,6 +3566,8 @@ ppc_section_flags (flagword flags, bfd_vma attr ATTRIBUTE_UNUSED, int type)
 static void
 ppc_byte (int ignore ATTRIBUTE_UNUSED)
 {
+  int count = 0;
+
   if (*input_line_pointer != '\"')
     {
       cons (1);
@@ -3563,8 +3591,11 @@ ppc_byte (int ignore ATTRIBUTE_UNUSED)
        }
 
       FRAG_APPEND_1_CHAR (c);
+      ++count;
     }
 
+  if (warn_476 && count != 0 && (now_seg->flags & SEC_CODE) != 0)
+    as_warn (_("data in executable section"));
   demand_empty_rest_of_line ();
 }
 \f
@@ -3595,10 +3626,9 @@ ppc_comm (int lcomm)
   symbolS *sym;
   char *pfrag;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
   end_name = input_line_pointer;
-  *end_name = endc;
+  (void) restore_line_pointer (endc);
 
   if (*input_line_pointer != ',')
     {
@@ -3649,12 +3679,11 @@ ppc_comm (int lcomm)
        }
       ++input_line_pointer;
 
-      lcomm_name = input_line_pointer;
-      lcomm_endc = get_symbol_end ();
+      lcomm_endc = get_symbol_name (&lcomm_name);
 
       lcomm_sym = symbol_find_or_make (lcomm_name);
 
-      *input_line_pointer = lcomm_endc;
+      (void) restore_line_pointer (lcomm_endc);
 
       /* The fourth argument to .lcomm is the alignment.  */
       if (*input_line_pointer != ',')
@@ -3757,12 +3786,11 @@ ppc_csect (int ignore ATTRIBUTE_UNUSED)
   symbolS *sym;
   offsetT align;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   sym = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   if (S_GET_NAME (sym)[0] == '\0')
     {
@@ -3930,15 +3958,14 @@ ppc_dwsect (int ignore ATTRIBUTE_UNUSED)
   /* Parse opt-label.  */
   if (*input_line_pointer == ',')
     {
-      const char *label;
+      char *label;
       char c;
 
       ++input_line_pointer;
 
-      label = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&label);
       opt_label = symbol_find_or_make (label);
-      *input_line_pointer = c;
+      (void) restore_line_pointer (c);
     }
   else
     opt_label = NULL;
@@ -3978,8 +4005,7 @@ ppc_dwsect (int ignore ATTRIBUTE_UNUSED)
   else
     {
       /* Create a new dw subsection.  */
-      subseg = (struct dw_subsection *)
-        xmalloc (sizeof (struct dw_subsection));
+      subseg = XNEW (struct dw_subsection);
 
       if (opt_label == NULL)
         {
@@ -4068,8 +4094,7 @@ ppc_named_section (int ignore ATTRIBUTE_UNUSED)
   char c;
   symbolS *sym;
 
-  user_name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&user_name);
 
   if (strcmp (user_name, ".text") == 0)
     real_name = ".text[PR]";
@@ -4078,12 +4103,12 @@ ppc_named_section (int ignore ATTRIBUTE_UNUSED)
   else
     {
       as_bad (_("the XCOFF file format does not support arbitrary sections"));
-      *input_line_pointer = c;
+      (void) restore_line_pointer (c);
       ignore_rest_of_line ();
       return;
     }
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   sym = symbol_find_or_make (real_name);
 
@@ -4100,12 +4125,11 @@ ppc_extern (int ignore ATTRIBUTE_UNUSED)
   char *name;
   char endc;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   (void) symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   demand_empty_rest_of_line ();
 }
@@ -4119,12 +4143,11 @@ ppc_lglobl (int ignore ATTRIBUTE_UNUSED)
   char endc;
   symbolS *sym;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   sym = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   symbol_get_tc (sym)->output = 1;
 
@@ -4157,14 +4180,13 @@ ppc_ref (int ignore ATTRIBUTE_UNUSED)
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
 
       fix_at_start (symbol_get_frag (ppc_current_csect), 0,
                    symbol_find_or_make (name), 0, FALSE, BFD_RELOC_NONE);
 
       *input_line_pointer = c;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       c = *input_line_pointer;
       if (c == ',')
        {
@@ -4194,12 +4216,11 @@ ppc_rename (int ignore ATTRIBUTE_UNUSED)
   symbolS *sym;
   int len;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   sym = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   if (*input_line_pointer != ',')
     {
@@ -4358,8 +4379,7 @@ ppc_function (int ignore ATTRIBUTE_UNUSED)
   symbolS *ext_sym;
   symbolS *lab_sym;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   /* Ignore any [PR] suffix.  */
   name = ppc_canonicalize_symbol_name (name);
@@ -4370,7 +4390,7 @@ ppc_function (int ignore ATTRIBUTE_UNUSED)
 
   ext_sym = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   if (*input_line_pointer != ',')
     {
@@ -4380,12 +4400,11 @@ ppc_function (int ignore ATTRIBUTE_UNUSED)
     }
   ++input_line_pointer;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   lab_sym = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   if (ext_sym != lab_sym)
     {
@@ -4564,12 +4583,11 @@ ppc_bs (int ignore ATTRIBUTE_UNUSED)
   if (ppc_current_block != NULL)
     as_bad (_("nested .bs blocks"));
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   csect = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   sym = symbol_make (".bs");
   S_SET_SEGMENT (sym, now_seg);
@@ -4846,12 +4864,11 @@ ppc_tc (int ignore ATTRIBUTE_UNUSED)
        return;
       }
 
-    name = input_line_pointer;
-    endc = get_symbol_end ();
+    endc = get_symbol_name (&name);
 
     sym = symbol_find_or_make (name);
 
-    *input_line_pointer = endc;
+    (void) restore_line_pointer (endc);
 
     if (S_IS_DEFINED (sym))
       {
@@ -4917,6 +4934,7 @@ ppc_tc (int ignore ATTRIBUTE_UNUSED)
 static void
 ppc_machine (int ignore ATTRIBUTE_UNUSED)
 {
+  char c;
   char *cpu_string;
 #define MAX_HISTORY 100
   static ppc_cpu_t *cpu_history;
@@ -4924,19 +4942,9 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
 
   SKIP_WHITESPACE ();
 
-  if (*input_line_pointer == '"')
-    {
-      int len;
-      cpu_string = demand_copy_C_string (&len);
-    }
-  else
-    {
-      char c;
-      cpu_string = input_line_pointer;
-      c = get_symbol_end ();
-      cpu_string = xstrdup (cpu_string);
-      *input_line_pointer = c;
-    }
+  c = get_symbol_name (&cpu_string);
+  cpu_string = xstrdup (cpu_string);
+  (void) restore_line_pointer (c);
 
   if (cpu_string != NULL)
     {
@@ -4950,7 +4958,7 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
       if (strcmp (cpu_string, "push") == 0)
        {
          if (cpu_history == NULL)
-           cpu_history = xmalloc (MAX_HISTORY * sizeof (*cpu_history));
+           cpu_history = XNEWVEC (ppc_cpu_t, MAX_HISTORY);
 
          if (curr_hist >= MAX_HISTORY)
            as_bad (_(".machine stack overflow"));
@@ -5175,17 +5183,15 @@ ppc_znop (int ignore ATTRIBUTE_UNUSED)
   char *name;
 
   /* Strip out the symbol name.  */
-  symbol_name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&symbol_name);
 
-  name = xmalloc (input_line_pointer - symbol_name + 1);
-  strcpy (name, symbol_name);
+  name = xstrdup (symbol_name);
 
   sym = symbol_find_or_make (name);
 
   *input_line_pointer = c;
 
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
 
   /* Look up the opcode in the hash table.  */
   opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, "nop");
@@ -5221,13 +5227,12 @@ ppc_pe_comm (int lcomm)
   symbolS *symbolP;
   offsetT align;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
 
   /* just after name is now '\0'.  */
   p = input_line_pointer;
   *p = c;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   if (*input_line_pointer != ',')
     {
       as_bad (_("expected comma after symbol-name: rest of line ignored."));
@@ -5352,15 +5357,13 @@ ppc_pe_section (int ignore ATTRIBUTE_UNUSED)
   segT sec;
   int align;
 
-  section_name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&section_name);
 
-  name = xmalloc (input_line_pointer - section_name + 1);
-  strcpy (name, section_name);
+  name = xstrdup (section_name);
 
   *input_line_pointer = c;
 
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
 
   exp = 0;
   flags = SEC_NO_FLAGS;
@@ -5508,12 +5511,11 @@ ppc_pe_function (int ignore ATTRIBUTE_UNUSED)
   char endc;
   symbolS *ext_sym;
 
-  name = input_line_pointer;
-  endc = get_symbol_end ();
+  endc = get_symbol_name (&name);
 
   ext_sym = symbol_find_or_make (name);
 
-  *input_line_pointer = endc;
+  (void) restore_line_pointer (endc);
 
   S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
   SF_SET_FUNCTION (ext_sym);
@@ -5754,9 +5756,7 @@ ppc_frob_symbol (symbolS *sym)
          char *snew;
 
          len = s - name;
-         snew = xmalloc (len + 1);
-         memcpy (snew, name, len);
-         snew[len] = '\0';
+         snew = xstrndup (name, len);
 
          S_SET_NAME (sym, snew);
        }
@@ -6055,7 +6055,7 @@ ppc_frob_section (asection *sec)
 
 #endif /* OBJ_XCOFF */
 \f
-char *
+const char *
 md_atof (int type, char *litp, int *sizep)
 {
   return ieee_md_atof (type, litp, sizep, target_big_endian);
@@ -6083,7 +6083,7 @@ md_section_align (asection *seg ATTRIBUTE_UNUSED, valueT addr)
 #else
   int align = bfd_get_section_alignment (stdoutput, seg);
 
-  return ((addr + (1 << align) - 1) & (-1 << align));
+  return ((addr + (1 << align) - 1) & -(1 << align));
 #endif
 }
 
@@ -6408,13 +6408,14 @@ ppc_handle_align (struct frag *fragP)
 
       if ((ppc_cpu & PPC_OPCODE_POWER6) != 0
          || (ppc_cpu & PPC_OPCODE_POWER7) != 0
-         || (ppc_cpu & PPC_OPCODE_POWER8) != 0)
+         || (ppc_cpu & PPC_OPCODE_POWER8) != 0
+         || (ppc_cpu & PPC_OPCODE_POWER9) != 0)
        {
-         /* For power6, power7 and power8, we want the last nop to be a group
-            terminating one.  Do this by inserting an rs_fill frag immediately
-            after this one, with its address set to the last nop location.
-            This will automatically reduce the number of nops in the current
-            frag by one.  */
+         /* For power6, power7, power8 and power9, we want the last nop to be
+            a group terminating one.  Do this by inserting an rs_fill frag
+            immediately after this one, with its address set to the last nop
+            location.  This will automatically reduce the number of nops in
+            the current frag by one.  */
          if (count > 4)
            {
              struct frag *group_nop = xmalloc (SIZEOF_STRUCT_FRAG + 4);
@@ -6429,13 +6430,14 @@ ppc_handle_align (struct frag *fragP)
            }
 
          if ((ppc_cpu & PPC_OPCODE_POWER7) != 0
-             || (ppc_cpu & PPC_OPCODE_POWER8) != 0)
+             || (ppc_cpu & PPC_OPCODE_POWER8) != 0
+             || (ppc_cpu & PPC_OPCODE_POWER9) != 0)
            {
              if (ppc_cpu & PPC_OPCODE_E500MC)
                /* e500mc group terminating nop: "ori 0,0,0".  */
                md_number_to_chars (dest, 0x60000000, 4);
              else
-               /* power7/power8 group terminating nop: "ori 2,2,0".  */
+               /* power7/power8/power9 group terminating nop: "ori 2,2,0".  */
                md_number_to_chars (dest, 0x60420000, 4);
            }
          else
@@ -6449,7 +6451,7 @@ ppc_handle_align (struct frag *fragP)
    fixups we generated by the calls to fix_new_exp, above.  */
 
 void
-md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 {
   valueT value = * valP;
   offsetT fieldval;
@@ -6461,6 +6463,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       /* Hack around bfd_install_relocation brain damage.  */
       if (fixP->fx_pcrel)
        value += fixP->fx_frag->fr_address + fixP->fx_where;
+
+      if (fixP->fx_addsy == abs_section_sym)
+       fixP->fx_done = 1;
     }
   else
     fixP->fx_done = 1;
@@ -6571,6 +6576,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
     case BFD_RELOC_HI16_S:
     case BFD_RELOC_HI16_S_PCREL:
+    case BFD_RELOC_PPC_REL16DX_HA:
 #ifdef OBJ_ELF
       if (REPORT_OVERFLOW_HI && ppc_obj64)
        {
@@ -6616,9 +6622,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   if (operand != NULL)
     {
       /* Handle relocs in an insn.  */
-      char *where;
-      unsigned long insn;
-
       switch (fixP->fx_r_type)
        {
 #ifdef OBJ_ELF
@@ -6743,6 +6746,29 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
          break;
 #endif
 
+       case BFD_RELOC_VTABLE_INHERIT:
+       case BFD_RELOC_VTABLE_ENTRY:
+       case BFD_RELOC_PPC_DTPMOD:
+       case BFD_RELOC_PPC_TPREL:
+       case BFD_RELOC_PPC_DTPREL:
+       case BFD_RELOC_PPC_COPY:
+       case BFD_RELOC_PPC_GLOB_DAT:
+       case BFD_RELOC_32_PLT_PCREL:
+       case BFD_RELOC_PPC_EMB_NADDR32:
+       case BFD_RELOC_PPC64_TOC:
+       case BFD_RELOC_CTOR:
+       case BFD_RELOC_32:
+       case BFD_RELOC_32_PCREL:
+       case BFD_RELOC_RVA:
+       case BFD_RELOC_64:
+       case BFD_RELOC_64_PCREL:
+       case BFD_RELOC_PPC64_ADDR64_LOCAL:
+         as_bad_where (fixP->fx_file, fixP->fx_line,
+                       _("%s unsupported as instruction fixup"),
+                       bfd_get_reloc_code_name (fixP->fx_r_type));
+         fixP->fx_done = 1;
+         return;
+
        default:
          break;
        }
@@ -6756,22 +6782,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 #endif
       if ((fieldval != 0 && APPLY_RELOC) || operand->insert != NULL)
        {
+         unsigned long insn;
+         unsigned char *where;
+
          /* Fetch the instruction, insert the fully resolved operand
             value, and stuff the instruction back again.  */
-         where = fixP->fx_frag->fr_literal + fixP->fx_where;
+         where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
          if (target_big_endian)
            {
              if (fixP->fx_size == 4)
-               insn = bfd_getb32 ((unsigned char *) where);
+               insn = bfd_getb32 (where);
              else
-               insn = bfd_getb16 ((unsigned char *) where);
+               insn = bfd_getb16 (where);
            }
          else
            {
              if (fixP->fx_size == 4)
-               insn = bfd_getl32 ((unsigned char *) where);
+               insn = bfd_getl32 (where);
              else
-               insn = bfd_getl16 ((unsigned char *) where);
+               insn = bfd_getl16 (where);
            }
          insn = ppc_insert_operand (insn, operand, fieldval,
                                     fixP->tc_fix_data.ppc_cpu,
@@ -6779,16 +6808,16 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
          if (target_big_endian)
            {
              if (fixP->fx_size == 4)
-               bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+               bfd_putb32 (insn, where);
              else
-               bfd_putb16 ((bfd_vma) insn, (unsigned char *) where);
+               bfd_putb16 (insn, where);
            }
          else
            {
              if (fixP->fx_size == 4)
-               bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+               bfd_putl32 (insn, where);
              else
-               bfd_putl16 ((bfd_vma) insn, (unsigned char *) where);
+               bfd_putl16 (insn, where);
            }
        }
 
@@ -6797,9 +6826,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        return;
 
       gas_assert (fixP->fx_addsy != NULL);
-      if (fixP->fx_r_type == BFD_RELOC_UNUSED)
+      if (fixP->fx_r_type == BFD_RELOC_NONE)
        {
-         char *sfile;
+         const char *sfile;
          unsigned int sline;
 
          /* Use expr_symbol_where to see if this is an expression
@@ -6962,6 +6991,16 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       if (fixP->fx_size && APPLY_RELOC)
        md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
                            fieldval, fixP->fx_size);
+      if (warn_476
+         && (seg->flags & SEC_CODE) != 0
+         && fixP->fx_size == 4
+         && fixP->fx_done
+         && !fixP->fx_tcbit
+         && (fixP->fx_r_type == BFD_RELOC_32
+             || fixP->fx_r_type == BFD_RELOC_CTOR
+             || fixP->fx_r_type == BFD_RELOC_32_PCREL))
+       as_warn_where (fixP->fx_file, fixP->fx_line,
+                      _("data in executable section"));
     }
 
   /* We are only able to convert some relocs to pc-relative.  */
@@ -6997,6 +7036,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        case BFD_RELOC_LO16_PCREL:
        case BFD_RELOC_HI16_PCREL:
        case BFD_RELOC_HI16_S_PCREL:
+       case BFD_RELOC_PPC_REL16DX_HA:
        case BFD_RELOC_64_PCREL:
        case BFD_RELOC_32_PCREL:
        case BFD_RELOC_16_PCREL:
@@ -7016,7 +7056,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        default:
          if (fixP->fx_addsy)
            {
-             char *sfile;
+             const char *sfile;
              unsigned int sline;
 
              /* Use expr_symbol_where to see if this is an
@@ -7087,9 +7127,9 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
 {
   arelent *reloc;
 
-  reloc = (arelent *) xmalloc (sizeof (arelent));
+  reloc = XNEW (arelent);
 
-  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  reloc->sym_ptr_ptr = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
@@ -7118,7 +7158,7 @@ tc_ppc_regname_to_dw2regnum (char *regname)
   unsigned int i;
   const char *p;
   char *q;
-  static struct { char *name; int dw2regnum; } regnames[] =
+  static struct { const char *name; int dw2regnum; } regnames[] =
     {
       { "sp", 1 }, { "r.sp", 1 }, { "rtoc", 2 }, { "r.toc", 2 },
       { "mq", 64 }, { "lr", 65 }, { "ctr", 66 }, { "ap", 67 },
This page took 0.042436 seconds and 4 git commands to generate.