cpu: add eBPF cpu description
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index 5e9251bdb9faad12b85d26fb03c41a50e243cfb9..e73539afa2b1d17e92b52b2f3297d3b7f1a23ea2 100644 (file)
@@ -1,5 +1,5 @@
 /* PowerPC-specific support for 32-bit ELF
-   Copyright (C) 1994-2018 Free Software Foundation, Inc.
+   Copyright (C) 1994-2019 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -186,1228 +186,384 @@ static const bfd_vma ppc_elf_vxworks_pic_plt0_entry
    + (SYM)->root.u.def.section->output_offset          \
    + (SYM)->root.u.def.value)
 \f
+/* Relocation HOWTO's.  */
+/* Like other ELF RELA targets that don't apply multiple
+   field-altering relocations to the same localation, src_mask is
+   always zero and pcrel_offset is the same as pc_relative.
+   PowerPC can always use a zero bitpos, even when the field is not at
+   the LSB.  For example, a REL24 could use rightshift=2, bisize=24
+   and bitpos=2 which matches the ABI description, or as we do here,
+   rightshift=0, bitsize=26 and bitpos=0.  */
+#define HOW(type, size, bitsize, mask, rightshift, pc_relative, \
+           complain, special_func)                             \
+  HOWTO (type, rightshift, size, bitsize, pc_relative, 0,      \
+        complain_overflow_ ## complain, special_func,          \
+        #type, FALSE, 0, mask, pc_relative)
+
 static reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
 
 static reloc_howto_type ppc_elf_howto_raw[] = {
   /* This reloc does nothing.  */
-  HOWTO (R_PPC_NONE,           /* type */
-        0,                     /* rightshift */
-        3,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_NONE",          /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_NONE, 3, 0, 0, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* A standard 32 bit relocation.  */
-  HOWTO (R_PPC_ADDR32,         /* 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_PPC_ADDR32",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR32, 2, 32, 0xffffffff, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* An absolute 26 bit branch; the lower two bits must be zero.
      FIXME: we don't check that, we just clear them.  */
-  HOWTO (R_PPC_ADDR24,         /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        26,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_ADDR24",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3fffffc,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR24, 2, 26, 0x3fffffc, 0, FALSE, signed,
+       bfd_elf_generic_reloc),
 
   /* A standard 16 bit relocation.  */
-  HOWTO (R_PPC_ADDR16,         /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_ADDR16",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR16, 1, 16, 0xffff, 0, FALSE, bitfield,
+       bfd_elf_generic_reloc),
 
   /* A 16 bit relocation without overflow.  */
-  HOWTO (R_PPC_ADDR16_LO,      /* 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_PPC_ADDR16_LO",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* The high order 16 bits of an address.  */
-  HOWTO (R_PPC_ADDR16_HI,      /* type */
-        16,                    /* 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_PPC_ADDR16_HI",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* The high order 16 bits of an address, plus 1 if the contents of
      the low 16 bits, treated as a signed number, is negative.  */
-  HOWTO (R_PPC_ADDR16_HA,      /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_addr16_ha_reloc, /* special_function */
-        "R_PPC_ADDR16_HA",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_addr16_ha_reloc),
 
   /* An absolute 16 bit branch; the lower two bits must be zero.
      FIXME: we don't check that, we just clear them.  */
-  HOWTO (R_PPC_ADDR14,         /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_ADDR14",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffc,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR14, 2, 16, 0xfffc, 0, FALSE, signed,
+       bfd_elf_generic_reloc),
 
   /* An absolute 16 bit branch, for which bit 10 should be set to
      indicate that the branch is expected to be taken. The lower two
      bits must be zero.  */
-  HOWTO (R_PPC_ADDR14_BRTAKEN, /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_ADDR14_BRTAKEN",/* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffc,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR14_BRTAKEN, 2, 16, 0xfffc, 0, FALSE, signed,
+       bfd_elf_generic_reloc),
 
   /* An absolute 16 bit branch, for which bit 10 should be set to
      indicate that the branch is not expected to be taken.  The lower
      two bits must be zero.  */
-  HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_ADDR14_BRNTAKEN",/* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffc,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_ADDR14_BRNTAKEN, 2, 16, 0xfffc, 0, FALSE, signed,
+       bfd_elf_generic_reloc),
 
   /* A relative 26 bit branch; the lower two bits must be zero.  */
-  HOWTO (R_PPC_REL24,          /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        26,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_REL24",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3fffffc,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL24, 2, 26, 0x3fffffc, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* A relative 16 bit branch; the lower two bits must be zero.  */
-  HOWTO (R_PPC_REL14,          /* type */
-        0,                     /* 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_PPC_REL14",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffc,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL14, 2, 16, 0xfffc, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* A relative 16 bit branch.  Bit 10 should be set to indicate that
      the branch is expected to be taken.  The lower two bits must be
      zero.  */
-  HOWTO (R_PPC_REL14_BRTAKEN,  /* type */
-        0,                     /* 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_PPC_REL14_BRTAKEN", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffc,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL14_BRTAKEN, 2, 16, 0xfffc, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* A relative 16 bit branch.  Bit 10 should be set to indicate that
      the branch is not expected to be taken.  The lower two bits must
      be zero.  */
-  HOWTO (R_PPC_REL14_BRNTAKEN, /* type */
-        0,                     /* 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_PPC_REL14_BRNTAKEN",/* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffc,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL14_BRNTAKEN, 2, 16, 0xfffc, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
      symbol.  */
-  HOWTO (R_PPC_GOT16,          /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT16",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
      the symbol.  */
-  HOWTO (R_PPC_GOT16_LO,       /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT16_LO",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
      the symbol.  */
-  HOWTO (R_PPC_GOT16_HI,       /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT16_HI",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                 /* pcrel_offset */
+  HOW (R_PPC_GOT16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
      the symbol.  */
-  HOWTO (R_PPC_GOT16_HA,       /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT16_HA",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_REL24, but referring to the procedure linkage table
      entry for the symbol.  */
-  HOWTO (R_PPC_PLTREL24,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        26,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_PLTREL24",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3fffffc,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_PLTREL24, 2, 26, 0x3fffffc, 0, TRUE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* This is used only by the dynamic linker.  The symbol should exist
      both in the object being run and in some shared library.  The
      dynamic linker copies the data addressed by the symbol from the
      shared library into the object, because the object being
      run has to have the data at some particular address.  */
-  HOWTO (R_PPC_COPY,           /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_COPY",          /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_COPY, 2, 32, 0, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR32, but used when setting global offset table
      entries.  */
-  HOWTO (R_PPC_GLOB_DAT,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GLOB_DAT",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GLOB_DAT, 2, 32, 0xffffffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Marks a procedure linkage table entry for a symbol.  */
-  HOWTO (R_PPC_JMP_SLOT,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_JMP_SLOT",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_JMP_SLOT, 2, 32, 0, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Used only by the dynamic linker.  When the object is run, this
      longword is set to the load address of the object, plus the
      addend.  */
-  HOWTO (R_PPC_RELATIVE,       /* 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_PPC_RELATIVE",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_RELATIVE, 2, 32, 0xffffffff, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* Like R_PPC_REL24, but uses the value of the symbol within the
      object rather than the final value.  Normally used for
      _GLOBAL_OFFSET_TABLE_.  */
-  HOWTO (R_PPC_LOCAL24PC,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        26,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_LOCAL24PC",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3fffffc,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_LOCAL24PC, 2, 26, 0x3fffffc, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* Like R_PPC_ADDR32, but may be unaligned.  */
-  HOWTO (R_PPC_UADDR32,                /* 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_PPC_UADDR32",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_UADDR32, 2, 32, 0xffffffff, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* Like R_PPC_ADDR16, but may be unaligned.  */
-  HOWTO (R_PPC_UADDR16,                /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_UADDR16",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_UADDR16, 1, 16, 0xffff, 0, FALSE, bitfield,
+       bfd_elf_generic_reloc),
 
   /* 32-bit PC relative */
-  HOWTO (R_PPC_REL32,          /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_REL32",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL32, 2, 32, 0xffffffff, 0, TRUE, dont,
+       bfd_elf_generic_reloc),
 
   /* 32-bit relocation to the symbol's procedure linkage table.
      FIXME: not supported.  */
-  HOWTO (R_PPC_PLT32,          /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_PLT32",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_PLT32, 2, 32, 0, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* 32-bit PC relative relocation to the symbol's procedure linkage table.
      FIXME: not supported.  */
-  HOWTO (R_PPC_PLTREL32,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_PLTREL32",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_PLTREL32, 2, 32, 0, 0, TRUE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
      the symbol.  */
-  HOWTO (R_PPC_PLT16_LO,       /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_PLT16_LO",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_PLT16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
      the symbol.  */
-  HOWTO (R_PPC_PLT16_HI,       /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_PLT16_HI",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                 /* pcrel_offset */
+  HOW (R_PPC_PLT16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
      the symbol.  */
-  HOWTO (R_PPC_PLT16_HA,       /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_PLT16_HA",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_PLT16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
      small data items.  */
-  HOWTO (R_PPC_SDAREL16,       /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_SDAREL16",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_SDAREL16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* 16-bit section relative relocation.  */
-  HOWTO (R_PPC_SECTOFF,                /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_SECTOFF",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_SECTOFF, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* 16-bit lower half section relative relocation.  */
-  HOWTO (R_PPC_SECTOFF_LO,       /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_SECTOFF_LO",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_SECTOFF_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* 16-bit upper half section relative relocation.  */
-  HOWTO (R_PPC_SECTOFF_HI,     /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_SECTOFF_HI",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                 /* pcrel_offset */
+  HOW (R_PPC_SECTOFF_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* 16-bit upper half adjusted section relative relocation.  */
-  HOWTO (R_PPC_SECTOFF_HA,     /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_SECTOFF_HA",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_SECTOFF_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Marker relocs for TLS.  */
-  HOWTO (R_PPC_TLS,
-        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_PPC_TLS",           /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
-
-  HOWTO (R_PPC_TLSGD,
-        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_PPC_TLSGD",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
-
-  HOWTO (R_PPC_TLSLD,
-        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_PPC_TLSLD",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TLS, 2, 32, 0, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
+
+  HOW (R_PPC_TLSGD, 2, 32, 0, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
+
+  HOW (R_PPC_TLSLD, 2, 32, 0, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* Marker relocs on inline plt call instructions.  */
-  HOWTO (R_PPC_PLTSEQ,
-        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_PPC_PLTSEQ",        /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
-
-  HOWTO (R_PPC_PLTCALL,
-        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_PPC_PLTCALL",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_PLTSEQ, 2, 32, 0, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
+
+  HOW (R_PPC_PLTCALL, 2, 32, 0, 0, FALSE, dont,
+       bfd_elf_generic_reloc),
 
   /* Computes the load module index of the load module that contains the
      definition of its TLS sym.  */
-  HOWTO (R_PPC_DTPMOD32,
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_DTPMOD32",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_DTPMOD32, 2, 32, 0xffffffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Computes a dtv-relative displacement, the difference between the value
      of sym+add and the base address of the thread-local storage block that
      contains the definition of sym, minus 0x8000.  */
-  HOWTO (R_PPC_DTPREL32,
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_DTPREL32",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_DTPREL32, 2, 32, 0xffffffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* A 16 bit dtprel reloc.  */
-  HOWTO (R_PPC_DTPREL16,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_DTPREL16",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_DTPREL16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like DTPREL16, but no overflow.  */
-  HOWTO (R_PPC_DTPREL16_LO,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_DTPREL16_LO",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_DTPREL16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like DTPREL16_LO, but next higher group of 16 bits.  */
-  HOWTO (R_PPC_DTPREL16_HI,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_DTPREL16_HI",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_DTPREL16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like DTPREL16_HI, but adjust for low 16 bits.  */
-  HOWTO (R_PPC_DTPREL16_HA,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_DTPREL16_HA",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_DTPREL16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Computes a tp-relative displacement, the difference between the value of
      sym+add and the value of the thread pointer (r13).  */
-  HOWTO (R_PPC_TPREL32,
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_TPREL32",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TPREL32, 2, 32, 0xffffffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* A 16 bit tprel reloc.  */
-  HOWTO (R_PPC_TPREL16,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_TPREL16",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TPREL16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like TPREL16, but no overflow.  */
-  HOWTO (R_PPC_TPREL16_LO,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_TPREL16_LO",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TPREL16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like TPREL16_LO, but next higher group of 16 bits.  */
-  HOWTO (R_PPC_TPREL16_HI,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_TPREL16_HI",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TPREL16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like TPREL16_HI, but adjust for low 16 bits.  */
-  HOWTO (R_PPC_TPREL16_HA,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_TPREL16_HA",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TPREL16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
      with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
      to the first entry.  */
-  HOWTO (R_PPC_GOT_TLSGD16,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSGD16",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSGD16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TLSGD16, but no overflow.  */
-  HOWTO (R_PPC_GOT_TLSGD16_LO,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSGD16_LO", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSGD16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TLSGD16_LO, but next higher group of 16 bits.  */
-  HOWTO (R_PPC_GOT_TLSGD16_HI,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSGD16_HI", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSGD16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TLSGD16_HI, but adjust for low 16 bits.  */
-  HOWTO (R_PPC_GOT_TLSGD16_HA,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSGD16_HA", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSGD16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
      with values (sym+add)@dtpmod and zero, and computes the offset to the
      first entry.  */
-  HOWTO (R_PPC_GOT_TLSLD16,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSLD16",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSLD16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TLSLD16, but no overflow.  */
-  HOWTO (R_PPC_GOT_TLSLD16_LO,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSLD16_LO", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSLD16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TLSLD16_LO, but next higher group of 16 bits.  */
-  HOWTO (R_PPC_GOT_TLSLD16_HI,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSLD16_HI", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSLD16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TLSLD16_HI, but adjust for low 16 bits.  */
-  HOWTO (R_PPC_GOT_TLSLD16_HA,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TLSLD16_HA", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TLSLD16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
      the offset to the entry.  */
-  HOWTO (R_PPC_GOT_DTPREL16,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_DTPREL16",  /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_DTPREL16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_DTPREL16, but no overflow.  */
-  HOWTO (R_PPC_GOT_DTPREL16_LO,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_DTPREL16_LO", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_DTPREL16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_DTPREL16_LO, but next higher group of 16 bits.  */
-  HOWTO (R_PPC_GOT_DTPREL16_HI,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_DTPREL16_HI", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_DTPREL16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_DTPREL16_HI, but adjust for low 16 bits.  */
-  HOWTO (R_PPC_GOT_DTPREL16_HA,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_DTPREL16_HA", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_DTPREL16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
      offset to the entry.  */
-  HOWTO (R_PPC_GOT_TPREL16,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TPREL16",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TPREL16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TPREL16, but no overflow.  */
-  HOWTO (R_PPC_GOT_TPREL16_LO,
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TPREL16_LO", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TPREL16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TPREL16_LO, but next higher group of 16 bits.  */
-  HOWTO (R_PPC_GOT_TPREL16_HI,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TPREL16_HI", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TPREL16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Like GOT_TPREL16_HI, but adjust for low 16 bits.  */
-  HOWTO (R_PPC_GOT_TPREL16_HA,
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_GOT_TPREL16_HA", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GOT_TPREL16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* The remaining relocs are from the Embedded ELF ABI, and are not
      in the SVR4 ELF ABI.  */
 
   /* 32 bit value resulting from the addend minus the symbol.  */
-  HOWTO (R_PPC_EMB_NADDR32,    /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_NADDR32",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_NADDR32, 2, 32, 0xffffffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* 16 bit value resulting from the addend minus the symbol.  */
-  HOWTO (R_PPC_EMB_NADDR16,    /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_NADDR16",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_NADDR16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* 16 bit value resulting from the addend minus the symbol.  */
-  HOWTO (R_PPC_EMB_NADDR16_LO, /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont,/* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_ADDR16_LO", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_NADDR16_LO, 1, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* The high order 16 bits of the addend minus the symbol.  */
-  HOWTO (R_PPC_EMB_NADDR16_HI, /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_NADDR16_HI", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_NADDR16_HI, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* The high order 16 bits of the result of the addend minus the address,
      plus 1 if the contents of the low 16 bits, treated as a signed number,
      is negative.  */
-  HOWTO (R_PPC_EMB_NADDR16_HA, /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_NADDR16_HA", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_NADDR16_HA, 1, 16, 0xffff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* 16 bit value resulting from allocating a 4 byte word to hold an
      address in the .sdata section, and returning the offset from
      _SDA_BASE_ for that relocation.  */
-  HOWTO (R_PPC_EMB_SDAI16,     /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_SDAI16",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_SDAI16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* 16 bit value resulting from allocating a 4 byte word to hold an
      address in the .sdata2 section, and returning the offset from
      _SDA2_BASE_ for that relocation.  */
-  HOWTO (R_PPC_EMB_SDA2I16,    /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_SDA2I16",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_SDA2I16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with
      small data items.  */
-  HOWTO (R_PPC_EMB_SDA2REL,    /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_SDA2REL",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_SDA2REL, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit
      signed offset from the appropriate base, and filling in the register
      field with the appropriate register (0, 2, or 13).  */
-  HOWTO (R_PPC_EMB_SDA21,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_SDA21",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_SDA21, 2, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Relocation not handled: R_PPC_EMB_MRKREF */
   /* Relocation not handled: R_PPC_EMB_RELSEC16 */
@@ -1419,441 +575,122 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
   /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling
      in the 16 bit signed offset from the appropriate base, and filling in the
      register field with the appropriate register (0, 2, or 13).  */
-  HOWTO (R_PPC_EMB_RELSDA,     /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_EMB_RELSDA",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_EMB_RELSDA, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* A relative 8 bit branch.  */
-  HOWTO (R_PPC_VLE_REL8,       /* type */
-        1,                     /* rightshift */
-        1,                     /* 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_PPC_VLE_REL8",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xff,                  /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_VLE_REL8, 1, 8, 0xff, 1, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* A relative 15 bit branch.  */
-  HOWTO (R_PPC_VLE_REL15,      /* type */
-        1,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        15,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        1,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_VLE_REL15",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xfffe,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_VLE_REL15, 2, 16, 0xfffe, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* A relative 24 bit branch.  */
-  HOWTO (R_PPC_VLE_REL24,      /* type */
-        1,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        1,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_VLE_REL24",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1fffffe,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_VLE_REL24, 2, 25, 0x1fffffe, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* The 16 LSBS in split16a format.  */
-  HOWTO (R_PPC_VLE_LO16A,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_LO16A",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_LO16A, 2, 16, 0x1f07ff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* The 16 LSBS in split16d format.  */
-  HOWTO (R_PPC_VLE_LO16D,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_LO16D",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3e007ff,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_LO16D, 2, 16, 0x3e007ff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 split16a format.  */
-  HOWTO (R_PPC_VLE_HI16A,      /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_HI16A",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_HI16A, 2, 16, 0x1f07ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 split16d format.  */
-  HOWTO (R_PPC_VLE_HI16D,      /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_HI16D",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3e007ff,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_HI16D, 2, 16, 0x3e007ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 (High Adjusted) in split16a format.  */
-  HOWTO (R_PPC_VLE_HA16A,      /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_HA16A",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_HA16A, 2, 16, 0x1f07ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 (High Adjusted) in split16d format.  */
-  HOWTO (R_PPC_VLE_HA16D,      /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_HA16D",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3e007ff,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_HA16D, 2, 16, 0x3e007ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* This reloc is like R_PPC_EMB_SDA21 but only applies to e_add16i
      instructions.  If the register base is 0 then the linker changes
      the e_add16i to an e_li instruction.  */
-  HOWTO (R_PPC_VLE_SDA21,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDA21",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDA21, 2, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 
   /* Like R_PPC_VLE_SDA21 but ignore overflow.  */
-  HOWTO (R_PPC_VLE_SDA21_LO,   /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDA21_LO",  /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDA21_LO, 2, 16, 0xffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* The 16 LSBS relative to _SDA_BASE_ in split16a format.  */
-  HOWTO (R_PPC_VLE_SDAREL_LO16A,/* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDAREL_LO16A", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDAREL_LO16A, 2, 16, 0x1f07ff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* The 16 LSBS relative to _SDA_BASE_ in split16d format.  */
-  HOWTO (R_PPC_VLE_SDAREL_LO16D, /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDAREL_LO16D", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3e007ff,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDAREL_LO16D, 2, 16, 0x3e007ff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 relative to _SDA_BASE_ in split16a format.  */
-  HOWTO (R_PPC_VLE_SDAREL_HI16A, /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDAREL_HI16A", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDAREL_HI16A, 2, 16, 0x1f07ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 relative to _SDA_BASE_ in split16d format.  */
-  HOWTO (R_PPC_VLE_SDAREL_HI16D, /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDAREL_HI16D", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3e007ff,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDAREL_HI16D, 2, 16, 0x3e007ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 (HA) relative to _SDA_BASE split16a format.  */
-  HOWTO (R_PPC_VLE_SDAREL_HA16A, /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDAREL_HA16A", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDAREL_HA16A, 2, 16, 0x1f07ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* Bits 16-31 (HA) relative to _SDA_BASE split16d format.  */
-  HOWTO (R_PPC_VLE_SDAREL_HA16D, /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_VLE_SDAREL_HA16D", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x3e007ff,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_SDAREL_HA16D, 2, 16, 0x3e007ff, 16, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* 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) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_IRELATIVE",     /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_VLE_ADDR20, 2, 20, 0x1f7fff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
+
+  HOW (R_PPC_IRELATIVE, 2, 32, 0xffffffff, 0, FALSE, dont,
+       ppc_elf_unhandled_reloc),
 
   /* A 16 bit relative relocation.  */
-  HOWTO (R_PPC_REL16,          /* type */
-        0,                     /* rightshift */
-        1,                     /* 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_PPC_REL16",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL16, 1, 16, 0xffff, 0, TRUE, signed,
+       bfd_elf_generic_reloc),
 
   /* A 16 bit relative relocation without overflow.  */
-  HOWTO (R_PPC_REL16_LO,       /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont,/* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_REL16_LO",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL16_LO, 1, 16, 0xffff, 0, TRUE, dont,
+       bfd_elf_generic_reloc),
 
   /* The high order 16 bits of a relative address.  */
-  HOWTO (R_PPC_REL16_HI,       /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_PPC_REL16_HI",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL16_HI, 1, 16, 0xffff, 16, TRUE, dont,
+       bfd_elf_generic_reloc),
 
   /* The high order 16 bits of a relative address, plus 1 if the contents of
      the low 16 bits, treated as a signed number, is negative.  */
-  HOWTO (R_PPC_REL16_HA,       /* type */
-        16,                    /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        ppc_elf_addr16_ha_reloc, /* special_function */
-        "R_PPC_REL16_HA",      /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL16_HA, 1, 16, 0xffff, 16, TRUE, dont,
+       ppc_elf_addr16_ha_reloc),
 
   /* Like R_PPC_REL16_HA but for split field in addpcis.  */
-  HOWTO (R_PPC_REL16DX_HA,     /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_addr16_ha_reloc, /* special_function */
-        "R_PPC_REL16DX_HA",    /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1fffc1,              /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+  HOW (R_PPC_REL16DX_HA, 2, 16, 0x1fffc1, 16, TRUE, signed,
+       ppc_elf_addr16_ha_reloc),
 
   /* A split-field reloc for addpcis, non-relative (gas internal use only).  */
-  HOWTO (R_PPC_16DX_HA,                /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_addr16_ha_reloc, /* special_function */
-        "R_PPC_16DX_HA",       /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0x1fffc1,              /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_16DX_HA, 2, 16, 0x1fffc1, 16, FALSE, signed,
+       ppc_elf_addr16_ha_reloc),
 
   /* GNU extension to record C++ vtable hierarchy.  */
-  HOWTO (R_PPC_GNU_VTINHERIT,  /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        NULL,                  /* special_function */
-        "R_PPC_GNU_VTINHERIT", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GNU_VTINHERIT, 0, 0, 0, 0, FALSE, dont,
+       NULL),
 
   /* GNU extension to record C++ vtable member usage.  */
-  HOWTO (R_PPC_GNU_VTENTRY,    /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        NULL,                  /* special_function */
-        "R_PPC_GNU_VTENTRY",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_GNU_VTENTRY, 0, 0, 0, 0, FALSE, dont,
+       NULL),
 
   /* Phony reloc to handle AIX style TOC entries.  */
-  HOWTO (R_PPC_TOC16,          /* type */
-        0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        ppc_elf_unhandled_reloc, /* special_function */
-        "R_PPC_TOC16",         /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+  HOW (R_PPC_TOC16, 1, 16, 0xffff, 0, FALSE, signed,
+       ppc_elf_unhandled_reloc),
 };
 \f
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
@@ -2411,16 +1248,16 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
        va_start (ap, note_type);
        memset (data, 0, sizeof (data));
        strncpy (data + 32, va_arg (ap, const char *), 16);
-#if GCC_VERSION == 8001
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
        DIAGNOSTIC_PUSH;
-       /* GCC 8.1 warns about 80 equals destination size with
+       /* GCC 8.0 and 8.1 warn about 80 equals destination size with
           -Wstringop-truncation:
           https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643
         */
        DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION;
 #endif
        strncpy (data + 48, va_arg (ap, const char *), 80);
-#if GCC_VERSION == 8001
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
        DIAGNOSTIC_POP;
 #endif
        va_end (ap);
@@ -4479,9 +3316,7 @@ ppc_elf_check_relocs (bfd *abfd,
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
        case R_PPC_GNU_VTENTRY:
-         BFD_ASSERT (h != NULL);
-         if (h != NULL
-             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
 
@@ -5049,10 +3884,10 @@ ppc_elf_vle_split16 (bfd *input_bfd,
                     split16_format_type split16_format,
                     bfd_boolean fixup)
 {
-  unsigned int insn, opcode, top5;
+  unsigned int insn, opcode;
 
   insn = bfd_get_32 (input_bfd, loc);
-  opcode = insn & 0xfc00f800;
+  opcode = insn & E_OPCODE_MASK;
   if (opcode == E_OR2I_INSN
       || opcode == E_AND2I_DOT_INSN
       || opcode == E_OR2IS_INSN
@@ -5089,10 +3924,22 @@ ppc_elf_vle_split16 (bfd *input_bfd,
               input_bfd, input_section, offset, opcode);
        }
     }
-  top5 = value & 0xf800;
-  top5 = top5 << (split16_format == split16a_type ? 5 : 10);
-  insn &= (split16_format == split16a_type ? ~0x1f07ff : ~0x3e007ff);
-  insn |= top5;
+  if (split16_format == split16a_type)
+    {
+      insn &= ~((0xf800 << 5) | 0x7ff);
+      insn |= (value & 0xf800) << 5;
+      if ((insn & E_LI_MASK) == E_LI_INSN)
+       {
+         /* Hack for e_li.  Extend sign.  */
+         insn &= ~(0xf0000 >> 5);
+         insn |= (-(value & 0x8000) & 0xf0000) >> 5;
+       }
+    }
+  else
+    {
+      insn &= ~((0xf800 << 10) | 0x7ff);
+      insn |= (value & 0xf800) << 10;
+    }
   insn |= value & 0x7ff;
   bfd_put_32 (input_bfd, insn, loc);
 }
@@ -7386,12 +6233,10 @@ ppc_elf_relax_section (bfd *abfd,
            {
              if (tsec != NULL)
                ;
-             else if (isym->st_shndx == SHN_UNDEF)
-               tsec = bfd_und_section_ptr;
              else if (isym->st_shndx == SHN_ABS)
                tsec = bfd_abs_section_ptr;
-             else if (isym->st_shndx == SHN_COMMON)
-               tsec = bfd_com_section_ptr;
+             else
+               continue;
 
              toff = isym->st_value;
              sym_type = ELF_ST_TYPE (isym->st_info);
@@ -7533,6 +6378,17 @@ ppc_elf_relax_section (bfd *abfd,
          if (tsec == isec)
            continue;
 
+         /* toff is used for the symbol index when the symbol is
+            undefined and we're doing a relocatable link, so we can't
+            support addends.  It would be possible to do so by
+            putting the addend in one_branch_fixup but addends on
+            branches are rare so it hardly seems worth supporting.  */
+         if (bfd_link_relocatable (link_info)
+             && tsec == bfd_und_section_ptr
+             && r_type != R_PPC_PLTREL24
+             && irel->r_addend != 0)
+           continue;
+
          /* There probably isn't any reason to handle symbols in
             SEC_MERGE sections;  SEC_MERGE doesn't seem a likely
             attribute for a code section, and we are only looking at
@@ -7556,7 +6412,8 @@ ppc_elf_relax_section (bfd *abfd,
                 a section symbol should not include the addend;  Such an
                 access is presumed to be an offset from "sym";  The
                 location of interest is just "sym".  */
-             if (sym_type == STT_SECTION)
+             if (sym_type == STT_SECTION
+                 && r_type != R_PPC_PLTREL24)
                toff += irel->r_addend;
 
              toff
@@ -7564,7 +6421,8 @@ ppc_elf_relax_section (bfd *abfd,
                                              elf_section_data (tsec)->sec_info,
                                              toff);
 
-             if (sym_type != STT_SECTION)
+             if (sym_type != STT_SECTION
+                 && r_type != R_PPC_PLTREL24)
                toff += irel->r_addend;
            }
          /* PLTREL24 addends are special.  */
@@ -7581,6 +6439,16 @@ ppc_elf_relax_section (bfd *abfd,
 
          roff = irel->r_offset;
 
+         /* Avoid creating a lot of unnecessary fixups when
+            relocatable if the output section size is such that a
+            fixup can be created at final link.
+            The max_branch_offset adjustment allows for some number
+            of other fixups being needed at final link.  */
+         if (bfd_link_relocatable (link_info)
+             && (isec->output_section->rawsize - (isec->output_offset + roff)
+                 < max_branch_offset - (max_branch_offset >> 4)))
+           continue;
+
          /* If the branch is in range, no need to do anything.  */
          if (tsec != bfd_und_section_ptr
              && (!bfd_link_relocatable (link_info)
@@ -8155,6 +7023,12 @@ ppc_elf_relocate_section (bfd *output_bfd,
                      (bfd_link_relocatable (info)) ? " (relocatable)" : "");
 #endif
 
+  if (!is_ppc_elf (input_bfd))
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
+
   got2 = bfd_get_section_by_name (input_bfd, ".got2");
 
   /* Initialize howto table if not already done.  */
@@ -8232,7 +7106,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
            howto = ppc_elf_howto_table[r_type];
 
          _bfd_clear_contents (howto, input_bfd, input_section,
-                              contents + rel->r_offset);
+                              contents, rel->r_offset);
          wrel->r_offset = rel->r_offset;
          wrel->r_info = 0;
          wrel->r_addend = 0;
@@ -9976,7 +8850,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
            }
          else if (htab->plt_type != PLT_NEW)
            info->callbacks->einfo
-             (_("%P: %H: %s relocation unsupported for bss-plt\n"),
+             (_("%X%P: %H: %s relocation unsupported for bss-plt\n"),
               input_bfd, input_section, rel->r_offset,
               howto->name);
          break;
@@ -9994,7 +8868,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
            }
          else if (htab->plt_type != PLT_NEW)
            info->callbacks->einfo
-             (_("%P: %H: %s relocation unsupported for bss-plt\n"),
+             (_("%X%P: %H: %s relocation unsupported for bss-plt\n"),
               input_bfd, input_section, rel->r_offset,
               howto->name);
          break;
@@ -10828,6 +9702,7 @@ ppc_finish_symbols (struct bfd_link_info *info)
                bfd_byte *loc;
                bfd_vma val;
                Elf_Internal_Rela rela;
+               unsigned char *p;
 
                if (!get_sym_h (NULL, &sym, &sym_sec, NULL, &local_syms,
                                lplt - local_plt, ibfd))
@@ -10872,14 +9747,9 @@ ppc_finish_symbols (struct bfd_link_info *info)
                loc = relplt->contents + (relplt->reloc_count++
                                          * sizeof (Elf32_External_Rela));
                bfd_elf32_swap_reloca_out (info->output_bfd, &rela, loc);
-             }
-           if ((ent->glink_offset & 1) == 0)
-             {
-               unsigned char *p = ((unsigned char *) htab->glink->contents
-                                   + ent->glink_offset);
 
+               p = (unsigned char *) htab->glink->contents + ent->glink_offset;
                write_glink_stub (NULL, ent, htab->elf.iplt, p, info);
-               ent->glink_offset |= 1;
              }
          }
 
This page took 0.049397 seconds and 4 git commands to generate.