Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
index bd0fee615c030e147a3904de85aa06fede099c80..a9119c497805e5bf2e54e8fa1fee81694326e2b1 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM
-   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+   Copyright (C) 1998-2021 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #include <limits.h>
 
 #include "bfd.h"
-#include "bfd_stdint.h"
 #include "libiberty.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf32-arm.h"
+#include "cpu-arm.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -56,8 +57,8 @@
    ? bfd_elf32_swap_reloc_out \
    : bfd_elf32_swap_reloca_out)
 
-#define elf_info_to_howto               0
-#define elf_info_to_howto_rel           elf32_arm_info_to_howto
+#define elf_info_to_howto              NULL
+#define elf_info_to_howto_rel          elf32_arm_info_to_howto
 
 #define ARM_ELF_ABI_VERSION            0
 #define ARM_ELF_OS_ABI_VERSION         ELFOSABI_ARM
 /* The Adjusted Place, as defined by AAELF.  */
 #define Pa(X) ((X) & 0xfffffffc)
 
-static bfd_boolean elf32_arm_write_section (bfd *output_bfd,
-                                           struct bfd_link_info *link_info,
-                                           asection *sec,
-                                           bfd_byte *contents);
+static bool elf32_arm_write_section (bfd *output_bfd,
+                                    struct bfd_link_info *link_info,
+                                    asection *sec,
+                                    bfd_byte *contents);
 
 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
    R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
@@ -81,755 +82,755 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         0,                     /* rightshift */
         3,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_NONE",          /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_PC24,           /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_PC24",          /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* 32 bit absolute */
   HOWTO (R_ARM_ABS32,          /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ABS32",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* standard 32bit pc-relative reloc */
   HOWTO (R_ARM_REL32,          /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_REL32",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* 8 bit absolute - R_ARM_LDR_PC_G0 in AAELF */
   HOWTO (R_ARM_LDR_PC_G0,      /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_LDR_PC_G0",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
    /* 16 bit absolute */
   HOWTO (R_ARM_ABS16,          /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ABS16",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x0000ffff,            /* src_mask */
         0x0000ffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* 12 bit absolute */
   HOWTO (R_ARM_ABS12,          /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ABS12",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_ABS5,       /* type */
         6,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         5,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_ABS5",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000007e0,            /* src_mask */
         0x000007e0,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* 8 bit absolute */
   HOWTO (R_ARM_ABS8,           /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ABS8",          /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000000ff,            /* src_mask */
         0x000000ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_SBREL32,                /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_SBREL32",       /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_CALL,       /* type */
         1,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_CALL",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x07ff2fff,            /* src_mask */
         0x07ff2fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_THM_PC8,                /* type */
+  HOWTO (R_ARM_THM_PC8,                /* type */
         1,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_PC8",       /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000000ff,            /* src_mask */
         0x000000ff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_BREL_ADJ,       /* type */
         1,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_BREL_ADJ",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_DESC,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_DESC",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_SWI8,       /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_SWI8",          /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000000,            /* src_mask */
         0x00000000,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* BLX instruction for the ARM.  */
   HOWTO (R_ARM_XPC25,          /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_XPC25",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* BLX instruction for the Thumb.  */
   HOWTO (R_ARM_THM_XPC22,      /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_XPC22",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x07ff2fff,            /* src_mask */
         0x07ff2fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* Dynamic TLS relocations.  */
 
   HOWTO (R_ARM_TLS_DTPMOD32,   /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_DTPMOD32",  /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_DTPOFF32,   /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_DTPOFF32",  /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_TPOFF32,    /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_TPOFF32",   /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* Relocs used in ARM Linux */
 
   HOWTO (R_ARM_COPY,           /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_COPY",          /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_GLOB_DAT,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GLOB_DAT",      /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_JUMP_SLOT,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_JUMP_SLOT",     /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_RELATIVE,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_RELATIVE",      /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_GOTOFF32,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOTOFF32",      /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_GOTPC,          /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOTPC",         /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_GOT32,          /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOT32",         /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_PLT32,          /* type */
-        2,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        24,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_PLT32",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_CALL,           /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_CALL",          /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_JUMP24,         /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_JUMP24",        /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_JUMP24,     /* type */
         1,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_JUMP24",    /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x07ff2fff,            /* src_mask */
         0x07ff2fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_BASE_ABS,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_BASE_ABS",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_ALU_PCREL7_0,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_PCREL_7_0", /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_ALU_PCREL15_8,  /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         8,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_PCREL_15_8",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_ALU_PCREL23_15, /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         16,                    /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_PCREL_23_15",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_LDR_SBREL_11_0, /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_LDR_SBREL_11_0",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_ALU_SBREL_19_12,        /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         12,                    /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_SBREL_19_12",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000ff000,            /* src_mask */
         0x000ff000,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_ALU_SBREL_27_20,        /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         20,                    /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_SBREL_27_20",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x0ff00000,            /* src_mask */
         0x0ff00000,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TARGET1,                /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TARGET1",       /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_ROSEGREL32,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ROSEGREL32",    /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_V4BX,           /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_V4BX",          /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TARGET2,                /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TARGET2",       /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_PREL31,         /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         31,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_PREL31",        /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x7fffffff,            /* src_mask */
         0x7fffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_MOVW_ABS_NC,    /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVW_ABS_NC",   /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000f0fff,            /* src_mask */
         0x000f0fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_MOVT_ABS,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVT_ABS",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000f0fff,            /* src_mask */
         0x000f0fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_MOVW_PREL_NC,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVW_PREL_NC",  /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000f0fff,            /* src_mask */
         0x000f0fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_MOVT_PREL,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVT_PREL",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000f0fff,            /* src_mask */
         0x000f0fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVW_ABS_NC,        /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVW_ABS_NC",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVT_ABS,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVT_ABS",  /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVW_PREL_NC,/* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVW_PREL_NC",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVT_PREL,  /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVT_PREL", /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_JUMP19,     /* type */
         1,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         19,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_JUMP19",    /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x043f2fff,            /* src_mask */
         0x043f2fff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_JUMP6,      /* type */
         1,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         6,                     /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_unsigned,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_JUMP6",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x02f8,                /* src_mask */
         0x02f8,                /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* These are declared as 13-bit signed relocations because we can
      address -4095 .. 4095(base) by altering ADDW to SUBW or vice
@@ -838,57 +839,57 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         13,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_ALU_PREL_11_0",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_PC12,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         13,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_PC12",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_ABS32_NOI,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ABS32_NOI",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_REL32_NOI,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_REL32_NOI",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* Group relocations.  */
 
@@ -896,379 +897,379 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_PC_G0_NC",  /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_PC_G0,      /* type */
+  HOWTO (R_ARM_ALU_PC_G0,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_PC_G0",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_PC_G0",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_ALU_PC_G1_NC,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ALU_PC_G1_NC",  /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_PC_G1,      /* type */
+  HOWTO (R_ARM_ALU_PC_G1,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_PC_G1",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_PC_G1",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_PC_G2,      /* type */
+  HOWTO (R_ARM_ALU_PC_G2,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_PC_G2",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_PC_G2",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDR_PC_G1,      /* type */
+  HOWTO (R_ARM_LDR_PC_G1,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDR_PC_G1",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDR_PC_G1",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDR_PC_G2,      /* type */
+  HOWTO (R_ARM_LDR_PC_G2,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDR_PC_G2",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDR_PC_G2",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDRS_PC_G0,     /* type */
+  HOWTO (R_ARM_LDRS_PC_G0,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDRS_PC_G0",    /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDRS_PC_G0",    /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDRS_PC_G1,     /* type */
+  HOWTO (R_ARM_LDRS_PC_G1,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDRS_PC_G1",    /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDRS_PC_G1",    /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDRS_PC_G2,     /* type */
+  HOWTO (R_ARM_LDRS_PC_G2,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDRS_PC_G2",    /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDRS_PC_G2",    /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDC_PC_G0,      /* type */
+  HOWTO (R_ARM_LDC_PC_G0,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDC_PC_G0",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDC_PC_G0",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDC_PC_G1,      /* type */
+  HOWTO (R_ARM_LDC_PC_G1,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDC_PC_G1",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDC_PC_G1",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDC_PC_G2,      /* type */
+  HOWTO (R_ARM_LDC_PC_G2,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDC_PC_G2",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDC_PC_G2",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_SB_G0_NC,           /* type */
+  HOWTO (R_ARM_ALU_SB_G0_NC,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_SB_G0_NC",  /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_SB_G0_NC",  /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_SB_G0,      /* type */
+  HOWTO (R_ARM_ALU_SB_G0,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_SB_G0",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_SB_G0",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_SB_G1_NC,           /* type */
+  HOWTO (R_ARM_ALU_SB_G1_NC,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_SB_G1_NC",  /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_SB_G1_NC",  /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_SB_G1,      /* type */
+  HOWTO (R_ARM_ALU_SB_G1,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_SB_G1",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_SB_G1",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_ALU_SB_G2,      /* type */
+  HOWTO (R_ARM_ALU_SB_G2,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_ALU_SB_G2",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_ALU_SB_G2",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDR_SB_G0,      /* type */
+  HOWTO (R_ARM_LDR_SB_G0,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDR_SB_G0",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDR_SB_G0",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDR_SB_G1,      /* type */
+  HOWTO (R_ARM_LDR_SB_G1,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDR_SB_G1",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDR_SB_G1",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDR_SB_G2,      /* type */
+  HOWTO (R_ARM_LDR_SB_G2,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDR_SB_G2",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDR_SB_G2",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDRS_SB_G0,     /* type */
+  HOWTO (R_ARM_LDRS_SB_G0,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDRS_SB_G0",    /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDRS_SB_G0",    /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDRS_SB_G1,     /* type */
+  HOWTO (R_ARM_LDRS_SB_G1,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDRS_SB_G1",    /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDRS_SB_G1",    /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDRS_SB_G2,     /* type */
+  HOWTO (R_ARM_LDRS_SB_G2,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDRS_SB_G2",    /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDRS_SB_G2",    /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDC_SB_G0,      /* type */
+  HOWTO (R_ARM_LDC_SB_G0,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDC_SB_G0",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDC_SB_G0",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDC_SB_G1,      /* type */
+  HOWTO (R_ARM_LDC_SB_G1,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDC_SB_G1",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDC_SB_G1",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
-  HOWTO (R_ARM_LDC_SB_G2,      /* type */
+  HOWTO (R_ARM_LDC_SB_G2,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_ARM_LDC_SB_G2",     /* name */
-        FALSE,                 /* partial_inplace */
+        "R_ARM_LDC_SB_G2",     /* name */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* End of group relocations.  */
 
@@ -1276,384 +1277,384 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVW_BREL_NC",  /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x0000ffff,            /* src_mask */
         0x0000ffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_MOVT_BREL,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVT_BREL",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x0000ffff,            /* src_mask */
         0x0000ffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_MOVW_BREL,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_MOVW_BREL",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x0000ffff,            /* src_mask */
         0x0000ffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVW_BREL_NC,/* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVW_BREL_NC",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVT_BREL,  /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVT_BREL", /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_MOVW_BREL,  /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_MOVW_BREL", /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x040f70ff,            /* src_mask */
         0x040f70ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_GOTDESC,    /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         NULL,                  /* special_function */
         "R_ARM_TLS_GOTDESC",   /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_CALL,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_CALL",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
         0x00ffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_DESCSEQ,    /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield,/* complain_on_overflow */
+        complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_DESCSEQ",   /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000000,            /* src_mask */
         0x00000000,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_TLS_CALL,   /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_TLS_CALL",  /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x07ff07ff,            /* src_mask */
         0x07ff07ff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_PLT32_ABS,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_PLT32_ABS",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_GOT_ABS,                /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOT_ABS",       /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                        /* pcrel_offset */
+        false),                        /* pcrel_offset */
 
   HOWTO (R_ARM_GOT_PREL,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOT_PREL",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_GOT_BREL12,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOT_BREL12",    /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_GOTOFF12,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_GOTOFF12",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
-  EMPTY_HOWTO (R_ARM_GOTRELAX),  /* reserved for future GOT-load optimizations */
+  EMPTY_HOWTO (R_ARM_GOTRELAX),         /* reserved for future GOT-load optimizations */
 
   /* GNU extension to record C++ vtable member usage */
-  HOWTO (R_ARM_GNU_VTENTRY,     /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+  HOWTO (R_ARM_GNU_VTENTRY,    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
-        "R_ARM_GNU_VTENTRY",   /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
+        "R_ARM_GNU_VTENTRY",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        false),                /* pcrel_offset */
 
   /* GNU extension to record C++ vtable hierarchy */
   HOWTO (R_ARM_GNU_VTINHERIT, /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        NULL,                  /* special_function */
+        NULL,                  /* special_function */
         "R_ARM_GNU_VTINHERIT", /* name */
-        FALSE,                 /* partial_inplace */
-        0,                     /* src_mask */
-        0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_JUMP11,     /* type */
         1,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         11,                    /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_JUMP11",    /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000007ff,            /* src_mask */
         0x000007ff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   HOWTO (R_ARM_THM_JUMP8,      /* type */
         1,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         8,                     /* bitsize */
-        TRUE,                  /* pc_relative */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_JUMP8",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x000000ff,            /* src_mask */
         0x000000ff,            /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        true),                 /* pcrel_offset */
 
   /* TLS relocations */
   HOWTO (R_ARM_TLS_GD32,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         NULL,                  /* special_function */
         "R_ARM_TLS_GD32",      /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_LDM32,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_LDM32",     /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_LDO32,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_LDO32",     /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_IE32,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                  /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                  /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         NULL,                  /* special_function */
         "R_ARM_TLS_IE32",      /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_LE32,       /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
-        NULL,                  /* special_function */
+        NULL,                  /* special_function */
         "R_ARM_TLS_LE32",      /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_LDO12,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_LDO12",     /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_LE12,       /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_LE12",      /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_TLS_IE12GP,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         12,                    /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_TLS_IE12GP",    /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000fff,            /* src_mask */
         0x00000fff,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   /* 112-127 private relocations.  */
   EMPTY_HOWTO (112),
@@ -1680,87 +1681,218 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield,/* complain_on_overflow */
+        complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_TLS_DESCSEQ",/* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0x00000000,            /* src_mask */
         0x00000000,            /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
   EMPTY_HOWTO (130),
   EMPTY_HOWTO (131),
   HOWTO (R_ARM_THM_ALU_ABS_G0_NC,/* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
-        FALSE,                 /* pc_relative.  */
+        false,                 /* pc_relative.  */
         0,                     /* bitpos.  */
         complain_overflow_bitfield,/* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
         "R_ARM_THM_ALU_ABS_G0_NC",/* name.  */
-        FALSE,                 /* partial_inplace.  */
+        false,                 /* partial_inplace.  */
         0x00000000,            /* src_mask.  */
         0x00000000,            /* dst_mask.  */
-        FALSE),                /* pcrel_offset.  */
+        false),                /* pcrel_offset.  */
   HOWTO (R_ARM_THM_ALU_ABS_G1_NC,/* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
-        FALSE,                 /* pc_relative.  */
+        false,                 /* pc_relative.  */
         0,                     /* bitpos.  */
         complain_overflow_bitfield,/* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
         "R_ARM_THM_ALU_ABS_G1_NC",/* name.  */
-        FALSE,                 /* partial_inplace.  */
+        false,                 /* partial_inplace.  */
         0x00000000,            /* src_mask.  */
         0x00000000,            /* dst_mask.  */
-        FALSE),                /* pcrel_offset.  */
+        false),                /* pcrel_offset.  */
   HOWTO (R_ARM_THM_ALU_ABS_G2_NC,/* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
-        FALSE,                 /* pc_relative.  */
+        false,                 /* pc_relative.  */
         0,                     /* bitpos.  */
         complain_overflow_bitfield,/* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
         "R_ARM_THM_ALU_ABS_G2_NC",/* name.  */
-        FALSE,                 /* partial_inplace.  */
+        false,                 /* partial_inplace.  */
         0x00000000,            /* src_mask.  */
         0x00000000,            /* dst_mask.  */
-        FALSE),                /* pcrel_offset.  */
+        false),                /* pcrel_offset.  */
   HOWTO (R_ARM_THM_ALU_ABS_G3_NC,/* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
-        FALSE,                 /* pc_relative.  */
+        false,                 /* pc_relative.  */
         0,                     /* bitpos.  */
         complain_overflow_bitfield,/* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
         "R_ARM_THM_ALU_ABS_G3_NC",/* name.  */
-        FALSE,                 /* partial_inplace.  */
+        false,                 /* partial_inplace.  */
         0x00000000,            /* src_mask.  */
         0x00000000,            /* dst_mask.  */
-        FALSE),                /* pcrel_offset.  */
+        false),                /* pcrel_offset.  */
+  /* Relocations for Armv8.1-M Mainline.  */
+  HOWTO (R_ARM_THM_BF16,       /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        true,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont,/* do not complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_BF16",      /* name.  */
+        false,                 /* partial_inplace.  */
+        0x001f0ffe,            /* src_mask.  */
+        0x001f0ffe,            /* dst_mask.  */
+        true),                 /* pcrel_offset.  */
+  HOWTO (R_ARM_THM_BF12,       /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        12,                    /* bitsize.  */
+        true,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont,/* do not complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_BF12",      /* name.  */
+        false,                 /* partial_inplace.  */
+        0x00010ffe,            /* src_mask.  */
+        0x00010ffe,            /* dst_mask.  */
+        true),                 /* pcrel_offset.  */
+  HOWTO (R_ARM_THM_BF18,       /* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        18,                    /* bitsize.  */
+        true,                  /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_dont,/* do not complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_BF18",      /* name.  */
+        false,                 /* partial_inplace.  */
+        0x007f0ffe,            /* src_mask.  */
+        0x007f0ffe,            /* dst_mask.  */
+        true),                 /* pcrel_offset.  */
 };
 
 /* 160 onwards: */
-static reloc_howto_type elf32_arm_howto_table_2[1] =
+static reloc_howto_type elf32_arm_howto_table_2[8] =
 {
   HOWTO (R_ARM_IRELATIVE,      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_IRELATIVE",     /* name */
-        TRUE,                  /* partial_inplace */
+        true,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
-        FALSE)                 /* pcrel_offset */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_GOTFUNCDESC,    /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_GOTFUNCDESC",   /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_GOTOFFFUNCDESC, /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_GOTOFFFUNCDESC",/* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_FUNCDESC,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_FUNCDESC",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_FUNCDESC_VALUE, /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_FUNCDESC_VALUE",/* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_TLS_GD32_FDPIC, /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_TLS_GD32_FDPIC",/* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_TLS_LDM32_FDPIC,        /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_TLS_LDM32_FDPIC",/* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+  HOWTO (R_ARM_TLS_IE32_FDPIC, /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_ARM_TLS_IE32_FDPIC",/* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
 };
 
 /* 249-255 extended, currently unused, relocations:  */
@@ -1770,57 +1902,57 @@ static reloc_howto_type elf32_arm_howto_table_3[4] =
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_RREL32",        /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_RABS32,         /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_RABS32",        /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_RPC24,          /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_RPC24",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        false),                /* pcrel_offset */
 
   HOWTO (R_ARM_RBASE,          /* type */
         0,                     /* rightshift */
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
-        FALSE,                 /* pc_relative */
+        false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_RBASE",         /* name */
-        FALSE,                 /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
         0,                     /* dst_mask */
-        FALSE)                 /* pcrel_offset */
+        false)                 /* pcrel_offset */
 };
 
 static reloc_howto_type *
@@ -1829,7 +1961,8 @@ elf32_arm_howto_from_type (unsigned int r_type)
   if (r_type < ARRAY_SIZE (elf32_arm_howto_table_1))
     return &elf32_arm_howto_table_1[r_type];
 
-  if (r_type == R_ARM_IRELATIVE)
+  if (r_type >= R_ARM_IRELATIVE
+      && r_type < R_ARM_IRELATIVE + ARRAY_SIZE (elf32_arm_howto_table_2))
     return &elf32_arm_howto_table_2[r_type - R_ARM_IRELATIVE];
 
   if (r_type >= R_ARM_RREL32
@@ -1839,36 +1972,44 @@ elf32_arm_howto_from_type (unsigned int r_type)
   return NULL;
 }
 
-static void
-elf32_arm_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * bfd_reloc,
+static bool
+elf32_arm_info_to_howto (bfd * abfd, arelent * bfd_reloc,
                         Elf_Internal_Rela * elf_reloc)
 {
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (elf_reloc->r_info);
-  bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
+  if ((bfd_reloc->howto = elf32_arm_howto_from_type (r_type)) == NULL)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+  return true;
 }
 
 struct elf32_arm_reloc_map
   {
     bfd_reloc_code_real_type  bfd_reloc_val;
-    unsigned char             elf_reloc_val;
+    unsigned char            elf_reloc_val;
   };
 
 /* All entries in this list must also be present in elf32_arm_howto_table.  */
 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
   {
-    {BFD_RELOC_NONE,                 R_ARM_NONE},
+    {BFD_RELOC_NONE,                R_ARM_NONE},
     {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
     {BFD_RELOC_ARM_PCREL_CALL,      R_ARM_CALL},
     {BFD_RELOC_ARM_PCREL_JUMP,      R_ARM_JUMP24},
-    {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
-    {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
-    {BFD_RELOC_32,                   R_ARM_ABS32},
-    {BFD_RELOC_32_PCREL,             R_ARM_REL32},
-    {BFD_RELOC_8,                    R_ARM_ABS8},
-    {BFD_RELOC_16,                   R_ARM_ABS16},
-    {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
+    {BFD_RELOC_ARM_PCREL_BLX,       R_ARM_XPC25},
+    {BFD_RELOC_THUMB_PCREL_BLX,             R_ARM_THM_XPC22},
+    {BFD_RELOC_32,                  R_ARM_ABS32},
+    {BFD_RELOC_32_PCREL,            R_ARM_REL32},
+    {BFD_RELOC_8,                   R_ARM_ABS8},
+    {BFD_RELOC_16,                  R_ARM_ABS16},
+    {BFD_RELOC_ARM_OFFSET_IMM,      R_ARM_ABS12},
     {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
     {BFD_RELOC_THUMB_PCREL_BRANCH25, R_ARM_THM_JUMP24},
     {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_CALL},
@@ -1876,35 +2017,42 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
     {BFD_RELOC_THUMB_PCREL_BRANCH20, R_ARM_THM_JUMP19},
     {BFD_RELOC_THUMB_PCREL_BRANCH9,  R_ARM_THM_JUMP8},
     {BFD_RELOC_THUMB_PCREL_BRANCH7,  R_ARM_THM_JUMP6},
-    {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
-    {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
-    {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
-    {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF32},
-    {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
-    {BFD_RELOC_ARM_GOT_PREL,         R_ARM_GOT_PREL},
-    {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
-    {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32},
+    {BFD_RELOC_ARM_GLOB_DAT,        R_ARM_GLOB_DAT},
+    {BFD_RELOC_ARM_JUMP_SLOT,       R_ARM_JUMP_SLOT},
+    {BFD_RELOC_ARM_RELATIVE,        R_ARM_RELATIVE},
+    {BFD_RELOC_ARM_GOTOFF,          R_ARM_GOTOFF32},
+    {BFD_RELOC_ARM_GOTPC,           R_ARM_GOTPC},
+    {BFD_RELOC_ARM_GOT_PREL,        R_ARM_GOT_PREL},
+    {BFD_RELOC_ARM_GOT32,           R_ARM_GOT32},
+    {BFD_RELOC_ARM_PLT32,           R_ARM_PLT32},
     {BFD_RELOC_ARM_TARGET1,         R_ARM_TARGET1},
     {BFD_RELOC_ARM_ROSEGREL32,      R_ARM_ROSEGREL32},
     {BFD_RELOC_ARM_SBREL32,         R_ARM_SBREL32},
     {BFD_RELOC_ARM_PREL31,          R_ARM_PREL31},
     {BFD_RELOC_ARM_TARGET2,         R_ARM_TARGET2},
-    {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32},
-    {BFD_RELOC_ARM_TLS_GOTDESC,      R_ARM_TLS_GOTDESC},
-    {BFD_RELOC_ARM_TLS_CALL,         R_ARM_TLS_CALL},
+    {BFD_RELOC_ARM_PLT32,           R_ARM_PLT32},
+    {BFD_RELOC_ARM_TLS_GOTDESC,             R_ARM_TLS_GOTDESC},
+    {BFD_RELOC_ARM_TLS_CALL,        R_ARM_TLS_CALL},
     {BFD_RELOC_ARM_THM_TLS_CALL,     R_ARM_THM_TLS_CALL},
-    {BFD_RELOC_ARM_TLS_DESCSEQ,      R_ARM_TLS_DESCSEQ},
+    {BFD_RELOC_ARM_TLS_DESCSEQ,             R_ARM_TLS_DESCSEQ},
     {BFD_RELOC_ARM_THM_TLS_DESCSEQ,  R_ARM_THM_TLS_DESCSEQ},
-    {BFD_RELOC_ARM_TLS_DESC,         R_ARM_TLS_DESC},
+    {BFD_RELOC_ARM_TLS_DESC,        R_ARM_TLS_DESC},
     {BFD_RELOC_ARM_TLS_GD32,        R_ARM_TLS_GD32},
     {BFD_RELOC_ARM_TLS_LDO32,       R_ARM_TLS_LDO32},
     {BFD_RELOC_ARM_TLS_LDM32,       R_ARM_TLS_LDM32},
     {BFD_RELOC_ARM_TLS_DTPMOD32,     R_ARM_TLS_DTPMOD32},
     {BFD_RELOC_ARM_TLS_DTPOFF32,     R_ARM_TLS_DTPOFF32},
-    {BFD_RELOC_ARM_TLS_TPOFF32,      R_ARM_TLS_TPOFF32},
-    {BFD_RELOC_ARM_TLS_IE32,         R_ARM_TLS_IE32},
-    {BFD_RELOC_ARM_TLS_LE32,         R_ARM_TLS_LE32},
-    {BFD_RELOC_ARM_IRELATIVE,        R_ARM_IRELATIVE},
+    {BFD_RELOC_ARM_TLS_TPOFF32,             R_ARM_TLS_TPOFF32},
+    {BFD_RELOC_ARM_TLS_IE32,        R_ARM_TLS_IE32},
+    {BFD_RELOC_ARM_TLS_LE32,        R_ARM_TLS_LE32},
+    {BFD_RELOC_ARM_IRELATIVE,       R_ARM_IRELATIVE},
+    {BFD_RELOC_ARM_GOTFUNCDESC,      R_ARM_GOTFUNCDESC},
+    {BFD_RELOC_ARM_GOTOFFFUNCDESC,   R_ARM_GOTOFFFUNCDESC},
+    {BFD_RELOC_ARM_FUNCDESC,         R_ARM_FUNCDESC},
+    {BFD_RELOC_ARM_FUNCDESC_VALUE,   R_ARM_FUNCDESC_VALUE},
+    {BFD_RELOC_ARM_TLS_GD32_FDPIC,   R_ARM_TLS_GD32_FDPIC},
+    {BFD_RELOC_ARM_TLS_LDM32_FDPIC,  R_ARM_TLS_LDM32_FDPIC},
+    {BFD_RELOC_ARM_TLS_IE32_FDPIC,   R_ARM_TLS_IE32_FDPIC},
     {BFD_RELOC_VTABLE_INHERIT,      R_ARM_GNU_VTINHERIT},
     {BFD_RELOC_VTABLE_ENTRY,        R_ARM_GNU_VTENTRY},
     {BFD_RELOC_ARM_MOVW,            R_ARM_MOVW_ABS_NC},
@@ -1947,7 +2095,10 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
     {BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC, R_ARM_THM_ALU_ABS_G3_NC},
     {BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC},
     {BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC},
-    {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC}
+    {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC},
+    {BFD_RELOC_ARM_THUMB_BF17, R_ARM_THM_BF16},
+    {BFD_RELOC_ARM_THUMB_BF13, R_ARM_THM_BF12},
+    {BFD_RELOC_ARM_THUMB_BF19, R_ARM_THM_BF18}
   };
 
 static reloc_howto_type *
@@ -1989,7 +2140,7 @@ elf32_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Support for core dump NOTE sections.  */
 
-static bfd_boolean
+static bool
 elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 {
   int offset;
@@ -1998,7 +2149,7 @@ elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
   switch (note->descsz)
     {
       default:
-       return FALSE;
+       return false;
 
       case 148:                /* Linux/ARM 32-bit.  */
        /* pr_cursig */
@@ -2019,13 +2170,13 @@ elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
                                          size, note->descpos + offset);
 }
 
-static bfd_boolean
+static bool
 elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   switch (note->descsz)
     {
       default:
-       return FALSE;
+       return false;
 
       case 124:                /* Linux/ARM elf_prpsinfo.  */
        elf_tdata (abfd)->core->pid
@@ -2047,7 +2198,7 @@ elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
       command[n - 1] = '\0';
   }
 
-  return TRUE;
+  return true;
 }
 
 static char *
@@ -2061,13 +2212,24 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-       char data[124];
+       char data[124] ATTRIBUTE_NONSTRING;
        va_list ap;
 
        va_start (ap, note_type);
        memset (data, 0, sizeof (data));
        strncpy (data + 28, va_arg (ap, const char *), 16);
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
+       DIAGNOSTIC_PUSH;
+       /* 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 + 44, va_arg (ap, const char *), 80);
+#if GCC_VERSION == 8000 || GCC_VERSION == 8001
+       DIAGNOSTIC_POP;
+#endif
        va_end (ap);
 
        return elfcore_write_note (abfd, buf, bufsiz,
@@ -2098,10 +2260,10 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
     }
 }
 
-#define TARGET_LITTLE_SYM               arm_elf32_le_vec
-#define TARGET_LITTLE_NAME              "elf32-littlearm"
-#define TARGET_BIG_SYM                  arm_elf32_be_vec
-#define TARGET_BIG_NAME                 "elf32-bigarm"
+#define TARGET_LITTLE_SYM              arm_elf32_le_vec
+#define TARGET_LITTLE_NAME             "elf32-littlearm"
+#define TARGET_BIG_SYM                 arm_elf32_be_vec
+#define TARGET_BIG_NAME                        "elf32-bigarm"
 
 #define elf_backend_grok_prstatus      elf32_arm_nabi_grok_prstatus
 #define elf_backend_grok_psinfo                elf32_arm_nabi_grok_psinfo
@@ -2140,10 +2302,15 @@ typedef unsigned short int insn16;
 
 #define CMSE_PREFIX "__acle_se_"
 
+#define CMSE_STUB_NAME ".gnu.sgstubs"
+
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
 #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
 
+/* FDPIC default stack size.  */
+#define DEFAULT_STACK_SIZE 0x8000
+
 static const unsigned long tls_trampoline [] =
 {
   0xe08e0000,          /* add r0, lr, r0 */
@@ -2164,6 +2331,43 @@ static const unsigned long dl_tlsdesc_lazy_trampoline [] =
   0x00000018, /* 4:   .word  _GLOBAL_OFFSET_TABLE_ - 2b - 8 */
 };
 
+/* NOTE: [Thumb nop sequence]
+   When adding code that transitions from Thumb to Arm the instruction that
+   should be used for the alignment padding should be 0xe7fd (b .-2) instead of
+   a nop for performance reasons.  */
+
+/* ARM FDPIC PLT entry.  */
+/* The last 5 words contain PLT lazy fragment code and data.  */
+static const bfd_vma elf32_arm_fdpic_plt_entry [] =
+  {
+    0xe59fc008,    /* ldr     r12, .L1 */
+    0xe08cc009,    /* add     r12, r12, r9 */
+    0xe59c9004,    /* ldr     r9, [r12, #4] */
+    0xe59cf000,    /* ldr     pc, [r12] */
+    0x00000000,    /* L1.     .word   foo(GOTOFFFUNCDESC) */
+    0x00000000,    /* L1.     .word   foo(funcdesc_value_reloc_offset) */
+    0xe51fc00c,    /* ldr     r12, [pc, #-12] */
+    0xe92d1000,    /* push    {r12} */
+    0xe599c004,    /* ldr     r12, [r9, #4] */
+    0xe599f000,    /* ldr     pc, [r9] */
+  };
+
+/* Thumb FDPIC PLT entry.  */
+/* The last 5 words contain PLT lazy fragment code and data.  */
+static const bfd_vma elf32_arm_fdpic_thumb_plt_entry [] =
+  {
+    0xc00cf8df,    /* ldr.w   r12, .L1 */
+    0x0c09eb0c,    /* add.w   r12, r12, r9 */
+    0x9004f8dc,    /* ldr.w   r9, [r12, #4] */
+    0xf000f8dc,    /* ldr.w   pc, [r12] */
+    0x00000000,    /* .L1     .word   foo(GOTOFFFUNCDESC) */
+    0x00000000,    /* .L2     .word   foo(funcdesc_value_reloc_offset) */
+    0xc008f85f,    /* ldr.w   r12, .L2 */
+    0xcd04f84d,    /* push    {r12} */
+    0xc004f8d9,    /* ldr.w   r12, [r9, #4] */
+    0xf000f8d9,    /* ldr.w   pc, [r9] */
+  };
+
 #ifdef FOUR_WORD_PLT
 
 /* The first entry in a procedure linkage table looks like
@@ -2196,11 +2400,11 @@ static const bfd_vma elf32_arm_plt_entry [] =
    linker first.  */
 static const bfd_vma elf32_arm_plt0_entry [] =
 {
-  0xe52de004,          /* str   lr, [sp, #-4]! */
-  0xe59fe004,          /* ldr   lr, [pc, #4]   */
-  0xe08fe00e,          /* add   lr, pc, lr     */
-  0xe5bef008,          /* ldr   pc, [lr, #8]!  */
-  0x00000000,          /* &GOT[0] - .          */
+  0xe52de004,          /* str   lr, [sp, #-4]! */
+  0xe59fe004,          /* ldr   lr, [pc, #4]   */
+  0xe08fe00e,          /* add   lr, pc, lr     */
+  0xe5bef008,          /* ldr   pc, [lr, #8]!  */
+  0x00000000,          /* &GOT[0] - .          */
 };
 
 /* By default subsequent entries in a procedure linkage table look like
@@ -2216,13 +2420,13 @@ static const bfd_vma elf32_arm_plt_entry_short [] =
    which can cope with arbitrary displacements.  */
 static const bfd_vma elf32_arm_plt_entry_long [] =
 {
-  0xe28fc200,           /* add   ip, pc, #0xN0000000 */
-  0xe28cc600,          /* add   ip, ip, #0xNN00000  */
+  0xe28fc200,          /* add   ip, pc, #0xN0000000 */
+  0xe28cc600,          /* add   ip, ip, #0xNN00000  */
   0xe28cca00,          /* add   ip, ip, #0xNN000    */
   0xe5bcf000,          /* ldr   pc, [ip, #0xNNN]!   */
 };
 
-static bfd_boolean elf32_arm_use_long_plt_entry = FALSE;
+static bool elf32_arm_use_long_plt_entry = false;
 
 #endif /* not FOUR_WORD_PLT */
 
@@ -2233,11 +2437,11 @@ static const bfd_vma elf32_thumb2_plt0_entry [] =
 {
   /* NOTE: As this is a mixture of 16-bit and 32-bit instructions,
      an instruction maybe encoded to one or two array elements.  */
-  0xf8dfb500,          /* push    {lr}          */
-  0x44fee008,          /* ldr.w   lr, [pc, #8]  */
-                       /* add     lr, pc        */
+  0xf8dfb500,          /* push    {lr}          */
+  0x44fee008,          /* ldr.w   lr, [pc, #8]  */
+                       /* add     lr, pc        */
   0xff08f85e,          /* ldr.w   pc, [lr, #8]! */
-  0x00000000,          /* &GOT[0] - .           */
+  0x00000000,          /* &GOT[0] - .           */
 };
 
 /* Subsequent entries in a procedure linkage table for thumb only target
@@ -2246,43 +2450,43 @@ static const bfd_vma elf32_thumb2_plt_entry [] =
 {
   /* NOTE: As this is a mixture of 16-bit and 32-bit instructions,
      an instruction maybe encoded to one or two array elements.  */
-  0x0c00f240,          /* movw    ip, #0xNNNN    */
-  0x0c00f2c0,          /* movt    ip, #0xNNNN    */
-  0xf8dc44fc,           /* add     ip, pc         */
-  0xbf00f000            /* ldr.w   pc, [ip]       */
-                       /* nop                    */
+  0x0c00f240,          /* movw    ip, #0xNNNN    */
+  0x0c00f2c0,          /* movt    ip, #0xNNNN    */
+  0xf8dc44fc,          /* add     ip, pc         */
+  0xe7fcf000           /* ldr.w   pc, [ip]       */
+                       /* b      .-4             */
 };
 
 /* The format of the first entry in the procedure linkage table
    for a VxWorks executable.  */
 static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] =
 {
-  0xe52dc008,          /* str    ip,[sp,#-8]!                  */
-  0xe59fc000,          /* ldr    ip,[pc]                       */
-  0xe59cf008,          /* ldr    pc,[ip,#8]                    */
-  0x00000000,          /* .long  _GLOBAL_OFFSET_TABLE_         */
+  0xe52dc008,          /* str    ip,[sp,#-8]!                  */
+  0xe59fc000,          /* ldr    ip,[pc]                       */
+  0xe59cf008,          /* ldr    pc,[ip,#8]                    */
+  0x00000000,          /* .long  _GLOBAL_OFFSET_TABLE_         */
 };
 
 /* The format of subsequent entries in a VxWorks executable.  */
 static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] =
 {
-  0xe59fc000,         /* ldr    ip,[pc]                        */
-  0xe59cf000,         /* ldr    pc,[ip]                        */
-  0x00000000,         /* .long  @got                           */
-  0xe59fc000,         /* ldr    ip,[pc]                        */
-  0xea000000,         /* b      _PLT                           */
-  0x00000000,         /* .long  @pltindex*sizeof(Elf32_Rela)   */
+  0xe59fc000,        /* ldr    ip,[pc]                 */
+  0xe59cf000,        /* ldr    pc,[ip]                 */
+  0x00000000,        /* .long  @got                            */
+  0xe59fc000,        /* ldr    ip,[pc]                 */
+  0xea000000,        /* b      _PLT                            */
+  0x00000000,        /* .long  @pltindex*sizeof(Elf32_Rela)    */
 };
 
 /* The format of entries in a VxWorks shared library.  */
 static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] =
 {
-  0xe59fc000,         /* ldr    ip,[pc]                        */
-  0xe79cf009,         /* ldr    pc,[ip,r9]                     */
-  0x00000000,         /* .long  @got                           */
-  0xe59fc000,         /* ldr    ip,[pc]                        */
-  0xe599f008,         /* ldr    pc,[r9,#8]                     */
-  0x00000000,         /* .long  @pltindex*sizeof(Elf32_Rela)   */
+  0xe59fc000,        /* ldr    ip,[pc]                 */
+  0xe79cf009,        /* ldr    pc,[ip,r9]                      */
+  0x00000000,        /* .long  @got                            */
+  0xe59fc000,        /* ldr    ip,[pc]                 */
+  0xe599f008,        /* ldr    pc,[r9,#8]                      */
+  0x00000000,        /* .long  @pltindex*sizeof(Elf32_Rela)    */
 };
 
 /* An initial stub used if the PLT entry is referenced from Thumb code.  */
@@ -2290,15 +2494,7 @@ static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] =
 static const bfd_vma elf32_arm_plt_thumb_stub [] =
 {
   0x4778,              /* bx pc */
-  0x46c0               /* nop   */
-};
-
-/* The entries in a PLT when using a DLL-based target with multiple
-   address spaces.  */
-static const bfd_vma elf32_arm_symbian_plt_entry [] =
-{
-  0xe51ff004,         /* ldr   pc, [pc, #-4] */
-  0x00000000,         /* dcd   R_ARM_GLOB_DAT(X) */
+  0xe7fd               /* b .-2 */
 };
 
 /* The first entry in a procedure linkage table looks like
@@ -2371,17 +2567,19 @@ enum stub_insn_type
 
 typedef struct
 {
-  bfd_vma              data;
+  bfd_vma             data;
   enum stub_insn_type  type;
-  unsigned int         r_type;
-  int                  reloc_addend;
+  unsigned int        r_type;
+  int                 reloc_addend;
 }  insn_sequence;
 
+/* See note [Thumb nop sequence] when adding a veneer.  */
+
 /* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx
    to reach the stub if necessary.  */
 static const insn_sequence elf32_arm_stub_long_branch_any_any[] =
 {
-  ARM_INSN (0xe51ff004),            /* ldr   pc, [pc, #-4] */
+  ARM_INSN (0xe51ff004),           /* ldr   pc, [pc, #-4] */
   DATA_WORD (0, R_ARM_ABS32, 0),    /* dcd   R_ARM_ABS32(X) */
 };
 
@@ -2389,27 +2587,27 @@ static const insn_sequence elf32_arm_stub_long_branch_any_any[] =
    available.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] =
 {
-  ARM_INSN (0xe59fc000),            /* ldr   ip, [pc, #0] */
-  ARM_INSN (0xe12fff1c),            /* bx    ip */
+  ARM_INSN (0xe59fc000),           /* ldr   ip, [pc, #0] */
+  ARM_INSN (0xe12fff1c),           /* bx    ip */
   DATA_WORD (0, R_ARM_ABS32, 0),    /* dcd   R_ARM_ABS32(X) */
 };
 
 /* Thumb -> Thumb long branch stub. Used on M-profile architectures.  */
 static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] =
 {
-  THUMB16_INSN (0xb401),             /* push {r0} */
-  THUMB16_INSN (0x4802),             /* ldr  r0, [pc, #8] */
-  THUMB16_INSN (0x4684),             /* mov  ip, r0 */
-  THUMB16_INSN (0xbc01),             /* pop  {r0} */
-  THUMB16_INSN (0x4760),             /* bx   ip */
-  THUMB16_INSN (0xbf00),             /* nop */
+  THUMB16_INSN (0xb401),            /* push {r0} */
+  THUMB16_INSN (0x4802),            /* ldr  r0, [pc, #8] */
+  THUMB16_INSN (0x4684),            /* mov  ip, r0 */
+  THUMB16_INSN (0xbc01),            /* pop  {r0} */
+  THUMB16_INSN (0x4760),            /* bx   ip */
+  THUMB16_INSN (0xbf00),            /* nop */
   DATA_WORD (0, R_ARM_ABS32, 0),     /* dcd  R_ARM_ABS32(X) */
 };
 
 /* Thumb -> Thumb long branch stub in thumb2 encoding.  Used on armv7.  */
 static const insn_sequence elf32_arm_stub_long_branch_thumb2_only[] =
 {
-  THUMB32_INSN (0xf85ff000),         /* ldr.w  pc, [pc, #-0] */
+  THUMB32_INSN (0xf85ff000),        /* ldr.w  pc, [pc, #-0] */
   DATA_WORD (0, R_ARM_ABS32, 0),     /* dcd  R_ARM_ABS32(x) */
 };
 
@@ -2419,17 +2617,17 @@ static const insn_sequence elf32_arm_stub_long_branch_thumb2_only_pure[] =
 {
   THUMB32_MOVW (0xf2400c00),        /* mov.w ip, R_ARM_MOVW_ABS_NC */
   THUMB32_MOVT (0xf2c00c00),        /* movt  ip, R_ARM_MOVT_ABS << 16 */
-  THUMB16_INSN (0x4760),             /* bx   ip */
+  THUMB16_INSN (0x4760),            /* bx   ip */
 };
 
 /* V4T Thumb -> Thumb long branch stub. Using the stack is not
    allowed.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] =
 {
-  THUMB16_INSN (0x4778),             /* bx   pc */
-  THUMB16_INSN (0x46c0),             /* nop */
-  ARM_INSN (0xe59fc000),             /* ldr  ip, [pc, #0] */
-  ARM_INSN (0xe12fff1c),             /* bx   ip */
+  THUMB16_INSN (0x4778),            /* bx   pc */
+  THUMB16_INSN (0xe7fd),            /* b   .-2 */
+  ARM_INSN (0xe59fc000),            /* ldr  ip, [pc, #0] */
+  ARM_INSN (0xe12fff1c),            /* bx   ip */
   DATA_WORD (0, R_ARM_ABS32, 0),     /* dcd  R_ARM_ABS32(X) */
 };
 
@@ -2437,9 +2635,9 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] =
    available.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] =
 {
-  THUMB16_INSN (0x4778),             /* bx   pc */
-  THUMB16_INSN (0x46c0),             /* nop   */
-  ARM_INSN (0xe51ff004),             /* ldr   pc, [pc, #-4] */
+  THUMB16_INSN (0x4778),            /* bx   pc */
+  THUMB16_INSN (0xe7fd),            /* b   .-2 */
+  ARM_INSN (0xe51ff004),            /* ldr   pc, [pc, #-4] */
   DATA_WORD (0, R_ARM_ABS32, 0),     /* dcd   R_ARM_ABS32(X) */
 };
 
@@ -2447,8 +2645,8 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] =
    one, when the destination is close enough.  */
 static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] =
 {
-  THUMB16_INSN (0x4778),             /* bx   pc */
-  THUMB16_INSN (0x46c0),             /* nop   */
+  THUMB16_INSN (0x4778),            /* bx   pc */
+  THUMB16_INSN (0xe7fd),            /* b   .-2 */
   ARM_REL_INSN (0xea000000, -8),     /* b    (X-8) */
 };
 
@@ -2456,8 +2654,8 @@ static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] =
    blx to reach the stub if necessary.  */
 static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] =
 {
-  ARM_INSN (0xe59fc000),             /* ldr   ip, [pc] */
-  ARM_INSN (0xe08ff00c),             /* add   pc, pc, ip */
+  ARM_INSN (0xe59fc000),            /* ldr   ip, [pc] */
+  ARM_INSN (0xe08ff00c),            /* add   pc, pc, ip */
   DATA_WORD (0, R_ARM_REL32, -4),    /* dcd   R_ARM_REL32(X-4) */
 };
 
@@ -2467,28 +2665,28 @@ static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] =
    ARMv7).  */
 static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] =
 {
-  ARM_INSN (0xe59fc004),             /* ldr   ip, [pc, #4] */
-  ARM_INSN (0xe08fc00c),             /* add   ip, pc, ip */
-  ARM_INSN (0xe12fff1c),             /* bx    ip */
+  ARM_INSN (0xe59fc004),            /* ldr   ip, [pc, #4] */
+  ARM_INSN (0xe08fc00c),            /* add   ip, pc, ip */
+  ARM_INSN (0xe12fff1c),            /* bx    ip */
   DATA_WORD (0, R_ARM_REL32, 0),     /* dcd   R_ARM_REL32(X) */
 };
 
 /* V4T ARM -> ARM long branch stub, PIC.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] =
 {
-  ARM_INSN (0xe59fc004),             /* ldr   ip, [pc, #4] */
-  ARM_INSN (0xe08fc00c),             /* add   ip, pc, ip */
-  ARM_INSN (0xe12fff1c),             /* bx    ip */
+  ARM_INSN (0xe59fc004),            /* ldr   ip, [pc, #4] */
+  ARM_INSN (0xe08fc00c),            /* add   ip, pc, ip */
+  ARM_INSN (0xe12fff1c),            /* bx    ip */
   DATA_WORD (0, R_ARM_REL32, 0),     /* dcd   R_ARM_REL32(X) */
 };
 
 /* V4T Thumb -> ARM long branch stub, PIC.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
 {
-  THUMB16_INSN (0x4778),             /* bx   pc */
-  THUMB16_INSN (0x46c0),             /* nop  */
-  ARM_INSN (0xe59fc000),             /* ldr  ip, [pc, #0] */
-  ARM_INSN (0xe08cf00f),             /* add  pc, ip, pc */
+  THUMB16_INSN (0x4778),            /* bx   pc */
+  THUMB16_INSN (0xe7fd),            /* b   .-2 */
+  ARM_INSN (0xe59fc000),            /* ldr  ip, [pc, #0] */
+  ARM_INSN (0xe08cf00f),            /* add  pc, ip, pc */
   DATA_WORD (0, R_ARM_REL32, -4),     /* dcd  R_ARM_REL32(X) */
 };
 
@@ -2496,12 +2694,12 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
    architectures.  */
 static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] =
 {
-  THUMB16_INSN (0xb401),             /* push {r0} */
-  THUMB16_INSN (0x4802),             /* ldr  r0, [pc, #8] */
-  THUMB16_INSN (0x46fc),             /* mov  ip, pc */
-  THUMB16_INSN (0x4484),             /* add  ip, r0 */
-  THUMB16_INSN (0xbc01),             /* pop  {r0} */
-  THUMB16_INSN (0x4760),             /* bx   ip */
+  THUMB16_INSN (0xb401),            /* push {r0} */
+  THUMB16_INSN (0x4802),            /* ldr  r0, [pc, #8] */
+  THUMB16_INSN (0x46fc),            /* mov  ip, pc */
+  THUMB16_INSN (0x4484),            /* add  ip, r0 */
+  THUMB16_INSN (0xbc01),            /* pop  {r0} */
+  THUMB16_INSN (0x4760),            /* bx   ip */
   DATA_WORD (0, R_ARM_REL32, 4),     /* dcd  R_ARM_REL32(X) */
 };
 
@@ -2509,11 +2707,11 @@ static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] =
    allowed.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] =
 {
-  THUMB16_INSN (0x4778),             /* bx   pc */
-  THUMB16_INSN (0x46c0),             /* nop */
-  ARM_INSN (0xe59fc004),             /* ldr  ip, [pc, #4] */
-  ARM_INSN (0xe08fc00c),             /* add   ip, pc, ip */
-  ARM_INSN (0xe12fff1c),             /* bx   ip */
+  THUMB16_INSN (0x4778),            /* bx   pc */
+  THUMB16_INSN (0xe7fd),            /* b   .-2 */
+  ARM_INSN (0xe59fc004),            /* ldr  ip, [pc, #4] */
+  ARM_INSN (0xe08fc00c),            /* add   ip, pc, ip */
+  ARM_INSN (0xe12fff1c),            /* bx   ip */
   DATA_WORD (0, R_ARM_REL32, 0),     /* dcd  R_ARM_REL32(X) */
 };
 
@@ -2521,8 +2719,8 @@ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] =
    long PIC stub.  We can use r1 as a scratch -- and cannot use ip.  */
 static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] =
 {
-  ARM_INSN (0xe59f1000),             /* ldr   r1, [pc] */
-  ARM_INSN (0xe08ff001),             /* add   pc, pc, r1 */
+  ARM_INSN (0xe59f1000),            /* ldr   r1, [pc] */
+  ARM_INSN (0xe08ff001),            /* add   pc, pc, r1 */
   DATA_WORD (0, R_ARM_REL32, -4),    /* dcd   R_ARM_REL32(X-4) */
 };
 
@@ -2530,10 +2728,10 @@ static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] =
    long PIC stub.  We can use r1 as a scratch -- and cannot use ip.  */
 static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] =
 {
-  THUMB16_INSN (0x4778),             /* bx   pc */
-  THUMB16_INSN (0x46c0),             /* nop */
-  ARM_INSN (0xe59f1000),             /* ldr  r1, [pc, #0] */
-  ARM_INSN (0xe081f00f),             /* add  pc, r1, pc */
+  THUMB16_INSN (0x4778),            /* bx   pc */
+  THUMB16_INSN (0xe7fd),            /* b   .-2 */
+  ARM_INSN (0xe59f1000),            /* ldr  r1, [pc, #0] */
+  ARM_INSN (0xe081f00f),            /* add  pc, r1, pc */
   DATA_WORD (0, R_ARM_REL32, -4),    /* dcd  R_ARM_REL32(X) */
 };
 
@@ -2542,25 +2740,25 @@ static const insn_sequence elf32_arm_stub_long_branch_arm_nacl[] =
 {
   ARM_INSN (0xe59fc00c),               /* ldr  ip, [pc, #12] */
   ARM_INSN (0xe3ccc13f),               /* bic  ip, ip, #0xc000000f */
-  ARM_INSN (0xe12fff1c),                /* bx  ip */
-  ARM_INSN (0xe320f000),                /* nop */
-  ARM_INSN (0xe125be70),                /* bkpt        0x5be0 */
-  DATA_WORD (0, R_ARM_ABS32, 0),        /* dcd R_ARM_ABS32(X) */
-  DATA_WORD (0, R_ARM_NONE, 0),         /* .word 0 */
-  DATA_WORD (0, R_ARM_NONE, 0),         /* .word 0 */
+  ARM_INSN (0xe12fff1c),               /* bx   ip */
+  ARM_INSN (0xe320f000),               /* nop */
+  ARM_INSN (0xe125be70),               /* bkpt 0x5be0 */
+  DATA_WORD (0, R_ARM_ABS32, 0),       /* dcd  R_ARM_ABS32(X) */
+  DATA_WORD (0, R_ARM_NONE, 0),                /* .word 0 */
+  DATA_WORD (0, R_ARM_NONE, 0),                /* .word 0 */
 };
 
 /* NaCl ARM -> ARM long branch stub, PIC.  */
 static const insn_sequence elf32_arm_stub_long_branch_arm_nacl_pic[] =
 {
   ARM_INSN (0xe59fc00c),               /* ldr  ip, [pc, #12] */
-  ARM_INSN (0xe08cc00f),                /* add ip, ip, pc */
+  ARM_INSN (0xe08cc00f),               /* add  ip, ip, pc */
   ARM_INSN (0xe3ccc13f),               /* bic  ip, ip, #0xc000000f */
-  ARM_INSN (0xe12fff1c),                /* bx  ip */
-  ARM_INSN (0xe125be70),                /* bkpt        0x5be0 */
-  DATA_WORD (0, R_ARM_REL32, 8),        /* dcd R_ARM_REL32(X+8) */
-  DATA_WORD (0, R_ARM_NONE, 0),         /* .word 0 */
-  DATA_WORD (0, R_ARM_NONE, 0),         /* .word 0 */
+  ARM_INSN (0xe12fff1c),               /* bx   ip */
+  ARM_INSN (0xe125be70),               /* bkpt 0x5be0 */
+  DATA_WORD (0, R_ARM_REL32, 8),       /* dcd  R_ARM_REL32(X+8) */
+  DATA_WORD (0, R_ARM_NONE, 0),                /* .word 0 */
+  DATA_WORD (0, R_ARM_NONE, 0),                /* .word 0 */
 };
 
 /* Stub used for transition to secure state (aka SG veneer).  */
@@ -2578,7 +2776,7 @@ static const insn_sequence elf32_arm_stub_cmse_branch_thumb_only[] =
 
 static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] =
 {
-  THUMB16_BCOND_INSN (0xd001),         /* b<cond>.n true.  */
+  THUMB16_BCOND_INSN (0xd001),        /* b<cond>.n true.  */
   THUMB32_B_INSN (0xf000b800, -4),     /* b.w insn_after_original_branch.  */
   THUMB32_B_INSN (0xf000b800, -4)      /* true: b.w original_branch_dest.  */
 };
@@ -2633,29 +2831,29 @@ static const insn_sequence elf32_arm_stub_a8_veneer_blx[] =
 
 /* One entry per long/short branch stub defined above.  */
 #define DEF_STUBS \
-  DEF_STUB(long_branch_any_any)        \
-  DEF_STUB(long_branch_v4t_arm_thumb) \
-  DEF_STUB(long_branch_thumb_only) \
-  DEF_STUB(long_branch_v4t_thumb_thumb)        \
-  DEF_STUB(long_branch_v4t_thumb_arm) \
-  DEF_STUB(short_branch_v4t_thumb_arm) \
-  DEF_STUB(long_branch_any_arm_pic) \
-  DEF_STUB(long_branch_any_thumb_pic) \
-  DEF_STUB(long_branch_v4t_thumb_thumb_pic) \
-  DEF_STUB(long_branch_v4t_arm_thumb_pic) \
-  DEF_STUB(long_branch_v4t_thumb_arm_pic) \
-  DEF_STUB(long_branch_thumb_only_pic) \
-  DEF_STUB(long_branch_any_tls_pic) \
-  DEF_STUB(long_branch_v4t_thumb_tls_pic) \
-  DEF_STUB(long_branch_arm_nacl) \
-  DEF_STUB(long_branch_arm_nacl_pic) \
-  DEF_STUB(cmse_branch_thumb_only) \
-  DEF_STUB(a8_veneer_b_cond) \
-  DEF_STUB(a8_veneer_b) \
-  DEF_STUB(a8_veneer_bl) \
-  DEF_STUB(a8_veneer_blx) \
-  DEF_STUB(long_branch_thumb2_only) \
-  DEF_STUB(long_branch_thumb2_only_pure)
+  DEF_STUB (long_branch_any_any)       \
+  DEF_STUB (long_branch_v4t_arm_thumb) \
+  DEF_STUB (long_branch_thumb_only) \
+  DEF_STUB (long_branch_v4t_thumb_thumb)       \
+  DEF_STUB (long_branch_v4t_thumb_arm) \
+  DEF_STUB (short_branch_v4t_thumb_arm) \
+  DEF_STUB (long_branch_any_arm_pic) \
+  DEF_STUB (long_branch_any_thumb_pic) \
+  DEF_STUB (long_branch_v4t_thumb_thumb_pic) \
+  DEF_STUB (long_branch_v4t_arm_thumb_pic) \
+  DEF_STUB (long_branch_v4t_thumb_arm_pic) \
+  DEF_STUB (long_branch_thumb_only_pic) \
+  DEF_STUB (long_branch_any_tls_pic) \
+  DEF_STUB (long_branch_v4t_thumb_tls_pic) \
+  DEF_STUB (long_branch_arm_nacl) \
+  DEF_STUB (long_branch_arm_nacl_pic) \
+  DEF_STUB (cmse_branch_thumb_only) \
+  DEF_STUB (a8_veneer_b_cond) \
+  DEF_STUB (a8_veneer_b) \
+  DEF_STUB (a8_veneer_bl) \
+  DEF_STUB (a8_veneer_blx) \
+  DEF_STUB (long_branch_thumb2_only) \
+  DEF_STUB (long_branch_thumb2_only_pure)
 
 #define DEF_STUB(x) arm_stub_##x,
 enum elf32_arm_stub_type
@@ -2890,7 +3088,7 @@ struct a8_erratum_reloc
   const char *sym_name;
   unsigned int r_type;
   enum arm_st_branch_type branch_type;
-  bfd_boolean non_a8_stub;
+  bool non_a8_stub;
 };
 
 /* The size of the thread control block.  */
@@ -2936,10 +3134,28 @@ struct arm_local_iplt_info
   struct elf_dyn_relocs *dyn_relocs;
 };
 
+/* Structure to handle FDPIC support for local functions.  */
+struct fdpic_local
+{
+  unsigned int funcdesc_cnt;
+  unsigned int gotofffuncdesc_cnt;
+  int funcdesc_offset;
+};
+
 struct elf_arm_obj_tdata
 {
   struct elf_obj_tdata root;
 
+  /* Zero to warn when linking objects with incompatible enum sizes.  */
+  int no_enum_size_warning;
+
+  /* Zero to warn when linking objects with incompatible wchar_t sizes.  */
+  int no_wchar_size_warning;
+
+  /* The number of entries in each of the arrays in this strcuture.
+     Used to avoid buffer overruns.  */
+  bfd_size_type num_entries;
+
   /* tls_type for each local got entry.  */
   char *local_got_tls_type;
 
@@ -2949,16 +3165,16 @@ struct elf_arm_obj_tdata
   /* Information for local symbols that need entries in .iplt.  */
   struct arm_local_iplt_info **local_iplt;
 
-  /* Zero to warn when linking objects with incompatible enum sizes.  */
-  int no_enum_size_warning;
-
-  /* Zero to warn when linking objects with incompatible wchar_t sizes.  */
-  int no_wchar_size_warning;
+  /* Maintains FDPIC counters and funcdesc info.  */
+  struct fdpic_local *local_fdpic_cnts;
 };
 
 #define elf_arm_tdata(bfd) \
   ((struct elf_arm_obj_tdata *) (bfd)->tdata.any)
 
+#define elf32_arm_num_entries(bfd) \
+  (elf_arm_tdata (bfd)->num_entries)
+
 #define elf32_arm_local_got_tls_type(bfd) \
   (elf_arm_tdata (bfd)->local_got_tls_type)
 
@@ -2968,12 +3184,15 @@ struct elf_arm_obj_tdata
 #define elf32_arm_local_iplt(bfd) \
   (elf_arm_tdata (bfd)->local_iplt)
 
+#define elf32_arm_local_fdpic_cnts(bfd) \
+  (elf_arm_tdata (bfd)->local_fdpic_cnts)
+
 #define is_arm_elf(bfd) \
   (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
    && elf_tdata (bfd) != NULL \
    && elf_object_id (bfd) == ARM_ELF_DATA)
 
-static bfd_boolean
+static bool
 elf32_arm_mkobject (bfd *abfd)
 {
   return bfd_elf_allocate_object (abfd, sizeof (struct elf_arm_obj_tdata),
@@ -2982,14 +3201,20 @@ elf32_arm_mkobject (bfd *abfd)
 
 #define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent))
 
+/* Structure to handle FDPIC support for extern functions.  */
+struct fdpic_global {
+  unsigned int gotofffuncdesc_cnt;
+  unsigned int gotfuncdesc_cnt;
+  unsigned int funcdesc_cnt;
+  int funcdesc_offset;
+  int gotfuncdesc_offset;
+};
+
 /* Arm ELF linker hash entry.  */
 struct elf32_arm_link_hash_entry
 {
   struct elf_link_hash_entry root;
 
-  /* Track dynamic relocs copied for this symbol.  */
-  struct elf_dyn_relocs *dyn_relocs;
-
   /* ARM-specific PLT information.  */
   struct arm_plt_info plt;
 
@@ -3017,19 +3242,23 @@ struct elf32_arm_link_hash_entry
   /* A pointer to the most recently used stub hash entry against this
      symbol.  */
   struct elf32_arm_stub_hash_entry *stub_cache;
+
+  /* Counter for FDPIC relocations against this symbol.  */
+  struct fdpic_global fdpic_cnts;
 };
 
 /* Traverse an arm ELF linker hash table.  */
 #define elf32_arm_link_hash_traverse(table, func, info)                        \
   (elf_link_hash_traverse                                              \
    (&(table)->root,                                                    \
-    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),   \
+    (bool (*) (struct elf_link_hash_entry *, void *)) (func),          \
     (info)))
 
 /* Get the ARM elf linker hash table from a link_info structure.  */
-#define elf32_arm_hash_table(info) \
-  (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
-  == ARM_ELF_DATA ? ((struct elf32_arm_link_hash_table *) ((info)->hash)) : NULL)
+#define elf32_arm_hash_table(p) \
+  ((is_elf_hash_table ((p)->hash)                                      \
+    && elf_hash_table_id (elf_hash_table (p)) == ARM_ELF_DATA)         \
+   ? (struct elf32_arm_link_hash_table *) (p)->hash : NULL)
 
 #define arm_stub_hash_lookup(table, string, create, copy) \
   ((struct elf32_arm_stub_hash_entry *) \
@@ -3132,17 +3361,8 @@ struct elf32_arm_link_hash_table
   /* The number of bytes in the subsequent PLT etries.  */
   bfd_size_type plt_entry_size;
 
-  /* True if the target system is VxWorks.  */
-  int vxworks_p;
-
-  /* True if the target system is Symbian OS.  */
-  int symbian_p;
-
-  /* True if the target system is Native Client.  */
-  int nacl_p;
-
   /* True if the target uses REL relocations.  */
-  int use_rel;
+  bool use_rel;
 
   /* Nonzero if import library must be a secure gateway import library
      as per ARMv8-M Security Extensions.  */
@@ -3161,29 +3381,16 @@ struct elf32_arm_link_hash_table
   /* The (unloaded but important) VxWorks .rela.plt.unloaded section.  */
   asection *srelplt2;
 
-  /* The offset into splt of the PLT entry for the TLS descriptor
-     resolver.  Special values are 0, if not necessary (or not found
-     to be necessary yet), and -1 if needed but not determined
-     yet.  */
-  bfd_vma dt_tlsdesc_plt;
-
-  /* The offset into sgot of the GOT entry used by the PLT entry
-     above.  */
-  bfd_vma dt_tlsdesc_got;
-
   /* Offset in .plt section of tls_arm_trampoline.  */
   bfd_vma tls_trampoline;
 
-  /* Data for R_ARM_TLS_LDM32 relocations.  */
+  /* Data for R_ARM_TLS_LDM32/R_ARM_TLS_LDM32_FDPIC relocations.  */
   union
   {
     bfd_signed_vma refcount;
     bfd_vma offset;
   } tls_ldm_got;
 
-  /* Small local sym cache.  */
-  struct sym_cache sym_cache;
-
   /* For convenience in allocate_dynrelocs.  */
   bfd * obfd;
 
@@ -3220,8 +3427,25 @@ struct elf32_arm_link_hash_table
   unsigned int bfd_count;
   unsigned int top_index;
   asection **input_list;
+
+  /* True if the target system uses FDPIC. */
+  int fdpic_p;
+
+  /* Fixup section. Used for FDPIC.  */
+  asection *srofixup;
 };
 
+/* Add an FDPIC read-only fixup.  */
+static void
+arm_elf_add_rofixup (bfd *output_bfd, asection *srofixup, bfd_vma offset)
+{
+  bfd_vma fixup_offset;
+
+  fixup_offset = srofixup->reloc_count++ * 4;
+  BFD_ASSERT (fixup_offset < srofixup->size);
+  bfd_put_32 (output_bfd, offset, srofixup->contents + fixup_offset);
+}
+
 static inline int
 ctz (unsigned int mask)
 {
@@ -3259,6 +3483,57 @@ elf32_arm_popcount (unsigned int mask)
 #endif
 }
 
+static void elf32_arm_add_dynreloc (bfd *output_bfd, struct bfd_link_info *info,
+                                   asection *sreloc, Elf_Internal_Rela *rel);
+
+static void
+arm_elf_fill_funcdesc (bfd *output_bfd,
+                      struct bfd_link_info *info,
+                      int *funcdesc_offset,
+                      int dynindx,
+                      int offset,
+                      bfd_vma addr,
+                      bfd_vma dynreloc_value,
+                      bfd_vma seg)
+{
+  if ((*funcdesc_offset & 1) == 0)
+    {
+      struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
+      asection *sgot = globals->root.sgot;
+
+      if (bfd_link_pic (info))
+       {
+         asection *srelgot = globals->root.srelgot;
+         Elf_Internal_Rela outrel;
+
+         outrel.r_info = ELF32_R_INFO (dynindx, R_ARM_FUNCDESC_VALUE);
+         outrel.r_offset = sgot->output_section->vma + sgot->output_offset + offset;
+         outrel.r_addend = 0;
+
+         elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+         bfd_put_32 (output_bfd, addr, sgot->contents + offset);
+         bfd_put_32 (output_bfd, seg, sgot->contents + offset + 4);
+       }
+      else
+       {
+         struct elf_link_hash_entry *hgot = globals->root.hgot;
+         bfd_vma got_value = hgot->root.u.def.value
+           + hgot->root.u.def.section->output_section->vma
+           + hgot->root.u.def.section->output_offset;
+
+         arm_elf_add_rofixup (output_bfd, globals->srofixup,
+                              sgot->output_section->vma + sgot->output_offset
+                              + offset);
+         arm_elf_add_rofixup (output_bfd, globals->srofixup,
+                              sgot->output_section->vma + sgot->output_offset
+                              + offset + 4);
+         bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + offset);
+         bfd_put_32 (output_bfd, got_value, sgot->contents + offset + 4);
+       }
+      *funcdesc_offset |= 1;
+    }
+}
+
 /* Create an entry in an ARM ELF linker hash table.  */
 
 static struct bfd_hash_entry *
@@ -3283,17 +3558,22 @@ elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
                                     table, string));
   if (ret != NULL)
     {
-      ret->dyn_relocs = NULL;
       ret->tls_type = GOT_UNKNOWN;
       ret->tlsdesc_got = (bfd_vma) -1;
       ret->plt.thumb_refcount = 0;
       ret->plt.maybe_thumb_refcount = 0;
       ret->plt.noncall_refcount = 0;
       ret->plt.got_offset = -1;
-      ret->is_iplt = FALSE;
+      ret->is_iplt = false;
       ret->export_glue = NULL;
 
       ret->stub_cache = NULL;
+
+      ret->fdpic_cnts.gotofffuncdesc_cnt = 0;
+      ret->fdpic_cnts.gotfuncdesc_cnt = 0;
+      ret->fdpic_cnts.funcdesc_cnt = 0;
+      ret->fdpic_cnts.funcdesc_offset = -1;
+      ret->fdpic_cnts.gotfuncdesc_offset = -1;
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -3302,36 +3582,66 @@ elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
 /* Ensure that we have allocated bookkeeping structures for ABFD's local
    symbols.  */
 
-static bfd_boolean
+static bool
 elf32_arm_allocate_local_sym_info (bfd *abfd)
 {
   if (elf_local_got_refcounts (abfd) == NULL)
     {
       bfd_size_type num_syms;
-      bfd_size_type size;
-      char *data;
+
+      elf32_arm_num_entries (abfd) = 0;
+
+      /* Whilst it might be tempting to allocate a single block of memory and
+        then divide it up amoungst the arrays in the elf_arm_obj_tdata
+        structure, this interferes with the work of memory checkers looking
+        for buffer overruns.  So allocate each array individually.  */
 
       num_syms = elf_tdata (abfd)->symtab_hdr.sh_info;
-      size = num_syms * (sizeof (bfd_signed_vma)
-                        + sizeof (struct arm_local_iplt_info *)
-                        + sizeof (bfd_vma)
-                        + sizeof (char));
-      data = bfd_zalloc (abfd, size);
-      if (data == NULL)
-       return FALSE;
 
-      elf_local_got_refcounts (abfd) = (bfd_signed_vma *) data;
-      data += num_syms * sizeof (bfd_signed_vma);
+      elf_local_got_refcounts (abfd) = bfd_zalloc
+       (abfd, num_syms * sizeof (* elf_local_got_refcounts (abfd)));
+
+      if (elf_local_got_refcounts (abfd) == NULL)
+       return false;
+
+      elf32_arm_local_tlsdesc_gotent (abfd) = bfd_zalloc
+       (abfd, num_syms * sizeof (* elf32_arm_local_tlsdesc_gotent (abfd)));
+
+      if (elf32_arm_local_tlsdesc_gotent (abfd) == NULL)
+       return false;
+
+      elf32_arm_local_iplt (abfd) = bfd_zalloc
+       (abfd, num_syms * sizeof (* elf32_arm_local_iplt (abfd)));
+
+      if (elf32_arm_local_iplt (abfd) == NULL)
+       return false;
+
+      elf32_arm_local_fdpic_cnts (abfd) = bfd_zalloc
+       (abfd, num_syms * sizeof (* elf32_arm_local_fdpic_cnts (abfd)));
+
+      if (elf32_arm_local_fdpic_cnts (abfd) == NULL)
+       return false;
+
+      elf32_arm_local_got_tls_type (abfd) = bfd_zalloc
+       (abfd, num_syms * sizeof (* elf32_arm_local_got_tls_type (abfd)));
 
-      elf32_arm_local_iplt (abfd) = (struct arm_local_iplt_info **) data;
-      data += num_syms * sizeof (struct arm_local_iplt_info *);
+      if (elf32_arm_local_got_tls_type (abfd) == NULL)
+       return false;
 
-      elf32_arm_local_tlsdesc_gotent (abfd) = (bfd_vma *) data;
-      data += num_syms * sizeof (bfd_vma);
+      elf32_arm_num_entries (abfd) = num_syms;
 
-      elf32_arm_local_got_tls_type (abfd) = data;
+#if GCC_VERSION >= 3000
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_tlsdesc_gotent (abfd))
+                 <= __alignof__ (*elf_local_got_refcounts (abfd)));
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_iplt (abfd))
+                 <= __alignof__ (*elf32_arm_local_tlsdesc_gotent (abfd)));
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_fdpic_cnts (abfd))
+                 <= __alignof__ (*elf32_arm_local_iplt (abfd)));
+      BFD_ASSERT (__alignof__ (*elf32_arm_local_got_tls_type (abfd))
+                 <= __alignof__ (*elf32_arm_local_fdpic_cnts (abfd)));
+#endif
     }
-  return TRUE;
+  return true;
 }
 
 /* Return the .iplt information for local symbol R_SYMNDX, which belongs
@@ -3347,6 +3657,7 @@ elf32_arm_create_local_iplt (bfd *abfd, unsigned long r_symndx)
     return NULL;
 
   BFD_ASSERT (r_symndx < elf_tdata (abfd)->symtab_hdr.sh_info);
+  BFD_ASSERT (r_symndx < elf32_arm_num_entries (abfd));
   ptr = &elf32_arm_local_iplt (abfd)[r_symndx];
   if (*ptr == NULL)
     *ptr = bfd_zalloc (abfd, sizeof (**ptr));
@@ -3361,7 +3672,7 @@ elf32_arm_create_local_iplt (bfd *abfd, unsigned long r_symndx)
    true, point *ROOT_PLT at the target-independent reference count/offset
    union and *ARM_PLT at the ARM-specific information.  */
 
-static bfd_boolean
+static bool
 elf32_arm_get_plt_info (bfd *abfd, struct elf32_arm_link_hash_table *globals,
                        struct elf32_arm_link_hash_entry *h,
                        unsigned long r_symndx, union gotplt_union **root_plt,
@@ -3370,39 +3681,45 @@ elf32_arm_get_plt_info (bfd *abfd, struct elf32_arm_link_hash_table *globals,
   struct arm_local_iplt_info *local_iplt;
 
   if (globals->root.splt == NULL && globals->root.iplt == NULL)
-    return FALSE;
+    return false;
 
   if (h != NULL)
     {
       *root_plt = &h->root.plt;
       *arm_plt = &h->plt;
-      return TRUE;
+      return true;
     }
 
   if (elf32_arm_local_iplt (abfd) == NULL)
-    return FALSE;
+    return false;
+
+  if (r_symndx >= elf32_arm_num_entries (abfd))
+    return false;
 
   local_iplt = elf32_arm_local_iplt (abfd)[r_symndx];
   if (local_iplt == NULL)
-    return FALSE;
+    return false;
 
   *root_plt = &local_iplt->root;
   *arm_plt = &local_iplt->arm;
-  return TRUE;
+  return true;
 }
 
+static bool using_thumb_only (struct elf32_arm_link_hash_table *globals);
+
 /* Return true if the PLT described by ARM_PLT requires a Thumb stub
    before it.  */
 
-static bfd_boolean
+static bool
 elf32_arm_plt_needs_thumb_stub_p (struct bfd_link_info *info,
                                  struct arm_plt_info *arm_plt)
 {
   struct elf32_arm_link_hash_table *htab;
 
   htab = elf32_arm_hash_table (info);
-  return (arm_plt->thumb_refcount != 0
-         || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0));
+
+  return (!using_thumb_only (htab) && (arm_plt->thumb_refcount != 0
+         || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0)));
 }
 
 /* Return a pointer to the head of the dynamic reloc list that should
@@ -3432,7 +3749,7 @@ elf32_arm_get_local_dynreloc_list (bfd *abfd, unsigned long r_symndx,
 
       s = bfd_section_from_elf_index (abfd, isym->st_shndx);
       if (s == NULL)
-       abort ();
+       return NULL;
 
       vpp = &elf_section_data (s)->local_dynrel;
       return (struct elf_dyn_relocs **) vpp;
@@ -3485,28 +3802,35 @@ stub_hash_newfunc (struct bfd_hash_entry *entry,
 /* Create .got, .gotplt, and .rel(a).got sections in DYNOBJ, and set up
    shortcuts to them in our hash table.  */
 
-static bfd_boolean
+static bool
 create_got_section (bfd *dynobj, struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *htab;
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
-
-  /* BPABI objects never have a GOT, or associated sections.  */
-  if (htab->symbian_p)
-    return TRUE;
+    return false;
 
   if (! _bfd_elf_create_got_section (dynobj, info))
-    return FALSE;
+    return false;
+
+  /* Also create .rofixup.  */
+  if (htab->fdpic_p)
+    {
+      htab->srofixup = bfd_make_section_with_flags (dynobj, ".rofixup",
+                                                   (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+                                                    | SEC_IN_MEMORY | SEC_LINKER_CREATED | SEC_READONLY));
+      if (htab->srofixup == NULL
+         || !bfd_set_section_alignment (htab->srofixup, 2))
+       return false;
+    }
 
-  return TRUE;
+  return true;
 }
 
 /* Create the .iplt, .rel(a).iplt and .igot.plt sections.  */
 
-static bfd_boolean
+static bool
 create_ifunc_sections (struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *htab;
@@ -3525,8 +3849,8 @@ create_ifunc_sections (struct bfd_link_info *info)
       s = bfd_make_section_anyway_with_flags (dynobj, ".iplt",
                                              flags | SEC_READONLY | SEC_CODE);
       if (s == NULL
-         || !bfd_set_section_alignment (dynobj, s, bed->plt_alignment))
-       return FALSE;
+         || !bfd_set_section_alignment (s, bed->plt_alignment))
+       return false;
       htab->root.iplt = s;
     }
 
@@ -3536,8 +3860,8 @@ create_ifunc_sections (struct bfd_link_info *info)
                                              RELOC_SECTION (htab, ".iplt"),
                                              flags | SEC_READONLY);
       if (s == NULL
-         || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
-       return FALSE;
+         || !bfd_set_section_alignment (s, bed->s->log_file_align))
+       return false;
       htab->root.irelplt = s;
     }
 
@@ -3545,16 +3869,16 @@ create_ifunc_sections (struct bfd_link_info *info)
     {
       s = bfd_make_section_anyway_with_flags (dynobj, ".igot.plt", flags);
       if (s == NULL
-         || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
-       return FALSE;
+         || !bfd_set_section_alignment (s, bed->s->log_file_align))
+       return false;
       htab->root.igotplt = s;
     }
-  return TRUE;
+  return true;
 }
 
 /* Determine if we're dealing with a Thumb only architecture.  */
 
-static bfd_boolean
+static bool
 using_thumb_only (struct elf32_arm_link_hash_table *globals)
 {
   int arch;
@@ -3567,53 +3891,57 @@ using_thumb_only (struct elf32_arm_link_hash_table *globals)
   arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   if (arch == TAG_CPU_ARCH_V6_M
       || arch == TAG_CPU_ARCH_V6S_M
       || arch == TAG_CPU_ARCH_V7E_M
       || arch == TAG_CPU_ARCH_V8M_BASE
-      || arch == TAG_CPU_ARCH_V8M_MAIN)
-    return TRUE;
+      || arch == TAG_CPU_ARCH_V8M_MAIN
+      || arch == TAG_CPU_ARCH_V8_1M_MAIN)
+    return true;
 
-  return FALSE;
+  return false;
 }
 
 /* Determine if we're dealing with a Thumb-2 object.  */
 
-static bfd_boolean
+static bool
 using_thumb2 (struct elf32_arm_link_hash_table *globals)
 {
   int arch;
   int thumb_isa = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
                                            Tag_THUMB_ISA_use);
 
-  if (thumb_isa)
+  /* No use of thumb permitted, or a legacy thumb-1/2 definition.  */
+  if (thumb_isa < 3)
     return thumb_isa == 2;
 
+  /* Variant of thumb is described by the architecture tag.  */
   arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   return (arch == TAG_CPU_ARCH_V6T2
          || arch == TAG_CPU_ARCH_V7
          || arch == TAG_CPU_ARCH_V7E_M
          || arch == TAG_CPU_ARCH_V8
          || arch == TAG_CPU_ARCH_V8R
-         || arch == TAG_CPU_ARCH_V8M_MAIN);
+         || arch == TAG_CPU_ARCH_V8M_MAIN
+         || arch == TAG_CPU_ARCH_V8_1M_MAIN);
 }
 
 /* Determine whether Thumb-2 BL instruction is available.  */
 
-static bfd_boolean
+static bool
 using_thumb2_bl (struct elf32_arm_link_hash_table *globals)
 {
   int arch =
     bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   /* Architecture was introduced after ARMv6T2 (eg. ARMv6-M).  */
   return (arch == TAG_CPU_ARCH_V6T2
@@ -3624,25 +3952,25 @@ using_thumb2_bl (struct elf32_arm_link_hash_table *globals)
    .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
    hash table.  */
 
-static bfd_boolean
+static bool
 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *htab;
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   if (!htab->root.sgot && !create_got_section (dynobj, info))
-    return FALSE;
+    return false;
 
   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
-    return FALSE;
+    return false;
 
-  if (htab->vxworks_p)
+  if (htab->root.target_os == is_vxworks)
     {
       if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
-       return FALSE;
+       return false;
 
       if (bfd_link_pic (info))
        {
@@ -3678,13 +4006,21 @@ elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
       htab->obfd = saved_obfd;
     }
 
+  if (htab->fdpic_p) {
+    htab->plt_header_size = 0;
+    if (info->flags & DF_BIND_NOW)
+      htab->plt_entry_size = 4 * (ARRAY_SIZE (elf32_arm_fdpic_plt_entry) - 5);
+    else
+      htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_fdpic_plt_entry);
+  }
+
   if (!htab->root.splt
       || !htab->root.srelplt
       || !htab->root.sdynbss
       || (!bfd_link_pic (info) && !htab->root.srelbss))
     abort ();
 
-  return TRUE;
+  return true;
 }
 
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
@@ -3699,38 +4035,7 @@ elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
   edir = (struct elf32_arm_link_hash_entry *) dir;
   eind = (struct elf32_arm_link_hash_entry *) ind;
 
-  if (eind->dyn_relocs != NULL)
-    {
-      if (edir->dyn_relocs != NULL)
-       {
-         struct elf_dyn_relocs **pp;
-         struct elf_dyn_relocs *p;
-
-         /* Add reloc counts against the indirect sym to the direct sym
-            list.  Merge any entries against the same section.  */
-         for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
-           {
-             struct elf_dyn_relocs *q;
-
-             for (q = edir->dyn_relocs; q != NULL; q = q->next)
-               if (q->sec == p->sec)
-                 {
-                   q->pc_count += p->pc_count;
-                   q->count += p->count;
-                   *pp = p->next;
-                   break;
-                 }
-             if (q == NULL)
-               pp = &p->next;
-           }
-         *pp = edir->dyn_relocs;
-       }
-
-      edir->dyn_relocs = eind->dyn_relocs;
-      eind->dyn_relocs = NULL;
-    }
-
-  if (ind->root.type == bfd_link_hash_indirect)
+  if (ind->root.type == bfd_link_hash_indirect)
     {
       /* Copy over PLT info.  */
       edir->plt.thumb_refcount += eind->plt.thumb_refcount;
@@ -3740,6 +4045,11 @@ elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
       edir->plt.noncall_refcount += eind->plt.noncall_refcount;
       eind->plt.noncall_refcount = 0;
 
+      /* Copy FDPIC counters.  */
+      edir->fdpic_cnts.gotofffuncdesc_cnt += eind->fdpic_cnts.gotofffuncdesc_cnt;
+      edir->fdpic_cnts.gotfuncdesc_cnt += eind->fdpic_cnts.gotfuncdesc_cnt;
+      edir->fdpic_cnts.funcdesc_cnt += eind->fdpic_cnts.funcdesc_cnt;
+
       /* We should only allocate a function to .iplt once the final
         symbol information is known.  */
       BFD_ASSERT (!eind->is_iplt);
@@ -3772,7 +4082,7 @@ static struct bfd_link_hash_table *
 elf32_arm_link_hash_table_create (bfd *abfd)
 {
   struct elf32_arm_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf32_arm_link_hash_table);
+  size_t amt = sizeof (struct elf32_arm_link_hash_table);
 
   ret = (struct elf32_arm_link_hash_table *) bfd_zmalloc (amt);
   if (ret == NULL)
@@ -3796,8 +4106,9 @@ elf32_arm_link_hash_table_create (bfd *abfd)
   ret->plt_header_size = 20;
   ret->plt_entry_size = elf32_arm_use_long_plt_entry ? 16 : 12;
 #endif
-  ret->use_rel = 1;
+  ret->use_rel = true;
   ret->obfd = abfd;
+  ret->fdpic_p = 0;
 
   if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
                            sizeof (struct elf32_arm_stub_hash_entry)))
@@ -3812,14 +4123,14 @@ elf32_arm_link_hash_table_create (bfd *abfd)
 
 /* Determine what kind of NOPs are available.  */
 
-static bfd_boolean
+static bool
 arch_has_arm_nop (struct elf32_arm_link_hash_table *globals)
 {
   const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
                                             Tag_CPU_arch);
 
   /* Force return logic to be reviewed for each new architecture.  */
-  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8M_MAIN);
+  BFD_ASSERT (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
 
   return (arch == TAG_CPU_ARCH_V6T2
          || arch == TAG_CPU_ARCH_V6K
@@ -3828,7 +4139,7 @@ arch_has_arm_nop (struct elf32_arm_link_hash_table *globals)
          || arch == TAG_CPU_ARCH_V8R);
 }
 
-static bfd_boolean
+static bool
 arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
 {
   switch (stub_type)
@@ -3842,13 +4153,13 @@ arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
     case arm_stub_long_branch_v4t_thumb_tls_pic:
     case arm_stub_long_branch_thumb_only_pic:
     case arm_stub_cmse_branch_thumb_only:
-      return TRUE;
+      return true;
     case arm_stub_none:
       BFD_FAIL ();
-      return FALSE;
+      return false;
       break;
     default:
-      return FALSE;
+      return false;
     }
 }
 
@@ -3870,7 +4181,7 @@ arm_type_of_stub (struct bfd_link_info *info,
   bfd_signed_vma branch_offset;
   unsigned int r_type;
   struct elf32_arm_link_hash_table * globals;
-  bfd_boolean thumb2, thumb2_bl, thumb_only;
+  bool thumb2, thumb2_bl, thumb_only;
   enum elf32_arm_stub_type stub_type = arm_stub_none;
   int use_plt = 0;
   enum arm_st_branch_type branch_type = *actual_branch_type;
@@ -3905,7 +4216,7 @@ arm_type_of_stub (struct bfd_link_info *info,
   /* ST_BRANCH_TO_ARM is nonsense to thumb-only targets when we
      are considering a function call relocation.  */
   if (thumb_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
-                     || r_type == R_ARM_THM_JUMP19)
+                    || r_type == R_ARM_THM_JUMP19)
       && branch_type == ST_BRANCH_TO_ARM)
     branch_type = ST_BRANCH_TO_THUMB;
 
@@ -3999,7 +4310,7 @@ arm_type_of_stub (struct bfd_link_info *info,
              && (((r_type == R_ARM_THM_CALL
                    || r_type == R_ARM_THM_TLS_CALL) && !globals->use_blx)
                  || (r_type == R_ARM_THM_JUMP24)
-                  || (r_type == R_ARM_THM_JUMP19))
+                 || (r_type == R_ARM_THM_JUMP19))
              && !use_plt))
        {
          /* If we need to insert a Thumb-Thumb long branch stub to a
@@ -4019,10 +4330,10 @@ arm_type_of_stub (struct bfd_link_info *info,
                {
                  if (input_sec->flags & SEC_ELF_PURECODE)
                    _bfd_error_handler
-                     (_("%B(%A): warning: long branch veneers used in"
+                     (_("%pB(%pA): warning: long branch veneers used in"
                         " section with SHF_ARM_PURECODE section"
                         " attribute is only supported for M-profile"
-                        " targets that implement the movw instruction."),
+                        " targets that implement the movw instruction"),
                       input_bfd, input_sec);
 
                  stub_type = (bfd_link_pic (info) | globals->pic_veneer)
@@ -4053,10 +4364,10 @@ arm_type_of_stub (struct bfd_link_info *info,
                    {
                      if (input_sec->flags & SEC_ELF_PURECODE)
                        _bfd_error_handler
-                         (_("%B(%A): warning: long branch veneers used in"
+                         (_("%pB(%pA): warning: long branch veneers used in"
                             " section with SHF_ARM_PURECODE section"
                             " attribute is only supported for M-profile"
-                            " targets that implement the movw instruction."),
+                            " targets that implement the movw instruction"),
                           input_bfd, input_sec);
 
                      stub_type = (bfd_link_pic (info) | globals->pic_veneer)
@@ -4072,10 +4383,10 @@ arm_type_of_stub (struct bfd_link_info *info,
            {
              if (input_sec->flags & SEC_ELF_PURECODE)
                _bfd_error_handler
-                 (_("%B(%A): warning: long branch veneers used in"
+                 (_("%pB(%pA): warning: long branch veneers used in"
                     " section with SHF_ARM_PURECODE section"
                     " attribute is only supported" " for M-profile"
-                    " targets that implement the movw instruction."),
+                    " targets that implement the movw instruction"),
                   input_bfd, input_sec);
 
              /* Thumb to arm.  */
@@ -4084,9 +4395,9 @@ arm_type_of_stub (struct bfd_link_info *info,
                  && !INTERWORK_FLAG (sym_sec->owner))
                {
                  _bfd_error_handler
-                   (_("%B(%s): warning: interworking not enabled.\n"
-                      "  first occurrence: %B: Thumb call to ARM"),
-                    sym_sec->owner, name, input_bfd);
+                   (_("%pB(%s): warning: interworking not enabled;"
+                      " first occurrence: %pB: %s call to %s"),
+                    sym_sec->owner, name, input_bfd, "Thumb", "ARM");
                }
 
              stub_type =
@@ -4124,10 +4435,10 @@ arm_type_of_stub (struct bfd_link_info *info,
     {
       if (input_sec->flags & SEC_ELF_PURECODE)
        _bfd_error_handler
-         (_("%B(%A): warning: long branch veneers used in"
+         (_("%pB(%pA): warning: long branch veneers used in"
             " section with SHF_ARM_PURECODE section"
             " attribute is only supported for M-profile"
-            " targets that implement the movw instruction."),
+            " targets that implement the movw instruction"),
           input_bfd, input_sec);
       if (branch_type == ST_BRANCH_TO_THUMB)
        {
@@ -4138,9 +4449,9 @@ arm_type_of_stub (struct bfd_link_info *info,
              && !INTERWORK_FLAG (sym_sec->owner))
            {
              _bfd_error_handler
-               (_("%B(%s): warning: interworking not enabled.\n"
-                  "  first occurrence: %B: ARM call to Thumb"),
-                sym_sec->owner, name, input_bfd);
+               (_("%pB(%s): warning: interworking not enabled;"
+                  " first occurrence: %pB: %s call to %s"),
+                sym_sec->owner, name, input_bfd, "ARM", "Thumb");
            }
 
          /* We have an extra 2-bytes reach because of
@@ -4179,11 +4490,11 @@ arm_type_of_stub (struct bfd_link_info *info,
                ? (r_type == R_ARM_TLS_CALL
                   /* TLS PIC Stub.  */
                   ? arm_stub_long_branch_any_tls_pic
-                  : (globals->nacl_p
+                  : (globals->root.target_os == is_nacl
                      ? arm_stub_long_branch_arm_nacl_pic
                      : arm_stub_long_branch_any_arm_pic))
                /* non-PIC stubs.  */
-               : (globals->nacl_p
+               : (globals->root.target_os == is_nacl
                   ? arm_stub_long_branch_arm_nacl
                   : arm_stub_long_branch_any_any);
            }
@@ -4256,6 +4567,27 @@ elf32_arm_get_stub_entry (const asection *input_section,
   if ((input_section->flags & SEC_CODE) == 0)
     return NULL;
 
+  /* If the input section is the CMSE stubs one and it needs a long
+     branch stub to reach it's final destination, give up with an
+     error message: this is not supported.  See PR ld/24709.  */
+  if (!strncmp (input_section->name, CMSE_STUB_NAME, strlen (CMSE_STUB_NAME)))
+    {
+      bfd *output_bfd = htab->obfd;
+      asection *out_sec = bfd_get_section_by_name (output_bfd, CMSE_STUB_NAME);
+
+      _bfd_error_handler (_("ERROR: CMSE stub (%s section) too far "
+                           "(%#" PRIx64 ") from destination (%#" PRIx64 ")"),
+                         CMSE_STUB_NAME,
+                         (uint64_t)out_sec->output_section->vma
+                           + out_sec->output_offset,
+                         (uint64_t)sym_sec->output_section->vma
+                           + sym_sec->output_offset
+                           + h->root.root.u.def.value);
+      /* Exit, rather than leave incompletely processed
+        relocations.  */
+      xexit (1);
+    }
+
   /* If this input section is part of a group of sections sharing one
      stub section, then use the id of the first section in the group.
      Stub names need to include a section id, as there may well be
@@ -4280,7 +4612,7 @@ elf32_arm_get_stub_entry (const asection *input_section,
        return NULL;
 
       stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table,
-                                       stub_name, FALSE, FALSE);
+                                       stub_name, false, false);
       if (h != NULL)
        h->stub_cache = stub_entry;
 
@@ -4293,7 +4625,7 @@ elf32_arm_get_stub_entry (const asection *input_section,
 /* Whether veneers of type STUB_TYPE require to be in a dedicated output
    section.  */
 
-static bfd_boolean
+static bool
 arm_dedicated_stub_output_section_required (enum elf32_arm_stub_type stub_type)
 {
   if (stub_type >= max_stub_type)
@@ -4302,10 +4634,10 @@ arm_dedicated_stub_output_section_required (enum elf32_arm_stub_type stub_type)
   switch (stub_type)
     {
     case arm_stub_cmse_branch_thumb_only:
-      return TRUE;
+      return true;
 
     default:
-      return FALSE;
+      return false;
     }
 
   abort ();  /* Should be unreachable.  */
@@ -4349,7 +4681,7 @@ arm_dedicated_stub_output_section_name (enum elf32_arm_stub_type stub_type)
   switch (stub_type)
     {
     case arm_stub_cmse_branch_thumb_only:
-      return ".gnu.sgstubs";
+      return CMSE_STUB_NAME;
 
     default:
       BFD_ASSERT (!arm_dedicated_stub_output_section_required (stub_type));
@@ -4396,7 +4728,7 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
 {
   asection *link_sec, *out_sec, **stub_sec_p;
   const char *stub_sec_prefix;
-  bfd_boolean dedicated_output_section =
+  bool dedicated_output_section =
     arm_dedicated_stub_output_section_required (stub_type);
   int align;
 
@@ -4412,7 +4744,7 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
       out_sec = bfd_get_section_by_name (output_bfd, out_sec_name);
       if (out_sec == NULL)
        {
-         _bfd_error_handler (_("No address assigned to the veneers output "
+         _bfd_error_handler (_("no address assigned to the veneers output "
                                "section %s"), out_sec_name);
          return NULL;
        }
@@ -4427,7 +4759,7 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
        stub_sec_p = &htab->stub_group[link_sec->id].stub_sec;
       stub_sec_prefix = link_sec->name;
       out_sec = link_sec->output_section;
-      align = htab->nacl_p ? 4 : 3;
+      align = htab->root.target_os == is_nacl ? 4 : 3;
     }
 
   if (*stub_sec_p == NULL)
@@ -4482,12 +4814,12 @@ elf32_arm_add_stub (const char *stub_name, asection *section,
 
   /* Enter this entry into the linker stub hash table.  */
   stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
-                                    TRUE, FALSE);
+                                    true, false);
   if (stub_entry == NULL)
     {
       if (section == NULL)
        section = stub_sec;
-      _bfd_error_handler (_("%B: cannot create stub entry %s"),
+      _bfd_error_handler (_("%pB: cannot create stub entry %s"),
                          section->owner, stub_name);
       return NULL;
     }
@@ -4554,7 +4886,7 @@ elf32_arm_tls_transition (struct bfd_link_info *info, int r_type,
 {
   int is_local = (h == NULL);
 
-  if (bfd_link_pic (info)
+  if (bfd_link_dll (info)
       || (h && h->root.type == bfd_link_hash_undefweak))
     return r_type;
 
@@ -4576,7 +4908,7 @@ static bfd_reloc_status_type elf32_arm_final_link_relocate
   (reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
    Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,
    const char *, unsigned char, enum arm_st_branch_type,
-   struct elf_link_hash_entry *, bfd_boolean *, char **);
+   struct elf_link_hash_entry *, bool *, char **);
 
 static unsigned int
 arm_stub_required_alignment (enum elf32_arm_stub_type stub_type)
@@ -4620,7 +4952,7 @@ arm_stub_required_alignment (enum elf32_arm_stub_type stub_type)
 /* Returns whether stubs of type STUB_TYPE take over the symbol they are
    veneering (TRUE) or have their own symbol (FALSE).  */
 
-static bfd_boolean
+static bool
 arm_stub_sym_claimed (enum elf32_arm_stub_type stub_type)
 {
   if (stub_type >= max_stub_type)
@@ -4629,10 +4961,10 @@ arm_stub_sym_claimed (enum elf32_arm_stub_type stub_type)
   switch (stub_type)
     {
     case arm_stub_cmse_branch_thumb_only:
-      return TRUE;
+      return true;
 
     default:
-      return FALSE;
+      return false;
     }
 
   abort ();  /* Should be unreachable.  */
@@ -4678,12 +5010,12 @@ arm_new_stubs_start_offset_ptr (struct elf32_arm_link_hash_table *htab,
     }
 }
 
-static bfd_boolean
+static bool
 arm_build_one_stub (struct bfd_hash_entry *gen_entry,
                    void * in_arg)
 {
 #define MAXRELOCS 3
-  bfd_boolean removed_sg_veneer;
+  bool removed_sg_veneer;
   struct elf32_arm_stub_hash_entry *stub_entry;
   struct elf32_arm_link_hash_table *globals;
   struct bfd_link_info *info;
@@ -4704,16 +5036,24 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
   info = (struct bfd_link_info *) in_arg;
 
+  /* Fail if the target section could not be assigned to an output
+     section.  The user should fix his linker script.  */
+  if (stub_entry->target_section->output_section == NULL
+      && info->non_contiguous_regions)
+    info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output section. "
+                             "Retry without --enable-non-contiguous-regions.\n"),
+                           stub_entry->target_section);
+
   globals = elf32_arm_hash_table (info);
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   stub_sec = stub_entry->stub_sec;
 
   if ((globals->fix_cortex_a8 < 0)
       != (arm_stub_required_alignment (stub_entry->stub_type) == 2))
     /* We have to do less-strictly-aligned fixes last.  */
-    return TRUE;
+    return true;
 
   /* Assign a slot at the end of section if none assigned yet.  */
   if (stub_entry->stub_offset == (bfd_vma) -1)
@@ -4790,7 +5130,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
 
        default:
          BFD_FAIL ();
-         return FALSE;
+         return false;
        }
     }
 
@@ -4814,7 +5154,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
   for (i = 0; i < nrelocs; i++)
     {
       Elf_Internal_Rela rel;
-      bfd_boolean unresolved_reloc;
+      bool unresolved_reloc;
       char *error_message;
       bfd_vma points_to =
        sym_value + template_sequence[stub_reloc_idx[i]].reloc_addend;
@@ -4843,7 +5183,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
           &error_message);
     }
 
-  return TRUE;
+  return true;
 #undef MAXRELOCS
 }
 
@@ -4894,7 +5234,7 @@ find_stub_size_and_template (enum elf32_arm_stub_type stub_type,
 /* As above, but don't actually build the stub.  Just bump offset so
    we know stub section sizes.  */
 
-static bfd_boolean
+static bool
 arm_size_one_stub (struct bfd_hash_entry *gen_entry,
                   void *in_arg ATTRIBUTE_UNUSED)
 {
@@ -4905,8 +5245,8 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
   /* Massage our args to the form they really have.  */
   stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
 
-  BFD_ASSERT((stub_entry->stub_type > arm_stub_none)
-            && stub_entry->stub_type < ARRAY_SIZE(stub_definitions));
+  BFD_ASSERT ((stub_entry->stub_type > arm_stub_none)
+             && stub_entry->stub_type < ARRAY_SIZE (stub_definitions));
 
   size = find_stub_size_and_template (stub_entry->stub_type, &template_sequence,
                                      &template_size);
@@ -4921,12 +5261,12 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
 
   /* Already accounted for.  */
   if (stub_entry->stub_offset != (bfd_vma) -1)
-    return TRUE;
+    return true;
 
   size = (size + 7) & ~7;
   stub_entry->stub_sec->size += size;
 
-  return TRUE;
+  return true;
 }
 
 /* External entry points for sizing and building linker stubs.  */
@@ -4944,13 +5284,11 @@ elf32_arm_setup_section_lists (bfd *output_bfd,
   unsigned int top_id, top_index;
   asection *section;
   asection **input_list, **list;
-  bfd_size_type amt;
+  size_t amt;
   struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
 
   if (htab == NULL)
     return 0;
-  if (! is_elf_hash_table (htab))
-    return 0;
 
   /* Count the number of input BFDs and find the top input section id.  */
   for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
@@ -5050,7 +5388,7 @@ elf32_arm_next_input_section (struct bfd_link_info *info,
 static void
 group_sections (struct elf32_arm_link_hash_table *htab,
                bfd_size_type stub_group_size,
-               bfd_boolean stubs_always_after_branch)
+               bool stubs_always_after_branch)
 {
   asection **list = htab->input_list;
 
@@ -5166,7 +5504,7 @@ static struct elf_link_hash_entry *find_thumb_glue (struct bfd_link_info *,
    NUM_A8_FIXES_P, A8_FIX_TABLE_SIZE_P.  Returns true if an error occurs, false
    otherwise.  */
 
-static bfd_boolean
+static bool
 cortex_a8_erratum_scan (bfd *input_bfd,
                        struct bfd_link_info *info,
                        struct a8_erratum_fix **a8_fixes_p,
@@ -5175,7 +5513,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                        struct a8_erratum_reloc *a8_relocs,
                        unsigned int num_a8_relocs,
                        unsigned prev_num_a8_fixes,
-                       bfd_boolean *stub_changed_p)
+                       bool *stub_changed_p)
 {
   asection *section;
   struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
@@ -5184,7 +5522,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
   unsigned int a8_fix_table_size = *a8_fix_table_size_p;
 
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   for (section = input_bfd->sections;
        section != NULL;
@@ -5207,7 +5545,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
       if (elf_section_data (section)->this_hdr.contents != NULL)
        contents = elf_section_data (section)->this_hdr.contents;
       else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
-       return TRUE;
+       return true;
 
       sec_data = elf32_arm_section_data (section);
 
@@ -5218,7 +5556,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
            ? section->size : sec_data->map[span + 1].vma;
          unsigned int i;
          char span_type = sec_data->map[span].type;
-         bfd_boolean last_was_32bit = FALSE, last_was_branch = FALSE;
+         bool last_was_32bit = false, last_was_branch = false;
 
          if (span_type != 't')
            continue;
@@ -5238,11 +5576,11 @@ cortex_a8_erratum_scan (bfd *input_bfd,
          for (i = span_start; i < span_end;)
            {
              unsigned int insn = bfd_getl16 (&contents[i]);
-             bfd_boolean insn_32bit = FALSE, is_blx = FALSE, is_b = FALSE;
-             bfd_boolean is_bl = FALSE, is_bcc = FALSE, is_32bit_branch;
+             bool insn_32bit = false, is_blx = false, is_b = false;
+             bool is_bl = false, is_bcc = false, is_32bit_branch;
 
              if ((insn & 0xe000) == 0xe000 && (insn & 0x1800) != 0x0000)
-               insn_32bit = TRUE;
+               insn_32bit = true;
 
              if (insn_32bit)
                {
@@ -5269,12 +5607,12 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                  && ! last_was_branch)
                {
                  bfd_signed_vma offset = 0;
-                 bfd_boolean force_target_arm = FALSE;
-                 bfd_boolean force_target_thumb = FALSE;
+                 bool force_target_arm = false;
+                 bool force_target_thumb = false;
                  bfd_vma target;
                  enum elf32_arm_stub_type stub_type = arm_stub_none;
                  struct a8_erratum_reloc key, *found;
-                 bfd_boolean use_plt = FALSE;
+                 bool use_plt = false;
 
                  key.from = base_vma + i;
                  found = (struct a8_erratum_reloc *)
@@ -5293,20 +5631,20 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                                               &error_message);
 
                      if (entry)
-                       found->non_a8_stub = TRUE;
+                       found->non_a8_stub = true;
 
                      /* Keep a simpler condition, for the sake of clarity.  */
                      if (htab->root.splt != NULL && found->hash != NULL
                          && found->hash->root.plt.offset != (bfd_vma) -1)
-                       use_plt = TRUE;
+                       use_plt = true;
 
                      if (found->r_type == R_ARM_THM_CALL)
                        {
                          if (found->branch_type == ST_BRANCH_TO_ARM
                              || use_plt)
-                           force_target_arm = TRUE;
+                           force_target_arm = true;
                          else
-                           force_target_thumb = TRUE;
+                           force_target_thumb = true;
                        }
                    }
 
@@ -5364,8 +5702,8 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                          && stub_type == arm_stub_a8_veneer_bl)
                        {
                          stub_type = arm_stub_a8_veneer_blx;
-                         is_blx = TRUE;
-                         is_bl = FALSE;
+                         is_blx = true;
+                         is_bl = false;
                        }
                      /* Conversely, if the original instruction was
                         BLX but the target is Thumb mode, use the BL
@@ -5374,8 +5712,8 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                               && stub_type == arm_stub_a8_veneer_blx)
                        {
                          stub_type = arm_stub_a8_veneer_bl;
-                         is_blx = FALSE;
-                         is_bl = TRUE;
+                         is_blx = false;
+                         is_bl = true;
                        }
 
                      if (is_blx)
@@ -5428,7 +5766,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
                                {
                                  free (stub_name);
                                  stub_name = NULL;
-                                 *stub_changed_p = TRUE;
+                                 *stub_changed_p = true;
                                }
                            }
 
@@ -5469,7 +5807,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
   *num_a8_fixes_p = num_a8_fixes;
   *a8_fix_table_size_p = a8_fix_table_size;
 
-  return FALSE;
+  return false;
 }
 
 /* Create or update a stub entry depending on whether the stub can already be
@@ -5495,16 +5833,16 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
                       Elf_Internal_Rela *irela, asection *sym_sec,
                       struct elf32_arm_link_hash_entry *hash, char *sym_name,
                       bfd_vma sym_value, enum arm_st_branch_type branch_type,
-                      bfd_boolean *new_stub)
+                      bool *new_stub)
 {
   const asection *id_sec;
   char *stub_name;
   struct elf32_arm_stub_hash_entry *stub_entry;
   unsigned int r_type;
-  bfd_boolean sym_claimed = arm_stub_sym_claimed (stub_type);
+  bool sym_claimed = arm_stub_sym_claimed (stub_type);
 
   BFD_ASSERT (stub_type != arm_stub_none);
-  *new_stub = FALSE;
+  *new_stub = false;
 
   if (sym_claimed)
     stub_name = sym_name;
@@ -5524,8 +5862,8 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
        return NULL;
     }
 
-  stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name, FALSE,
-                                    FALSE);
+  stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name, false,
+                                    false);
   /* The proper stub has already been created, just update its value.  */
   if (stub_entry != NULL)
     {
@@ -5580,7 +5918,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
        sprintf (stub_entry->output_name, STUB_ENTRY_NAME, sym_name);
     }
 
-  *new_stub = TRUE;
+  *new_stub = true;
   return stub_entry;
 }
 
@@ -5605,7 +5943,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab,
 
    The return value gives whether a stub failed to be allocated.  */
 
-static bfd_boolean
+static bool
 cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
           obj_attribute *out_attr, struct elf_link_hash_entry **sym_hashes,
           int *cmse_stub_created)
@@ -5620,7 +5958,7 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
   bfd_vma sym_value;
   asection *section;
   struct elf32_arm_stub_hash_entry *stub_entry;
-  bfd_boolean is_v8m, new_stub, cmse_invalid, ret = TRUE;
+  bool is_v8m, new_stub, cmse_invalid, ret = true;
 
   bed = get_elf_backend_data (input_bfd);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -5635,64 +5973,61 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
                                       symtab_hdr->sh_info, 0, NULL, NULL,
                                       NULL);
   if (symtab_hdr->sh_info && local_syms == NULL)
-    return FALSE;
+    return false;
 
   /* Scan symbols.  */
   for (i = 0; i < sym_count; i++)
     {
-      cmse_invalid = FALSE;
+      cmse_invalid = false;
 
       if (i < ext_start)
        {
          cmse_sym = &local_syms[i];
-         /* Not a special symbol.  */
-         if (!ARM_GET_SYM_CMSE_SPCL (cmse_sym->st_target_internal))
-           continue;
          sym_name = bfd_elf_string_from_elf_section (input_bfd,
                                                      symtab_hdr->sh_link,
                                                      cmse_sym->st_name);
+         if (!sym_name || !startswith (sym_name, CMSE_PREFIX))
+           continue;
+
          /* Special symbol with local binding.  */
-         cmse_invalid = TRUE;
+         cmse_invalid = true;
        }
       else
        {
          cmse_hash = elf32_arm_hash_entry (sym_hashes[i - ext_start]);
          sym_name = (char *) cmse_hash->root.root.root.string;
-
-         /* Not a special symbol.  */
-         if (!ARM_GET_SYM_CMSE_SPCL (cmse_hash->root.target_internal))
+         if (!startswith (sym_name, CMSE_PREFIX))
            continue;
 
          /* Special symbol has incorrect binding or type.  */
          if ((cmse_hash->root.root.type != bfd_link_hash_defined
               && cmse_hash->root.root.type != bfd_link_hash_defweak)
              || cmse_hash->root.type != STT_FUNC)
-           cmse_invalid = TRUE;
+           cmse_invalid = true;
        }
 
       if (!is_v8m)
        {
-         _bfd_error_handler (_("%B: Special symbol `%s' only allowed for "
-                               "ARMv8-M architecture or later."),
+         _bfd_error_handler (_("%pB: special symbol `%s' only allowed for "
+                               "ARMv8-M architecture or later"),
                              input_bfd, sym_name);
-         is_v8m = TRUE; /* Avoid multiple warning.  */
-         ret = FALSE;
+         is_v8m = true; /* Avoid multiple warning.  */
+         ret = false;
        }
 
       if (cmse_invalid)
        {
-         _bfd_error_handler (_("%B: invalid special symbol `%s'."),
+         _bfd_error_handler (_("%pB: invalid special symbol `%s'; it must be"
+                               " a global or weak function symbol"),
                              input_bfd, sym_name);
-         _bfd_error_handler (_("It must be a global or weak function "
-                               "symbol."));
-         ret = FALSE;
+         ret = false;
          if (i < ext_start)
            continue;
        }
 
       sym_name += strlen (CMSE_PREFIX);
       hash = (struct elf32_arm_link_hash_entry *)
-       elf_link_hash_lookup (&(htab)->root, sym_name, FALSE, FALSE, TRUE);
+       elf_link_hash_lookup (&(htab)->root, sym_name, false, false, true);
 
       /* No associated normal symbol or it is neither global nor weak.  */
       if (!hash
@@ -5721,14 +6056,14 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
          if (hash || j < ext_start)
            {
              _bfd_error_handler
-               (_("%B: invalid standard symbol `%s'."), input_bfd, sym_name);
-             _bfd_error_handler
-               (_("It must be a global or weak function symbol."));
+               (_("%pB: invalid standard symbol `%s'; it must be "
+                  "a global or weak function symbol"),
+                input_bfd, sym_name);
            }
          else
            _bfd_error_handler
-             (_("%B: absent standard symbol `%s'."), input_bfd, sym_name);
-         ret = FALSE;
+             (_("%pB: absent standard symbol `%s'"), input_bfd, sym_name);
+         ret = false;
          if (!hash)
            continue;
        }
@@ -5739,9 +6074,9 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
       if (cmse_hash->root.root.u.def.section != section)
        {
          _bfd_error_handler
-           (_("%B: `%s' and its special symbol are in different sections."),
+           (_("%pB: `%s' and its special symbol are in different sections"),
             input_bfd, sym_name);
-         ret = FALSE;
+         ret = false;
        }
       if (cmse_hash->root.root.u.def.value != sym_value)
        continue; /* Ignore: could be an entry function starting with SG.  */
@@ -5751,15 +6086,15 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
       if (section->output_section == NULL)
        {
          _bfd_error_handler
-           (_("%B: entry function `%s' not output."), input_bfd, sym_name);
+           (_("%pB: entry function `%s' not output"), input_bfd, sym_name);
          continue;
        }
 
       if (hash->root.size == 0)
        {
          _bfd_error_handler
-           (_("%B: entry function `%s' is empty."), input_bfd, sym_name);
-         ret = FALSE;
+           (_("%pB: entry function `%s' is empty"), input_bfd, sym_name);
+         ret = false;
        }
 
       if (!ret)
@@ -5771,7 +6106,7 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
                                 sym_value, branch_type, &new_stub);
 
       if (stub_entry == NULL)
-        ret = FALSE;
+        ret = false;
       else
        {
          BFD_ASSERT (new_stub);
@@ -5788,7 +6123,7 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab,
    code entry function, ie can be called from non secure code without using a
    veneer.  */
 
-static bfd_boolean
+static bool
 cmse_entry_fct_p (struct elf32_arm_link_hash_entry *hash)
 {
   bfd_byte contents[4];
@@ -5800,9 +6135,9 @@ cmse_entry_fct_p (struct elf32_arm_link_hash_entry *hash)
   /* Defined symbol of function type.  */
   if (hash->root.root.type != bfd_link_hash_defined
       && hash->root.root.type != bfd_link_hash_defweak)
-    return FALSE;
+    return false;
   if (hash->root.type != STT_FUNC)
-    return FALSE;
+    return false;
 
   /* Read first instruction.  */
   section = hash->root.root.u.def.section;
@@ -5810,7 +6145,7 @@ cmse_entry_fct_p (struct elf32_arm_link_hash_entry *hash)
   offset = hash->root.root.u.def.value - section->vma;
   if (!bfd_get_section_contents (abfd, section, contents, offset,
                                 sizeof (contents)))
-    return FALSE;
+    return false;
 
   first_insn = bfd_get_32 (abfd, contents);
 
@@ -5822,7 +6157,7 @@ cmse_entry_fct_p (struct elf32_arm_link_hash_entry *hash)
    secure gateway veneers (ie. the veneers was not in the input import library)
    and there is no output import library (GEN_INFO->out_implib_bfd is NULL.  */
 
-static bfd_boolean
+static bool
 arm_list_new_cmse_stub (struct bfd_hash_entry *gen_entry, void *gen_info)
 {
   struct elf32_arm_stub_hash_entry *stub_entry;
@@ -5833,15 +6168,15 @@ arm_list_new_cmse_stub (struct bfd_hash_entry *gen_entry, void *gen_info)
   info = (struct bfd_link_info *) gen_info;
 
   if (info->out_implib_bfd)
-    return TRUE;
+    return true;
 
   if (stub_entry->stub_type != arm_stub_cmse_branch_thumb_only)
-    return TRUE;
+    return true;
 
   if (stub_entry->stub_offset == (bfd_vma) -1)
     _bfd_error_handler ("  %s", stub_entry->output_name);
 
-  return TRUE;
+  return true;
 }
 
 /* Set offset of each secure gateway veneers so that its address remain
@@ -5857,7 +6192,7 @@ arm_list_new_cmse_stub (struct bfd_hash_entry *gen_entry, void *gen_info)
    and this function and HTAB->new_cmse_stub_offset is set to the biggest
    veneer observed set for new veneers to be layed out after.  */
 
-static bfd_boolean
+static bool
 set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
                                  struct elf32_arm_link_hash_table *htab,
                                  int *cmse_stub_created)
@@ -5868,7 +6203,7 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
   long i, symcount;
   bfd *in_implib_bfd;
   asection *stub_out_sec;
-  bfd_boolean ret = TRUE;
+  bool ret = true;
   Elf_Internal_Sym *intsym;
   const char *out_sec_name;
   bfd_size_type cmse_stub_size;
@@ -5882,27 +6217,30 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
 
   /* No input secure gateway import library.  */
   if (!htab->in_implib_bfd)
-    return TRUE;
+    return true;
 
   in_implib_bfd = htab->in_implib_bfd;
   if (!htab->cmse_implib)
     {
-      _bfd_error_handler (_("%B: --in-implib only supported for Secure "
-                           "Gateway import libraries."), in_implib_bfd);
-      return FALSE;
+      _bfd_error_handler (_("%pB: --in-implib only supported for Secure "
+                           "Gateway import libraries"), in_implib_bfd);
+      return false;
     }
 
   /* Get symbol table size.  */
   symsize = bfd_get_symtab_upper_bound (in_implib_bfd);
   if (symsize < 0)
-    return FALSE;
+    return false;
 
   /* Read in the input secure gateway import library's symbol table.  */
-  sympp = (asymbol **) xmalloc (symsize);
+  sympp = (asymbol **) bfd_malloc (symsize);
+  if (sympp == NULL)
+    return false;
+
   symcount = bfd_canonicalize_symtab (in_implib_bfd, sympp);
   if (symcount < 0)
     {
-      ret = FALSE;
+      ret = false;
       goto free_sym_buf;
     }
 
@@ -5933,38 +6271,38 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
          || (ARM_GET_SYM_BRANCH_TYPE (intsym->st_target_internal)
              != ST_BRANCH_TO_THUMB))
        {
-         _bfd_error_handler (_("%B: invalid import library entry: `%s'."),
+         _bfd_error_handler (_("%pB: invalid import library entry: `%s'; "
+                               "symbol should be absolute, global and "
+                               "refer to Thumb functions"),
                              in_implib_bfd, sym_name);
-         _bfd_error_handler (_("Symbol should be absolute, global and "
-                               "refer to Thumb functions."));
-         ret = FALSE;
+         ret = false;
          continue;
        }
 
       veneer_value = bfd_asymbol_value (sym);
       stub_offset = veneer_value - cmse_stub_sec_vma;
       stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, sym_name,
-                                        FALSE, FALSE);
+                                        false, false);
       hash = (struct elf32_arm_link_hash_entry *)
-       elf_link_hash_lookup (&(htab)->root, sym_name, FALSE, FALSE, TRUE);
+       elf_link_hash_lookup (&(htab)->root, sym_name, false, false, true);
 
       /* Stub entry should have been created by cmse_scan or the symbol be of
         a secure function callable from non secure code.  */
       if (!stub_entry && !hash)
        {
-         bfd_boolean new_stub;
+         bool new_stub;
 
          _bfd_error_handler
-           (_("Entry function `%s' disappeared from secure code."), sym_name);
+           (_("entry function `%s' disappeared from secure code"), sym_name);
          hash = (struct elf32_arm_link_hash_entry *)
-           elf_link_hash_lookup (&(htab)->root, sym_name, TRUE, TRUE, TRUE);
+           elf_link_hash_lookup (&(htab)->root, sym_name, true, true, true);
          stub_entry
            = elf32_arm_create_stub (htab, arm_stub_cmse_branch_thumb_only,
                                     NULL, NULL, bfd_abs_section_ptr, hash,
                                     sym_name, veneer_value,
                                     ST_BRANCH_TO_THUMB, &new_stub);
          if (stub_entry == NULL)
-           ret = FALSE;
+           ret = false;
          else
          {
            BFD_ASSERT (new_stub);
@@ -5979,9 +6317,9 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
        {
          if (!cmse_entry_fct_p (hash))
            {
-             _bfd_error_handler (_("`%s' refers to a non entry function."),
+             _bfd_error_handler (_("`%s' refers to a non entry function"),
                                  sym_name);
-             ret = FALSE;
+             ret = false;
            }
          continue;
        }
@@ -5994,7 +6332,7 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
          if (!!(flags & BSF_GLOBAL)
              != (hash->root.root.type == bfd_link_hash_defined))
            _bfd_error_handler
-             (_("%B: visibility of symbol `%s' has changed."), in_implib_bfd,
+             (_("%pB: visibility of symbol `%s' has changed"), in_implib_bfd,
               sym_name);
 
          stub_entry->stub_offset = stub_offset;
@@ -6003,9 +6341,9 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
       /* Size should match that of a SG veneer.  */
       if (intsym->st_size != cmse_stub_size)
        {
-         _bfd_error_handler (_("%B: incorrect size for symbol `%s'."),
+         _bfd_error_handler (_("%pB: incorrect size for symbol `%s'"),
                              in_implib_bfd, sym_name);
-         ret = FALSE;
+         ret = false;
        }
 
       /* Previous veneer address is before current SG veneer section.  */
@@ -6015,16 +6353,16 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
          if (stub_entry)
            stub_entry->stub_offset = 0;
          stub_offset = 0;
-         ret = FALSE;
+         ret = false;
        }
 
       /* Complain if stub offset not a multiple of stub size.  */
       if (stub_offset % cmse_stub_size)
        {
          _bfd_error_handler
-           (_("Offset of veneer for entry function `%s' not a multiple of "
-              "its size."), sym_name);
-         ret = FALSE;
+           (_("offset of veneer for entry function `%s' not a multiple of "
+              "its size"), sym_name);
+         ret = false;
        }
 
       if (!ret)
@@ -6050,12 +6388,12 @@ set_cmse_veneer_addr_from_implib (struct bfd_link_info *info,
   if (cmse_stub_array_start != cmse_stub_sec_vma)
     {
       _bfd_error_handler
-       (_("Start address of `%s' is different from previous link."),
+       (_("start address of `%s' is different from previous link"),
         out_sec_name);
-      ret = FALSE;
+      ret = false;
     }
 
-free_sym_buf:
+ free_sym_buf:
   free (sympp);
   return ret;
 }
@@ -6066,7 +6404,7 @@ free_sym_buf:
    PC-relative calls to a target that is unreachable with a "bl"
    instruction.  */
 
-bfd_boolean
+bool
 elf32_arm_size_stubs (bfd *output_bfd,
                      bfd *stub_bfd,
                      struct bfd_link_info *info,
@@ -6076,11 +6414,11 @@ elf32_arm_size_stubs (bfd *output_bfd,
                                                      unsigned int),
                      void (*layout_sections_again) (void))
 {
-  bfd_boolean ret = TRUE;
+  bool ret = true;
   obj_attribute *out_attr;
   int cmse_stub_created = 0;
   bfd_size_type stub_group_size;
-  bfd_boolean m_profile, stubs_always_after_branch, first_veneer_scan = TRUE;
+  bool m_profile, stubs_always_after_branch, first_veneer_scan = true;
   struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
   struct a8_erratum_fix *a8_fixes = NULL;
   unsigned int num_a8_fixes = 0, a8_fix_table_size = 10;
@@ -6088,7 +6426,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
   unsigned int num_a8_relocs = 0, a8_reloc_table_size = 10, i;
 
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   if (htab->fix_cortex_a8)
     {
@@ -6155,7 +6493,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
       unsigned int bfd_indx;
       asection *stub_sec;
       enum elf32_arm_stub_type stub_type;
-      bfd_boolean stub_changed = FALSE;
+      bool stub_changed = false;
       unsigned prev_num_a8_fixes = num_a8_fixes;
 
       num_a8_fixes = 0;
@@ -6169,6 +6507,10 @@ elf32_arm_size_stubs (bfd *output_bfd,
 
          if (!is_arm_elf (input_bfd))
            continue;
+         if ((input_bfd->flags & DYNAMIC) != 0
+             && (elf_sym_hashes (input_bfd) == NULL
+                 || (elf_dyn_lib_class (input_bfd) & DYN_AS_NEEDED) != 0))
+           continue;
 
          num_a8_relocs = 0;
 
@@ -6189,7 +6531,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                goto error_ret_free_local;
 
              if (cmse_stub_created != 0)
-               stub_changed = TRUE;
+               stub_changed = true;
            }
 
          /* Walk over each section attached to the input bfd.  */
@@ -6232,7 +6574,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                  const char *sym_name;
                  unsigned char st_type;
                  enum arm_st_branch_type branch_type;
-                 bfd_boolean created_stub = FALSE;
+                 bool created_stub = false;
 
                  r_type = ELF32_R_TYPE (irela->r_info);
                  r_indx = ELF32_R_SYM (irela->r_info);
@@ -6245,11 +6587,9 @@ elf32_arm_size_stubs (bfd *output_bfd,
                        free (internal_relocs);
                    /* Fall through.  */
                    error_ret_free_local:
-                     if (local_syms != NULL
-                         && (symtab_hdr->contents
-                             != (unsigned char *) local_syms))
+                     if (symtab_hdr->contents != (unsigned char *) local_syms)
                        free (local_syms);
-                     return FALSE;
+                     return false;
                    }
 
                  hash = NULL;
@@ -6269,8 +6609,9 @@ elf32_arm_size_stubs (bfd *output_bfd,
                      && (r_type != (unsigned int) R_ARM_PLT32)
                      && !((r_type == (unsigned int) R_ARM_TLS_CALL
                            || r_type == (unsigned int) R_ARM_THM_TLS_CALL)
-                          && r_type == elf32_arm_tls_transition
-                              (info, r_type, &hash->root)
+                          && r_type == (elf32_arm_tls_transition
+                                        (info, r_type,
+                                         (struct elf_link_hash_entry *) hash))
                           && ((hash ? hash->tls_type
                                : (elf32_arm_local_got_tls_type
                                   (input_bfd)[r_indx]))
@@ -6420,7 +6761,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 
                  do
                    {
-                     bfd_boolean new_stub;
+                     bool new_stub;
                      struct elf32_arm_stub_hash_entry *stub_entry;
 
                      /* Determine what (if any) linker stub is needed.  */
@@ -6445,7 +6786,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                      else if (!new_stub)
                        break;
                      else
-                       stub_changed = TRUE;
+                       stub_changed = true;
                    }
                  while (0);
 
@@ -6524,10 +6865,10 @@ elf32_arm_size_stubs (bfd *output_bfd,
       if (first_veneer_scan
          && !set_cmse_veneer_addr_from_implib (info, htab,
                                                &cmse_stub_created))
-       ret = FALSE;
+       ret = false;
 
       if (prev_num_a8_fixes != num_a8_fixes)
-       stub_changed = TRUE;
+       stub_changed = true;
 
       if (!stub_changed)
        break;
@@ -6593,7 +6934,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
                         a8_fixes[i].section, htab, a8_fixes[i].stub_type);
 
            if (stub_sec == NULL)
-             return FALSE;
+             return false;
 
            stub_sec->size
              += find_stub_size_and_template (a8_fixes[i].stub_type, NULL,
@@ -6603,7 +6944,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
 
       /* Ask the linker to do its stuff.  */
       (*htab->layout_sections_again) ();
-      first_veneer_scan = FALSE;
+      first_veneer_scan = false;
     }
 
   /* Add stubs for Cortex-A8 erratum fixes now.  */
@@ -6621,12 +6962,12 @@ elf32_arm_size_stubs (bfd *output_bfd,
          int template_size, size = 0;
 
          stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
-                                            TRUE, FALSE);
+                                            true, false);
          if (stub_entry == NULL)
            {
-             _bfd_error_handler (_("%B: cannot create stub entry %s"),
+             _bfd_error_handler (_("%pB: cannot create stub entry %s"),
                                  section->owner, stub_name);
-             return FALSE;
+             return false;
            }
 
          stub_entry->stub_sec = stub_sec;
@@ -6667,7 +7008,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
    functions here.  This function is called via arm_elf_finish in the
    linker.  */
 
-bfd_boolean
+bool
 elf32_arm_build_stubs (struct bfd_link_info *info)
 {
   asection *stub_sec;
@@ -6677,7 +7018,7 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   for (stub_sec = htab->stub_bfd->sections;
        stub_sec != NULL;
@@ -6696,7 +7037,7 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
       size = stub_sec->size;
       stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
       if (stub_sec->contents == NULL && size != 0)
-       return FALSE;
+       return false;
 
       stub_sec->size = 0;
     }
@@ -6727,7 +7068,7 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
       bfd_hash_traverse (table, arm_build_one_stub, info);
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Locate the Thumb encoded calling stub for NAME.  */
@@ -6754,11 +7095,11 @@ find_thumb_glue (struct bfd_link_info *link_info,
   sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
 
   hash = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
+    (&(hash_table)->root, tmp_name, false, false, true);
 
   if (hash == NULL
-      && asprintf (error_message, _("unable to find THUMB glue '%s' for '%s'"),
-                  tmp_name, name) == -1)
+      && asprintf (error_message, _("unable to find %s glue '%s' for '%s'"),
+                  "Thumb", tmp_name, name) == -1)
     *error_message = (char *) bfd_errmsg (bfd_error_system_call);
 
   free (tmp_name);
@@ -6784,17 +7125,16 @@ find_arm_glue (struct bfd_link_info *link_info,
 
   tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen (name)
                                  + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1);
-
   BFD_ASSERT (tmp_name);
 
   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
 
   myh = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
+    (&(hash_table)->root, tmp_name, false, false, true);
 
   if (myh == NULL
-      && asprintf (error_message, _("unable to find ARM glue '%s' for '%s'"),
-                  tmp_name, name) == -1)
+      && asprintf (error_message, _("unable to find %s glue '%s' for '%s'"),
+                  "ARM", tmp_name, name) == -1)
     *error_message = (char *) bfd_errmsg (bfd_error_system_call);
 
   free (tmp_name);
@@ -6841,21 +7181,21 @@ static const insn32 a2t1p_ldr_insn = 0xe59fc004;
 static const insn32 a2t2p_add_pc_insn = 0xe08cc00f;
 static const insn32 a2t3p_bx_r12_insn = 0xe12fff1c;
 
-/* Thumb->ARM:                          Thumb->(non-interworking aware) ARM
+/* Thumb->ARM:                         Thumb->(non-interworking aware) ARM
 
-     .thumb                             .thumb
-     .align 2                           .align 2
- __func_from_thumb:                 __func_from_thumb:
-     bx pc                              push {r6, lr}
-     nop                                ldr  r6, __func_addr
-     .arm                               mov  lr, pc
-     b func                             bx   r6
+     .thumb                            .thumb
+     .align 2                          .align 2
+ __func_from_thumb:                __func_from_thumb:
+     bx pc                             push {r6, lr}
+     nop                               ldr  r6, __func_addr
+     .arm                              mov  lr, pc
+     b func                            bx   r6
                                        .arm
                                    ;; back_to_thumb
                                        ldmia r13! {r6, lr}
                                        bx    lr
                                    __func_addr:
-                                       .word        func  */
+                                       .word        func  */
 
 #define THUMB2ARM_GLUE_SIZE 8
 static const insn16 t2a1_bx_pc_insn = 0x4778;
@@ -6895,13 +7235,13 @@ arm_allocate_glue_section_space (bfd * abfd, bfd_size_type size, const char * na
   s = bfd_get_linker_section (abfd, name);
   BFD_ASSERT (s != NULL);
 
-  contents = (bfd_byte *) bfd_alloc (abfd, size);
+  contents = (bfd_byte *) bfd_zalloc (abfd, size);
 
   BFD_ASSERT (s->size == size);
   s->contents = contents;
 }
 
-bfd_boolean
+bool
 bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
 {
   struct elf32_arm_link_hash_table * globals;
@@ -6929,7 +7269,7 @@ bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
                                   globals->bx_glue_size,
                                   ARM_BX_GLUE_SECTION_NAME);
 
-  return TRUE;
+  return true;
 }
 
 /* Allocate space and symbols for calling a Thumb function from Arm mode.
@@ -6959,13 +7299,12 @@ record_arm_to_thumb_glue (struct bfd_link_info * link_info,
 
   tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen (name)
                                  + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1);
-
   BFD_ASSERT (tmp_name);
 
   sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
 
   myh = elf_link_hash_lookup
-    (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+    (&(globals)->root, tmp_name, false, false, true);
 
   if (myh != NULL)
     {
@@ -6982,7 +7321,7 @@ record_arm_to_thumb_glue (struct bfd_link_info * link_info,
   val = globals->arm_glue_size + 1;
   _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
                                    tmp_name, BSF_GLOBAL, s, val,
-                                   NULL, TRUE, FALSE, &bh);
+                                   NULL, true, false, &bh);
 
   myh = (struct elf_link_hash_entry *) bh;
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -7037,13 +7376,12 @@ record_arm_bx_glue (struct bfd_link_info * link_info, int reg)
   /* Add symbol for veneer.  */
   tmp_name = (char *)
       bfd_malloc ((bfd_size_type) strlen (ARM_BX_GLUE_ENTRY_NAME) + 1);
-
   BFD_ASSERT (tmp_name);
 
   sprintf (tmp_name, ARM_BX_GLUE_ENTRY_NAME, reg);
 
   myh = elf_link_hash_lookup
-    (&(globals)->root, tmp_name, FALSE, FALSE, FALSE);
+    (&(globals)->root, tmp_name, false, false, false);
 
   BFD_ASSERT (myh == NULL);
 
@@ -7051,7 +7389,7 @@ record_arm_bx_glue (struct bfd_link_info * link_info, int reg)
   val = globals->bx_glue_size;
   _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
                                    tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
-                                   NULL, TRUE, FALSE, &bh);
+                                   NULL, true, false, &bh);
 
   myh = (struct elf_link_hash_entry *) bh;
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -7129,14 +7467,13 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
 
   tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen
                                  (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10);
-
   BFD_ASSERT (tmp_name);
 
   sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME,
           hash_table->num_vfp11_fixes);
 
   myh = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
+    (&(hash_table)->root, tmp_name, false, false, false);
 
   BFD_ASSERT (myh == NULL);
 
@@ -7144,7 +7481,7 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
   val = hash_table->vfp11_erratum_glue_size;
   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
                                    tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
-                                   NULL, TRUE, FALSE, &bh);
+                                   NULL, true, false, &bh);
 
   myh = (struct elf_link_hash_entry *) bh;
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -7169,7 +7506,7 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
           hash_table->num_vfp11_fixes);
 
   myh = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
+    (&(hash_table)->root, tmp_name, false, false, false);
 
   if (myh != NULL)
     abort ();
@@ -7177,7 +7514,7 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
   bh = NULL;
   val = offset + 4;
   _bfd_generic_link_add_one_symbol (link_info, branch_bfd, tmp_name, BSF_LOCAL,
-                                   branch_sec, val, NULL, TRUE, FALSE, &bh);
+                                   branch_sec, val, NULL, true, false, &bh);
 
   myh = (struct elf_link_hash_entry *) bh;
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -7195,7 +7532,7 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
       _bfd_generic_link_add_one_symbol (link_info,
                                        hash_table->bfd_of_glue_owner, "$a",
                                        BSF_LOCAL, s, 0, NULL,
-                                       TRUE, FALSE, &bh);
+                                       true, false, &bh);
 
       myh = (struct elf_link_hash_entry *) bh;
       myh->type = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
@@ -7249,14 +7586,13 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
 
   tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen
                                  (STM32L4XX_ERRATUM_VENEER_ENTRY_NAME) + 10);
-
   BFD_ASSERT (tmp_name);
 
   sprintf (tmp_name, STM32L4XX_ERRATUM_VENEER_ENTRY_NAME,
           hash_table->num_stm32l4xx_fixes);
 
   myh = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
+    (&(hash_table)->root, tmp_name, false, false, false);
 
   BFD_ASSERT (myh == NULL);
 
@@ -7264,7 +7600,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
   val = hash_table->stm32l4xx_erratum_glue_size;
   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
                                    tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
-                                   NULL, TRUE, FALSE, &bh);
+                                   NULL, true, false, &bh);
 
   myh = (struct elf_link_hash_entry *) bh;
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -7289,7 +7625,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
           hash_table->num_stm32l4xx_fixes);
 
   myh = elf_link_hash_lookup
-    (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
+    (&(hash_table)->root, tmp_name, false, false, false);
 
   if (myh != NULL)
     abort ();
@@ -7297,7 +7633,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
   bh = NULL;
   val = offset + 4;
   _bfd_generic_link_add_one_symbol (link_info, branch_bfd, tmp_name, BSF_LOCAL,
-                                   branch_sec, val, NULL, TRUE, FALSE, &bh);
+                                   branch_sec, val, NULL, true, false, &bh);
 
   myh = (struct elf_link_hash_entry *) bh;
   myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -7314,7 +7650,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
       _bfd_generic_link_add_one_symbol (link_info,
                                        hash_table->bfd_of_glue_owner, "$t",
                                        BSF_LOCAL, s, 0, NULL,
-                                       TRUE, FALSE, &bh);
+                                       true, false, &bh);
 
       myh = (struct elf_link_hash_entry *) bh;
       myh->type = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
@@ -7341,7 +7677,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
 
 /* Create a fake section for use by the ARM backend of the linker.  */
 
-static bfd_boolean
+static bool
 arm_make_glue_section (bfd * abfd, const char * name)
 {
   asection * sec;
@@ -7349,19 +7685,19 @@ arm_make_glue_section (bfd * abfd, const char * name)
   sec = bfd_get_linker_section (abfd, name);
   if (sec != NULL)
     /* Already made.  */
-    return TRUE;
+    return true;
 
   sec = bfd_make_section_anyway_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS);
 
   if (sec == NULL
-      || !bfd_set_section_alignment (abfd, sec, 2))
-    return FALSE;
+      || !bfd_set_section_alignment (sec, 2))
+    return false;
 
   /* Set the gc mark to prevent the section from being removed by garbage
      collection, despite the fact that no relocs refer to this section.  */
   sec->gc_mark = 1;
 
-  return TRUE;
+  return true;
 }
 
 /* Set size of .plt entries.  This function is called from the
@@ -7370,25 +7706,25 @@ arm_make_glue_section (bfd * abfd, const char * name)
 void
 bfd_elf32_arm_use_long_plt (void)
 {
-  elf32_arm_use_long_plt_entry = TRUE;
+  elf32_arm_use_long_plt_entry = true;
 }
 
 /* Add the glue sections to ABFD.  This function is called from the
    linker scripts in ld/emultempl/{armelf}.em.  */
 
-bfd_boolean
+bool
 bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
                                        struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
-  bfd_boolean dostm32l4xx = globals
+  bool dostm32l4xx = globals
     && globals->stm32l4xx_fix != BFD_ARM_STM32L4XX_FIX_NONE;
-  bfd_boolean addglue;
+  bool addglue;
 
   /* If we are only performing a partial
      link do not bother adding the glue.  */
   if (bfd_link_relocatable (info))
-    return TRUE;
+    return true;
 
   addglue = arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
     && arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)
@@ -7437,7 +7773,7 @@ bfd_elf32_arm_keep_private_stub_output_sections (struct bfd_link_info *info)
    This function is called from the linker scripts in ld/emultempl/
    {armelf/pe}.em.  */
 
-bfd_boolean
+bool
 bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *globals;
@@ -7445,7 +7781,7 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
   /* If we are only performing a partial link
      do not bother getting a bfd to hold the glue.  */
   if (bfd_link_relocatable (info))
-    return TRUE;
+    return true;
 
   /* Make sure we don't attach the glue sections to a dynamic object.  */
   BFD_ASSERT (!(abfd->flags & DYNAMIC));
@@ -7454,12 +7790,12 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
   BFD_ASSERT (globals != NULL);
 
   if (globals->bfd_of_glue_owner != NULL)
-    return TRUE;
+    return true;
 
   /* Save the bfd for later use.  */
   globals->bfd_of_glue_owner = abfd;
 
-  return TRUE;
+  return true;
 }
 
 static void
@@ -7482,7 +7818,7 @@ check_use_blx (struct elf32_arm_link_hash_table *globals)
     }
 }
 
-bfd_boolean
+bool
 bfd_elf32_arm_process_before_allocation (bfd *abfd,
                                         struct bfd_link_info *link_info)
 {
@@ -7497,7 +7833,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
   /* If we are only performing a partial link do not bother
      to construct any glue.  */
   if (bfd_link_relocatable (link_info))
-    return TRUE;
+    return true;
 
   /* Here we have a bfd that is to be included on the link.  We have a
      hook to do reloc rummaging, before section sizes are nailed down.  */
@@ -7508,22 +7844,22 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
 
   if (globals->byteswap_code && !bfd_big_endian (abfd))
     {
-      _bfd_error_handler (_("%B: BE8 images only valid in big-endian mode."),
+      _bfd_error_handler (_("%pB: BE8 images only valid in big-endian mode"),
                          abfd);
-      return FALSE;
+      return false;
     }
 
   /* PR 5398: If we have not decided to include any loadable sections in
      the output then we will not have a glue owner bfd.  This is OK, it
      just means that there is nothing else for us to do here.  */
   if (globals->bfd_of_glue_owner == NULL)
-    return TRUE;
+    return true;
 
   /* Rummage around all the relocs and map the glue vectors.  */
   sec = abfd->sections;
 
   if (sec == NULL)
-    return TRUE;
+    return true;
 
   for (; sec != NULL; sec = sec->next)
     {
@@ -7537,7 +7873,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
 
       /* Load the relocs.  */
       internal_relocs
-       = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, FALSE);
+       = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, false);
 
       if (internal_relocs == NULL)
        goto error_return;
@@ -7619,28 +7955,24 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
            }
        }
 
-      if (contents != NULL
-         && elf_section_data (sec)->this_hdr.contents != contents)
+      if (elf_section_data (sec)->this_hdr.contents != contents)
        free (contents);
       contents = NULL;
 
-      if (internal_relocs != NULL
-         && elf_section_data (sec)->relocs != internal_relocs)
+      if (elf_section_data (sec)->relocs != internal_relocs)
        free (internal_relocs);
       internal_relocs = NULL;
     }
 
-  return TRUE;
+  return true;
 
-error_return:
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+ error_return:
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
-  return FALSE;
+  return false;
 }
 #endif
 
@@ -7739,7 +8071,7 @@ bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)
 
        default:
          /* Give a warning, but do as the user requests anyway.  */
-         _bfd_error_handler (_("%B: warning: selected VFP11 erratum "
+         _bfd_error_handler (_("%pB: warning: selected VFP11 erratum "
            "workaround is not necessary for target architecture"), obfd);
        }
     }
@@ -7766,7 +8098,7 @@ bfd_elf32_arm_set_stm32l4xx_fix (bfd *obfd, struct bfd_link_info *link_info)
       if (globals->stm32l4xx_fix != BFD_ARM_STM32L4XX_FIX_NONE)
        /* Give a warning, but do as the user requests anyway.  */
        _bfd_error_handler
-         (_("%B: warning: selected STM32L4XX erratum "
+         (_("%pB: warning: selected STM32L4XX erratum "
             "workaround is not necessary for target architecture"), obfd);
     }
 }
@@ -7792,7 +8124,7 @@ enum bfd_arm_vfp11_pipe
    encounter VFP3 instructions, so we allow the full range for DP registers.  */
 
 static unsigned int
-bfd_arm_vfp11_regno (unsigned int insn, bfd_boolean is_double, unsigned int rx,
+bfd_arm_vfp11_regno (unsigned int insn, bool is_double, unsigned int rx,
                     unsigned int x)
 {
   if (is_double)
@@ -7815,7 +8147,7 @@ bfd_arm_vfp11_write_mask (unsigned int *wmask, unsigned int reg)
 
 /* Return TRUE if WMASK overwrites anything in REGS.  */
 
-static bfd_boolean
+static bool
 bfd_arm_vfp11_antidependency (unsigned int wmask, int *regs, int numregs)
 {
   int i;
@@ -7825,7 +8157,7 @@ bfd_arm_vfp11_antidependency (unsigned int wmask, int *regs, int numregs)
       unsigned int reg = regs[i];
 
       if (reg < 32 && (wmask & (1 << reg)) != 0)
-       return TRUE;
+       return true;
 
       reg -= 32;
 
@@ -7833,10 +8165,10 @@ bfd_arm_vfp11_antidependency (unsigned int wmask, int *regs, int numregs)
        continue;
 
       if ((wmask & (3 << (reg * 2))) != 0)
-       return TRUE;
+       return true;
     }
 
-  return FALSE;
+  return false;
 }
 
 /* In this function, we're interested in two things: finding input registers
@@ -7852,7 +8184,7 @@ bfd_arm_vfp11_insn_decode (unsigned int insn, unsigned int *destmask, int *regs,
                           int *numregs)
 {
   enum bfd_arm_vfp11_pipe vpipe = VFP11_BAD;
-  bfd_boolean is_double = ((insn & 0xf00) == 0xb00) ? 1 : 0;
+  bool is_double = ((insn & 0xf00) == 0xb00) ? 1 : 0;
 
   if ((insn & 0x0f000e10) == 0x0e000a00)  /* A data-processing insn.  */
     {
@@ -8040,7 +8372,7 @@ static int elf32_arm_compare_mapping (const void * a, const void * b);
    (available from ARM) for details of the erratum.  A short version is
    described in ld.texinfo.  */
 
-bfd_boolean
+bool
 bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
 {
   asection *sec;
@@ -8051,7 +8383,7 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
   int use_vector = (globals->vfp11_fix == BFD_ARM_VFP11_FIX_VECTOR);
 
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   /* We use a simple FSM to match troublesome VFP11 instruction sequences.
      The states transition as follows:
@@ -8082,21 +8414,21 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
   /* If we are only performing a partial link do not bother
      to construct any glue.  */
   if (bfd_link_relocatable (link_info))
-    return TRUE;
+    return true;
 
   /* Skip if this bfd does not correspond to an ELF image.  */
   if (! is_arm_elf (abfd))
-    return TRUE;
+    return true;
 
   /* We should have chosen a fix type by the time we get here.  */
   BFD_ASSERT (globals->vfp11_fix != BFD_ARM_VFP11_FIX_DEFAULT);
 
   if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_NONE)
-    return TRUE;
+    return true;
 
   /* Skip this BFD if it corresponds to an executable or dynamic object.  */
   if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
-    return TRUE;
+    return true;
 
   for (sec = abfd->sections; sec != NULL; sec = sec->next)
     {
@@ -8142,14 +8474,14 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
            {
              unsigned int next_i = i + 4;
              unsigned int insn = bfd_big_endian (abfd)
-               ? (contents[i] << 24)
-                 | (contents[i + 1] << 16)
-                 | (contents[i + 2] << 8)
-                 | contents[i + 3]
-               : (contents[i + 3] << 24)
-                 | (contents[i + 2] << 16)
-                 | (contents[i + 1] << 8)
-                 | contents[i];
+               ? (((unsigned) contents[i] << 24)
+                  | (contents[i + 1] << 16)
+                  | (contents[i + 2] << 8)
+                  | contents[i + 3])
+               : (((unsigned) contents[i + 3] << 24)
+                  | (contents[i + 2] << 16)
+                  | (contents[i + 1] << 8)
+                  | contents[i]);
              unsigned int writemask = 0;
              enum bfd_arm_vfp11_pipe vpipe;
 
@@ -8240,20 +8572,18 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
            }
        }
 
-      if (contents != NULL
-         && elf_section_data (sec)->this_hdr.contents != contents)
+      if (elf_section_data (sec)->this_hdr.contents != contents)
        free (contents);
       contents = NULL;
     }
 
-  return TRUE;
+  return true;
 
-error_return:
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+ error_return:
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
 
-  return FALSE;
+  return false;
 }
 
 /* Find virtual-memory addresses for VFP11 erratum veneers and return locations
@@ -8280,6 +8610,7 @@ bfd_elf32_arm_vfp11_fix_veneer_locations (bfd *abfd,
 
   tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen
                                  (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10);
+  BFD_ASSERT (tmp_name);
 
   for (sec = abfd->sections; sec != NULL; sec = sec->next)
     {
@@ -8300,11 +8631,11 @@ bfd_elf32_arm_vfp11_fix_veneer_locations (bfd *abfd,
                       errnode->u.b.veneer->u.v.id);
 
              myh = elf_link_hash_lookup
-               (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+               (&(globals)->root, tmp_name, false, false, true);
 
              if (myh == NULL)
-               _bfd_error_handler (_("%B: unable to find VFP11 veneer "
-                                     "`%s'"), abfd, tmp_name);
+               _bfd_error_handler (_("%pB: unable to find %s veneer `%s'"),
+                                   abfd, "VFP11", tmp_name);
 
              vma = myh->root.u.def.section->output_section->vma
                    + myh->root.u.def.section->output_offset
@@ -8320,11 +8651,11 @@ bfd_elf32_arm_vfp11_fix_veneer_locations (bfd *abfd,
                       errnode->u.v.id);
 
              myh = elf_link_hash_lookup
-               (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+               (&(globals)->root, tmp_name, false, false, true);
 
              if (myh == NULL)
-               _bfd_error_handler (_("%B: unable to find VFP11 veneer "
-                                     "`%s'"), abfd, tmp_name);
+               _bfd_error_handler (_("%pB: unable to find %s veneer `%s'"),
+                                   abfd, "VFP11", tmp_name);
 
              vma = myh->root.u.def.section->output_section->vma
                    + myh->root.u.def.section->output_offset
@@ -8367,6 +8698,7 @@ bfd_elf32_arm_stm32l4xx_fix_veneer_locations (bfd *abfd,
 
   tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen
                                  (STM32L4XX_ERRATUM_VENEER_ENTRY_NAME) + 10);
+  BFD_ASSERT (tmp_name);
 
   for (sec = abfd->sections; sec != NULL; sec = sec->next)
     {
@@ -8386,11 +8718,11 @@ bfd_elf32_arm_stm32l4xx_fix_veneer_locations (bfd *abfd,
                       errnode->u.b.veneer->u.v.id);
 
              myh = elf_link_hash_lookup
-               (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+               (&(globals)->root, tmp_name, false, false, true);
 
              if (myh == NULL)
-               _bfd_error_handler (_("%B: unable to find STM32L4XX veneer "
-                                     "`%s'"), abfd, tmp_name);
+               _bfd_error_handler (_("%pB: unable to find %s veneer `%s'"),
+                                   abfd, "STM32L4XX", tmp_name);
 
              vma = myh->root.u.def.section->output_section->vma
                + myh->root.u.def.section->output_offset
@@ -8405,11 +8737,11 @@ bfd_elf32_arm_stm32l4xx_fix_veneer_locations (bfd *abfd,
                       errnode->u.v.id);
 
              myh = elf_link_hash_lookup
-               (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+               (&(globals)->root, tmp_name, false, false, true);
 
              if (myh == NULL)
-               _bfd_error_handler (_("%B: unable to find STM32L4XX veneer "
-                                     "`%s'"), abfd, tmp_name);
+               _bfd_error_handler (_("%pB: unable to find %s veneer `%s'"),
+                                   abfd, "STM32L4XX", tmp_name);
 
              vma = myh->root.u.def.section->output_section->vma
                + myh->root.u.def.section->output_offset
@@ -8427,7 +8759,7 @@ bfd_elf32_arm_stm32l4xx_fix_veneer_locations (bfd *abfd,
   free (tmp_name);
 }
 
-static inline bfd_boolean
+static inline bool
 is_thumb2_ldmia (const insn32 insn)
 {
   /* Encoding T2: LDM<c>.W <Rn>{!},<registers>
@@ -8435,7 +8767,7 @@ is_thumb2_ldmia (const insn32 insn)
   return (insn & 0xffd02000) == 0xe8900000;
 }
 
-static inline bfd_boolean
+static inline bool
 is_thumb2_ldmdb (const insn32 insn)
 {
   /* Encoding T1: LDMDB<c> <Rn>{!},<registers>
@@ -8443,7 +8775,7 @@ is_thumb2_ldmdb (const insn32 insn)
   return (insn & 0xffd02000) == 0xe9100000;
 }
 
-static inline bfd_boolean
+static inline bool
 is_thumb2_vldm (const insn32 insn)
 {
   /* A6.5 Extension register load or store instruction
@@ -8475,7 +8807,7 @@ is_thumb2_vldm (const insn32 insn)
    . replaces only if > 8-word accesses
    . or (testing purposes only) replaces all accesses.  */
 
-static bfd_boolean
+static bool
 stm32l4xx_need_create_replacing_stub (const insn32 insn,
                                      bfd_arm_stm32l4xx_fix stm32l4xx_fix)
 {
@@ -8490,15 +8822,15 @@ stm32l4xx_need_create_replacing_stub (const insn32 insn,
 
   /* DEFAULT mode accounts for the real bug condition situation,
      ALL mode inserts stubs for each LDM/VLDM instruction (testing).  */
-  return
-    (stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_DEFAULT) ? nb_words > 8 :
-    (stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_ALL) ? TRUE : FALSE;
+  return (stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_DEFAULT
+         ? nb_words > 8
+         : stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_ALL);
 }
 
 /* Look for potentially-troublesome code sequences which might trigger
    the STM STM32L4XX erratum.  */
 
-bfd_boolean
+bool
 bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
                                      struct bfd_link_info *link_info)
 {
@@ -8507,23 +8839,23 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
 
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   /* If we are only performing a partial link do not bother
      to construct any glue.  */
   if (bfd_link_relocatable (link_info))
-    return TRUE;
+    return true;
 
   /* Skip if this bfd does not correspond to an ELF image.  */
   if (! is_arm_elf (abfd))
-    return TRUE;
+    return true;
 
   if (globals->stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_NONE)
-    return TRUE;
+    return true;
 
   /* Skip this BFD if it corresponds to an executable or dynamic object.  */
   if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
-    return TRUE;
+    return true;
 
   for (sec = abfd->sections; sec != NULL; sec = sec->next)
     {
@@ -8570,17 +8902,17 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
          for (i = span_start; i < span_end;)
            {
              unsigned int insn = bfd_get_16 (abfd, &contents[i]);
-             bfd_boolean insn_32bit = FALSE;
-             bfd_boolean is_ldm = FALSE;
-             bfd_boolean is_vldm = FALSE;
-             bfd_boolean is_not_last_in_it_block = FALSE;
+             bool insn_32bit = false;
+             bool is_ldm = false;
+             bool is_vldm = false;
+             bool is_not_last_in_it_block = false;
 
              /* The first 16-bits of all 32-bit thumb2 instructions start
                 with opcode[15..13]=0b111 and the encoded op1 can be anything
                 except opcode[12..11]!=0b00.
                 See 32-bit Thumb instruction encoding.  */
              if ((insn & 0xe000) == 0xe000 && (insn & 0x1800) != 0x0000)
-               insn_32bit = TRUE;
+               insn_32bit = true;
 
              /* Compute the predicate that tells if the instruction
                 is concerned by the IT block
@@ -8615,11 +8947,11 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
                          {
                            _bfd_error_handler
                              /* xgettext:c-format */
-                             (_("%B(%A+%#x): error: multiple load detected"
-                                " in non-last IT block instruction :"
-                                " STM32L4XX veneer cannot be generated.\n"
-                                "Use gcc option -mrestrict-it to generate"
-                                " only one instruction per IT block.\n"),
+                             (_("%pB(%pA+%#x): error: multiple load detected"
+                                " in non-last IT block instruction:"
+                                " STM32L4XX veneer cannot be generated"
+                                "use gcc option -mrestrict-it to generate"
+                                " only one instruction per IT block"),
                               abfd, sec, i);
                          }
                        else
@@ -8658,7 +8990,7 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
                     There can be no nested IT blocks so an IT block
                     is naturally a new one for which it is worth
                     computing its size.  */
-                 bfd_boolean is_newitblock = ((insn & 0xff00) == 0xbf00)
+                 bool is_newitblock = ((insn & 0xff00) == 0xbf00)
                    && ((insn & 0x000f) != 0x0000);
                  /* If we have a new IT block we compute its size.  */
                  if (is_newitblock)
@@ -8675,20 +9007,18 @@ bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
            }
        }
 
-      if (contents != NULL
-         && elf_section_data (sec)->this_hdr.contents != contents)
+      if (elf_section_data (sec)->this_hdr.contents != contents)
        free (contents);
       contents = NULL;
     }
 
-  return TRUE;
+  return true;
 
-error_return:
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+ error_return:
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
 
-  return FALSE;
+  return false;
 }
 
 /* Set target relocation values needed during linking.  */
@@ -8705,7 +9035,9 @@ bfd_elf32_arm_set_target_params (struct bfd *output_bfd,
     return;
 
   globals->target1_is_rel = params->target1_is_rel;
-  if (strcmp (params->target2_type, "rel") == 0)
+  if (globals->fdpic_p)
+    globals->target2_reloc = R_ARM_GOT32;
+  else if (strcmp (params->target2_type, "rel") == 0)
     globals->target2_reloc = R_ARM_REL32;
   else if (strcmp (params->target2_type, "abs") == 0)
     globals->target2_reloc = R_ARM_ABS32;
@@ -8713,14 +9045,17 @@ bfd_elf32_arm_set_target_params (struct bfd *output_bfd,
     globals->target2_reloc = R_ARM_GOT_PREL;
   else
     {
-      _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
+      _bfd_error_handler (_("invalid TARGET2 relocation type '%s'"),
                          params->target2_type);
     }
   globals->fix_v4bx = params->fix_v4bx;
   globals->use_blx |= params->use_blx;
   globals->vfp11_fix = params->vfp11_denorm_fix;
   globals->stm32l4xx_fix = params->stm32l4xx_fix;
-  globals->pic_veneer = params->pic_veneer;
+  if (globals->fdpic_p)
+    globals->pic_veneer = 1;
+  else
+    globals->pic_veneer = params->pic_veneer;
   globals->fix_cortex_a8 = params->fix_cortex_a8;
   globals->fix_arm1176 = params->fix_arm1176;
   globals->cmse_implib = params->cmse_implib;
@@ -8762,15 +9097,15 @@ insert_thumb_branch (bfd *abfd, long int offset, bfd_byte *insn)
 
 static int
 elf32_thumb_to_arm_stub (struct bfd_link_info * info,
-                        const char *           name,
-                        bfd *                  input_bfd,
-                        bfd *                  output_bfd,
-                        asection *             input_section,
-                        bfd_byte *             hit_data,
-                        asection *             sym_sec,
-                        bfd_vma                offset,
-                        bfd_signed_vma         addend,
-                        bfd_vma                val,
+                        const char *           name,
+                        bfd *                  input_bfd,
+                        bfd *                  output_bfd,
+                        asection *             input_section,
+                        bfd_byte *             hit_data,
+                        asection *             sym_sec,
+                        bfd_vma                offset,
+                        bfd_signed_vma         addend,
+                        bfd_vma                val,
                         char **error_message)
 {
   asection * s = 0;
@@ -8781,7 +9116,7 @@ elf32_thumb_to_arm_stub (struct bfd_link_info * info,
 
   myh = find_thumb_glue (info, name, error_message);
   if (myh == NULL)
-    return FALSE;
+    return false;
 
   globals = elf32_arm_hash_table (info);
   BFD_ASSERT (globals != NULL);
@@ -8803,11 +9138,11 @@ elf32_thumb_to_arm_stub (struct bfd_link_info * info,
          && !INTERWORK_FLAG (sym_sec->owner))
        {
          _bfd_error_handler
-           (_("%B(%s): warning: interworking not enabled.\n"
-              "  first occurrence: %B: Thumb call to ARM"),
-            sym_sec->owner, name, input_bfd);
+           (_("%pB(%s): warning: interworking not enabled;"
+              " first occurrence: %pB: %s call to %s"),
+            sym_sec->owner, name, input_bfd, "Thumb", "ARM");
 
-         return FALSE;
+         return false;
        }
 
       --my_offset;
@@ -8856,20 +9191,20 @@ elf32_thumb_to_arm_stub (struct bfd_link_info * info,
 
   insert_thumb_branch (input_bfd, ret_offset, hit_data - input_section->vma);
 
-  return TRUE;
+  return true;
 }
 
 /* Populate an Arm to Thumb stub.  Returns the stub symbol.  */
 
 static struct elf_link_hash_entry *
 elf32_arm_create_thumb_stub (struct bfd_link_info * info,
-                            const char *           name,
-                            bfd *                  input_bfd,
-                            bfd *                  output_bfd,
-                            asection *             sym_sec,
-                            bfd_vma                val,
-                            asection *             s,
-                            char **                error_message)
+                            const char *           name,
+                            bfd *                  input_bfd,
+                            bfd *                  output_bfd,
+                            asection *             sym_sec,
+                            bfd_vma                val,
+                            asection *             s,
+                            char **                error_message)
 {
   bfd_vma my_offset;
   long int ret_offset;
@@ -8893,9 +9228,9 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
          && !INTERWORK_FLAG (sym_sec->owner))
        {
          _bfd_error_handler
-           (_("%B(%s): warning: interworking not enabled.\n"
-              "  first occurrence: %B: arm call to thumb"),
-            sym_sec->owner, name, input_bfd);
+           (_("%pB(%s): warning: interworking not enabled;"
+              " first occurrence: %pB: %s call to %s"),
+            sym_sec->owner, name, input_bfd, "ARM", "Thumb");
        }
 
       --my_offset;
@@ -8958,15 +9293,15 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
 
 static int
 elf32_arm_to_thumb_stub (struct bfd_link_info * info,
-                        const char *           name,
-                        bfd *                  input_bfd,
-                        bfd *                  output_bfd,
-                        asection *             input_section,
-                        bfd_byte *             hit_data,
-                        asection *             sym_sec,
-                        bfd_vma                offset,
-                        bfd_signed_vma         addend,
-                        bfd_vma                val,
+                        const char *           name,
+                        bfd *                  input_bfd,
+                        bfd *                  output_bfd,
+                        asection *             input_section,
+                        bfd_byte *             hit_data,
+                        asection *             sym_sec,
+                        bfd_vma                offset,
+                        bfd_signed_vma         addend,
+                        bfd_vma                val,
                         char **error_message)
 {
   unsigned long int tmp;
@@ -8989,7 +9324,7 @@ elf32_arm_to_thumb_stub (struct bfd_link_info * info,
   myh = elf32_arm_create_thumb_stub (info, name, input_bfd, output_bfd,
                                     sym_sec, val, s, error_message);
   if (!myh)
-    return FALSE;
+    return false;
 
   my_offset = myh->root.u.def.value;
   tmp = bfd_get_32 (input_bfd, hit_data);
@@ -9008,12 +9343,12 @@ elf32_arm_to_thumb_stub (struct bfd_link_info * info,
 
   bfd_put_32 (output_bfd, (bfd_vma) tmp, hit_data - input_section->vma);
 
-  return TRUE;
+  return true;
 }
 
 /* Populate Arm stub for an exported Thumb function.  */
 
-static bfd_boolean
+static bool
 elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
 {
   struct bfd_link_info * info = (struct bfd_link_info *) inf;
@@ -9028,7 +9363,7 @@ elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
   eh = elf32_arm_hash_entry (h);
   /* Allocate stubs for exported Thumb functions on v4t.  */
   if (eh->export_glue == NULL)
-    return TRUE;
+    return true;
 
   globals = elf32_arm_hash_table (info);
   BFD_ASSERT (globals != NULL);
@@ -9052,7 +9387,7 @@ elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
                                     globals->obfd, sec, val, s,
                                     &error_message);
   BFD_ASSERT (myh);
-  return TRUE;
+  return true;
 }
 
 /* Populate ARMv4 BX veneers.  Returns the absolute adress of the veneer.  */
@@ -9179,7 +9514,7 @@ elf32_arm_add_dynreloc (bfd *output_bfd, struct bfd_link_info *info,
 
 static void
 elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
-                             bfd_boolean is_iplt_entry,
+                             bool is_iplt_entry,
                              union gotplt_union *root_plt,
                              struct arm_plt_info *arm_plt)
 {
@@ -9195,7 +9530,7 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
       sgotplt = htab->root.igotplt;
 
       /* NaCl uses a special first entry in .iplt too.  */
-      if (htab->nacl_p && splt->size == 0)
+      if (htab->root.target_os == is_nacl && splt->size == 0)
        splt->size += htab->plt_header_size;
 
       /* Allocate room for an R_ARM_IRELATIVE relocation in .rel.iplt.  */
@@ -9206,8 +9541,22 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
       splt = htab->root.splt;
       sgotplt = htab->root.sgotplt;
 
-      /* Allocate room for an R_JUMP_SLOT relocation in .rel.plt.  */
-      elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
+    if (htab->fdpic_p)
+      {
+       /* Allocate room for R_ARM_FUNCDESC_VALUE.  */
+       /* For lazy binding, relocations will be put into .rel.plt, in
+          .rel.got otherwise.  */
+       /* FIXME: today we don't support lazy binding so put it in .rel.got */
+       if (info->flags & DF_BIND_NOW)
+         elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+       else
+         elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
+      }
+    else
+      {
+       /* Allocate room for an R_JUMP_SLOT relocation in .rel.plt.  */
+       elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
+      }
 
       /* If this is the first .plt entry, make room for the special
         first entry.  */
@@ -9223,16 +9572,17 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
   root_plt->offset = splt->size;
   splt->size += htab->plt_entry_size;
 
-  if (!htab->symbian_p)
-    {
-      /* We also need to make an entry in the .got.plt section, which
-        will be placed in the .got section by the linker script.  */
-      if (is_iplt_entry)
-       arm_plt->got_offset = sgotplt->size;
-      else
-       arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc;
-      sgotplt->size += 4;
-    }
+  /* We also need to make an entry in the .got.plt section, which
+     will be placed in the .got section by the linker script.  */
+  if (is_iplt_entry)
+    arm_plt->got_offset = sgotplt->size;
+  else
+    arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc;
+  if (htab->fdpic_p)
+    /* Function descriptor takes 64 bits in GOT.  */
+    sgotplt->size += 8;
+  else
+    sgotplt->size += 4;
 }
 
 static bfd_vma
@@ -9258,7 +9608,7 @@ arm_movt_immediate (bfd_vma value)
 
    Returns FALSE if there was a problem.  */
 
-static bfd_boolean
+static bool
 elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
                              union gotplt_union *root_plt,
                              struct arm_plt_info *arm_plt,
@@ -9271,7 +9621,6 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
   bfd_byte *loc;
   bfd_vma plt_index;
   Elf_Internal_Rela rel;
-  bfd_vma plt_header_size;
   bfd_vma got_header_size;
 
   htab = elf32_arm_hash_table (info);
@@ -9286,7 +9635,6 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
       /* There are no reserved entries in .igot.plt, and no special
         first entry in .iplt.  */
       got_header_size = 0;
-      plt_header_size = 0;
     }
   else
     {
@@ -9295,288 +9643,344 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
       srel = htab->root.srelplt;
 
       got_header_size = get_elf_backend_data (output_bfd)->got_header_size;
-      plt_header_size = htab->plt_header_size;
     }
   BFD_ASSERT (splt != NULL && srel != NULL);
 
-  /* Fill in the entry in the procedure linkage table.  */
-  if (htab->symbian_p)
+  bfd_vma got_offset, got_address, plt_address;
+  bfd_vma got_displacement, initial_got_entry;
+  bfd_byte * ptr;
+
+  BFD_ASSERT (sgot != NULL);
+
+  /* Get the offset into the .(i)got.plt table of the entry that
+     corresponds to this function.  */
+  got_offset = (arm_plt->got_offset & -2);
+
+  /* Get the index in the procedure linkage table which
+     corresponds to this symbol.  This is the index of this symbol
+     in all the symbols for which we are making plt entries.
+     After the reserved .got.plt entries, all symbols appear in
+     the same order as in .plt.  */
+  if (htab->fdpic_p)
+    /* Function descriptor takes 8 bytes.  */
+    plt_index = (got_offset - got_header_size) / 8;
+  else
+    plt_index = (got_offset - got_header_size) / 4;
+
+  /* Calculate the address of the GOT entry.  */
+  got_address = (sgot->output_section->vma
+                + sgot->output_offset
+                + got_offset);
+
+  /* ...and the address of the PLT entry.  */
+  plt_address = (splt->output_section->vma
+                + splt->output_offset
+                + root_plt->offset);
+
+  ptr = splt->contents + root_plt->offset;
+  if (htab->root.target_os == is_vxworks && bfd_link_pic (info))
     {
-      BFD_ASSERT (dynindx >= 0);
-      put_arm_insn (htab, output_bfd,
-                   elf32_arm_symbian_plt_entry[0],
-                   splt->contents + root_plt->offset);
-      bfd_put_32 (output_bfd,
-                 elf32_arm_symbian_plt_entry[1],
-                 splt->contents + root_plt->offset + 4);
-
-      /* Fill in the entry in the .rel.plt section.  */
-      rel.r_offset = (splt->output_section->vma
-                     + splt->output_offset
-                     + root_plt->offset + 4);
-      rel.r_info = ELF32_R_INFO (dynindx, R_ARM_GLOB_DAT);
-
-      /* Get the index in the procedure linkage table which
-        corresponds to this symbol.  This is the index of this symbol
-        in all the symbols for which we are making plt entries.  The
-        first entry in the procedure linkage table is reserved.  */
-      plt_index = ((root_plt->offset - plt_header_size)
-                  / htab->plt_entry_size);
+      unsigned int i;
+      bfd_vma val;
+
+      for (i = 0; i != htab->plt_entry_size / 4; i++, ptr += 4)
+       {
+         val = elf32_arm_vxworks_shared_plt_entry[i];
+         if (i == 2)
+           val |= got_address - sgot->output_section->vma;
+         if (i == 5)
+           val |= plt_index * RELOC_SIZE (htab);
+         if (i == 2 || i == 5)
+           bfd_put_32 (output_bfd, val, ptr);
+         else
+           put_arm_insn (htab, output_bfd, val, ptr);
+       }
     }
-  else
+  else if (htab->root.target_os == is_vxworks)
     {
-      bfd_vma got_offset, got_address, plt_address;
-      bfd_vma got_displacement, initial_got_entry;
-      bfd_byte * ptr;
+      unsigned int i;
+      bfd_vma val;
 
-      BFD_ASSERT (sgot != NULL);
+      for (i = 0; i != htab->plt_entry_size / 4; i++, ptr += 4)
+       {
+         val = elf32_arm_vxworks_exec_plt_entry[i];
+         if (i == 2)
+           val |= got_address;
+         if (i == 4)
+           val |= 0xffffff & -((root_plt->offset + i * 4 + 8) >> 2);
+         if (i == 5)
+           val |= plt_index * RELOC_SIZE (htab);
+         if (i == 2 || i == 5)
+           bfd_put_32 (output_bfd, val, ptr);
+         else
+           put_arm_insn (htab, output_bfd, val, ptr);
+       }
 
-      /* Get the offset into the .(i)got.plt table of the entry that
-        corresponds to this function.  */
-      got_offset = (arm_plt->got_offset & -2);
+      loc = (htab->srelplt2->contents
+            + (plt_index * 2 + 1) * RELOC_SIZE (htab));
 
-      /* Get the index in the procedure linkage table which
-        corresponds to this symbol.  This is the index of this symbol
-        in all the symbols for which we are making plt entries.
-        After the reserved .got.plt entries, all symbols appear in
-        the same order as in .plt.  */
-      plt_index = (got_offset - got_header_size) / 4;
+      /* Create the .rela.plt.unloaded R_ARM_ABS32 relocation
+        referencing the GOT for this PLT entry.  */
+      rel.r_offset = plt_address + 8;
+      rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+      rel.r_addend = got_offset;
+      SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+      loc += RELOC_SIZE (htab);
 
-      /* Calculate the address of the GOT entry.  */
-      got_address = (sgot->output_section->vma
-                    + sgot->output_offset
-                    + got_offset);
+      /* Create the R_ARM_ABS32 relocation referencing the
+        beginning of the PLT for this GOT entry.  */
+      rel.r_offset = got_address;
+      rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32);
+      rel.r_addend = 0;
+      SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+    }
+  else if (htab->root.target_os == is_nacl)
+    {
+      /* Calculate the displacement between the PLT slot and the
+        common tail that's part of the special initial PLT slot.  */
+      int32_t tail_displacement
+       = ((splt->output_section->vma + splt->output_offset
+           + ARM_NACL_PLT_TAIL_OFFSET)
+          - (plt_address + htab->plt_entry_size + 4));
+      BFD_ASSERT ((tail_displacement & 3) == 0);
+      tail_displacement >>= 2;
 
-      /* ...and the address of the PLT entry.  */
-      plt_address = (splt->output_section->vma
-                    + splt->output_offset
-                    + root_plt->offset);
+      BFD_ASSERT ((tail_displacement & 0xff000000) == 0
+                 || (-tail_displacement & 0xff000000) == 0);
 
-      ptr = splt->contents + root_plt->offset;
-      if (htab->vxworks_p && bfd_link_pic (info))
+      /* Calculate the displacement between the PLT slot and the entry
+        in the GOT.  The offset accounts for the value produced by
+        adding to pc in the penultimate instruction of the PLT stub.  */
+      got_displacement = (got_address
+                         - (plt_address + htab->plt_entry_size));
+
+      /* NaCl does not support interworking at all.  */
+      BFD_ASSERT (!elf32_arm_plt_needs_thumb_stub_p (info, arm_plt));
+
+      put_arm_insn (htab, output_bfd,
+                   elf32_arm_nacl_plt_entry[0]
+                   | arm_movw_immediate (got_displacement),
+                   ptr + 0);
+      put_arm_insn (htab, output_bfd,
+                   elf32_arm_nacl_plt_entry[1]
+                   | arm_movt_immediate (got_displacement),
+                   ptr + 4);
+      put_arm_insn (htab, output_bfd,
+                   elf32_arm_nacl_plt_entry[2],
+                   ptr + 8);
+      put_arm_insn (htab, output_bfd,
+                   elf32_arm_nacl_plt_entry[3]
+                   | (tail_displacement & 0x00ffffff),
+                   ptr + 12);
+    }
+  else if (htab->fdpic_p)
+    {
+      const bfd_vma *plt_entry = using_thumb_only (htab)
+       ? elf32_arm_fdpic_thumb_plt_entry
+       : elf32_arm_fdpic_plt_entry;
+
+      /* Fill-up Thumb stub if needed.  */
+      if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
        {
-         unsigned int i;
-         bfd_vma val;
+         put_thumb_insn (htab, output_bfd,
+                         elf32_arm_plt_thumb_stub[0], ptr - 4);
+         put_thumb_insn (htab, output_bfd,
+                         elf32_arm_plt_thumb_stub[1], ptr - 2);
+       }
+      /* As we are using 32 bit instructions even for the Thumb
+        version, we have to use 'put_arm_insn' instead of
+        'put_thumb_insn'.  */
+      put_arm_insn (htab, output_bfd, plt_entry[0], ptr + 0);
+      put_arm_insn (htab, output_bfd, plt_entry[1], ptr + 4);
+      put_arm_insn (htab, output_bfd, plt_entry[2], ptr + 8);
+      put_arm_insn (htab, output_bfd, plt_entry[3], ptr + 12);
+      bfd_put_32 (output_bfd, got_offset, ptr + 16);
 
-         for (i = 0; i != htab->plt_entry_size / 4; i++, ptr += 4)
-           {
-             val = elf32_arm_vxworks_shared_plt_entry[i];
-             if (i == 2)
-               val |= got_address - sgot->output_section->vma;
-             if (i == 5)
-               val |= plt_index * RELOC_SIZE (htab);
-             if (i == 2 || i == 5)
-               bfd_put_32 (output_bfd, val, ptr);
-             else
-               put_arm_insn (htab, output_bfd, val, ptr);
-           }
+      if (!(info->flags & DF_BIND_NOW))
+       {
+         /* funcdesc_value_reloc_offset.  */
+         bfd_put_32 (output_bfd,
+                     htab->root.srelplt->reloc_count * RELOC_SIZE (htab),
+                     ptr + 20);
+         put_arm_insn (htab, output_bfd, plt_entry[6], ptr + 24);
+         put_arm_insn (htab, output_bfd, plt_entry[7], ptr + 28);
+         put_arm_insn (htab, output_bfd, plt_entry[8], ptr + 32);
+         put_arm_insn (htab, output_bfd, plt_entry[9], ptr + 36);
        }
-      else if (htab->vxworks_p)
+    }
+  else if (using_thumb_only (htab))
+    {
+      /* PR ld/16017: Generate thumb only PLT entries.  */
+      if (!using_thumb2 (htab))
        {
-         unsigned int i;
-         bfd_vma val;
-
-         for (i = 0; i != htab->plt_entry_size / 4; i++, ptr += 4)
-           {
-             val = elf32_arm_vxworks_exec_plt_entry[i];
-             if (i == 2)
-               val |= got_address;
-             if (i == 4)
-               val |= 0xffffff & -((root_plt->offset + i * 4 + 8) >> 2);
-             if (i == 5)
-               val |= plt_index * RELOC_SIZE (htab);
-             if (i == 2 || i == 5)
-               bfd_put_32 (output_bfd, val, ptr);
-             else
-               put_arm_insn (htab, output_bfd, val, ptr);
-           }
+         /* FIXME: We ought to be able to generate thumb-1 PLT
+            instructions...  */
+         _bfd_error_handler (_("%pB: warning: thumb-1 mode PLT generation not currently supported"),
+                             output_bfd);
+         return false;
+       }
 
-         loc = (htab->srelplt2->contents
-                + (plt_index * 2 + 1) * RELOC_SIZE (htab));
+      /* Calculate the displacement between the PLT slot and the entry in
+        the GOT.  The 12-byte offset accounts for the value produced by
+        adding to pc in the 3rd instruction of the PLT stub.  */
+      got_displacement = got_address - (plt_address + 12);
 
-         /* Create the .rela.plt.unloaded R_ARM_ABS32 relocation
-            referencing the GOT for this PLT entry.  */
-         rel.r_offset = plt_address + 8;
-         rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
-         rel.r_addend = got_offset;
-         SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
-         loc += RELOC_SIZE (htab);
+      /* As we are using 32 bit instructions we have to use 'put_arm_insn'
+        instead of 'put_thumb_insn'.  */
+      put_arm_insn (htab, output_bfd,
+                   elf32_thumb2_plt_entry[0]
+                   | ((got_displacement & 0x000000ff) << 16)
+                   | ((got_displacement & 0x00000700) << 20)
+                   | ((got_displacement & 0x00000800) >>  1)
+                   | ((got_displacement & 0x0000f000) >> 12),
+                   ptr + 0);
+      put_arm_insn (htab, output_bfd,
+                   elf32_thumb2_plt_entry[1]
+                   | ((got_displacement & 0x00ff0000)      )
+                   | ((got_displacement & 0x07000000) <<  4)
+                   | ((got_displacement & 0x08000000) >> 17)
+                   | ((got_displacement & 0xf0000000) >> 28),
+                   ptr + 4);
+      put_arm_insn (htab, output_bfd,
+                   elf32_thumb2_plt_entry[2],
+                   ptr + 8);
+      put_arm_insn (htab, output_bfd,
+                   elf32_thumb2_plt_entry[3],
+                   ptr + 12);
+    }
+  else
+    {
+      /* Calculate the displacement between the PLT slot and the
+        entry in the GOT.  The eight-byte offset accounts for the
+        value produced by adding to pc in the first instruction
+        of the PLT stub.  */
+      got_displacement = got_address - (plt_address + 8);
 
-         /* Create the R_ARM_ABS32 relocation referencing the
-            beginning of the PLT for this GOT entry.  */
-         rel.r_offset = got_address;
-         rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32);
-         rel.r_addend = 0;
-         SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+      if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
+       {
+         put_thumb_insn (htab, output_bfd,
+                         elf32_arm_plt_thumb_stub[0], ptr - 4);
+         put_thumb_insn (htab, output_bfd,
+                         elf32_arm_plt_thumb_stub[1], ptr - 2);
        }
-      else if (htab->nacl_p)
+
+      if (!elf32_arm_use_long_plt_entry)
        {
-         /* Calculate the displacement between the PLT slot and the
-            common tail that's part of the special initial PLT slot.  */
-         int32_t tail_displacement
-           = ((splt->output_section->vma + splt->output_offset
-               + ARM_NACL_PLT_TAIL_OFFSET)
-              - (plt_address + htab->plt_entry_size + 4));
-         BFD_ASSERT ((tail_displacement & 3) == 0);
-         tail_displacement >>= 2;
-
-         BFD_ASSERT ((tail_displacement & 0xff000000) == 0
-                     || (-tail_displacement & 0xff000000) == 0);
-
-         /* Calculate the displacement between the PLT slot and the entry
-            in the GOT.  The offset accounts for the value produced by
-            adding to pc in the penultimate instruction of the PLT stub.  */
-         got_displacement = (got_address
-                             - (plt_address + htab->plt_entry_size));
-
-         /* NaCl does not support interworking at all.  */
-         BFD_ASSERT (!elf32_arm_plt_needs_thumb_stub_p (info, arm_plt));
+         BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
 
          put_arm_insn (htab, output_bfd,
-                       elf32_arm_nacl_plt_entry[0]
-                       | arm_movw_immediate (got_displacement),
+                       elf32_arm_plt_entry_short[0]
+                       | ((got_displacement & 0x0ff00000) >> 20),
                        ptr + 0);
          put_arm_insn (htab, output_bfd,
-                       elf32_arm_nacl_plt_entry[1]
-                       | arm_movt_immediate (got_displacement),
-                       ptr + 4);
+                       elf32_arm_plt_entry_short[1]
+                       | ((got_displacement & 0x000ff000) >> 12),
+                       ptr+ 4);
          put_arm_insn (htab, output_bfd,
-                       elf32_arm_nacl_plt_entry[2],
+                       elf32_arm_plt_entry_short[2]
+                       | (got_displacement & 0x00000fff),
                        ptr + 8);
-         put_arm_insn (htab, output_bfd,
-                       elf32_arm_nacl_plt_entry[3]
-                       | (tail_displacement & 0x00ffffff),
-                       ptr + 12);
+#ifdef FOUR_WORD_PLT
+         bfd_put_32 (output_bfd, elf32_arm_plt_entry_short[3], ptr + 12);
+#endif
        }
-      else if (using_thumb_only (htab))
+      else
        {
-         /* PR ld/16017: Generate thumb only PLT entries.  */
-         if (!using_thumb2 (htab))
-           {
-             /* FIXME: We ought to be able to generate thumb-1 PLT
-                instructions...  */
-             _bfd_error_handler (_("%B: Warning: thumb-1 mode PLT generation not currently supported"),
-                                 output_bfd);
-             return FALSE;
-           }
-
-         /* Calculate the displacement between the PLT slot and the entry in
-            the GOT.  The 12-byte offset accounts for the value produced by
-            adding to pc in the 3rd instruction of the PLT stub.  */
-         got_displacement = got_address - (plt_address + 12);
-
-         /* As we are using 32 bit instructions we have to use 'put_arm_insn'
-            instead of 'put_thumb_insn'.  */
          put_arm_insn (htab, output_bfd,
-                       elf32_thumb2_plt_entry[0]
-                       | ((got_displacement & 0x000000ff) << 16)
-                       | ((got_displacement & 0x00000700) << 20)
-                       | ((got_displacement & 0x00000800) >>  1)
-                       | ((got_displacement & 0x0000f000) >> 12),
+                       elf32_arm_plt_entry_long[0]
+                       | ((got_displacement & 0xf0000000) >> 28),
                        ptr + 0);
          put_arm_insn (htab, output_bfd,
-                       elf32_thumb2_plt_entry[1]
-                       | ((got_displacement & 0x00ff0000)      )
-                       | ((got_displacement & 0x07000000) <<  4)
-                       | ((got_displacement & 0x08000000) >> 17)
-                       | ((got_displacement & 0xf0000000) >> 28),
+                       elf32_arm_plt_entry_long[1]
+                       | ((got_displacement & 0x0ff00000) >> 20),
                        ptr + 4);
          put_arm_insn (htab, output_bfd,
-                       elf32_thumb2_plt_entry[2],
-                       ptr + 8);
+                       elf32_arm_plt_entry_long[2]
+                       | ((got_displacement & 0x000ff000) >> 12),
+                       ptr+ 8);
          put_arm_insn (htab, output_bfd,
-                       elf32_thumb2_plt_entry[3],
+                       elf32_arm_plt_entry_long[3]
+                       | (got_displacement & 0x00000fff),
                        ptr + 12);
        }
-      else
-       {
-         /* Calculate the displacement between the PLT slot and the
-            entry in the GOT.  The eight-byte offset accounts for the
-            value produced by adding to pc in the first instruction
-            of the PLT stub.  */
-         got_displacement = got_address - (plt_address + 8);
-
-         if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
-           {
-             put_thumb_insn (htab, output_bfd,
-                             elf32_arm_plt_thumb_stub[0], ptr - 4);
-             put_thumb_insn (htab, output_bfd,
-                             elf32_arm_plt_thumb_stub[1], ptr - 2);
-           }
-
-         if (!elf32_arm_use_long_plt_entry)
-           {
-             BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
-
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_short[0]
-                           | ((got_displacement & 0x0ff00000) >> 20),
-                           ptr + 0);
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_short[1]
-                           | ((got_displacement & 0x000ff000) >> 12),
-                           ptr+ 4);
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_short[2]
-                           | (got_displacement & 0x00000fff),
-                           ptr + 8);
-#ifdef FOUR_WORD_PLT
-             bfd_put_32 (output_bfd, elf32_arm_plt_entry_short[3], ptr + 12);
-#endif
-           }
-         else
-           {
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_long[0]
-                           | ((got_displacement & 0xf0000000) >> 28),
-                           ptr + 0);
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_long[1]
-                           | ((got_displacement & 0x0ff00000) >> 20),
-                           ptr + 4);
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_long[2]
-                           | ((got_displacement & 0x000ff000) >> 12),
-                           ptr+ 8);
-             put_arm_insn (htab, output_bfd,
-                           elf32_arm_plt_entry_long[3]
-                           | (got_displacement & 0x00000fff),
-                           ptr + 12);
-           }
-       }
+    }
 
-      /* Fill in the entry in the .rel(a).(i)plt section.  */
-      rel.r_offset = got_address;
-      rel.r_addend = 0;
-      if (dynindx == -1)
+  /* Fill in the entry in the .rel(a).(i)plt section.  */
+  rel.r_offset = got_address;
+  rel.r_addend = 0;
+  if (dynindx == -1)
+    {
+      /* .igot.plt entries use IRELATIVE relocations against SYM_VALUE.
+        The dynamic linker or static executable then calls SYM_VALUE
+        to determine the correct run-time value of the .igot.plt entry.  */
+      rel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+      initial_got_entry = sym_value;
+    }
+  else
+    {
+      /* For FDPIC we will have to resolve a R_ARM_FUNCDESC_VALUE
+        used by PLT entry.  */
+      if (htab->fdpic_p)
        {
-         /* .igot.plt entries use IRELATIVE relocations against SYM_VALUE.
-            The dynamic linker or static executable then calls SYM_VALUE
-            to determine the correct run-time value of the .igot.plt entry.  */
-         rel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
-         initial_got_entry = sym_value;
+         rel.r_info = ELF32_R_INFO (dynindx, R_ARM_FUNCDESC_VALUE);
+         initial_got_entry = 0;
        }
       else
        {
          rel.r_info = ELF32_R_INFO (dynindx, R_ARM_JUMP_SLOT);
          initial_got_entry = (splt->output_section->vma
                               + splt->output_offset);
+
+         /* PR ld/16017
+            When thumb only we need to set the LSB for any address that
+            will be used with an interworking branch instruction.  */
+         if (using_thumb_only (htab))
+           initial_got_entry |= 1;
        }
+    }
 
-      /* Fill in the entry in the global offset table.  */
-      bfd_put_32 (output_bfd, initial_got_entry,
+  /* Fill in the entry in the global offset table.  */
+  bfd_put_32 (output_bfd, initial_got_entry,
+             sgot->contents + got_offset);
+
+  if (htab->fdpic_p && !(info->flags & DF_BIND_NOW))
+    {
+      /* Setup initial funcdesc value.  */
+      /* FIXME: we don't support lazy binding because there is a
+        race condition between both words getting written and
+        some other thread attempting to read them. The ARM
+        architecture does not have an atomic 64 bit load/store
+        instruction that could be used to prevent it; it is
+        recommended that threaded FDPIC applications run with the
+        LD_BIND_NOW environment variable set.  */
+      bfd_put_32 (output_bfd, plt_address + 0x18,
                  sgot->contents + got_offset);
+      bfd_put_32 (output_bfd, -1 /*TODO*/,
+                 sgot->contents + got_offset + 4);
     }
 
   if (dynindx == -1)
     elf32_arm_add_dynreloc (output_bfd, info, srel, &rel);
   else
     {
-      loc = srel->contents + plt_index * RELOC_SIZE (htab);
-      SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+      if (htab->fdpic_p)
+       {
+         /* For FDPIC we put PLT relocationss into .rel.got when not
+            lazy binding otherwise we put them in .rel.plt.  For now,
+            we don't support lazy binding so put it in .rel.got.  */
+         if (info->flags & DF_BIND_NOW)
+           elf32_arm_add_dynreloc (output_bfd, info, htab->root.srelgot, &rel);
+         else
+           elf32_arm_add_dynreloc (output_bfd, info, htab->root.srelplt, &rel);
+       }
+      else
+       {
+         loc = srel->contents + plt_index * RELOC_SIZE (htab);
+         SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+       }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Some relocations map to different relocations depending on the
@@ -9720,8 +10124,10 @@ elf32_arm_tls_relax (struct elf32_arm_link_hash_table *globals,
              | bfd_get_16 (input_bfd, contents + rel->r_offset + 2);
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("%B(%A+%#Lx): unexpected Thumb instruction '%#lx' in TLS trampoline"),
-            input_bfd, input_sec, rel->r_offset, insn);
+           (_("%pB(%pA+%#" PRIx64 "): "
+              "unexpected %s instruction '%#lx' in TLS trampoline"),
+            input_bfd, input_sec, (uint64_t) rel->r_offset,
+            "Thumb", insn);
          return bfd_reloc_notsupported;
        }
       break;
@@ -9760,8 +10166,10 @@ elf32_arm_tls_relax (struct elf32_arm_link_hash_table *globals,
        {
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("%B(%A+%#Lx): unexpected ARM instruction '%#lx' in TLS trampoline"),
-            input_bfd, input_sec, rel->r_offset, insn);
+           (_("%pB(%pA+%#" PRIx64 "): "
+              "unexpected %s instruction '%#lx' in TLS trampoline"),
+            input_bfd, input_sec, (uint64_t) rel->r_offset,
+            "ARM", insn);
          return bfd_reloc_notsupported;
        }
       break;
@@ -9820,7 +10228,7 @@ calculate_group_reloc_mask (bfd_vma value, int n, bfd_vma *final_residual)
          /* Determine the most significant bit in the residual and
             align the resulting value to a 2-bit boundary.  */
          for (msb = 30; msb >= 0; msb -= 2)
-           if (residual & (3 << msb))
+           if (residual & (3u << msb))
              break;
 
          /* The desired shift is now (msb - 6), or zero, whichever
@@ -9864,43 +10272,43 @@ identify_add_or_sub (bfd_vma insn)
 /* Perform a relocation as part of a final link.  */
 
 static bfd_reloc_status_type
-elf32_arm_final_link_relocate (reloc_howto_type *           howto,
-                              bfd *                        input_bfd,
-                              bfd *                        output_bfd,
-                              asection *                   input_section,
-                              bfd_byte *                   contents,
-                              Elf_Internal_Rela *          rel,
-                              bfd_vma                      value,
-                              struct bfd_link_info *       info,
-                              asection *                   sym_sec,
-                              const char *                 sym_name,
-                              unsigned char                st_type,
-                              enum arm_st_branch_type      branch_type,
+elf32_arm_final_link_relocate (reloc_howto_type *          howto,
+                              bfd *                        input_bfd,
+                              bfd *                        output_bfd,
+                              asection *                   input_section,
+                              bfd_byte *                   contents,
+                              Elf_Internal_Rela *          rel,
+                              bfd_vma                      value,
+                              struct bfd_link_info *       info,
+                              asection *                   sym_sec,
+                              const char *                 sym_name,
+                              unsigned char                st_type,
+                              enum arm_st_branch_type      branch_type,
                               struct elf_link_hash_entry * h,
-                              bfd_boolean *                unresolved_reloc_p,
-                              char **                      error_message)
-{
-  unsigned long                 r_type = howto->type;
-  unsigned long                 r_symndx;
-  bfd_byte *                    hit_data = contents + rel->r_offset;
-  bfd_vma *                     local_got_offsets;
-  bfd_vma *                     local_tlsdesc_gotents;
-  asection *                    sgot;
-  asection *                    splt;
-  asection *                    sreloc = NULL;
-  asection *                    srelgot;
-  bfd_vma                       addend;
-  bfd_signed_vma                signed_addend;
-  unsigned char                 dynreloc_st_type;
-  bfd_vma                       dynreloc_value;
+                              bool *                       unresolved_reloc_p,
+                              char **                      error_message)
+{
+  unsigned long                        r_type = howto->type;
+  unsigned long                        r_symndx;
+  bfd_byte *                   hit_data = contents + rel->r_offset;
+  bfd_vma *                    local_got_offsets;
+  bfd_vma *                    local_tlsdesc_gotents;
+  asection *                   sgot;
+  asection *                   splt;
+  asection *                   sreloc = NULL;
+  asection *                   srelgot;
+  bfd_vma                      addend;
+  bfd_signed_vma               signed_addend;
+  unsigned char                        dynreloc_st_type;
+  bfd_vma                      dynreloc_value;
   struct elf32_arm_link_hash_table * globals;
   struct elf32_arm_link_hash_entry *eh;
-  union gotplt_union           *root_plt;
-  struct arm_plt_info          *arm_plt;
-  bfd_vma                       plt_offset;
-  bfd_vma                       gotplt_offset;
-  bfd_boolean                   has_iplt_entry;
-  bfd_boolean                   resolved_to_zero;
+  union gotplt_union          *root_plt;
+  struct arm_plt_info         *arm_plt;
+  bfd_vma                      plt_offset;
+  bfd_vma                      gotplt_offset;
+  bool                         has_iplt_entry;
+  bool                         resolved_to_zero;
 
   globals = elf32_arm_hash_table (info);
   if (globals == NULL)
@@ -9934,16 +10342,22 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
   if (globals->use_rel)
     {
-      addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask;
+      bfd_vma sign;
 
-      if (addend & ((howto->src_mask + 1) >> 1))
+      switch (howto->size)
        {
-         signed_addend = -1;
-         signed_addend &= ~ howto->src_mask;
-         signed_addend |= addend;
+       case 0: addend = bfd_get_8 (input_bfd, hit_data); break;
+       case 1: addend = bfd_get_16 (input_bfd, hit_data); break;
+       case 2: addend = bfd_get_32 (input_bfd, hit_data); break;
+       default: addend = 0; break;
        }
-      else
-       signed_addend = addend;
+      /* Note: the addend and signed_addend calculated here are
+        incorrect for any split field.  */
+      addend &= howto->src_mask;
+      sign = howto->src_mask & ~(howto->src_mask >> 1);
+      signed_addend = (addend ^ sign) - sign;
+      signed_addend = (bfd_vma) signed_addend << howto->rightshift;
+      addend <<= howto->rightshift;
     }
   else
     addend = signed_addend = rel->r_addend;
@@ -9965,7 +10379,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
   /* Find out whether the symbol has a PLT.  Set ST_VALUE, BRANCH_TYPE and
      VALUE appropriately for relocations that we resolve at link time.  */
-  has_iplt_entry = FALSE;
+  has_iplt_entry = false;
   if (elf32_arm_get_plt_info (input_bfd, globals, eh, r_symndx, &root_plt,
                              &arm_plt)
       && root_plt->offset != (bfd_vma) -1)
@@ -9975,7 +10389,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
       if (h == NULL || eh->is_iplt)
        {
-         has_iplt_entry = TRUE;
+         has_iplt_entry = true;
          splt = globals->root.iplt;
 
          /* Populate .iplt entries here, because not all of them will
@@ -10026,11 +10440,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
     case R_ARM_NONE:
       /* We don't need to find a value for this symbol.  It's just a
         marker.  */
-      *unresolved_reloc_p = FALSE;
+      *unresolved_reloc_p = false;
       return bfd_reloc_ok;
 
     case R_ARM_ABS12:
-      if (!globals->vxworks_p)
+      if (globals->root.target_os != is_vxworks)
        return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
       /* Fall through.  */
 
@@ -10065,7 +10479,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          value = (splt->output_section->vma
                   + splt->output_offset
                   + plt_offset);
-         *unresolved_reloc_p = FALSE;
+         *unresolved_reloc_p = false;
          return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                           contents, rel->r_offset, value,
                                           rel->r_addend);
@@ -10075,9 +10489,10 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
         relocations are copied into the output file to be resolved at
         run time.  */
       if ((bfd_link_pic (info)
-          || globals->root.is_relocatable_executable)
+          || globals->root.is_relocatable_executable
+          || globals->fdpic_p)
          && (input_section->flags & SEC_ALLOC)
-         && !(globals->vxworks_p
+         && !(globals->root.target_os == is_vxworks
               && strcmp (input_section->output_section->name,
                          ".tls_vars") == 0)
          && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
@@ -10095,7 +10510,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          && r_type != R_ARM_PLT32)
        {
          Elf_Internal_Rela outrel;
-         bfd_boolean skip, relocate;
+         bool skip, relocate;
+         int isrofixup = 0;
 
          if ((r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI)
              && !h->def_regular)
@@ -10106,13 +10522,13 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                v = _("PIE executable");
 
              _bfd_error_handler
-               (_("%B: relocation %s against external or undefined symbol `%s'"
+               (_("%pB: relocation %s against external or undefined symbol `%s'"
                   " can not be used when making a %s; recompile with -fPIC"), input_bfd,
                 elf32_arm_howto_table_1[r_type].name, h->root.root.string, v);
              return bfd_reloc_notsupported;
            }
 
-         *unresolved_reloc_p = FALSE;
+         *unresolved_reloc_p = false;
 
          if (sreloc == NULL && globals->root.dynamic_sections_created)
            {
@@ -10123,17 +10539,17 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                return bfd_reloc_notsupported;
            }
 
-         skip = FALSE;
-         relocate = FALSE;
+         skip = false;
+         relocate = false;
 
          outrel.r_addend = addend;
          outrel.r_offset =
            _bfd_elf_section_offset (output_bfd, info, input_section,
                                     rel->r_offset);
          if (outrel.r_offset == (bfd_vma) -1)
-           skip = TRUE;
+           skip = true;
          else if (outrel.r_offset == (bfd_vma) -2)
-           skip = TRUE, relocate = TRUE;
+           skip = true, relocate = true;
          outrel.r_offset += (input_section->output_section->vma
                              + input_section->output_offset);
 
@@ -10151,61 +10567,32 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              int symbol;
 
              /* This symbol is local, or marked to become local.  */
-             BFD_ASSERT (r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI);
-             if (globals->symbian_p)
-               {
-                 asection *osec;
-
-                 /* On Symbian OS, the data segment and text segement
-                    can be relocated independently.  Therefore, we
-                    must indicate the segment to which this
-                    relocation is relative.  The BPABI allows us to
-                    use any symbol in the right segment; we just use
-                    the section symbol as it is convenient.  (We
-                    cannot use the symbol given by "h" directly as it
-                    will not appear in the dynamic symbol table.)
-
-                    Note that the dynamic linker ignores the section
-                    symbol value, so we don't subtract osec->vma
-                    from the emitted reloc addend.  */
-                 if (sym_sec)
-                   osec = sym_sec->output_section;
-                 else
-                   osec = input_section->output_section;
-                 symbol = elf_section_data (osec)->dynindx;
-                 if (symbol == 0)
-                   {
-                     struct elf_link_hash_table *htab = elf_hash_table (info);
-
-                     if ((osec->flags & SEC_READONLY) == 0
-                         && htab->data_index_section != NULL)
-                       osec = htab->data_index_section;
-                     else
-                       osec = htab->text_index_section;
-                     symbol = elf_section_data (osec)->dynindx;
-                   }
-                 BFD_ASSERT (symbol != 0);
-               }
-             else
-               /* On SVR4-ish systems, the dynamic loader cannot
-                  relocate the text and data segments independently,
-                  so the symbol does not matter.  */
-               symbol = 0;
+             BFD_ASSERT (r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI
+                         || (globals->fdpic_p && !bfd_link_pic (info)));
+             /* On SVR4-ish systems, the dynamic loader cannot
+                relocate the text and data segments independently,
+                so the symbol does not matter.  */
+             symbol = 0;
              if (dynreloc_st_type == STT_GNU_IFUNC)
                /* We have an STT_GNU_IFUNC symbol that doesn't resolve
                   to the .iplt entry.  Instead, every non-call reference
                   must use an R_ARM_IRELATIVE relocation to obtain the
                   correct run-time address.  */
                outrel.r_info = ELF32_R_INFO (symbol, R_ARM_IRELATIVE);
+             else if (globals->fdpic_p && !bfd_link_pic (info))
+               isrofixup = 1;
              else
                outrel.r_info = ELF32_R_INFO (symbol, R_ARM_RELATIVE);
              if (globals->use_rel)
-               relocate = TRUE;
+               relocate = true;
              else
                outrel.r_addend += dynreloc_value;
            }
 
-         elf32_arm_add_dynreloc (output_bfd, info, sreloc, &outrel);
+         if (isrofixup)
+           arm_elf_add_rofixup (output_bfd, globals->srofixup, outrel.r_offset);
+         else
+           elf32_arm_add_dynreloc (output_bfd, info, sreloc, &outrel);
 
          /* If this reloc is against an external symbol, we do not want to
             fiddle with the addend.  Otherwise, we need to include the symbol
@@ -10237,9 +10624,10 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                 instruction instead ?  */
              if (branch_type != ST_BRANCH_TO_THUMB)
                _bfd_error_handler
-                 (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
-                  input_bfd,
-                  h ? h->root.root.string : "(local)");
+                 (_("\%pB: warning: %s BLX instruction targets"
+                    " %s function '%s'"),
+                  input_bfd, "ARM",
+                  "ARM", h ? h->root.root.string : "(local)");
            }
          else if (r_type == R_ARM_PC24)
            {
@@ -10287,7 +10675,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                               + stub_entry->stub_sec->output_section->vma);
 
                    if (plt_offset != (bfd_vma) -1)
-                     *unresolved_reloc_p = FALSE;
+                     *unresolved_reloc_p = false;
                  }
                }
              else
@@ -10299,7 +10687,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                      value = (splt->output_section->vma
                               + splt->output_offset
                               + plt_offset);
-                     *unresolved_reloc_p = FALSE;
+                     *unresolved_reloc_p = false;
                      /* The PLT entry is in ARM mode, regardless of the
                         target function.  */
                      branch_type = ST_BRANCH_TO_ARM;
@@ -10329,11 +10717,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          value -= (input_section->output_section->vma
                    + input_section->output_offset);
          value -= rel->r_offset;
-         if (globals->use_rel)
-           value += (signed_addend << howto->size);
-         else
-           /* RELA addends do not have to be adjusted by howto->size.  */
-           value += signed_addend;
+         value += signed_addend;
 
          signed_addend = value;
          signed_addend >>= howto->rightshift;
@@ -10437,9 +10821,6 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       return bfd_reloc_ok;
 
     case R_ARM_ABS8:
-      /* PR 16202: Refectch the addend using the correct size.  */
-      if (globals->use_rel)
-       addend = bfd_get_8 (input_bfd, hit_data);
       value += addend;
 
       /* There is no way to tell whether the user intended to use a signed or
@@ -10452,9 +10833,6 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       return bfd_reloc_ok;
 
     case R_ARM_ABS16:
-      /* PR 16202: Refectch the addend using the correct size.  */
-      if (globals->use_rel)
-       addend = bfd_get_16 (input_bfd, hit_data);
       value += addend;
 
       /* See comment for R_ARM_ABS8.  */
@@ -10508,7 +10886,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* PR 21523: Use an absolute value.  The user of this reloc will
           have already selected an ADD or SUB insn appropriately.  */
-       value = labs (relocation);
+       value = llabs (relocation);
 
        if (value >= 0x1000)
          return bfd_reloc_overflow;
@@ -10606,7 +10984,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       {
        bfd_vma relocation;
        bfd_vma reloc_sign;
-       bfd_boolean overflow = FALSE;
+       bool overflow = false;
        bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
        bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
        bfd_signed_vma reloc_signed_max;
@@ -10663,9 +11041,10 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
               instruction instead ?  */
            if (branch_type == ST_BRANCH_TO_THUMB)
              _bfd_error_handler
-               (_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
-                input_bfd,
-                h ? h->root.root.string : "(local)");
+               (_("%pB: warning: %s BLX instruction targets"
+                  " %s function '%s'"),
+                input_bfd, "Thumb",
+                "Thumb", h ? h->root.root.string : "(local)");
          }
        else
          {
@@ -10732,7 +11111,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                             + stub_entry->stub_sec->output_section->vma);
 
                    if (plt_offset != (bfd_vma) -1)
-                     *unresolved_reloc_p = FALSE;
+                     *unresolved_reloc_p = false;
                  }
 
                /* If this call becomes a call to Arm, force BLX.  */
@@ -10770,7 +11149,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  value -= PLT_THUMB_STUB_SIZE;
                branch_type = ST_BRANCH_TO_THUMB;
              }
-           *unresolved_reloc_p = FALSE;
+           *unresolved_reloc_p = false;
          }
 
        relocation = value + signed_addend;
@@ -10799,7 +11178,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* Assumes two's complement.  */
        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
-         overflow = TRUE;
+         overflow = true;
 
        if ((lower_insn & 0x5000) == 0x4000)
          /* For a BLX instruction, make sure that the relocation is rounded up
@@ -10832,13 +11211,13 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       /* Thumb32 conditional branch instruction.  */
       {
        bfd_vma relocation;
-       bfd_boolean overflow = FALSE;
+       bool overflow = false;
        bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
        bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
        bfd_signed_vma reloc_signed_max = 0xffffe;
        bfd_signed_vma reloc_signed_min = -0x100000;
        bfd_signed_vma signed_check;
-        enum elf32_arm_stub_type stub_type = arm_stub_none;
+       enum elf32_arm_stub_type stub_type = arm_stub_none;
        struct elf32_arm_stub_hash_entry *stub_entry;
        struct elf32_arm_link_hash_entry *hash;
 
@@ -10869,26 +11248,26 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                     + plt_offset);
            /* Target the Thumb stub before the ARM PLT entry.  */
            value -= PLT_THUMB_STUB_SIZE;
-           *unresolved_reloc_p = FALSE;
+           *unresolved_reloc_p = false;
          }
 
        hash = (struct elf32_arm_link_hash_entry *)h;
 
        stub_type = arm_type_of_stub (info, input_section, rel,
-                                     st_type, &branch_type,
-                                     hash, value, sym_sec,
-                                     input_bfd, sym_name);
+                                     st_type, &branch_type,
+                                     hash, value, sym_sec,
+                                     input_bfd, sym_name);
        if (stub_type != arm_stub_none)
          {
            stub_entry = elf32_arm_get_stub_entry (input_section,
-                                                  sym_sec, h,
-                                                  rel, globals,
-                                                  stub_type);
+                                                  sym_sec, h,
+                                                  rel, globals,
+                                                  stub_type);
            if (stub_entry != NULL)
              {
-               value = (stub_entry->stub_offset
-                        + stub_entry->stub_sec->output_offset
-                        + stub_entry->stub_sec->output_section->vma);
+               value = (stub_entry->stub_offset
+                       + stub_entry->stub_sec->output_offset
+                       + stub_entry->stub_sec->output_section->vma);
              }
          }
 
@@ -10899,7 +11278,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        signed_check = (bfd_signed_vma) relocation;
 
        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
-         overflow = TRUE;
+         overflow = true;
 
        /* Put RELOCATION back into the insn.  */
        {
@@ -10932,25 +11311,12 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* CZB cannot jump backward.  */
        if (r_type == R_ARM_THM_JUMP6)
-         reloc_signed_min = 0;
-
-       if (globals->use_rel)
          {
-           /* Need to refetch addend.  */
-           addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
-           if (addend & ((howto->src_mask + 1) >> 1))
-             {
-               signed_addend = -1;
-               signed_addend &= ~ howto->src_mask;
-               signed_addend |= addend;
-             }
-           else
-             signed_addend = addend;
-           /* The value in the insn has been right shifted.  We need to
-              undo this, so that we can perform the address calculation
-              in terms of bytes.  */
-           signed_addend <<= howto->rightshift;
+           reloc_signed_min = 0;
+           if (globals->use_rel)
+             signed_addend = ((addend & 0x200) >> 3) | ((addend & 0xf8) >> 2);
          }
+
        relocation = value + signed_addend;
 
        relocation -= (input_section->output_section->vma
@@ -11036,7 +11402,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       if (sgot == NULL)
        return bfd_reloc_notsupported;
 
-      *unresolved_reloc_p = FALSE;
+      *unresolved_reloc_p = false;
       value = sgot->output_section->vma;
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
@@ -11074,13 +11440,15 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              off &= ~1;
              if (globals->root.dynamic_sections_created
                  && !SYMBOL_REFERENCES_LOCAL (info, h))
-               *unresolved_reloc_p = FALSE;
+               *unresolved_reloc_p = false;
            }
          else
            {
              Elf_Internal_Rela outrel;
+             int isrofixup = 0;
 
-             if (h->dynindx != -1 && !SYMBOL_REFERENCES_LOCAL (info, h))
+             if (((h->dynindx != -1) || globals->fdpic_p)
+                 && !SYMBOL_REFERENCES_LOCAL (info, h))
                {
                  /* If the symbol doesn't resolve locally in a static
                     object, we have an undefined reference.  If the
@@ -11089,7 +11457,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  if (globals->root.dynamic_sections_created)
                    {
                      outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
-                     *unresolved_reloc_p = FALSE;
+                     *unresolved_reloc_p = false;
                    }
                  else
                    outrel.r_info = 0;
@@ -11100,31 +11468,41 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  if (dynreloc_st_type == STT_GNU_IFUNC)
                    outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
                  else if (bfd_link_pic (info)
-                          && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-                              || h->root.type != bfd_link_hash_undefweak))
+                          && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
                    outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
                  else
-                   outrel.r_info = 0;
+                   {
+                     outrel.r_info = 0;
+                     if (globals->fdpic_p)
+                       isrofixup = 1;
+                   }
                  outrel.r_addend = dynreloc_value;
                }
 
              /* The GOT entry is initialized to zero by default.
                 See if we should install a different value.  */
              if (outrel.r_addend != 0
-                 && (outrel.r_info == 0 || globals->use_rel))
+                 && (globals->use_rel || outrel.r_info == 0))
                {
                  bfd_put_32 (output_bfd, outrel.r_addend,
                              sgot->contents + off);
                  outrel.r_addend = 0;
                }
 
-             if (outrel.r_info != 0)
+             if (isrofixup)
+               arm_elf_add_rofixup (output_bfd,
+                                    elf32_arm_hash_table (info)->srofixup,
+                                    sgot->output_section->vma
+                                    + sgot->output_offset + off);
+
+             else if (outrel.r_info != 0)
                {
                  outrel.r_offset = (sgot->output_section->vma
                                     + sgot->output_offset
                                     + off);
                  elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
                }
+
              h->got.offset |= 1;
            }
          value = sgot->output_offset + off;
@@ -11145,21 +11523,37 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            off &= ~1;
          else
            {
-             if (globals->use_rel)
-               bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+             Elf_Internal_Rela outrel;
+             int isrofixup = 0;
 
-             if (bfd_link_pic (info) || dynreloc_st_type == STT_GNU_IFUNC)
+             if (dynreloc_st_type == STT_GNU_IFUNC)
+               outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+             else if (bfd_link_pic (info))
+               outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+             else
                {
-                 Elf_Internal_Rela outrel;
+                 outrel.r_info = 0;
+                 if (globals->fdpic_p)
+                   isrofixup = 1;
+               }
 
+             /* The GOT entry is initialized to zero by default.
+                See if we should install a different value.  */
+             if (globals->use_rel || outrel.r_info == 0)
+               bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+
+             if (isrofixup)
+               arm_elf_add_rofixup (output_bfd,
+                                    globals->srofixup,
+                                    sgot->output_section->vma
+                                    + sgot->output_offset + off);
+
+             else if (outrel.r_info != 0)
+               {
                  outrel.r_addend = addend + dynreloc_value;
                  outrel.r_offset = (sgot->output_section->vma
                                     + sgot->output_offset
                                     + off);
-                 if (dynreloc_st_type == STT_GNU_IFUNC)
-                   outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
-                 else
-                   outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
                  elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
                }
 
@@ -11183,6 +11577,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                                       rel->r_addend);
 
     case R_ARM_TLS_LDM32:
+    case R_ARM_TLS_LDM32_FDPIC:
       {
        bfd_vma off;
 
@@ -11197,7 +11592,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            /* If we don't know the module number, create a relocation
               for it.  */
-           if (bfd_link_pic (info))
+           if (bfd_link_dll (info))
              {
                Elf_Internal_Rela outrel;
 
@@ -11221,18 +11616,32 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            globals->tls_ldm_got.offset |= 1;
          }
 
-       value = sgot->output_section->vma + sgot->output_offset + off
-         - (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
+       if (r_type == R_ARM_TLS_LDM32_FDPIC)
+         {
+           bfd_put_32 (output_bfd,
+                       globals->root.sgot->output_offset + off,
+                       contents + rel->r_offset);
+
+           return bfd_reloc_ok;
+         }
+       else
+         {
+           value = sgot->output_section->vma + sgot->output_offset + off
+             - (input_section->output_section->vma
+                + input_section->output_offset + rel->r_offset);
 
-       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                        contents, rel->r_offset, value,
-                                        rel->r_addend);
+           return _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                            contents, rel->r_offset, value,
+                                            rel->r_addend);
+         }
       }
 
     case R_ARM_TLS_CALL:
     case R_ARM_THM_TLS_CALL:
     case R_ARM_TLS_GD32:
+    case R_ARM_TLS_GD32_FDPIC:
     case R_ARM_TLS_IE32:
+    case R_ARM_TLS_IE32_FDPIC:
     case R_ARM_TLS_GOTDESC:
     case R_ARM_TLS_DESCSEQ:
     case R_ARM_THM_TLS_DESCSEQ:
@@ -11245,7 +11654,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        if (h != NULL)
          {
-           bfd_boolean dyn;
+           bool dyn;
            dyn = globals->root.dynamic_sections_created;
            if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
                                                 bfd_link_pic (info),
@@ -11253,7 +11662,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                && (!bfd_link_pic (info)
                    || !SYMBOL_REFERENCES_LOCAL (info, h)))
              {
-               *unresolved_reloc_p = FALSE;
+               *unresolved_reloc_p = false;
                indx = h->dynindx;
              }
            off = h->got.offset;
@@ -11263,6 +11672,16 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        else
          {
            BFD_ASSERT (local_got_offsets != NULL);
+
+           if (r_symndx >= elf32_arm_num_entries (input_bfd))
+             {
+               _bfd_error_handler (_("\
+%pB: expected symbol index in range 0..%lu but found local symbol with index %lu"),
+                                   input_bfd,
+                                   (unsigned long) elf32_arm_num_entries (input_bfd),
+                                   r_symndx);
+               return false;
+             }
            off = local_got_offsets[r_symndx];
            offplt = local_tlsdesc_gotents[r_symndx];
            tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
@@ -11270,7 +11689,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* Linker relaxations happens from one of the
           R_ARM_{GOTDESC,CALL,DESCSEQ} relocations to IE or LE.  */
-       if (ELF32_R_TYPE(rel->r_info) != r_type)
+       if (ELF32_R_TYPE (rel->r_info) != r_type)
          tls_type = GOT_TLS_IE;
 
        BFD_ASSERT (tls_type != GOT_UNKNOWN);
@@ -11279,7 +11698,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          off &= ~1;
        else
          {
-           bfd_boolean need_relocs = FALSE;
+           bool need_relocs = false;
            Elf_Internal_Rela outrel;
            int cur_off = off;
 
@@ -11287,13 +11706,13 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
               now, and emit any relocations.  If both an IE GOT and a
               GD GOT are necessary, we emit the GD first.  */
 
-           if ((bfd_link_pic (info) || indx != 0)
+           if ((bfd_link_dll (info) || indx != 0)
                && (h == NULL
                    || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                        && !resolved_to_zero)
                    || h->root.type != bfd_link_hash_undefweak))
              {
-               need_relocs = TRUE;
+               need_relocs = true;
                BFD_ASSERT (srelgot != NULL);
              }
 
@@ -11304,7 +11723,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                /* We should have relaxed, unless this is an undefined
                   weak symbol.  */
                BFD_ASSERT ((h && (h->root.type == bfd_link_hash_undefweak))
-                           || bfd_link_pic (info));
+                           || bfd_link_dll (info));
                BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8
                            <= globals->root.sgotplt->size);
 
@@ -11420,13 +11839,13 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              local_got_offsets[r_symndx] |= 1;
          }
 
-       if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
+       if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32 && r_type != R_ARM_TLS_GD32_FDPIC)
          off += 8;
        else if (tls_type & GOT_TLS_GDESC)
          off = offplt;
 
-       if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL
-           || ELF32_R_TYPE(rel->r_info) == R_ARM_THM_TLS_CALL)
+       if (ELF32_R_TYPE (rel->r_info) == R_ARM_TLS_CALL
+           || ELF32_R_TYPE (rel->r_info) == R_ARM_THM_TLS_CALL)
          {
            bfd_signed_vma offset;
            /* TLS stubs are arm mode.  The original symbol is a
@@ -11454,7 +11873,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                        + globals->root.splt->output_offset
                        + globals->tls_trampoline);
 
-           if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL)
+           if (ELF32_R_TYPE (rel->r_info) == R_ARM_TLS_CALL)
              {
                unsigned long inst;
 
@@ -11510,9 +11929,9 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            unsigned long data, insn;
            unsigned thumb;
 
-           data = bfd_get_32 (input_bfd, hit_data);
+           data = bfd_get_signed_32 (input_bfd, hit_data);
            thumb = data & 1;
-           data &= ~1u;
+           data &= ~1ul;
 
            if (thumb)
              {
@@ -11531,8 +11950,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  {
                    _bfd_error_handler
                      /* xgettext:c-format */
-                     (_("%B(%A+%#Lx): unexpected Thumb instruction '%#lx' referenced by TLS_GOTDESC"),
-                      input_bfd, input_section, rel->r_offset, insn);
+                     (_("%pB(%pA+%#" PRIx64 "): "
+                        "unexpected %s instruction '%#lx' "
+                        "referenced by TLS_GOTDESC"),
+                      input_bfd, input_section, (uint64_t) rel->r_offset,
+                      "Thumb", insn);
                    return bfd_reloc_notsupported;
                  }
              }
@@ -11554,8 +11976,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  default:
                    _bfd_error_handler
                      /* xgettext:c-format */
-                     (_("%B(%A+%#Lx): unexpected ARM instruction '%#lx' referenced by TLS_GOTDESC"),
-                      input_bfd, input_section, rel->r_offset, insn);
+                     (_("%pB(%pA+%#" PRIx64 "): "
+                        "unexpected %s instruction '%#lx' "
+                        "referenced by TLS_GOTDESC"),
+                      input_bfd, input_section, (uint64_t) rel->r_offset,
+                      "ARM", insn);
                    return bfd_reloc_notsupported;
                  }
              }
@@ -11573,9 +11998,23 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                   - (input_section->output_section->vma
                      + input_section->output_offset + rel->r_offset));
 
-       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                        contents, rel->r_offset, value,
-                                        rel->r_addend);
+       if (globals->fdpic_p && (r_type == R_ARM_TLS_GD32_FDPIC ||
+                                r_type == R_ARM_TLS_IE32_FDPIC))
+         {
+           /* For FDPIC relocations, resolve to the offset of the GOT
+              entry from the start of GOT.  */
+           bfd_put_32 (output_bfd,
+                       globals->root.sgot->output_offset + off,
+                       contents + rel->r_offset);
+
+           return bfd_reloc_ok;
+         }
+       else
+         {
+           return _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                            contents, rel->r_offset, value,
+                                            rel->r_addend);
+         }
       }
 
     case R_ARM_TLS_LE32:
@@ -11583,8 +12022,9 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        {
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("%B(%A+%#Lx): %s relocation not permitted in shared object"),
-            input_bfd, input_section, rel->r_offset, howto->name);
+           (_("%pB(%pA+%#" PRIx64 "): %s relocation not permitted "
+              "in shared object"),
+            input_bfd, input_section, (uint64_t) rel->r_offset, howto->name);
          return bfd_reloc_notsupported;
        }
       else
@@ -11690,7 +12130,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            addend = ((insn >> 4)  & 0xf000)
                   | ((insn >> 15) & 0x0800)
                   | ((insn >> 4)  & 0x0700)
-                  | (insn         & 0x00ff);
+                  | (insn         & 0x00ff);
            signed_addend = (addend ^ 0x8000) - 0x8000;
          }
 
@@ -11796,8 +12236,9 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              {
                _bfd_error_handler
                  /* xgettext:c-format */
-                 (_("%B(%A+%#Lx): Only ADD or SUB instructions are allowed for ALU group relocations"),
-                 input_bfd, input_section, rel->r_offset);
+                 (_("%pB(%pA+%#" PRIx64 "): only ADD or SUB instructions "
+                    "are allowed for ALU group relocations"),
+                 input_bfd, input_section, (uint64_t) rel->r_offset);
                return bfd_reloc_overflow;
              }
 
@@ -11836,9 +12277,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            _bfd_error_handler
              /* xgettext:c-format */
-             (_("%B(%A+%#Lx): Overflow whilst splitting %#Lx for group relocation %s"),
-              input_bfd, input_section, rel->r_offset,
-              signed_value < 0 ? -signed_value : signed_value, howto->name);
+             (_("%pB(%pA+%#" PRIx64 "): overflow whilst "
+                "splitting %#" PRIx64 " for group relocation %s"),
+              input_bfd, input_section, (uint64_t) rel->r_offset,
+              (uint64_t) (signed_value < 0 ? -signed_value : signed_value),
+              howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -11926,9 +12369,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            _bfd_error_handler
              /* xgettext:c-format */
-             (_("%B(%A+%#Lx): Overflow whilst splitting %#Lx for group relocation %s"),
-              input_bfd, input_section, rel->r_offset,
-              signed_value < 0 ? -signed_value : signed_value, howto->name);
+             (_("%pB(%pA+%#" PRIx64 "): overflow whilst "
+                "splitting %#" PRIx64 " for group relocation %s"),
+              input_bfd, input_section, (uint64_t) rel->r_offset,
+              (uint64_t) (signed_value < 0 ? -signed_value : signed_value),
+              howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -12012,9 +12457,11 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            _bfd_error_handler
              /* xgettext:c-format */
-             (_("%B(%A+%#Lx): Overflow whilst splitting %#Lx for group relocation %s"),
-              input_bfd, input_section, rel->r_offset,
-              signed_value < 0 ? -signed_value : signed_value, howto->name);
+             (_("%pB(%pA+%#" PRIx64 "): overflow whilst "
+                "splitting %#" PRIx64 " for group relocation %s"),
+              input_bfd, input_section, (uint64_t) rel->r_offset,
+              (uint64_t) (signed_value < 0 ? -signed_value : signed_value),
+              howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -12070,82 +12517,471 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            abort ();
          }
 
-       /* If REL, extract the addend from the insn.  If RELA, it will
-          have already been fetched for us.  */
+       /* If REL, extract the addend from the insn.  If RELA, it will
+          have already been fetched for us.  */
+       if (globals->use_rel)
+         {
+           int negative = (insn & (1 << 23)) ? 1 : -1;
+           signed_addend = negative * ((insn & 0xff) << 2);
+         }
+
+       /* Compute the value (X) to go in the place.  */
+       if (r_type == R_ARM_LDC_PC_G0
+           || r_type == R_ARM_LDC_PC_G1
+           || r_type == R_ARM_LDC_PC_G2)
+         /* PC relative.  */
+         signed_value = value - pc + signed_addend;
+       else
+         /* Section base relative.  */
+         signed_value = value - sb + signed_addend;
+
+       /* Calculate the value of the relevant G_{n-1} to obtain
+          the residual at that stage.  */
+       calculate_group_reloc_mask (signed_value < 0 ? - signed_value : signed_value,
+                                   group - 1, &residual);
+
+       /* Check for overflow.  (The absolute value to go in the place must be
+          divisible by four and, after having been divided by four, must
+          fit in eight bits.)  */
+       if ((residual & 0x3) != 0 || residual >= 0x400)
+         {
+           _bfd_error_handler
+             /* xgettext:c-format */
+             (_("%pB(%pA+%#" PRIx64 "): overflow whilst "
+                "splitting %#" PRIx64 " for group relocation %s"),
+              input_bfd, input_section, (uint64_t) rel->r_offset,
+              (uint64_t) (signed_value < 0 ? -signed_value : signed_value),
+              howto->name);
+           return bfd_reloc_overflow;
+         }
+
+       /* Mask out the value and U bit.  */
+       insn &= 0xff7fff00;
+
+       /* Set the U bit if the value to go in the place is non-negative.  */
+       if (signed_value >= 0)
+         insn |= 1 << 23;
+
+       /* Encode the offset.  */
+       insn |= residual >> 2;
+
+       bfd_put_32 (input_bfd, insn, hit_data);
+      }
+      return bfd_reloc_ok;
+
+    case R_ARM_THM_ALU_ABS_G0_NC:
+    case R_ARM_THM_ALU_ABS_G1_NC:
+    case R_ARM_THM_ALU_ABS_G2_NC:
+    case R_ARM_THM_ALU_ABS_G3_NC:
+       {
+           const int shift_array[4] = {0, 8, 16, 24};
+           bfd_vma insn = bfd_get_16 (input_bfd, hit_data);
+           bfd_vma addr = value;
+           int shift = shift_array[r_type - R_ARM_THM_ALU_ABS_G0_NC];
+
+           /* Compute address.  */
+           if (globals->use_rel)
+               signed_addend = insn & 0xff;
+           addr += signed_addend;
+           if (branch_type == ST_BRANCH_TO_THUMB)
+               addr |= 1;
+           /* Clean imm8 insn.  */
+           insn &= 0xff00;
+           /* And update with correct part of address.  */
+           insn |= (addr >> shift) & 0xff;
+           /* Update insn.  */
+           bfd_put_16 (input_bfd, insn, hit_data);
+       }
+
+       *unresolved_reloc_p = false;
+       return bfd_reloc_ok;
+
+    case R_ARM_GOTOFFFUNCDESC:
+      {
+       if (h == NULL)
+         {
+           struct fdpic_local *local_fdpic_cnts = elf32_arm_local_fdpic_cnts (input_bfd);
+           int dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+
+           if (r_symndx >= elf32_arm_num_entries (input_bfd))
+             {
+               * error_message = _("local symbol index too big");
+               return bfd_reloc_dangerous;
+             }
+
+           int offset = local_fdpic_cnts[r_symndx].funcdesc_offset & ~1;
+           bfd_vma addr = dynreloc_value - sym_sec->output_section->vma;
+           bfd_vma seg = -1;
+
+           if (bfd_link_pic (info) && dynindx == 0)
+             {
+               * error_message = _("no dynamic index information available");
+               return bfd_reloc_dangerous;
+             }
+
+           /* Resolve relocation.  */
+           bfd_put_32 (output_bfd, (offset + sgot->output_offset)
+                      , contents + rel->r_offset);
+           /* Emit R_ARM_FUNCDESC_VALUE or two fixups on funcdesc if
+              not done yet.  */
+           arm_elf_fill_funcdesc (output_bfd, info,
+                                  &local_fdpic_cnts[r_symndx].funcdesc_offset,
+                                  dynindx, offset, addr, dynreloc_value, seg);
+         }
+       else
+         {
+           int dynindx;
+           int offset = eh->fdpic_cnts.funcdesc_offset & ~1;
+           bfd_vma addr;
+           bfd_vma seg = -1;
+
+           /* For static binaries, sym_sec can be null.  */
+           if (sym_sec)
+             {
+               dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+               addr = dynreloc_value - sym_sec->output_section->vma;
+             }
+           else
+             {
+               dynindx = 0;
+               addr = 0;
+             }
+
+           if (bfd_link_pic (info) && dynindx == 0)
+             {
+               * error_message = _("no dynamic index information available");
+               return bfd_reloc_dangerous;
+             }
+
+           /* This case cannot occur since funcdesc is allocated by
+              the dynamic loader so we cannot resolve the relocation.  */
+           if (h->dynindx != -1)
+             {
+               * error_message = _("invalid dynamic index");
+               return bfd_reloc_dangerous;
+             }
+
+           /* Resolve relocation.  */
+           bfd_put_32 (output_bfd, (offset + sgot->output_offset),
+                       contents + rel->r_offset);
+           /* Emit R_ARM_FUNCDESC_VALUE on funcdesc if not done yet.  */
+           arm_elf_fill_funcdesc (output_bfd, info,
+                                  &eh->fdpic_cnts.funcdesc_offset,
+                                  dynindx, offset, addr, dynreloc_value, seg);
+         }
+      }
+      *unresolved_reloc_p = false;
+      return bfd_reloc_ok;
+
+    case R_ARM_GOTFUNCDESC:
+      {
+       if (h != NULL)
+         {
+           Elf_Internal_Rela outrel;
+
+           /* Resolve relocation.  */
+           bfd_put_32 (output_bfd, ((eh->fdpic_cnts.gotfuncdesc_offset & ~1)
+                                    + sgot->output_offset),
+                       contents + rel->r_offset);
+           /* Add funcdesc and associated R_ARM_FUNCDESC_VALUE.  */
+           if (h->dynindx == -1)
+             {
+               int dynindx;
+               int offset = eh->fdpic_cnts.funcdesc_offset & ~1;
+               bfd_vma addr;
+               bfd_vma seg = -1;
+
+               /* For static binaries sym_sec can be null.  */
+               if (sym_sec)
+                 {
+                   dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+                   addr = dynreloc_value - sym_sec->output_section->vma;
+                 }
+               else
+                 {
+                   dynindx = 0;
+                   addr = 0;
+                 }
+
+               /* Emit R_ARM_FUNCDESC_VALUE on funcdesc if not done yet.  */
+               arm_elf_fill_funcdesc (output_bfd, info,
+                                      &eh->fdpic_cnts.funcdesc_offset,
+                                      dynindx, offset, addr, dynreloc_value, seg);
+             }
+
+           /* Add a dynamic relocation on GOT entry if not already done.  */
+           if ((eh->fdpic_cnts.gotfuncdesc_offset & 1) == 0)
+             {
+               if (h->dynindx == -1)
+                 {
+                   outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+                   if (h->root.type == bfd_link_hash_undefweak)
+                     bfd_put_32 (output_bfd, 0, sgot->contents
+                                 + (eh->fdpic_cnts.gotfuncdesc_offset & ~1));
+                   else
+                     bfd_put_32 (output_bfd, sgot->output_section->vma
+                                 + sgot->output_offset
+                                 + (eh->fdpic_cnts.funcdesc_offset & ~1),
+                                 sgot->contents
+                                 + (eh->fdpic_cnts.gotfuncdesc_offset & ~1));
+                 }
+               else
+                 {
+                   outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_FUNCDESC);
+                 }
+               outrel.r_offset = sgot->output_section->vma
+                 + sgot->output_offset
+                 + (eh->fdpic_cnts.gotfuncdesc_offset & ~1);
+               outrel.r_addend = 0;
+               if (h->dynindx == -1 && !bfd_link_pic (info))
+                 if (h->root.type == bfd_link_hash_undefweak)
+                   arm_elf_add_rofixup (output_bfd, globals->srofixup, -1);
+                 else
+                   arm_elf_add_rofixup (output_bfd, globals->srofixup,
+                                        outrel.r_offset);
+               else
+                 elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+               eh->fdpic_cnts.gotfuncdesc_offset |= 1;
+             }
+         }
+       else
+         {
+           /* Such relocation on static function should not have been
+              emitted by the compiler.  */
+           return bfd_reloc_notsupported;
+         }
+      }
+      *unresolved_reloc_p = false;
+      return bfd_reloc_ok;
+
+    case R_ARM_FUNCDESC:
+      {
+       if (h == NULL)
+         {
+           struct fdpic_local *local_fdpic_cnts = elf32_arm_local_fdpic_cnts (input_bfd);
+           Elf_Internal_Rela outrel;
+           int dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+
+           if (r_symndx >= elf32_arm_num_entries (input_bfd))
+             {
+               * error_message = _("local symbol index too big");
+               return bfd_reloc_dangerous;
+             }
+
+           int offset = local_fdpic_cnts[r_symndx].funcdesc_offset & ~1;
+           bfd_vma addr = dynreloc_value - sym_sec->output_section->vma;
+           bfd_vma seg = -1;
+
+           if (bfd_link_pic (info) && dynindx == 0)
+             {
+               * error_message = _("dynamic index information not available");
+               return bfd_reloc_dangerous;
+             }
+
+           /* Replace static FUNCDESC relocation with a
+              R_ARM_RELATIVE dynamic relocation or with a rofixup for
+              executable.  */
+           outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+           outrel.r_offset = input_section->output_section->vma
+             + input_section->output_offset + rel->r_offset;
+           outrel.r_addend = 0;
+           if (bfd_link_pic (info))
+             elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+           else
+             arm_elf_add_rofixup (output_bfd, globals->srofixup, outrel.r_offset);
+
+           bfd_put_32 (input_bfd, sgot->output_section->vma
+                       + sgot->output_offset + offset, hit_data);
+
+           /* Emit R_ARM_FUNCDESC_VALUE on funcdesc if not done yet.  */
+           arm_elf_fill_funcdesc (output_bfd, info,
+                                  &local_fdpic_cnts[r_symndx].funcdesc_offset,
+                                  dynindx, offset, addr, dynreloc_value, seg);
+         }
+       else
+         {
+           if (h->dynindx == -1)
+             {
+               int dynindx;
+               int offset = eh->fdpic_cnts.funcdesc_offset & ~1;
+               bfd_vma addr;
+               bfd_vma seg = -1;
+               Elf_Internal_Rela outrel;
+
+               /* For static binaries sym_sec can be null.  */
+               if (sym_sec)
+                 {
+                   dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+                   addr = dynreloc_value - sym_sec->output_section->vma;
+                 }
+               else
+                 {
+                   dynindx = 0;
+                   addr = 0;
+                 }
+
+               if (bfd_link_pic (info) && dynindx == 0)
+                 abort ();
+
+               /* Replace static FUNCDESC relocation with a
+                  R_ARM_RELATIVE dynamic relocation.  */
+               outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+               outrel.r_offset = input_section->output_section->vma
+                 + input_section->output_offset + rel->r_offset;
+               outrel.r_addend = 0;
+               if (bfd_link_pic (info))
+                 elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+               else
+                 arm_elf_add_rofixup (output_bfd, globals->srofixup, outrel.r_offset);
+
+               bfd_put_32 (input_bfd, sgot->output_section->vma
+                           + sgot->output_offset + offset, hit_data);
+
+               /* Emit R_ARM_FUNCDESC_VALUE on funcdesc if not done yet.  */
+               arm_elf_fill_funcdesc (output_bfd, info,
+                                      &eh->fdpic_cnts.funcdesc_offset,
+                                      dynindx, offset, addr, dynreloc_value, seg);
+             }
+           else
+             {
+               Elf_Internal_Rela outrel;
+
+               /* Add a dynamic relocation.  */
+               outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_FUNCDESC);
+               outrel.r_offset = input_section->output_section->vma
+                 + input_section->output_offset + rel->r_offset;
+               outrel.r_addend = 0;
+               elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+             }
+         }
+      }
+      *unresolved_reloc_p = false;
+      return bfd_reloc_ok;
+
+    case R_ARM_THM_BF16:
+      {
+       bfd_vma relocation;
+       bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+       bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+
        if (globals->use_rel)
          {
-           int negative = (insn & (1 << 23)) ? 1 : -1;
-           signed_addend = negative * ((insn & 0xff) << 2);
+           bfd_vma immA  = (upper_insn & 0x001f);
+           bfd_vma immB  = (lower_insn & 0x07fe) >> 1;
+           bfd_vma immC  = (lower_insn & 0x0800) >> 11;
+           addend  = (immA << 12);
+           addend |= (immB << 2);
+           addend |= (immC << 1);
+           addend |= 1;
+           /* Sign extend.  */
+           signed_addend = (addend & 0x10000) ? addend - (1 << 17) : addend;
          }
 
-       /* Compute the value (X) to go in the place.  */
-       if (r_type == R_ARM_LDC_PC_G0
-           || r_type == R_ARM_LDC_PC_G1
-           || r_type == R_ARM_LDC_PC_G2)
-         /* PC relative.  */
-         signed_value = value - pc + signed_addend;
-       else
-         /* Section base relative.  */
-         signed_value = value - sb + signed_addend;
+       relocation  = value + signed_addend;
+       relocation -= (input_section->output_section->vma
+                      + input_section->output_offset
+                      + rel->r_offset);
 
-       /* Calculate the value of the relevant G_{n-1} to obtain
-          the residual at that stage.  */
-       calculate_group_reloc_mask (signed_value < 0 ? - signed_value : signed_value,
-                                   group - 1, &residual);
+       /* Put RELOCATION back into the insn.  */
+       {
+         bfd_vma immA = (relocation & 0x0001f000) >> 12;
+         bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+         bfd_vma immC = (relocation & 0x00000002) >> 1;
 
-       /* Check for overflow.  (The absolute value to go in the place must be
-          divisible by four and, after having been divided by four, must
-          fit in eight bits.)  */
-       if ((residual & 0x3) != 0 || residual >= 0x400)
+         upper_insn = (upper_insn & 0xffe0) | immA;
+         lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
+       }
+
+       /* Put the relocated value back in the object file:  */
+       bfd_put_16 (input_bfd, upper_insn, hit_data);
+       bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+       return bfd_reloc_ok;
+      }
+
+    case R_ARM_THM_BF12:
+      {
+       bfd_vma relocation;
+       bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+       bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+
+       if (globals->use_rel)
          {
-           _bfd_error_handler
-             /* xgettext:c-format */
-             (_("%B(%A+%#Lx): Overflow whilst splitting %#Lx for group relocation %s"),
-              input_bfd, input_section, rel->r_offset,
-              signed_value < 0 ? -signed_value : signed_value, howto->name);
-           return bfd_reloc_overflow;
+           bfd_vma immA  = (upper_insn & 0x0001);
+           bfd_vma immB  = (lower_insn & 0x07fe) >> 1;
+           bfd_vma immC  = (lower_insn & 0x0800) >> 11;
+           addend  = (immA << 12);
+           addend |= (immB << 2);
+           addend |= (immC << 1);
+           addend |= 1;
+           /* Sign extend.  */
+           addend = (addend & 0x1000) ? addend - (1 << 13) : addend;
+           signed_addend = addend;
          }
 
-       /* Mask out the value and U bit.  */
-       insn &= 0xff7fff00;
+       relocation  = value + signed_addend;
+       relocation -= (input_section->output_section->vma
+                      + input_section->output_offset
+                      + rel->r_offset);
 
-       /* Set the U bit if the value to go in the place is non-negative.  */
-       if (signed_value >= 0)
-         insn |= 1 << 23;
+       /* Put RELOCATION back into the insn.  */
+       {
+         bfd_vma immA = (relocation & 0x00001000) >> 12;
+         bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+         bfd_vma immC = (relocation & 0x00000002) >> 1;
 
-       /* Encode the offset.  */
-       insn |= residual >> 2;
+         upper_insn = (upper_insn & 0xfffe) | immA;
+         lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
+       }
 
-       bfd_put_32 (input_bfd, insn, hit_data);
+       /* Put the relocated value back in the object file:  */
+       bfd_put_16 (input_bfd, upper_insn, hit_data);
+       bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+       return bfd_reloc_ok;
       }
-      return bfd_reloc_ok;
 
-    case R_ARM_THM_ALU_ABS_G0_NC:
-    case R_ARM_THM_ALU_ABS_G1_NC:
-    case R_ARM_THM_ALU_ABS_G2_NC:
-    case R_ARM_THM_ALU_ABS_G3_NC:
+    case R_ARM_THM_BF18:
+      {
+       bfd_vma relocation;
+       bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+       bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+
+       if (globals->use_rel)
+         {
+           bfd_vma immA  = (upper_insn & 0x007f);
+           bfd_vma immB  = (lower_insn & 0x07fe) >> 1;
+           bfd_vma immC  = (lower_insn & 0x0800) >> 11;
+           addend  = (immA << 12);
+           addend |= (immB << 2);
+           addend |= (immC << 1);
+           addend |= 1;
+           /* Sign extend.  */
+           addend = (addend & 0x40000) ? addend - (1 << 19) : addend;
+           signed_addend = addend;
+         }
+
+       relocation  = value + signed_addend;
+       relocation -= (input_section->output_section->vma
+                      + input_section->output_offset
+                      + rel->r_offset);
+
+       /* Put RELOCATION back into the insn.  */
        {
-           const int shift_array[4] = {0, 8, 16, 24};
-           bfd_vma insn = bfd_get_16 (input_bfd, hit_data);
-           bfd_vma addr = value;
-           int shift = shift_array[r_type - R_ARM_THM_ALU_ABS_G0_NC];
+         bfd_vma immA = (relocation & 0x0007f000) >> 12;
+         bfd_vma immB = (relocation & 0x00000ffc) >> 2;
+         bfd_vma immC = (relocation & 0x00000002) >> 1;
 
-           /* Compute address.  */
-           if (globals->use_rel)
-               signed_addend = insn & 0xff;
-           addr += signed_addend;
-           if (branch_type == ST_BRANCH_TO_THUMB)
-               addr |= 1;
-           /* Clean imm8 insn.  */
-           insn &= 0xff00;
-           /* And update with correct part of address.  */
-           insn |= (addr >> shift) & 0xff;
-           /* Update insn.  */
-           bfd_put_16 (input_bfd, insn, hit_data);
+         upper_insn = (upper_insn & 0xff80) | immA;
+         lower_insn = (lower_insn & 0xf001) | (immC << 11) | (immB << 1);
        }
 
-       *unresolved_reloc_p = FALSE;
+       /* Put the relocated value back in the object file:  */
+       bfd_put_16 (input_bfd, upper_insn, hit_data);
+       bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
        return bfd_reloc_ok;
+      }
 
     default:
       return bfd_reloc_notsupported;
@@ -12154,10 +12990,10 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS.  */
 static void
-arm_add_to_rel (bfd *              abfd,
-               bfd_byte *         address,
+arm_add_to_rel (bfd *             abfd,
+               bfd_byte *         address,
                reloc_howto_type * howto,
-               bfd_signed_vma     increment)
+               bfd_signed_vma     increment)
 {
   bfd_signed_vma addend;
 
@@ -12184,7 +13020,7 @@ arm_add_to_rel (bfd *              abfd,
     }
   else
     {
-      bfd_vma        contents;
+      bfd_vma       contents;
 
       contents = bfd_get_32 (abfd, address);
 
@@ -12228,13 +13064,16 @@ arm_add_to_rel (bfd *              abfd,
 
 #define IS_ARM_TLS_RELOC(R_TYPE)       \
   ((R_TYPE) == R_ARM_TLS_GD32          \
+   || (R_TYPE) == R_ARM_TLS_GD32_FDPIC  \
    || (R_TYPE) == R_ARM_TLS_LDO32      \
    || (R_TYPE) == R_ARM_TLS_LDM32      \
+   || (R_TYPE) == R_ARM_TLS_LDM32_FDPIC        \
    || (R_TYPE) == R_ARM_TLS_DTPOFF32   \
    || (R_TYPE) == R_ARM_TLS_DTPMOD32   \
    || (R_TYPE) == R_ARM_TLS_TPOFF32    \
    || (R_TYPE) == R_ARM_TLS_LE32       \
    || (R_TYPE) == R_ARM_TLS_IE32       \
+   || (R_TYPE) == R_ARM_TLS_IE32_FDPIC \
    || IS_ARM_TLS_GNU_RELOC (R_TYPE))
 
 /* Specific set of relocations for the gnu tls dialect.  */
@@ -12247,15 +13086,15 @@ arm_add_to_rel (bfd *              abfd,
 
 /* Relocate an ARM ELF section.  */
 
-static bfd_boolean
-elf32_arm_relocate_section (bfd *                  output_bfd,
+static int
+elf32_arm_relocate_section (bfd *                 output_bfd,
                            struct bfd_link_info * info,
-                           bfd *                  input_bfd,
-                           asection *             input_section,
-                           bfd_byte *             contents,
-                           Elf_Internal_Rela *    relocs,
-                           Elf_Internal_Sym *     local_syms,
-                           asection **            local_sections)
+                           bfd *                  input_bfd,
+                           asection *             input_section,
+                           bfd_byte *             contents,
+                           Elf_Internal_Rela *    relocs,
+                           Elf_Internal_Sym *     local_syms,
+                           asection **            local_sections)
 {
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
@@ -12266,7 +13105,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
 
   globals = elf32_arm_hash_table (info);
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   symtab_hdr = & elf_symtab_hdr (input_bfd);
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -12275,17 +13114,17 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; rel++)
     {
-      int                          r_type;
-      reloc_howto_type *           howto;
-      unsigned long                r_symndx;
-      Elf_Internal_Sym *           sym;
-      asection *                   sec;
+      int                         r_type;
+      reloc_howto_type *          howto;
+      unsigned long               r_symndx;
+      Elf_Internal_Sym *          sym;
+      asection *                  sec;
       struct elf_link_hash_entry * h;
-      bfd_vma                      relocation;
-      bfd_reloc_status_type        r;
-      arelent                      bfd_reloc;
-      char                         sym_type;
-      bfd_boolean                  unresolved_reloc = FALSE;
+      bfd_vma                     relocation;
+      bfd_reloc_status_type       r;
+      arelent                     bfd_reloc;
+      char                        sym_type;
+      bool                        unresolved_reloc = false;
       char *error_message = NULL;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -12326,7 +13165,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
              (info, bfd_elf_string_from_elf_section
               (input_bfd, symtab_hdr->sh_link, sym->st_name),
               input_bfd, input_section,
-              rel->r_offset, TRUE);
+              rel->r_offset, true);
 
          if (globals->use_rel)
            {
@@ -12366,10 +13205,11 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
                        {
                          _bfd_error_handler
                            /* xgettext:c-format */
-                           (_("%B(%A+%#Lx): %s relocation against SEC_MERGE section"),
+                           (_("%pB(%pA+%#" PRIx64 "): "
+                              "%s relocation against SEC_MERGE section"),
                             input_bfd, input_section,
-                            rel->r_offset, howto->name);
-                         return FALSE;
+                            (uint64_t) rel->r_offset, howto->name);
+                         return false;
                        }
 
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
@@ -12427,7 +13267,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
        }
       else
        {
-         bfd_boolean warned, ignored;
+         bool warned, ignored;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
@@ -12465,7 +13305,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
          name = (bfd_elf_string_from_elf_section
                  (input_bfd, symtab_hdr->sh_link, sym->st_name));
          if (name == NULL || *name == '\0')
-           name = bfd_section_name (input_bfd, sec);
+           name = bfd_section_name (sec);
        }
 
       if (r_symndx != STN_UNDEF
@@ -12478,12 +13318,12 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
          _bfd_error_handler
            ((sym_type == STT_TLS
              /* xgettext:c-format */
-             ? _("%B(%A+%#Lx): %s used with TLS symbol %s")
+             ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
              /* xgettext:c-format */
-             : _("%B(%A+%#Lx): %s used with non-TLS symbol %s")),
+             : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
             input_bfd,
             input_section,
-            rel->r_offset,
+            (uint64_t) rel->r_offset,
             howto->name,
             name);
        }
@@ -12533,13 +13373,14 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
        {
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
+           (_("%pB(%pA+%#" PRIx64 "): "
+              "unresolvable %s relocation against symbol `%s'"),
             input_bfd,
             input_section,
-            rel->r_offset,
+            (uint64_t) rel->r_offset,
             howto->name,
             h->root.root.string);
-         return FALSE;
+         return false;
        }
 
       if (r != bfd_reloc_ok)
@@ -12558,7 +13399,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
 
            case bfd_reloc_undefined:
              (*info->callbacks->undefined_symbol)
-               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
+               (info, name, input_bfd, input_section, rel->r_offset, true);
              break;
 
            case bfd_reloc_outofrange:
@@ -12586,7 +13427,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Add a new unwind edit to the list described by HEAD, TAIL.  If TINDEX is zero,
@@ -12634,35 +13475,37 @@ add_unwind_table_edit (arm_unwind_table_edit **head,
 static _arm_elf_section_data *get_arm_elf_section_data (asection *);
 
 /* Increase the size of EXIDX_SEC by ADJUST bytes.  ADJUST mau be negative.  */
+
 static void
-adjust_exidx_size(asection *exidx_sec, int adjust)
+adjust_exidx_size (asection *exidx_sec, int adjust)
 {
   asection *out_sec;
 
   if (!exidx_sec->rawsize)
     exidx_sec->rawsize = exidx_sec->size;
 
-  bfd_set_section_size (exidx_sec->owner, exidx_sec, exidx_sec->size + adjust);
+  bfd_set_section_size (exidx_sec, exidx_sec->size + adjust);
   out_sec = exidx_sec->output_section;
   /* Adjust size of output section.  */
-  bfd_set_section_size (out_sec->owner, out_sec, out_sec->size +adjust);
+  bfd_set_section_size (out_sec, out_sec->size + adjust);
 }
 
 /* Insert an EXIDX_CANTUNWIND marker at the end of a section.  */
+
 static void
-insert_cantunwind_after(asection *text_sec, asection *exidx_sec)
+insert_cantunwind_after (asection *text_sec, asection *exidx_sec)
 {
   struct _arm_elf_section_data *exidx_arm_data;
 
   exidx_arm_data = get_arm_elf_section_data (exidx_sec);
-  add_unwind_table_edit (
-    &exidx_arm_data->u.exidx.unwind_edit_list,
-    &exidx_arm_data->u.exidx.unwind_edit_tail,
-    INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX);
+  add_unwind_table_edit
+    (&exidx_arm_data->u.exidx.unwind_edit_list,
+     &exidx_arm_data->u.exidx.unwind_edit_tail,
+     INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX);
 
   exidx_arm_data->additional_reloc_count++;
 
-  adjust_exidx_size(exidx_sec, 8);
+  adjust_exidx_size (exidx_sec, 8);
 }
 
 /* Scan .ARM.exidx tables, and create a list describing edits which should be
@@ -12677,11 +13520,11 @@ insert_cantunwind_after(asection *text_sec, asection *exidx_sec)
    The edits are applied when the tables are written
    (in elf32_arm_write_section).  */
 
-bfd_boolean
+bool
 elf32_arm_fix_exidx_coverage (asection **text_section_order,
                              unsigned int num_text_sections,
                              struct bfd_link_info *info,
-                             bfd_boolean merge_exidx_entries)
+                             bool merge_exidx_entries)
 {
   bfd *inp;
   unsigned int last_second_word = 0, i;
@@ -12752,7 +13595,7 @@ elf32_arm_fix_exidx_coverage (asection **text_section_order,
          if (sec->size == 0)
            continue;
 
-         insert_cantunwind_after(last_text_sec, last_exidx_sec);
+         insert_cantunwind_after (last_text_sec, last_exidx_sec);
          last_unwind_type = 0;
          continue;
        }
@@ -12836,7 +13679,7 @@ elf32_arm_fix_exidx_coverage (asection **text_section_order,
       exidx_arm_data->u.exidx.unwind_edit_tail = unwind_edit_tail;
 
       if (deleted_exidx_bytes > 0)
-       adjust_exidx_size(exidx_sec, -deleted_exidx_bytes);
+       adjust_exidx_size (exidx_sec, - deleted_exidx_bytes);
 
       last_exidx_sec = exidx_sec;
       last_text_sec = sec;
@@ -12845,12 +13688,12 @@ elf32_arm_fix_exidx_coverage (asection **text_section_order,
   /* Add terminating CANTUNWIND entry.  */
   if (!bfd_link_relocatable (info) && last_exidx_sec
       && last_unwind_type != 0)
-    insert_cantunwind_after(last_text_sec, last_exidx_sec);
+    insert_cantunwind_after (last_text_sec, last_exidx_sec);
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elf32_arm_output_glue_section (struct bfd_link_info *info, bfd *obfd,
                               bfd *ibfd, const char *name)
 {
@@ -12858,31 +13701,31 @@ elf32_arm_output_glue_section (struct bfd_link_info *info, bfd *obfd,
 
   sec = bfd_get_linker_section (ibfd, name);
   if (sec == NULL || (sec->flags & SEC_EXCLUDE) != 0)
-    return TRUE;
+    return true;
 
   osec = sec->output_section;
   if (elf32_arm_write_section (obfd, info, sec, sec->contents))
-    return TRUE;
+    return true;
 
   if (! bfd_set_section_contents (obfd, osec, sec->contents,
                                  sec->output_offset, sec->size))
-    return FALSE;
+    return false;
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
   asection *sec, *osec;
 
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   /* Invoke the regular ELF backend linker to do all the work.  */
   if (!bfd_elf_final_link (abfd, info))
-    return FALSE;
+    return false;
 
   /* Process stub sections (eg BE8 encoding, ...).  */
   struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
@@ -12897,7 +13740,7 @@ elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
          elf32_arm_write_section (abfd, info, sec, sec->contents);
          if (! bfd_set_section_contents (abfd, osec, sec->contents,
                                          sec->output_offset, sec->size))
-           return FALSE;
+           return false;
        }
     }
 
@@ -12908,30 +13751,30 @@ elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
       if (! elf32_arm_output_glue_section (info, abfd,
                                           globals->bfd_of_glue_owner,
                                           ARM2THUMB_GLUE_SECTION_NAME))
-       return FALSE;
+       return false;
 
       if (! elf32_arm_output_glue_section (info, abfd,
                                           globals->bfd_of_glue_owner,
                                           THUMB2ARM_GLUE_SECTION_NAME))
-       return FALSE;
+       return false;
 
       if (! elf32_arm_output_glue_section (info, abfd,
                                           globals->bfd_of_glue_owner,
                                           VFP11_ERRATUM_VENEER_SECTION_NAME))
-       return FALSE;
+       return false;
 
       if (! elf32_arm_output_glue_section (info, abfd,
                                           globals->bfd_of_glue_owner,
                                           STM32L4XX_ERRATUM_VENEER_SECTION_NAME))
-       return FALSE;
+       return false;
 
       if (! elf32_arm_output_glue_section (info, abfd,
                                           globals->bfd_of_glue_owner,
                                           ARM_BX_GLUE_SECTION_NAME))
-       return FALSE;
+       return false;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Return a best guess for the machine number based on the attributes.  */
@@ -12943,6 +13786,7 @@ bfd_arm_get_mach_from_attributes (bfd * abfd)
 
   switch (arch)
     {
+    case TAG_CPU_ARCH_PRE_V4: return bfd_mach_arm_3M;
     case TAG_CPU_ARCH_V4: return bfd_mach_arm_4;
     case TAG_CPU_ARCH_V4T: return bfd_mach_arm_4T;
     case TAG_CPU_ARCH_V5T: return bfd_mach_arm_5T;
@@ -12980,14 +13824,47 @@ bfd_arm_get_mach_from_attributes (bfd * abfd)
        return bfd_mach_arm_5TE;
       }
 
+    case TAG_CPU_ARCH_V5TEJ:
+       return bfd_mach_arm_5TEJ;
+    case TAG_CPU_ARCH_V6:
+       return bfd_mach_arm_6;
+    case TAG_CPU_ARCH_V6KZ:
+       return bfd_mach_arm_6KZ;
+    case TAG_CPU_ARCH_V6T2:
+       return bfd_mach_arm_6T2;
+    case TAG_CPU_ARCH_V6K:
+       return bfd_mach_arm_6K;
+    case TAG_CPU_ARCH_V7:
+       return bfd_mach_arm_7;
+    case TAG_CPU_ARCH_V6_M:
+       return bfd_mach_arm_6M;
+    case TAG_CPU_ARCH_V6S_M:
+       return bfd_mach_arm_6SM;
+    case TAG_CPU_ARCH_V7E_M:
+       return bfd_mach_arm_7EM;
+    case TAG_CPU_ARCH_V8:
+       return bfd_mach_arm_8;
+    case TAG_CPU_ARCH_V8R:
+       return bfd_mach_arm_8R;
+    case TAG_CPU_ARCH_V8M_BASE:
+       return bfd_mach_arm_8M_BASE;
+    case TAG_CPU_ARCH_V8M_MAIN:
+       return bfd_mach_arm_8M_MAIN;
+    case TAG_CPU_ARCH_V8_1M_MAIN:
+       return bfd_mach_arm_8_1M_MAIN;
+
     default:
+      /* Force entry to be added for any new known Tag_CPU_arch value.  */
+      BFD_ASSERT (arch > MAX_TAG_CPU_ARCH);
+
+      /* Unknown Tag_CPU_arch value.  */
       return bfd_mach_arm_unknown;
     }
 }
 
 /* Set the right machine number.  */
 
-static bfd_boolean
+static bool
 elf32_arm_object_p (bfd *abfd)
 {
   unsigned int mach;
@@ -13003,12 +13880,12 @@ elf32_arm_object_p (bfd *abfd)
     }
 
   bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
-  return TRUE;
+  return true;
 }
 
 /* Function to keep ARM specific flags in the ELF header.  */
 
-static bfd_boolean
+static bool
 elf32_arm_set_private_flags (bfd *abfd, flagword flags)
 {
   if (elf_flags_init (abfd)
@@ -13018,33 +13895,33 @@ elf32_arm_set_private_flags (bfd *abfd, flagword flags)
        {
          if (flags & EF_ARM_INTERWORK)
            _bfd_error_handler
-             (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
+             (_("warning: not setting interworking flag of %pB since it has already been specified as non-interworking"),
               abfd);
          else
            _bfd_error_handler
-             (_("Warning: Clearing the interworking flag of %B due to outside request"),
+             (_("warning: clearing the interworking flag of %pB due to outside request"),
               abfd);
        }
     }
   else
     {
       elf_elfheader (abfd)->e_flags = flags;
-      elf_flags_init (abfd) = TRUE;
+      elf_flags_init (abfd) = true;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Copy backend specific data from one object module to another.  */
 
-static bfd_boolean
+static bool
 elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   flagword in_flags;
   flagword out_flags;
 
   if (! is_arm_elf (ibfd) || ! is_arm_elf (obfd))
-    return TRUE;
+    return true;
 
   in_flags  = elf_elfheader (ibfd)->e_flags;
   out_flags = elf_elfheader (obfd)->e_flags;
@@ -13055,11 +13932,11 @@ elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     {
       /* Cannot mix APCS26 and APCS32 code.  */
       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
-       return FALSE;
+       return false;
 
       /* Cannot mix float APCS and non-float APCS code.  */
       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
-       return FALSE;
+       return false;
 
       /* If the src and dest have different interworking flags
         then turn off the interworking bit.  */
@@ -13067,7 +13944,7 @@ elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
        {
          if (out_flags & EF_ARM_INTERWORK)
            _bfd_error_handler
-             (_("Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
+             (_("warning: clearing the interworking flag of %pB because non-interworking code in %pB has been linked with it"),
               obfd, ibfd);
 
          in_flags &= ~EF_ARM_INTERWORK;
@@ -13079,7 +13956,7 @@ elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     }
 
   elf_elfheader (obfd)->e_flags = in_flags;
-  elf_flags_init (obfd) = TRUE;
+  elf_flags_init (obfd) = true;
 
   return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
 }
@@ -13148,23 +14025,23 @@ elf32_arm_obj_attrs_order (int num)
 }
 
 /* Attribute numbers >=64 (mod 128) can be safely ignored.  */
-static bfd_boolean
+static bool
 elf32_arm_obj_attrs_handle_unknown (bfd *abfd, int tag)
 {
   if ((tag & 127) < 64)
     {
       _bfd_error_handler
-       (_("%B: Unknown mandatory EABI object attribute %d"),
+       (_("%pB: unknown mandatory EABI object attribute %d"),
         abfd, tag);
       bfd_set_error (bfd_error_bad_value);
-      return FALSE;
+      return false;
     }
   else
     {
       _bfd_error_handler
-       (_("Warning: %B: Unknown EABI object attribute %d"),
+       (_("warning: %pB: unknown EABI object attribute %d"),
         abfd, tag);
-      return TRUE;
+      return true;
     }
 }
 
@@ -13263,8 +14140,8 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
     };
   const int v6_m[] =
     {
-      -1,        /* PRE_V4.  */
-      -1,        /* V4.  */
+      -1,       /* PRE_V4.  */
+      -1,       /* V4.  */
       T(V6K),    /* V4T.  */
       T(V6K),    /* V5T.  */
       T(V6K),    /* V5TE.  */
@@ -13278,8 +14155,8 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
     };
   const int v6s_m[] =
     {
-      -1,        /* PRE_V4.  */
-      -1,        /* V4.  */
+      -1,       /* PRE_V4.  */
+      -1,       /* V4.  */
       T(V6K),    /* V4T.  */
       T(V6K),    /* V5T.  */
       T(V6K),    /* V5TE.  */
@@ -13294,8 +14171,8 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
     };
   const int v7e_m[] =
     {
-      -1,        /* PRE_V4.  */
-      -1,        /* V4.  */
+      -1,       /* PRE_V4.  */
+      -1,       /* V4.  */
       T(V7E_M),  /* V4T.  */
       T(V7E_M),  /* V5T.  */
       T(V7E_M),  /* V5TE.  */
@@ -13387,6 +14264,31 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       T(V8M_MAIN),     /* V8-M BASELINE.  */
       T(V8M_MAIN)      /* V8-M MAINLINE.  */
     };
+  const int v8_1m_mainline[] =
+    {
+      -1,              /* PRE_V4.  */
+      -1,              /* V4.  */
+      -1,              /* V4T.  */
+      -1,              /* V5T.  */
+      -1,              /* V5TE.  */
+      -1,              /* V5TEJ.  */
+      -1,              /* V6.  */
+      -1,              /* V6KZ.  */
+      -1,              /* V6T2.  */
+      -1,              /* V6K.  */
+      T(V8_1M_MAIN),   /* V7.  */
+      T(V8_1M_MAIN),   /* V6_M.  */
+      T(V8_1M_MAIN),   /* V6S_M.  */
+      T(V8_1M_MAIN),   /* V7E_M.  */
+      -1,              /* V8.  */
+      -1,              /* V8R.  */
+      T(V8_1M_MAIN),   /* V8-M BASELINE.  */
+      T(V8_1M_MAIN),   /* V8-M MAINLINE.  */
+      -1,              /* Unused (18).  */
+      -1,              /* Unused (19).  */
+      -1,              /* Unused (20).  */
+      T(V8_1M_MAIN)    /* V8.1-M MAINLINE.  */
+    };
   const int v4t_plus_v6_m[] =
     {
       -1,              /* PRE_V4.  */
@@ -13407,6 +14309,10 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       -1,              /* V8R.  */
       T(V8M_BASE),     /* V8-M BASELINE.  */
       T(V8M_MAIN),     /* V8-M MAINLINE.  */
+      -1,              /* Unused (18).  */
+      -1,              /* Unused (19).  */
+      -1,              /* Unused (20).  */
+      T(V8_1M_MAIN),   /* V8.1-M MAINLINE.  */
       T(V4T_PLUS_V6_M) /* V4T plus V6_M.  */
     };
   const int *comb[] =
@@ -13421,6 +14327,10 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       v8r,
       v8m_baseline,
       v8m_mainline,
+      NULL,
+      NULL,
+      NULL,
+      v8_1m_mainline,
       /* Pseudo-architecture.  */
       v4t_plus_v6_m
     };
@@ -13429,7 +14339,7 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
 
   if (oldtag > MAX_TAG_CPU_ARCH || newtag > MAX_TAG_CPU_ARCH)
     {
-      _bfd_error_handler (_("error: %B: Unknown CPU architecture"), ibfd);
+      _bfd_error_handler (_("error: %pB: unknown CPU architecture"), ibfd);
       return -1;
     }
 
@@ -13467,7 +14377,7 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
 
   if (result == -1)
     {
-      _bfd_error_handler (_("error: %B: Conflicting CPU architectures %d/%d"),
+      _bfd_error_handler (_("error: %pB: conflicting CPU architectures %d/%d"),
                          ibfd, oldtag, newtag);
       return -1;
     }
@@ -13478,7 +14388,7 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
 
 /* Query attributes object to see if integer divide instructions may be
    present in an object.  */
-static bfd_boolean
+static bool
 elf32_arm_attributes_accept_div (const obj_attribute *attr)
 {
   int arch = attr[Tag_CPU_arch].i;
@@ -13489,28 +14399,28 @@ elf32_arm_attributes_accept_div (const obj_attribute *attr)
     case 0:
       /* Integer divide allowed if instruction contained in archetecture.  */
       if (arch == TAG_CPU_ARCH_V7 && (profile == 'R' || profile == 'M'))
-       return TRUE;
+       return true;
       else if (arch >= TAG_CPU_ARCH_V7E_M)
-       return TRUE;
+       return true;
       else
-       return FALSE;
+       return false;
 
     case 1:
       /* Integer divide explicitly prohibited.  */
-      return FALSE;
+      return false;
 
     default:
       /* Unrecognised case - treat as allowing divide everywhere.  */
     case 2:
       /* Integer divide allowed in ARM state.  */
-      return TRUE;
+      return true;
     }
 }
 
 /* Query attributes object to see if integer divide instructions are
    forbidden to be in the object.  This is not the inverse of
    elf32_arm_attributes_accept_div.  */
-static bfd_boolean
+static bool
 elf32_arm_attributes_forbid_div (const obj_attribute *attr)
 {
   return attr[Tag_DIV_use].i == 1;
@@ -13519,7 +14429,7 @@ elf32_arm_attributes_forbid_div (const obj_attribute *attr)
 /* Merge EABI object attributes from IBFD into OBFD.  Raise an error if there
    are conflicting attributes.  */
 
-static bfd_boolean
+static bool
 elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
 {
   bfd *obfd = info->output_bfd;
@@ -13529,20 +14439,20 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
      2 = weak requirement.  */
   static const int order_021[3] = {0, 2, 1};
   int i;
-  bfd_boolean result = TRUE;
+  bool result = true;
   const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
 
   /* Skip the linker stubs file.  This preserves previous behavior
      of accepting unknown attributes in the first input file - but
      is that a bug?  */
   if (ibfd->flags & BFD_LINKER_CREATED)
-    return TRUE;
+    return true;
 
   /* Skip any input that hasn't attribute section.
      This enables to link object files without attribute section with
      any others.  */
   if (bfd_get_section_by_name (ibfd, sec_name) == NULL)
-    return TRUE;
+    return true;
 
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
     {
@@ -13564,9 +14474,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
                != out_attr[Tag_MPextension_use].i)
            {
              _bfd_error_handler
-               (_("Error: %B has both the current and legacy "
+               (_("Error: %pB has both the current and legacy "
                   "Tag_MPextension_use attributes"), ibfd);
-             result = FALSE;
+             result = false;
            }
 
          out_attr[Tag_MPextension_use] =
@@ -13593,10 +14503,10 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
               && in_attr[Tag_ABI_VFP_args].i != AEABI_VFP_args_compatible)
        {
          _bfd_error_handler
-           (_("error: %B uses VFP register arguments, %B does not"),
+           (_("error: %pB uses VFP register arguments, %pB does not"),
             in_attr[Tag_ABI_VFP_args].i ? ibfd : obfd,
             in_attr[Tag_ABI_VFP_args].i ? obfd : ibfd);
-         result = FALSE;
+         result = false;
        }
     }
 
@@ -13653,7 +14563,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
 
            /* Return with error if failed to merge.  */
            if (arch_attr == -1)
-             return FALSE;
+             return false;
 
            out_attr[i].i = arch_attr;
 
@@ -13701,6 +14611,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
        case Tag_CPU_unaligned_access:
        case Tag_T2EE_use:
        case Tag_MPextension_use:
+       case Tag_MVE_arch:
          /* Use the largest value specified.  */
          if (in_attr[i].i > out_attr[i].i)
            out_attr[i].i = in_attr[i].i;
@@ -13722,9 +14633,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
                 binaries in the toolchain have had the attributes set
                 properly.
              _bfd_error_handler
-               (_("error: %B: 8-byte data alignment conflicts with %B"),
+               (_("error: %pB: 8-byte data alignment conflicts with %pB"),
                 obfd, ibfd);
-             result = FALSE; */
+             result = false; */
            }
          /* Fall through.  */
        case Tag_ABI_FP_denormal:
@@ -13751,10 +14662,10 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              else
                {
                  _bfd_error_handler
-                   (_("error: %B: unable to merge virtualization attributes "
-                      "with %B"),
+                   (_("error: %pB: unable to merge virtualization attributes "
+                      "with %pB"),
                     obfd, ibfd);
-                 result = FALSE;
+                 result = false;
                }
            }
          break;
@@ -13777,11 +14688,11 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              else
                {
                  _bfd_error_handler
-                   (_("error: %B: Conflicting architecture profiles %c/%c"),
+                   (_("error: %pB: conflicting architecture profiles %c/%c"),
                     ibfd,
                     in_attr[i].i ? in_attr[i].i : '0',
                     out_attr[i].i ? out_attr[i].i : '0');
-                 result = FALSE;
+                 result = false;
                }
            }
          break;
@@ -13916,7 +14827,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              /* It's sometimes ok to mix different configs, so this is only
                 a warning.  */
              _bfd_error_handler
-               (_("Warning: %B: Conflicting platform configuration"), ibfd);
+               (_("warning: %pB: conflicting platform configuration"), ibfd);
            }
          break;
        case Tag_ABI_PCS_R9_use:
@@ -13925,8 +14836,8 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              && in_attr[i].i != AEABI_R9_unused)
            {
              _bfd_error_handler
-               (_("error: %B: Conflicting use of R9"), ibfd);
-             result = FALSE;
+               (_("error: %pB: conflicting use of R9"), ibfd);
+             result = false;
            }
          if (out_attr[i].i == AEABI_R9_unused)
            out_attr[i].i = in_attr[i].i;
@@ -13937,9 +14848,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_unused)
            {
              _bfd_error_handler
-               (_("error: %B: SB relative addressing conflicts with use of R9"),
+               (_("error: %pB: SB relative addressing conflicts with use of R9"),
                 ibfd);
-             result = FALSE;
+             result = false;
            }
          /* Use the smallest value specified.  */
          if (in_attr[i].i < out_attr[i].i)
@@ -13950,7 +14861,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              && !elf_arm_tdata (obfd)->no_wchar_size_warning)
            {
              _bfd_error_handler
-               (_("warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"),
+               (_("warning: %pB uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"),
                 ibfd, in_attr[i].i, out_attr[i].i);
            }
          else if (in_attr[i].i && !out_attr[i].i)
@@ -13973,15 +14884,15 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
                  static const char *aeabi_enum_names[] =
                    { "", "variable-size", "32-bit", "" };
                  const char *in_name =
-                   in_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
+                   in_attr[i].i < ARRAY_SIZE (aeabi_enum_names)
                    ? aeabi_enum_names[in_attr[i].i]
                    : "<unknown>";
                  const char *out_name =
-                   out_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
+                   out_attr[i].i < ARRAY_SIZE (aeabi_enum_names)
                    ? aeabi_enum_names[out_attr[i].i]
                    : "<unknown>";
                  _bfd_error_handler
-                   (_("warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),
+                   (_("warning: %pB uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),
                     ibfd, in_name, out_name);
                }
            }
@@ -13993,9 +14904,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
          if (in_attr[i].i != out_attr[i].i)
            {
              _bfd_error_handler
-               (_("error: %B uses iWMMXt register arguments, %B does not"),
+               (_("error: %pB uses iWMMXt register arguments, %pB does not"),
                 ibfd, obfd);
-             result = FALSE;
+             result = false;
            }
          break;
        case Tag_compatibility:
@@ -14010,9 +14921,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              if (in_attr[i].i != out_attr[i].i)
                {
                  _bfd_error_handler
-                   (_("error: fp16 format mismatch between %B and %B"),
+                   (_("error: fp16 format mismatch between %pB and %pB"),
                     ibfd, obfd);
-                 result = FALSE;
+                 result = false;
                }
            }
          if (in_attr[i].i != 0)
@@ -14046,10 +14957,10 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
              if (in_attr[Tag_MPextension_use].i != in_attr[i].i)
                {
                  _bfd_error_handler
-                   (_("%B has both the current and legacy "
+                   (_("%pB has both the current and legacy "
                       "Tag_MPextension_use attributes"),
                     ibfd);
-                 result = FALSE;
+                 result = false;
                }
            }
 
@@ -14087,7 +14998,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
 
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
   if (!_bfd_elf_merge_object_attributes (ibfd, info))
-    return FALSE;
+    return false;
 
   /* Check for any attributes not known on ARM.  */
   result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
@@ -14098,14 +15009,14 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, struct bfd_link_info *info)
 
 /* Return TRUE if the two EABI versions are incompatible.  */
 
-static bfd_boolean
+static bool
 elf32_arm_versions_compatible (unsigned iver, unsigned over)
 {
   /* v4 and v5 are the same spec before and after it was released,
      so allow mixing them.  */
   if ((iver == EF_ARM_EABI_VER4 && over == EF_ARM_EABI_VER5)
       || (iver == EF_ARM_EABI_VER5 && over == EF_ARM_EABI_VER4))
-    return TRUE;
+    return true;
 
   return (iver == over);
 }
@@ -14113,12 +15024,12 @@ elf32_arm_versions_compatible (unsigned iver, unsigned over)
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
-static bfd_boolean
+static bool
 elf32_arm_merge_private_bfd_data (bfd *, struct bfd_link_info *);
 
 /* Display the flags field.  */
 
-static bfd_boolean
+static bool
 elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
 {
   FILE * file = (FILE *) ptr;
@@ -14133,7 +15044,7 @@ elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
   /* Ignore init flag - it may not be set, despite the flags field
      containing valid data.  */
 
-  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
+  fprintf (file, _("private flags = 0x%lx:"), elf_elfheader (abfd)->e_flags);
 
   switch (EF_ARM_EABI_VERSION (flags))
     {
@@ -14245,14 +15156,20 @@ elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
   if (flags & EF_ARM_RELEXEC)
     fprintf (file, _(" [relocatable executable]"));
 
-  flags &= ~EF_ARM_RELEXEC;
+  if (flags & EF_ARM_PIC)
+    fprintf (file, _(" [position independent]"));
+
+  if (elf_elfheader (abfd)->e_ident[EI_OSABI] == ELFOSABI_ARM_FDPIC)
+    fprintf (file, _(" [FDPIC ABI supplement]"));
+
+  flags &= ~ (EF_ARM_RELEXEC | EF_ARM_PIC);
 
   if (flags)
-    fprintf (file, _("<Unrecognised flag bits set>"));
+    fprintf (file, _(" <Unrecognised flag bits set>"));
 
   fputc ('\n', file);
 
-  return TRUE;
+  return true;
 }
 
 static int
@@ -14299,7 +15216,7 @@ elf32_arm_gc_mark_hook (asection *sec,
 
 /* Look through the relocs for a section during the first phase.  */
 
-static bfd_boolean
+static bool
 elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
                        asection *sec, const Elf_Internal_Rela *relocs)
 {
@@ -14310,19 +15227,19 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
   bfd *dynobj;
   asection *sreloc;
   struct elf32_arm_link_hash_table *htab;
-  bfd_boolean call_reloc_p;
-  bfd_boolean may_become_dynamic_p;
-  bfd_boolean may_need_local_target_p;
+  bool call_reloc_p;
+  bool may_become_dynamic_p;
+  bool may_need_local_target_p;
   unsigned long nsyms;
 
   if (bfd_link_relocatable (info))
-    return TRUE;
+    return true;
 
   BFD_ASSERT (is_arm_elf (abfd));
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   sreloc = NULL;
 
@@ -14332,13 +15249,13 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
       && ! htab->root.dynamic_sections_created)
     {
       if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
-       return FALSE;
+       return false;
     }
 
   if (htab->root.dynobj == NULL)
     htab->root.dynobj = abfd;
   if (!create_ifunc_sections (info))
-    return FALSE;
+    return false;
 
   dynobj = htab->root.dynobj;
 
@@ -14365,9 +15282,9 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
             object file containing relocations but no symbol table.  */
          && (r_symndx > STN_UNDEF || nsyms > 0))
        {
-         _bfd_error_handler (_("%B: bad symbol index: %d"), abfd,
+         _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd,
                              r_symndx);
-         return FALSE;
+         return false;
        }
 
       h = NULL;
@@ -14377,10 +15294,10 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          if (r_symndx < symtab_hdr->sh_info)
            {
              /* A local symbol.  */
-             isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+             isym = bfd_sym_from_r_symndx (&htab->root.sym_cache,
                                            abfd, r_symndx);
              if (isym == NULL)
-               return FALSE;
+               return false;
            }
          else
            {
@@ -14393,18 +15310,72 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       eh = (struct elf32_arm_link_hash_entry *) h;
 
-      call_reloc_p = FALSE;
-      may_become_dynamic_p = FALSE;
-      may_need_local_target_p = FALSE;
+      call_reloc_p = false;
+      may_become_dynamic_p = false;
+      may_need_local_target_p = false;
 
       /* Could be done earlier, if h were already available.  */
       r_type = elf32_arm_tls_transition (info, r_type, h);
       switch (r_type)
        {
+       case R_ARM_GOTOFFFUNCDESC:
+         {
+           if (h == NULL)
+             {
+               if (!elf32_arm_allocate_local_sym_info (abfd))
+                 return false;
+               if (r_symndx >= elf32_arm_num_entries (abfd))
+                 return false;
+               elf32_arm_local_fdpic_cnts (abfd) [r_symndx].gotofffuncdesc_cnt += 1;
+               elf32_arm_local_fdpic_cnts (abfd) [r_symndx].funcdesc_offset = -1;
+             }
+           else
+             {
+               eh->fdpic_cnts.gotofffuncdesc_cnt++;
+             }
+         }
+         break;
+
+       case R_ARM_GOTFUNCDESC:
+         {
+           if (h == NULL)
+             {
+               /* Such a relocation is not supposed to be generated
+                  by gcc on a static function.  */
+               /* Anyway if needed it could be handled.  */
+               return false;
+             }
+           else
+             {
+               eh->fdpic_cnts.gotfuncdesc_cnt++;
+             }
+         }
+         break;
+
+       case R_ARM_FUNCDESC:
+         {
+           if (h == NULL)
+             {
+               if (!elf32_arm_allocate_local_sym_info (abfd))
+                 return false;
+               if (r_symndx >= elf32_arm_num_entries (abfd))
+                 return false;
+               elf32_arm_local_fdpic_cnts (abfd) [r_symndx].funcdesc_cnt += 1;
+               elf32_arm_local_fdpic_cnts (abfd) [r_symndx].funcdesc_offset = -1;
+             }
+           else
+             {
+               eh->fdpic_cnts.funcdesc_cnt++;
+             }
+         }
+         break;
+
          case R_ARM_GOT32:
          case R_ARM_GOT_PREL:
          case R_ARM_TLS_GD32:
+         case R_ARM_TLS_GD32_FDPIC:
          case R_ARM_TLS_IE32:
+         case R_ARM_TLS_IE32_FDPIC:
          case R_ARM_TLS_GOTDESC:
          case R_ARM_TLS_DESCSEQ:
          case R_ARM_THM_TLS_DESCSEQ:
@@ -14417,8 +15388,10 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
              switch (r_type)
                {
                case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
+               case R_ARM_TLS_GD32_FDPIC: tls_type = GOT_TLS_GD; break;
 
                case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
+               case R_ARM_TLS_IE32_FDPIC: tls_type = GOT_TLS_IE; break;
 
                case R_ARM_TLS_GOTDESC:
                case R_ARM_TLS_CALL: case R_ARM_THM_TLS_CALL:
@@ -14440,7 +15413,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
                {
                  /* This is a global offset table entry for a local symbol.  */
                  if (!elf32_arm_allocate_local_sym_info (abfd))
-                   return FALSE;
+                   return false;
+                 if (r_symndx >= elf32_arm_num_entries (abfd))
+                   {
+                     _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd,
+                                         r_symndx);
+                     return false;
+                   }
+
                  elf_local_got_refcounts (abfd)[r_symndx] += 1;
                  old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
                }
@@ -14476,7 +15456,8 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
            /* Fall through.  */
 
          case R_ARM_TLS_LDM32:
-           if (r_type == R_ARM_TLS_LDM32)
+         case R_ARM_TLS_LDM32_FDPIC:
+           if (r_type == R_ARM_TLS_LDM32 || r_type == R_ARM_TLS_LDM32_FDPIC)
                htab->tls_ldm_got.refcount++;
            /* Fall through.  */
 
@@ -14484,7 +15465,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          case R_ARM_GOTPC:
            if (htab->root.sgot == NULL
                && !create_got_section (htab->root.dynobj, info))
-             return FALSE;
+             return false;
            break;
 
          case R_ARM_PC24:
@@ -14495,16 +15476,16 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          case R_ARM_THM_CALL:
          case R_ARM_THM_JUMP24:
          case R_ARM_THM_JUMP19:
-           call_reloc_p = TRUE;
-           may_need_local_target_p = TRUE;
+           call_reloc_p = true;
+           may_need_local_target_p = true;
            break;
 
          case R_ARM_ABS12:
            /* VxWorks uses dynamic R_ARM_ABS12 relocations for
               ldr __GOTT_INDEX__ offsets.  */
-           if (!htab->vxworks_p)
+           if (htab->root.target_os != is_vxworks)
              {
-               may_need_local_target_p = TRUE;
+               may_need_local_target_p = true;
                break;
              }
            else goto jump_over;
@@ -14518,11 +15499,11 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
            if (bfd_link_pic (info))
              {
                _bfd_error_handler
-                 (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+                 (_("%pB: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
                   abfd, elf32_arm_howto_table_1[r_type].name,
                   (h) ? h->root.root.string : "a local symbol");
                bfd_set_error (bfd_error_bad_value);
-               return FALSE;
+               return false;
              }
 
            /* Fall through.  */
@@ -14542,7 +15523,8 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          case R_ARM_THM_MOVT_PREL:
 
            /* Should the interworking branches be listed here?  */
-           if ((bfd_link_pic (info) || htab->root.is_relocatable_executable)
+           if ((bfd_link_pic (info) || htab->root.is_relocatable_executable
+                || htab->fdpic_p)
                && (sec->flags & SEC_ALLOC) != 0)
              {
                if (h == NULL
@@ -14552,34 +15534,32 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
                       we treat local relative references as calls;
                       see the related SYMBOL_CALLS_LOCAL code in
                       allocate_dynrelocs.  */
-                   call_reloc_p = TRUE;
-                   may_need_local_target_p = TRUE;
+                   call_reloc_p = true;
+                   may_need_local_target_p = true;
                  }
                else
                  /* We are creating a shared library or relocatable
                     executable, and this is a reloc against a global symbol,
                     or a non-PC-relative reloc against a local symbol.
                     We may need to copy the reloc into the output.  */
-                 may_become_dynamic_p = TRUE;
+                 may_become_dynamic_p = true;
              }
            else
-             may_need_local_target_p = TRUE;
+             may_need_local_target_p = true;
            break;
 
        /* This relocation describes the C++ object vtable hierarchy.
           Reconstruct it for later use during GC.  */
        case R_ARM_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-           return FALSE;
+           return false;
          break;
 
        /* This relocation describes which C++ vtable entries are actually
           used.  Record for later use during GC.  */
        case R_ARM_GNU_VTENTRY:
-         BFD_ASSERT (h != NULL);
-         if (h != NULL
-             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
-           return FALSE;
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+           return false;
          break;
        }
 
@@ -14617,7 +15597,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
            {
              local_iplt = elf32_arm_create_local_iplt (abfd, r_symndx);
              if (local_iplt == NULL)
-               return FALSE;
+               return false;
              root_plt = &local_iplt->root;
              arm_plt = &local_iplt->arm;
            }
@@ -14653,38 +15633,28 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
                (sec, dynobj, 2, abfd, ! htab->use_rel);
 
              if (sreloc == NULL)
-               return FALSE;
-
-             /* BPABI objects never have dynamic relocations mapped.  */
-             if (htab->symbian_p)
-               {
-                 flagword flags;
-
-                 flags = bfd_get_section_flags (dynobj, sreloc);
-                 flags &= ~(SEC_LOAD | SEC_ALLOC);
-                 bfd_set_section_flags (dynobj, sreloc, flags);
-               }
+               return false;
            }
 
          /* If this is a global symbol, count the number of
             relocations we need for this symbol.  */
          if (h != NULL)
-           head = &((struct elf32_arm_link_hash_entry *) h)->dyn_relocs;
+           head = &h->dyn_relocs;
          else
            {
              head = elf32_arm_get_local_dynreloc_list (abfd, r_symndx, isym);
              if (head == NULL)
-               return FALSE;
+               return false;
            }
 
          p = *head;
          if (p == NULL || p->sec != sec)
            {
-             bfd_size_type amt = sizeof *p;
+             size_t amt = sizeof *p;
 
              p = (struct elf_dyn_relocs *) bfd_alloc (htab->root.dynobj, amt);
              if (p == NULL)
-               return FALSE;
+               return false;
              p->next = *head;
              *head = p;
              p->sec = sec;
@@ -14695,10 +15665,22 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          if (elf32_arm_howto_from_type (r_type)->pc_relative)
            p->pc_count += 1;
          p->count += 1;
+         if (h == NULL && htab->fdpic_p && !bfd_link_pic (info)
+             && r_type != R_ARM_ABS32 && r_type != R_ARM_ABS32_NOI)
+           {
+             /* Here we only support R_ARM_ABS32 and R_ARM_ABS32_NOI
+                that will become rofixup.  */
+             /* This is due to the fact that we suppose all will become rofixup.  */
+             _bfd_error_handler
+               (_("FDPIC does not yet support %s relocation"
+                  " to become dynamic for executable"),
+                elf32_arm_howto_table_1[r_type].name);
+             abort ();
+           }
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 static void
@@ -14770,7 +15752,7 @@ elf32_arm_update_relocs (asection *o,
          eadi = get_arm_elf_section_data (i);
          edit_list = eadi->u.exidx.unwind_edit_list;
          edit_tail = eadi->u.exidx.unwind_edit_tail;
-         offset = o->vma + i->output_offset;
+         offset = i->output_offset;
 
          if (eadi->elf.rel.hdr &&
              eadi->elf.rel.hdr->sh_entsize == rel_hdr->sh_entsize)
@@ -14869,7 +15851,7 @@ elf32_arm_update_relocs (asection *o,
    their own section (as would be the case if code was compiled with
    -ffunction-sections).  */
 
-static bfd_boolean
+static bool
 elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
                                  elf_gc_mark_hook_fn gc_mark_hook)
 {
@@ -14882,7 +15864,9 @@ elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
   const struct elf_backend_data *bed;
   struct elf_link_hash_entry **sym_hashes;
   struct elf32_arm_link_hash_entry *cmse_hash;
-  bfd_boolean again, is_v8m, first_bfd_browse = TRUE;
+  bool again, is_v8m, first_bfd_browse = true;
+  bool debug_sec_need_to_be_marked = false;
+  asection *isec;
 
   _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
 
@@ -14892,10 +15876,10 @@ elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
 
   /* Marking EH data may cause additional code sections to be marked,
      requiring multiple passes.  */
-  again = TRUE;
+  again = true;
   while (again)
     {
-      again = FALSE;
+      again = false;
       for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
        {
          asection *o;
@@ -14915,9 +15899,9 @@ elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
                  && !o->gc_mark
                  && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark)
                {
-                 again = TRUE;
+                 again = true;
                  if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
-                   return FALSE;
+                   return false;
                }
            }
 
@@ -14938,153 +15922,105 @@ elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
 
                  /* Assume it is a special symbol.  If not, cmse_scan will
                     warn about it and user can do something about it.  */
-                 if (ARM_GET_SYM_CMSE_SPCL (cmse_hash->root.target_internal))
+                 if (startswith (cmse_hash->root.root.root.string,
+                                   CMSE_PREFIX))
                    {
                      cmse_sec = cmse_hash->root.root.u.def.section;
                      if (!cmse_sec->gc_mark
                          && !_bfd_elf_gc_mark (info, cmse_sec, gc_mark_hook))
-                       return FALSE;
+                       return false;
+                     /* The debug sections related to these secure entry
+                        functions are marked on enabling below flag.  */
+                     debug_sec_need_to_be_marked = true;
+                   }
+               }
+
+             if (debug_sec_need_to_be_marked)
+               {
+                 /* Looping over all the sections of the object file containing
+                    Armv8-M secure entry functions and marking all the debug
+                    sections.  */
+                 for (isec = sub->sections; isec != NULL; isec = isec->next)
+                   {
+                     /* If not a debug sections, skip it.  */
+                     if (!isec->gc_mark && (isec->flags & SEC_DEBUGGING))
+                       isec->gc_mark = 1 ;
                    }
+                 debug_sec_need_to_be_marked = false;
                }
            }
        }
-      first_bfd_browse = FALSE;
+      first_bfd_browse = false;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Treat mapping symbols as special target symbols.  */
 
-static bfd_boolean
+static bool
 elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
 {
   return bfd_is_arm_special_symbol_name (sym->name,
                                         BFD_ARM_SPECIAL_SYM_TYPE_ANY);
 }
 
-/* This is a copy of elf_find_function() from elf.c except that
-   ARM mapping symbols are ignored when looking for function names
-   and STT_ARM_TFUNC is considered to a function type.  */
+/* If the ELF symbol SYM might be a function in SEC, return the
+   function size and set *CODE_OFF to the function's entry point,
+   otherwise return zero.  */
 
-static bfd_boolean
-arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
-                      asymbol **    symbols,
-                      asection *    section,
-                      bfd_vma       offset,
-                      const char ** filename_ptr,
-                      const char ** functionname_ptr)
+static bfd_size_type
+elf32_arm_maybe_function_sym (const asymbol *sym, asection *sec,
+                             bfd_vma *code_off)
 {
-  const char * filename = NULL;
-  asymbol * func = NULL;
-  bfd_vma low_func = 0;
-  asymbol ** p;
+  bfd_size_type size;
+  elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
 
-  for (p = symbols; *p != NULL; p++)
-    {
-      elf_symbol_type *q;
+  if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+                    | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
+      || sym->section != sec)
+    return 0;
 
-      q = (elf_symbol_type *) *p;
+  size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
 
-      switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
-       {
-       default:
-         break;
-       case STT_FILE:
-         filename = bfd_asymbol_name (&q->symbol);
-         break;
-       case STT_FUNC:
-       case STT_ARM_TFUNC:
+  if (!(sym->flags & BSF_SYNTHETIC))
+    switch (ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info))
+      {
        case STT_NOTYPE:
-         /* Skip mapping symbols.  */
-         if ((q->symbol.flags & BSF_LOCAL)
-             && bfd_is_arm_special_symbol_name (q->symbol.name,
-                   BFD_ARM_SPECIAL_SYM_TYPE_ANY))
-           continue;
+         /* Ignore symbols created by the annobin plugin for gcc and clang.
+            These symbols are hidden, local, notype and have a size of 0.  */
+         if (size == 0
+             && sym->flags & BSF_LOCAL
+             && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
+           return 0;
          /* Fall through.  */
-         if (bfd_get_section (&q->symbol) == section
-             && q->symbol.value >= low_func
-             && q->symbol.value <= offset)
-           {
-             func = (asymbol *) q;
-             low_func = q->symbol.value;
-           }
+       case STT_FUNC:
+       case STT_ARM_TFUNC:
+         /* FIXME: Allow STT_GNU_IFUNC as well ?  */
          break;
-       }
-    }
-
-  if (func == NULL)
-    return FALSE;
-
-  if (filename_ptr)
-    *filename_ptr = filename;
-  if (functionname_ptr)
-    *functionname_ptr = bfd_asymbol_name (func);
-
-  return TRUE;
-}
-
-
-/* Find the nearest line to a particular section and offset, for error
-   reporting.   This code is a duplicate of the code in elf.c, except
-   that it uses arm_elf_find_function.  */
-
-static bfd_boolean
-elf32_arm_find_nearest_line (bfd *          abfd,
-                            asymbol **     symbols,
-                            asection *     section,
-                            bfd_vma        offset,
-                            const char **  filename_ptr,
-                            const char **  functionname_ptr,
-                            unsigned int * line_ptr,
-                            unsigned int * discriminator_ptr)
-{
-  bfd_boolean found = FALSE;
-
-  if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
-                                    filename_ptr, functionname_ptr,
-                                    line_ptr, discriminator_ptr,
-                                    dwarf_debug_sections, 0,
-                                    & elf_tdata (abfd)->dwarf2_find_line_info))
-    {
-      if (!*functionname_ptr)
-       arm_elf_find_function (abfd, symbols, section, offset,
-                              *filename_ptr ? NULL : filename_ptr,
-                              functionname_ptr);
-
-      return TRUE;
-    }
-
-  /* Skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain
-     uses DWARF1.  */
-
-  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
-                                            & found, filename_ptr,
-                                            functionname_ptr, line_ptr,
-                                            & elf_tdata (abfd)->line_info))
-    return FALSE;
+       default:
+         return 0;
+      }
 
-  if (found && (*functionname_ptr || *line_ptr))
-    return TRUE;
+  if ((sym->flags & BSF_LOCAL)
+      && bfd_is_arm_special_symbol_name (sym->name,
+                                        BFD_ARM_SPECIAL_SYM_TYPE_ANY))
+    return 0;
 
-  if (symbols == NULL)
-    return FALSE;
+  *code_off = sym->value;
 
-  if (! arm_elf_find_function (abfd, symbols, section, offset,
-                              filename_ptr, functionname_ptr))
-    return FALSE;
+  /* Do not return 0 for the function's size.  */
+  return size ? size : 1;
 
-  *line_ptr = 0;
-  return TRUE;
 }
 
-static bfd_boolean
-elf32_arm_find_inliner_info (bfd *          abfd,
+static bool
+elf32_arm_find_inliner_info (bfd *         abfd,
                             const char **  filename_ptr,
                             const char **  functionname_ptr,
                             unsigned int * line_ptr)
 {
-  bfd_boolean found;
+  bool found;
   found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
                                         functionname_ptr, line_ptr,
                                         & elf_tdata (abfd)->dwarf2_find_line_info);
@@ -15097,7 +16033,7 @@ elf32_arm_find_inliner_info (bfd *          abfd,
    change the definition to something the rest of the link can
    understand.  */
 
-static bfd_boolean
+static bool
 elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
                                 struct elf_link_hash_entry * h)
 {
@@ -15108,7 +16044,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
 
   globals = elf32_arm_hash_table (info);
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -15148,7 +16084,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
          h->needs_plt = 0;
        }
 
-      return TRUE;
+      return true;
     }
   else
     {
@@ -15172,13 +16108,13 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
       h->root.u.def.section = def->root.u.def.section;
       h->root.u.def.value = def->root.u.def.value;
-      return TRUE;
+      return true;
     }
 
   /* If there are no non-GOT references, we do not need a copy
      relocation.  */
   if (!h->non_got_ref)
-    return TRUE;
+    return true;
 
   /* This is a reference to a symbol defined by a dynamic object which
      is not a function.  */
@@ -15190,7 +16126,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
      can reference data in shared objects directly, so we don't need to
      do anything here.  */
   if (bfd_link_pic (info) || globals->root.is_relocatable_executable)
-    return TRUE;
+    return true;
 
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
@@ -15229,7 +16165,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
 /* Allocate space in .plt, .got and associated reloc sections for
    dynamic relocs.  */
 
-static bfd_boolean
+static bool
 allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
 {
   struct bfd_link_info *info;
@@ -15238,14 +16174,14 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
   struct elf_dyn_relocs *p;
 
   if (h->root.type == bfd_link_hash_indirect)
-    return TRUE;
+    return true;
 
   eh = (struct elf32_arm_link_hash_entry *) h;
 
   info = (struct bfd_link_info *) inf;
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   if ((htab->root.dynamic_sections_created || h->type == STT_GNU_IFUNC)
       && h->plt.refcount > 0)
@@ -15256,7 +16192,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
          && h->root.type == bfd_link_hash_undefweak)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
-           return FALSE;
+           return false;
        }
 
       /* If the call in the PLT entry binds locally, the associated
@@ -15303,7 +16239,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
          /* VxWorks executables have a second set of relocations for
             each PLT entry.  They go in a separate relocation section,
             which is processed by the kernel loader.  */
-         if (htab->vxworks_p && !bfd_link_pic (info))
+         if (htab->root.target_os == is_vxworks && !bfd_link_pic (info))
            {
              /* There is a relocation for the initial PLT entry:
                 an R_ARM_32 relocation for _GLOBAL_OFFSET_TABLE_.  */
@@ -15334,113 +16270,216 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
   if (h->got.refcount > 0)
     {
       asection *s;
-      bfd_boolean dyn;
+      bool dyn;
       int tls_type = elf32_arm_hash_entry (h)->tls_type;
       int indx;
 
       /* Make sure this symbol is output as a dynamic symbol.
         Undefined weak syms won't yet be marked as dynamic.  */
-      if (h->dynindx == -1 && !h->forced_local
+      if (htab->root.dynamic_sections_created
+         && h->dynindx == -1
+         && !h->forced_local
          && h->root.type == bfd_link_hash_undefweak)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
-           return FALSE;
+           return false;
        }
 
-      if (!htab->symbian_p)
+      s = htab->root.sgot;
+      h->got.offset = s->size;
+
+      if (tls_type == GOT_UNKNOWN)
+       abort ();
+
+      if (tls_type == GOT_NORMAL)
+       /* Non-TLS symbols need one GOT slot.  */
+       s->size += 4;
+      else
        {
-         s = htab->root.sgot;
-         h->got.offset = s->size;
+         if (tls_type & GOT_TLS_GDESC)
+           {
+             /* R_ARM_TLS_DESC needs 2 GOT slots.  */
+             eh->tlsdesc_got
+               = (htab->root.sgotplt->size
+                  - elf32_arm_compute_jump_table_size (htab));
+             htab->root.sgotplt->size += 8;
+             h->got.offset = (bfd_vma) -2;
+             /* plt.got_offset needs to know there's a TLS_DESC
+                reloc in the middle of .got.plt.  */
+             htab->num_tls_desc++;
+           }
 
-         if (tls_type == GOT_UNKNOWN)
-           abort ();
+         if (tls_type & GOT_TLS_GD)
+           {
+             /* R_ARM_TLS_GD32 and R_ARM_TLS_GD32_FDPIC need two
+                consecutive GOT slots.  If the symbol is both GD
+                and GDESC, got.offset may have been
+                overwritten.  */
+             h->got.offset = s->size;
+             s->size += 8;
+           }
 
-         if (tls_type == GOT_NORMAL)
-           /* Non-TLS symbols need one GOT slot.  */
+         if (tls_type & GOT_TLS_IE)
+           /* R_ARM_TLS_IE32/R_ARM_TLS_IE32_FDPIC need one GOT
+              slot.  */
            s->size += 4;
-         else
+       }
+
+      dyn = htab->root.dynamic_sections_created;
+
+      indx = 0;
+      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
+         && (!bfd_link_pic (info)
+             || !SYMBOL_REFERENCES_LOCAL (info, h)))
+       indx = h->dynindx;
+
+      if (tls_type != GOT_NORMAL
+         && (bfd_link_dll (info) || indx != 0)
+         && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+             || h->root.type != bfd_link_hash_undefweak))
+       {
+         if (tls_type & GOT_TLS_IE)
+           elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+
+         if (tls_type & GOT_TLS_GD)
+           elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+
+         if (tls_type & GOT_TLS_GDESC)
            {
-             if (tls_type & GOT_TLS_GDESC)
-               {
-                 /* R_ARM_TLS_DESC needs 2 GOT slots.  */
-                 eh->tlsdesc_got
-                   = (htab->root.sgotplt->size
-                      - elf32_arm_compute_jump_table_size (htab));
-                 htab->root.sgotplt->size += 8;
-                 h->got.offset = (bfd_vma) -2;
-                 /* plt.got_offset needs to know there's a TLS_DESC
-                    reloc in the middle of .got.plt.  */
-                 htab->num_tls_desc++;
-               }
+             elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
+             /* GDESC needs a trampoline to jump to.  */
+             htab->tls_trampoline = -1;
+           }
+
+         /* Only GD needs it.  GDESC just emits one relocation per
+            2 entries.  */
+         if ((tls_type & GOT_TLS_GD) && indx != 0)
+           elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+       }
+      else if (((indx != -1) || htab->fdpic_p)
+              && !SYMBOL_REFERENCES_LOCAL (info, h))
+       {
+         if (htab->root.dynamic_sections_created)
+           /* Reserve room for the GOT entry's R_ARM_GLOB_DAT relocation.  */
+           elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+       }
+      else if (h->type == STT_GNU_IFUNC
+              && eh->plt.noncall_refcount == 0)
+       /* No non-call references resolve the STT_GNU_IFUNC's PLT entry;
+          they all resolve dynamically instead.  Reserve room for the
+          GOT entry's R_ARM_IRELATIVE relocation.  */
+       elf32_arm_allocate_irelocs (info, htab->root.srelgot, 1);
+      else if (bfd_link_pic (info)
+              && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+       /* Reserve room for the GOT entry's R_ARM_RELATIVE relocation.  */
+       elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+      else if (htab->fdpic_p && tls_type == GOT_NORMAL)
+       /* Reserve room for rofixup for FDPIC executable.  */
+       /* TLS relocs do not need space since they are completely
+          resolved.  */
+       htab->srofixup->size += 4;
+    }
+  else
+    h->got.offset = (bfd_vma) -1;
+
+  /* FDPIC support.  */
+  if (eh->fdpic_cnts.gotofffuncdesc_cnt > 0)
+    {
+      /* Symbol musn't be exported.  */
+      if (h->dynindx != -1)
+       abort ();
 
-             if (tls_type & GOT_TLS_GD)
-               {
-                 /* R_ARM_TLS_GD32 needs 2 consecutive GOT slots.  If
-                    the symbol is both GD and GDESC, got.offset may
-                    have been overwritten.  */
-                 h->got.offset = s->size;
-                 s->size += 8;
-               }
+      /* We only allocate one function descriptor with its associated
+        relocation.  */
+      if (eh->fdpic_cnts.funcdesc_offset == -1)
+       {
+         asection *s = htab->root.sgot;
 
-             if (tls_type & GOT_TLS_IE)
-               /* R_ARM_TLS_IE32 needs one GOT slot.  */
-               s->size += 4;
-           }
+         eh->fdpic_cnts.funcdesc_offset = s->size;
+         s->size += 8;
+         /* We will add an R_ARM_FUNCDESC_VALUE relocation or two rofixups.  */
+         if (bfd_link_pic (info))
+           elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+         else
+           htab->srofixup->size += 8;
+       }
+    }
 
-         dyn = htab->root.dynamic_sections_created;
+  if (eh->fdpic_cnts.gotfuncdesc_cnt > 0)
+    {
+      asection *s = htab->root.sgot;
 
-         indx = 0;
-         if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
-                                              bfd_link_pic (info),
-                                              h)
-             && (!bfd_link_pic (info)
-                 || !SYMBOL_REFERENCES_LOCAL (info, h)))
-           indx = h->dynindx;
+      if (htab->root.dynamic_sections_created && h->dynindx == -1
+         && !h->forced_local)
+       if (! bfd_elf_link_record_dynamic_symbol (info, h))
+         return false;
 
-         if (tls_type != GOT_NORMAL
-             && (bfd_link_pic (info) || indx != 0)
-             && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-                 || h->root.type != bfd_link_hash_undefweak))
+      if (h->dynindx == -1)
+       {
+         /* We only allocate one function descriptor with its
+            associated relocation.  */
+         if (eh->fdpic_cnts.funcdesc_offset == -1)
            {
-             if (tls_type & GOT_TLS_IE)
-               elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
 
-             if (tls_type & GOT_TLS_GD)
+             eh->fdpic_cnts.funcdesc_offset = s->size;
+             s->size += 8;
+             /* We will add an R_ARM_FUNCDESC_VALUE relocation or two
+                rofixups.  */
+             if (bfd_link_pic (info))
                elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+             else
+               htab->srofixup->size += 8;
+           }
+       }
 
-             if (tls_type & GOT_TLS_GDESC)
-               {
-                 elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
-                 /* GDESC needs a trampoline to jump to.  */
-                 htab->tls_trampoline = -1;
-               }
+      /* Add one entry into the GOT and a R_ARM_FUNCDESC or
+        R_ARM_RELATIVE/rofixup relocation on it.  */
+      eh->fdpic_cnts.gotfuncdesc_offset = s->size;
+      s->size += 4;
+      if (h->dynindx == -1 && !bfd_link_pic (info))
+       htab->srofixup->size += 4;
+      else
+       elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+    }
 
-             /* Only GD needs it.  GDESC just emits one relocation per
-                2 entries.  */
-             if ((tls_type & GOT_TLS_GD) && indx != 0)
-               elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
-           }
-         else if (indx != -1 && !SYMBOL_REFERENCES_LOCAL (info, h))
+  if (eh->fdpic_cnts.funcdesc_cnt > 0)
+    {
+      if (htab->root.dynamic_sections_created && h->dynindx == -1
+         && !h->forced_local)
+       if (! bfd_elf_link_record_dynamic_symbol (info, h))
+         return false;
+
+      if (h->dynindx == -1)
+       {
+         /* We only allocate one function descriptor with its
+            associated relocation.  */
+         if (eh->fdpic_cnts.funcdesc_offset == -1)
            {
-             if (htab->root.dynamic_sections_created)
-               /* Reserve room for the GOT entry's R_ARM_GLOB_DAT relocation.  */
+             asection *s = htab->root.sgot;
+
+             eh->fdpic_cnts.funcdesc_offset = s->size;
+             s->size += 8;
+             /* We will add an R_ARM_FUNCDESC_VALUE relocation or two
+                rofixups.  */
+             if (bfd_link_pic (info))
                elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+             else
+               htab->srofixup->size += 8;
            }
-         else if (h->type == STT_GNU_IFUNC
-                  && eh->plt.noncall_refcount == 0)
-           /* No non-call references resolve the STT_GNU_IFUNC's PLT entry;
-              they all resolve dynamically instead.  Reserve room for the
-              GOT entry's R_ARM_IRELATIVE relocation.  */
-           elf32_arm_allocate_irelocs (info, htab->root.srelgot, 1);
-         else if (bfd_link_pic (info)
-                  && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-                      || h->root.type != bfd_link_hash_undefweak))
-           /* Reserve room for the GOT entry's R_ARM_RELATIVE relocation.  */
-           elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+       }
+      if (h->dynindx == -1 && !bfd_link_pic (info))
+       {
+         /* For FDPIC executable we replace R_ARM_RELATIVE with a rofixup.  */
+         htab->srofixup->size += 4 * eh->fdpic_cnts.funcdesc_cnt;
+       }
+      else
+       {
+         /* Will need one dynamic reloc per reference. will be either
+            R_ARM_FUNCDESC or R_ARM_RELATIVE for hidden symbols.  */
+         elf32_arm_allocate_dynrelocs (info, htab->root.srelgot,
+                                       eh->fdpic_cnts.funcdesc_cnt);
        }
     }
-  else
-    h->got.offset = (bfd_vma) -1;
 
   /* Allocate stubs for exported Thumb functions on v4t.  */
   if (!htab->use_blx && h->dynindx != -1
@@ -15460,7 +16499,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
       _bfd_generic_link_add_one_symbol (info, s->owner,
                                        name, BSF_GLOBAL, s,
                                        h->root.u.def.value,
-                                       NULL, TRUE, FALSE, &bh);
+                                       NULL, true, false, &bh);
 
       myh = (struct elf_link_hash_entry *) bh;
       myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
@@ -15475,8 +16514,8 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
       h->root.u.def.value = th->root.u.def.value & ~1;
     }
 
-  if (eh->dyn_relocs == NULL)
-    return TRUE;
+  if (h->dyn_relocs == NULL)
+    return true;
 
   /* In the shared -Bsymbolic case, discard space allocated for
      dynamic pc-relative relocs against symbols which turn out to be
@@ -15484,7 +16523,9 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
      space for pc-relative relocs that have become local due to symbol
      visibility changes.  */
 
-  if (bfd_link_pic (info) || htab->root.is_relocatable_executable)
+  if (bfd_link_pic (info)
+      || htab->root.is_relocatable_executable
+      || htab->fdpic_p)
     {
       /* Relocs that use pc_count are PC-relative forms, which will appear
         on something like ".long foo - ." or "movw REG, foo - .".  We want
@@ -15496,7 +16537,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
        {
          struct elf_dyn_relocs **pp;
 
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+         for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
            {
              p->count -= p->pc_count;
              p->pc_count = 0;
@@ -15507,11 +16548,11 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
            }
        }
 
-      if (htab->vxworks_p)
+      if (htab->root.target_os == is_vxworks)
        {
          struct elf_dyn_relocs **pp;
 
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+         for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
            {
              if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
                *pp = p->next;
@@ -15522,20 +16563,20 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
 
       /* Also discard relocs on undefined weak syms with non-default
         visibility.  */
-      if (eh->dyn_relocs != NULL
+      if (h->dyn_relocs != NULL
          && h->root.type == bfd_link_hash_undefweak)
        {
          if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
              || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
-           eh->dyn_relocs = NULL;
+           h->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
             symbol in PIEs.  */
-         else if (h->dynindx == -1
+         else if (htab->root.dynamic_sections_created && h->dynindx == -1
                   && !h->forced_local)
            {
              if (! bfd_elf_link_record_dynamic_symbol (info, h))
-               return FALSE;
+               return false;
            }
        }
 
@@ -15546,7 +16587,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
             against them.  For normal symbols we output a relocation
             against the section that contains them.  */
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
-           return FALSE;
+           return false;
        }
 
     }
@@ -15569,7 +16610,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
              && h->root.type == bfd_link_hash_undefweak)
            {
              if (! bfd_elf_link_record_dynamic_symbol (info, h))
-               return FALSE;
+               return false;
            }
 
          /* If that succeeded, we know we'll be keeping all the
@@ -15578,50 +16619,30 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
            goto keep;
        }
 
-      eh->dyn_relocs = NULL;
+      h->dyn_relocs = NULL;
 
     keep: ;
     }
 
   /* Finally, allocate space.  */
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  for (p = h->dyn_relocs; p != NULL; p = p->next)
     {
       asection *sreloc = elf_section_data (p->sec)->sreloc;
+
       if (h->type == STT_GNU_IFUNC
          && eh->plt.noncall_refcount == 0
          && SYMBOL_REFERENCES_LOCAL (info, h))
        elf32_arm_allocate_irelocs (info, sreloc, p->count);
+      else if (h->dynindx != -1
+              && (!bfd_link_pic (info) || !info->symbolic || !h->def_regular))
+       elf32_arm_allocate_dynrelocs (info, sreloc, p->count);
+      else if (htab->fdpic_p && !bfd_link_pic (info))
+       htab->srofixup->size += 4 * p->count;
       else
        elf32_arm_allocate_dynrelocs (info, sreloc, p->count);
     }
 
-  return TRUE;
-}
-
-/* Find any dynamic relocs that apply to read-only sections.  */
-
-static bfd_boolean
-elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
-{
-  struct elf32_arm_link_hash_entry * eh;
-  struct elf_dyn_relocs * p;
-
-  eh = (struct elf32_arm_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec;
-
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-       {
-         struct bfd_link_info *info = (struct bfd_link_info *) inf;
-
-         info->flags |= DF_TEXTREL;
-
-         /* Not an error, just cut short the traversal.  */
-         return FALSE;
-       }
-    }
-  return TRUE;
+  return true;
 }
 
 void
@@ -15639,20 +16660,19 @@ bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *info,
 
 /* Set the sizes of the dynamic sections.  */
 
-static bfd_boolean
+static bool
 elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
                                 struct bfd_link_info * info)
 {
   bfd * dynobj;
   asection * s;
-  bfd_boolean plt;
-  bfd_boolean relocs;
+  bool relocs;
   bfd *ibfd;
   struct elf32_arm_link_hash_table *htab;
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   dynobj = elf_hash_table (info)->dynobj;
   BFD_ASSERT (dynobj != NULL);
@@ -15682,8 +16702,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
       asection *srel;
-      bfd_boolean is_vxworks = htab->vxworks_p;
       unsigned int symndx;
+      struct fdpic_local *local_fdpic_cnts;
 
       if (! is_arm_elf (ibfd))
        continue;
@@ -15703,7 +16723,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
                     linker script /DISCARD/, so we'll be discarding
                     the relocs too.  */
                }
-             else if (is_vxworks
+             else if (htab->root.target_os == is_vxworks
                       && strcmp (p->sec->output_section->name,
                                  ".tls_vars") == 0)
                {
@@ -15713,7 +16733,10 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
              else if (p->count != 0)
                {
                  srel = elf_section_data (p->sec)->sreloc;
-                 elf32_arm_allocate_dynrelocs (info, srel, p->count);
+                 if (htab->fdpic_p && !bfd_link_pic (info))
+                   htab->srofixup->size += 4 * p->count;
+                 else
+                   elf32_arm_allocate_dynrelocs (info, srel, p->count);
                  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
                    info->flags |= DF_TEXTREL;
                }
@@ -15721,7 +16744,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
        }
 
       local_got = elf_local_got_refcounts (ibfd);
-      if (!local_got)
+      if (local_got == NULL)
        continue;
 
       symtab_hdr = & elf_symtab_hdr (ibfd);
@@ -15730,22 +16753,64 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       local_iplt_ptr = elf32_arm_local_iplt (ibfd);
       local_tls_type = elf32_arm_local_got_tls_type (ibfd);
       local_tlsdesc_gotent = elf32_arm_local_tlsdesc_gotent (ibfd);
+      local_fdpic_cnts = elf32_arm_local_fdpic_cnts (ibfd);
       symndx = 0;
       s = htab->root.sgot;
       srel = htab->root.srelgot;
       for (; local_got < end_local_got;
           ++local_got, ++local_iplt_ptr, ++local_tls_type,
-          ++local_tlsdesc_gotent, ++symndx)
+          ++local_tlsdesc_gotent, ++symndx, ++local_fdpic_cnts)
        {
+         if (symndx >= elf32_arm_num_entries (ibfd))
+           return false;
+
          *local_tlsdesc_gotent = (bfd_vma) -1;
          local_iplt = *local_iplt_ptr;
+
+         /* FDPIC support.  */
+         if (local_fdpic_cnts->gotofffuncdesc_cnt > 0)
+           {
+             if (local_fdpic_cnts->funcdesc_offset == -1)
+               {
+                 local_fdpic_cnts->funcdesc_offset = s->size;
+                 s->size += 8;
+
+                 /* We will add an R_ARM_FUNCDESC_VALUE relocation or two rofixups.  */
+                 if (bfd_link_pic (info))
+                   elf32_arm_allocate_dynrelocs (info, srel, 1);
+                 else
+                   htab->srofixup->size += 8;
+               }
+           }
+
+         if (local_fdpic_cnts->funcdesc_cnt > 0)
+           {
+             if (local_fdpic_cnts->funcdesc_offset == -1)
+               {
+                 local_fdpic_cnts->funcdesc_offset = s->size;
+                 s->size += 8;
+
+                 /* We will add an R_ARM_FUNCDESC_VALUE relocation or two rofixups.  */
+                 if (bfd_link_pic (info))
+                   elf32_arm_allocate_dynrelocs (info, srel, 1);
+                 else
+                   htab->srofixup->size += 8;
+               }
+
+             /* We will add n R_ARM_RELATIVE relocations or n rofixups.  */
+             if (bfd_link_pic (info))
+               elf32_arm_allocate_dynrelocs (info, srel, local_fdpic_cnts->funcdesc_cnt);
+             else
+               htab->srofixup->size += 4 * local_fdpic_cnts->funcdesc_cnt;
+           }
+
          if (local_iplt != NULL)
            {
              struct elf_dyn_relocs *p;
 
              if (local_iplt->root.refcount > 0)
                {
-                 elf32_arm_allocate_plt_entry (info, TRUE,
+                 elf32_arm_allocate_plt_entry (info, true,
                                                &local_iplt->root,
                                                &local_iplt->arm);
                  if (local_iplt->arm.noncall_refcount == 0)
@@ -15802,9 +16867,10 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
                  s->size += 4;
                }
 
-             isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, symndx);
+             isym = bfd_sym_from_r_symndx (&htab->root.sym_cache, ibfd,
+                                           symndx);
              if (isym == NULL)
-               return FALSE;
+               return false;
 
              /* If all references to an STT_GNU_IFUNC PLT are calls,
                 then all non-call references, including this GOT entry,
@@ -15813,13 +16879,15 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
                  && (local_iplt == NULL
                      || local_iplt->arm.noncall_refcount == 0))
                elf32_arm_allocate_irelocs (info, srel, 1);
-             else if (bfd_link_pic (info) || output_bfd->flags & DYNAMIC)
+             else if (bfd_link_pic (info) || output_bfd->flags & DYNAMIC || htab->fdpic_p)
                {
-                 if ((bfd_link_pic (info) && !(*local_tls_type & GOT_TLS_GDESC))
-                     || *local_tls_type & GOT_TLS_GD)
+                 if ((bfd_link_pic (info) && !(*local_tls_type & GOT_TLS_GDESC)))
                    elf32_arm_allocate_dynrelocs (info, srel, 1);
+                 else if (htab->fdpic_p && *local_tls_type & GOT_NORMAL)
+                   htab->srofixup->size += 4;
 
-                 if (bfd_link_pic (info) && *local_tls_type & GOT_TLS_GDESC)
+                 if ((bfd_link_pic (info) || htab->fdpic_p)
+                     && *local_tls_type & GOT_TLS_GDESC)
                    {
                      elf32_arm_allocate_dynrelocs (info,
                                                    htab->root.srelplt, 1);
@@ -15835,7 +16903,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
   if (htab->tls_ldm_got.refcount > 0)
     {
       /* Allocate two GOT entries and one dynamic relocation (if necessary)
-        for R_ARM_TLS_LDM32 relocations.  */
+        for R_ARM_TLS_LDM32/R_ARM_TLS_LDM32_FDPIC relocations.  */
       htab->tls_ldm_got.offset = htab->root.sgot->size;
       htab->root.sgot->size += 8;
       if (bfd_link_pic (info))
@@ -15844,6 +16912,11 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
   else
     htab->tls_ldm_got.offset = -1;
 
+  /* At the very end of the .rofixup section is a pointer to the GOT,
+     reserve space for it. */
+  if (htab->fdpic_p && htab->srofixup != NULL)
+    htab->srofixup->size += 4;
+
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
   elf_link_hash_traverse (& htab->root, allocate_dynrelocs_for_symbol, info);
@@ -15860,7 +16933,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       if (!bfd_elf32_arm_process_before_allocation (ibfd, info)
          || !bfd_elf32_arm_vfp11_erratum_scan (ibfd, info)
          || !bfd_elf32_arm_stm32l4xx_erratum_scan (ibfd, info))
-       _bfd_error_handler (_("Errors encountered processing file %B"), ibfd);
+       _bfd_error_handler (_("errors encountered processing file %pB"), ibfd);
     }
 
   /* Allocate space for the glue sections now that we've sized them.  */
@@ -15872,7 +16945,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
      for them, it suffices to multiply the reloc count by the jump
      slot size.  */
   if (htab->root.srelplt)
-    htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size(htab);
+    htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size (htab);
 
   if (htab->tls_trampoline)
     {
@@ -15884,12 +16957,14 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
 
       /* If we're not using lazy TLS relocations, don't generate the
         PLT and GOT entries they require.  */
-      if (!(info->flags & DF_BIND_NOW))
+      if ((info->flags & DF_BIND_NOW))
+       htab->root.tlsdesc_plt = 0;
+      else
        {
-         htab->dt_tlsdesc_got = htab->root.sgot->size;
+         htab->root.tlsdesc_got = htab->root.sgot->size;
          htab->root.sgot->size += 4;
 
-         htab->dt_tlsdesc_plt = htab->root.splt->size;
+         htab->root.tlsdesc_plt = htab->root.splt->size;
          htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline);
        }
     }
@@ -15897,8 +16972,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */
-  plt = FALSE;
-  relocs = FALSE;
+  relocs = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char * name;
@@ -15908,21 +16982,21 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
 
       /* It's OK to base decisions on the section name, because none
         of the dynobj section names depend upon the input files.  */
-      name = bfd_get_section_name (dynobj, s);
+      name = bfd_section_name (s);
 
       if (s == htab->root.splt)
        {
          /* Remember whether there is a PLT.  */
-         plt = s->size != 0;
+         ;
        }
-      else if (CONST_STRNEQ (name, ".rel"))
+      else if (startswith (name, ".rel"))
        {
          if (s->size != 0)
            {
              /* Remember whether there are any reloc sections other
                 than .rel(a).plt and .rela.plt.unloaded.  */
              if (s != htab->root.srelplt && s != htab->srelplt2)
-               relocs = TRUE;
+               relocs = true;
 
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
@@ -15934,7 +17008,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
               && s != htab->root.iplt
               && s != htab->root.igotplt
               && s != htab->root.sdynbss
-              && s != htab->root.sdynrelro)
+              && s != htab->root.sdynrelro
+              && s != htab->srofixup)
        {
          /* It's not one of our sections, so don't allocate space.  */
          continue;
@@ -15961,89 +17036,27 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       /* Allocate memory for the section contents.  */
       s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)
-       return FALSE;
-    }
-
-  if (elf_hash_table (info)->dynamic_sections_created)
-    {
-      /* Add some entries to the .dynamic section.  We fill in the
-        values later, in elf32_arm_finish_dynamic_sections, but we
-        must add the entries now so that we get the correct size for
-        the .dynamic section.  The DT_DEBUG entry is filled in by the
-        dynamic linker and used by the debugger.  */
-#define add_dynamic_entry(TAG, VAL) \
-  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
-
-     if (bfd_link_executable (info))
-       {
-         if (!add_dynamic_entry (DT_DEBUG, 0))
-           return FALSE;
-       }
-
-      if (plt)
-       {
-         if (   !add_dynamic_entry (DT_PLTGOT, 0)
-             || !add_dynamic_entry (DT_PLTRELSZ, 0)
-             || !add_dynamic_entry (DT_PLTREL,
-                                    htab->use_rel ? DT_REL : DT_RELA)
-             || !add_dynamic_entry (DT_JMPREL, 0))
-           return FALSE;
-
-         if (htab->dt_tlsdesc_plt
-             && (!add_dynamic_entry (DT_TLSDESC_PLT,0)
-                 || !add_dynamic_entry (DT_TLSDESC_GOT,0)))
-           return FALSE;
-       }
-
-      if (relocs)
-       {
-         if (htab->use_rel)
-           {
-             if (!add_dynamic_entry (DT_REL, 0)
-                 || !add_dynamic_entry (DT_RELSZ, 0)
-                 || !add_dynamic_entry (DT_RELENT, RELOC_SIZE (htab)))
-               return FALSE;
-           }
-         else
-           {
-             if (!add_dynamic_entry (DT_RELA, 0)
-                 || !add_dynamic_entry (DT_RELASZ, 0)
-                 || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
-               return FALSE;
-           }
-       }
-
-      /* If any dynamic relocs apply to a read-only section,
-        then we need a DT_TEXTREL entry.  */
-      if ((info->flags & DF_TEXTREL) == 0)
-       elf_link_hash_traverse (& htab->root, elf32_arm_readonly_dynrelocs,
-                               info);
-
-      if ((info->flags & DF_TEXTREL) != 0)
-       {
-         if (!add_dynamic_entry (DT_TEXTREL, 0))
-           return FALSE;
-       }
-      if (htab->vxworks_p
-         && !elf_vxworks_add_dynamic_entries (output_bfd, info))
-       return FALSE;
+       return false;
     }
-#undef add_dynamic_entry
 
-  return TRUE;
+  return _bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info,
+                                                 relocs);
 }
 
 /* Size sections even though they're not dynamic.  We use it to setup
    _TLS_MODULE_BASE_, if needed.  */
 
-static bfd_boolean
+static bool
 elf32_arm_always_size_sections (bfd *output_bfd,
                                struct bfd_link_info *info)
 {
   asection *tls_sec;
+  struct elf32_arm_link_hash_table *htab;
+
+  htab = elf32_arm_hash_table (info);
 
   if (bfd_link_relocatable (info))
-    return TRUE;
+    return true;
 
   tls_sec = elf_hash_table (info)->tls_sec;
 
@@ -16052,7 +17065,7 @@ elf32_arm_always_size_sections (bfd *output_bfd,
       struct elf_link_hash_entry *tlsbase;
 
       tlsbase = elf_link_hash_lookup
-       (elf_hash_table (info), "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
+       (elf_hash_table (info), "_TLS_MODULE_BASE_", true, true, false);
 
       if (tlsbase)
        {
@@ -16062,24 +17075,30 @@ elf32_arm_always_size_sections (bfd *output_bfd,
 
          if (!(_bfd_generic_link_add_one_symbol
                (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
-                tls_sec, 0, NULL, FALSE,
+                tls_sec, 0, NULL, false,
                 bed->collect, &bh)))
-           return FALSE;
+           return false;
 
          tlsbase->type = STT_TLS;
          tlsbase = (struct elf_link_hash_entry *)bh;
          tlsbase->def_regular = 1;
          tlsbase->other = STV_HIDDEN;
-         (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+         (*bed->elf_backend_hide_symbol) (info, tlsbase, true);
        }
     }
-  return TRUE;
+
+  if (htab->fdpic_p && !bfd_link_relocatable (info)
+      && !bfd_elf_stack_segment_size (output_bfd, info,
+                                     "__stacksize", DEFAULT_STACK_SIZE))
+    return false;
+
+  return true;
 }
 
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
 
-static bfd_boolean
+static bool
 elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
                                 struct bfd_link_info * info,
                                 struct elf_link_hash_entry * h,
@@ -16090,7 +17109,7 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   eh = (struct elf32_arm_link_hash_entry *) h;
 
@@ -16101,7 +17120,7 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
          BFD_ASSERT (h->dynindx != -1);
          if (! elf32_arm_populate_plt_entry (output_bfd, info, &h->plt, &eh->plt,
                                              h->dynindx, 0))
-           return FALSE;
+           return false;
        }
 
       if (!h->def_regular)
@@ -16157,13 +17176,15 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  On VxWorks,
-     the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it is relative
-     to the ".got" section.  */
+     and for FDPIC, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute:
+     it is relative to the ".got" section.  */
   if (h == htab->root.hdynamic
-      || (!htab->vxworks_p && h == htab->root.hgot))
+      || (!htab->fdpic_p
+         && htab->root.target_os != is_vxworks
+         && h == htab->root.hgot))
     sym->st_shndx = SHN_ABS;
 
-  return TRUE;
+  return true;
 }
 
 static void
@@ -16218,7 +17239,7 @@ arm_nacl_put_plt0 (struct elf32_arm_link_hash_table *htab, bfd *output_bfd,
 
 /* Finish up the dynamic sections.  */
 
-static bfd_boolean
+static bool
 elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info)
 {
   bfd * dynobj;
@@ -16228,7 +17249,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -16236,7 +17257,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
   /* A broken linker script might have discarded the dynamic sections.
      Catch this here so that we do not seg-fault later on.  */
   if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
-    return FALSE;
+    return false;
   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
@@ -16246,7 +17267,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 
       splt = htab->root.splt;
       BFD_ASSERT (splt != NULL && sdyn != NULL);
-      BFD_ASSERT (htab->symbian_p || sgot != NULL);
+      BFD_ASSERT (sgot != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
@@ -16261,35 +17282,22 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 
          switch (dyn.d_tag)
            {
-             unsigned int type;
-
            default:
-             if (htab->vxworks_p
+             if (htab->root.target_os == is_vxworks
                  && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_HASH:
-             name = ".hash";
-             goto get_vma_if_bpabi;
            case DT_STRTAB:
-             name = ".dynstr";
-             goto get_vma_if_bpabi;
            case DT_SYMTAB:
-             name = ".dynsym";
-             goto get_vma_if_bpabi;
            case DT_VERSYM:
-             name = ".gnu.version";
-             goto get_vma_if_bpabi;
            case DT_VERDEF:
-             name = ".gnu.version_d";
-             goto get_vma_if_bpabi;
            case DT_VERNEED:
-             name = ".gnu.version_r";
-             goto get_vma_if_bpabi;
+             break;
 
            case DT_PLTGOT:
-             name = htab->symbian_p ? ".got" : ".got.plt";
+             name = ".got.plt";
              goto get_vma;
            case DT_JMPREL:
              name = RELOC_SECTION (htab, ".plt");
@@ -16300,23 +17308,12 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
                  _bfd_error_handler
                    (_("could not find section %s"), name);
                  bfd_set_error (bfd_error_invalid_operation);
-                 return FALSE;
+                 return false;
                }
-             if (!htab->symbian_p)
-               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
-             else
-               /* In the BPABI, tags in the PT_DYNAMIC section point
-                  at the file offset, not the memory address, for the
-                  convenience of the post linker.  */
-               dyn.d_un.d_ptr = s->output_section->filepos + s->output_offset;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
-           get_vma_if_bpabi:
-             if (htab->symbian_p)
-               goto get_vma;
-             break;
-
            case DT_PLTRELSZ:
              s = htab->root.srelplt;
              BFD_ASSERT (s != NULL);
@@ -16328,48 +17325,19 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
            case DT_RELASZ:
            case DT_REL:
            case DT_RELA:
-             /* In the BPABI, the DT_REL tag must point at the file
-                offset, not the VMA, of the first relocation
-                section.  So, we use code similar to that in
-                elflink.c, but do not check for SHF_ALLOC on the
-                relocation section, since relocation sections are
-                never allocated under the BPABI.  PLT relocs are also
-                included.  */
-             if (htab->symbian_p)
-               {
-                 unsigned int i;
-                 type = ((dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
-                         ? SHT_REL : SHT_RELA);
-                 dyn.d_un.d_val = 0;
-                 for (i = 1; i < elf_numsections (output_bfd); i++)
-                   {
-                     Elf_Internal_Shdr *hdr
-                       = elf_elfsections (output_bfd)[i];
-                     if (hdr->sh_type == type)
-                       {
-                         if (dyn.d_tag == DT_RELSZ
-                             || dyn.d_tag == DT_RELASZ)
-                           dyn.d_un.d_val += hdr->sh_size;
-                         else if ((ufile_ptr) hdr->sh_offset
-                                  <= dyn.d_un.d_val - 1)
-                           dyn.d_un.d_val = hdr->sh_offset;
-                       }
-                   }
-                 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
-               }
              break;
 
            case DT_TLSDESC_PLT:
              s = htab->root.splt;
              dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
-                               + htab->dt_tlsdesc_plt);
+                               + htab->root.tlsdesc_plt);
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_TLSDESC_GOT:
              s = htab->root.sgot;
              dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
-                               + htab->dt_tlsdesc_got);
+                               + htab->root.tlsdesc_got);
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
@@ -16388,7 +17356,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
                  struct elf_link_hash_entry * eh;
 
                  eh = elf_link_hash_lookup (elf_hash_table (info), name,
-                                            FALSE, FALSE, TRUE);
+                                            false, false, true);
                  if (eh != NULL
                      && ARM_GET_SYM_BRANCH_TYPE (eh->target_internal)
                         == ST_BRANCH_TO_THUMB)
@@ -16411,7 +17379,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
          got_address = sgot->output_section->vma + sgot->output_offset;
          plt_address = splt->output_section->vma + splt->output_offset;
 
-         if (htab->vxworks_p)
+         if (htab->root.target_os == is_vxworks)
            {
              /* The VxWorks GOT is relocated by the dynamic linker.
                 Therefore, we must emit relocations rather than simply
@@ -16434,7 +17402,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
              SWAP_RELOC_OUT (htab) (output_bfd, &rel,
                                     htab->srelplt2->contents);
            }
-         else if (htab->nacl_p)
+         else if (htab->root.target_os == is_nacl)
            arm_nacl_put_plt0 (htab, output_bfd, splt,
                               got_address + 8 - (plt_address + 16));
          else if (using_thumb_only (htab))
@@ -16480,7 +17448,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
       if (splt->output_section->owner == output_bfd)
        elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
 
-      if (htab->dt_tlsdesc_plt)
+      if (htab->root.tlsdesc_plt)
        {
          bfd_vma got_address
            = sgot->output_section->vma + sgot->output_offset;
@@ -16490,18 +17458,18 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
            = splt->output_section->vma + splt->output_offset;
 
          arm_put_trampoline (htab, output_bfd,
-                             splt->contents + htab->dt_tlsdesc_plt,
+                             splt->contents + htab->root.tlsdesc_plt,
                              dl_tlsdesc_lazy_trampoline, 6);
 
          bfd_put_32 (output_bfd,
-                     gotplt_address + htab->dt_tlsdesc_got
-                     - (plt_address + htab->dt_tlsdesc_plt)
+                     gotplt_address + htab->root.tlsdesc_got
+                     - (plt_address + htab->root.tlsdesc_plt)
                      - dl_tlsdesc_lazy_trampoline[6],
-                     splt->contents + htab->dt_tlsdesc_plt + 24);
+                     splt->contents + htab->root.tlsdesc_plt + 24);
          bfd_put_32 (output_bfd,
-                     got_address - (plt_address + htab->dt_tlsdesc_plt)
+                     got_address - (plt_address + htab->root.tlsdesc_plt)
                      - dl_tlsdesc_lazy_trampoline[7],
-                     splt->contents + htab->dt_tlsdesc_plt + 24 + 4);
+                     splt->contents + htab->root.tlsdesc_plt + 24 + 4);
        }
 
       if (htab->tls_trampoline)
@@ -16515,7 +17483,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 #endif
        }
 
-      if (htab->vxworks_p
+      if (htab->root.target_os == is_vxworks
          && !bfd_link_pic (info)
          && htab->root.splt->size > 0)
        {
@@ -16545,7 +17513,9 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
        }
     }
 
-  if (htab->nacl_p && htab->root.iplt != NULL && htab->root.iplt->size > 0)
+  if (htab->root.target_os == is_nacl
+      && htab->root.iplt != NULL
+      && htab->root.iplt->size > 0)
     /* NaCl uses a special first entry in .iplt too.  */
     arm_nacl_put_plt0 (htab, output_bfd, htab->root.iplt, 0);
 
@@ -16567,22 +17537,38 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
       elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
     }
 
-  return TRUE;
+  /* At the very end of the .rofixup section is a pointer to the GOT.  */
+  if (htab->fdpic_p && htab->srofixup != NULL)
+    {
+      struct elf_link_hash_entry *hgot = htab->root.hgot;
+
+      bfd_vma got_value = hgot->root.u.def.value
+       + hgot->root.u.def.section->output_section->vma
+       + hgot->root.u.def.section->output_offset;
+
+      arm_elf_add_rofixup (output_bfd, htab->srofixup, got_value);
+
+      /* Make sure we allocated and generated the same number of fixups.  */
+      BFD_ASSERT (htab->srofixup->reloc_count * 4 == htab->srofixup->size);
+    }
+
+  return true;
 }
 
-static void
-elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+static bool
+elf32_arm_init_file_header (bfd *abfd, struct bfd_link_info *link_info)
 {
   Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form.  */
   struct elf32_arm_link_hash_table *globals;
   struct elf_segment_map *m;
 
+  if (!_bfd_elf_init_file_header (abfd, link_info))
+    return false;
+
   i_ehdrp = elf_elfheader (abfd);
 
   if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_UNKNOWN)
     i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_ARM;
-  else
-    _bfd_elf_post_process_headers (abfd, link_info);
   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
 
   if (link_info)
@@ -16590,6 +17576,9 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
       globals = elf32_arm_hash_table (link_info);
       if (globals != NULL && globals->byteswap_code)
        i_ehdrp->e_flags |= EF_ARM_BE8;
+
+      if (globals->fdpic_p)
+       i_ehdrp->e_ident[EI_OSABI] |= ELFOSABI_ARM_FDPIC;
     }
 
   if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_VER5
@@ -16621,6 +17610,7 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
          m->p_flags_valid = 1;
        }
     }
+  return true;
 }
 
 static enum elf_reloc_type_class
@@ -16644,30 +17634,37 @@ elf32_arm_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
 }
 
 static void
-elf32_arm_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+arm_final_write_processing (bfd *abfd)
 {
   bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
 }
 
+static bool
+elf32_arm_final_write_processing (bfd *abfd)
+{
+  arm_final_write_processing (abfd);
+  return _bfd_elf_final_write_processing (abfd);
+}
+
 /* Return TRUE if this is an unwinding table entry.  */
 
-static bfd_boolean
+static bool
 is_arm_elf_unwind_section_name (bfd * abfd ATTRIBUTE_UNUSED, const char * name)
 {
-  return (CONST_STRNEQ (name, ELF_STRING_ARM_unwind)
-         || CONST_STRNEQ (name, ELF_STRING_ARM_unwind_once));
+  return (startswith (name, ELF_STRING_ARM_unwind)
+         || startswith (name, ELF_STRING_ARM_unwind_once));
 }
 
 
 /* Set the type and flags for an ARM section.  We do this by
    the section name, which is a hack, but ought to work.  */
 
-static bfd_boolean
+static bool
 elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
 {
   const char * name;
 
-  name = bfd_get_section_name (abfd, sec);
+  name = bfd_section_name (sec);
 
   if (is_arm_elf_unwind_section_name (abfd, name))
     {
@@ -16678,14 +17675,14 @@ elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
   if (sec->flags & SEC_ELF_PURECODE)
     hdr->sh_flags |= SHF_ARM_PURECODE;
 
-  return TRUE;
+  return true;
 }
 
 /* Handle an ARM specific section when reading an object file.  This is
    called when bfd_section_from_shdr finds a section with an unknown
    type.  */
 
-static bfd_boolean
+static bool
 elf32_arm_section_from_shdr (bfd *abfd,
                             Elf_Internal_Shdr * hdr,
                             const char *name,
@@ -16704,13 +17701,13 @@ elf32_arm_section_from_shdr (bfd *abfd,
       break;
 
     default:
-      return FALSE;
+      return false;
     }
 
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
-    return FALSE;
+    return false;
 
-  return TRUE;
+  return true;
 }
 
 static _arm_elf_section_data *
@@ -16742,7 +17739,7 @@ enum map_symbol_type
 
 /* Output a single mapping symbol.  */
 
-static bfd_boolean
+static bool
 elf32_arm_output_map_sym (output_arch_syminfo *osi,
                          enum map_symbol_type type,
                          bfd_vma offset)
@@ -16765,9 +17762,9 @@ elf32_arm_output_map_sym (output_arch_syminfo *osi,
 /* Output mapping symbols for the PLT entry described by ROOT_PLT and ARM_PLT.
    IS_IPLT_ENTRY_P says whether the PLT is in .iplt rather than .plt.  */
 
-static bfd_boolean
+static bool
 elf32_arm_output_plt_map_1 (output_arch_syminfo *osi,
-                           bfd_boolean is_iplt_entry_p,
+                           bool is_iplt_entry_p,
                            union gotplt_union *root_plt,
                            struct arm_plt_info *arm_plt)
 {
@@ -16775,11 +17772,11 @@ elf32_arm_output_plt_map_1 (output_arch_syminfo *osi,
   bfd_vma addr, plt_header_size;
 
   if (root_plt->offset == (bfd_vma) -1)
-    return TRUE;
+    return true;
 
   htab = elf32_arm_hash_table (osi->info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   if (is_iplt_entry_p)
     {
@@ -16795,49 +17792,59 @@ elf32_arm_output_plt_map_1 (output_arch_syminfo *osi,
                    (osi->info->output_bfd, osi->sec->output_section));
 
   addr = root_plt->offset & -2;
-  if (htab->symbian_p)
-    {
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
-      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
-       return FALSE;
-    }
-  else if (htab->vxworks_p)
+  if (htab->root.target_os == is_vxworks)
     {
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
+       return false;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
-       return FALSE;
+       return false;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 12))
-       return FALSE;
+       return false;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 20))
-       return FALSE;
+       return false;
     }
-  else if (htab->nacl_p)
+  else if (htab->root.target_os == is_nacl)
     {
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
+       return false;
+    }
+  else if (htab->fdpic_p)
+    {
+      enum map_symbol_type type = using_thumb_only (htab)
+       ? ARM_MAP_THUMB
+       : ARM_MAP_ARM;
+
+      if (elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt))
+       if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
+         return false;
+      if (!elf32_arm_output_map_sym (osi, type, addr))
+       return false;
+      if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16))
+       return false;
+      if (htab->plt_entry_size == 4 * ARRAY_SIZE (elf32_arm_fdpic_plt_entry))
+       if (!elf32_arm_output_map_sym (osi, type, addr + 24))
+         return false;
     }
   else if (using_thumb_only (htab))
     {
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
-       return FALSE;
+       return false;
     }
   else
     {
-      bfd_boolean thumb_stub_p;
+      bool thumb_stub_p;
 
       thumb_stub_p = elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt);
       if (thumb_stub_p)
        {
          if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
-           return FALSE;
+           return false;
        }
 #ifdef FOUR_WORD_PLT
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-       return FALSE;
+       return false;
       if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
-       return FALSE;
+       return false;
 #else
       /* A three-word PLT with no Thumb thunk contains only Arm code,
         so only need to output a mapping symbol for the first PLT entry and
@@ -16845,24 +17852,24 @@ elf32_arm_output_plt_map_1 (output_arch_syminfo *osi,
       if (thumb_stub_p || addr == plt_header_size)
        {
          if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
-           return FALSE;
+           return false;
        }
 #endif
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Output mapping symbols for PLT entries associated with H.  */
 
-static bfd_boolean
+static bool
 elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
 {
   output_arch_syminfo *osi = (output_arch_syminfo *) inf;
   struct elf32_arm_link_hash_entry *eh;
 
   if (h->root.type == bfd_link_hash_indirect)
-    return TRUE;
+    return true;
 
   if (h->root.type == bfd_link_hash_warning)
     /* When warning symbols are created, they **replace** the "real"
@@ -16891,7 +17898,7 @@ arm_stub_claim_sym (struct elf32_arm_stub_hash_entry *stub_entry)
 
 /* Output a single local symbol for a generated stub.  */
 
-static bfd_boolean
+static bool
 elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
                           bfd_vma offset, bfd_vma size)
 {
@@ -16908,7 +17915,7 @@ elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
   return osi->func (osi->flaginfo, name, &sym, osi->sec, NULL) == 1;
 }
 
-static bfd_boolean
+static bool
 arm_map_one_stub (struct bfd_hash_entry * gen_entry,
                  void * in_arg)
 {
@@ -16932,7 +17939,7 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
   /* Ensure this stub is attached to the current section being
      processed.  */
   if (stub_sec != osi->sec)
-    return TRUE;
+    return true;
 
   addr = (bfd_vma) stub_entry->stub_offset;
   template_sequence = stub_entry->stub_template;
@@ -16947,13 +17954,13 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
        case ARM_TYPE:
          if (!elf32_arm_output_stub_sym (osi, stub_name, addr,
                                          stub_entry->stub_size))
-           return FALSE;
+           return false;
          break;
        case THUMB16_TYPE:
        case THUMB32_TYPE:
          if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
                                          stub_entry->stub_size))
-           return FALSE;
+           return false;
          break;
        default:
          BFD_FAIL ();
@@ -16982,14 +17989,14 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
 
        default:
          BFD_FAIL ();
-         return FALSE;
+         return false;
        }
 
       if (template_sequence[i].type != prev_type)
        {
          prev_type = template_sequence[i].type;
          if (!elf32_arm_output_map_sym (osi, sym_type, addr + size))
-           return FALSE;
+           return false;
        }
 
       switch (template_sequence[i].type)
@@ -17009,18 +18016,18 @@ arm_map_one_stub (struct bfd_hash_entry * gen_entry,
 
        default:
          BFD_FAIL ();
-         return FALSE;
+         return false;
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Output mapping symbols for linker generated sections,
    and for those data-only sections that do not have a
    $d.  */
 
-static bfd_boolean
+static bool
 elf32_arm_output_arch_local_syms (bfd *output_bfd,
                                  struct bfd_link_info *info,
                                  void *flaginfo,
@@ -17037,7 +18044,7 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
 
   htab = elf32_arm_hash_table (info);
   if (htab == NULL)
-    return FALSE;
+    return false;
 
   check_use_blx (htab);
 
@@ -17156,51 +18163,52 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
       osi.sec_shndx = (_bfd_elf_section_from_bfd_section
                       (output_bfd, osi.sec->output_section));
 
-      /* Output mapping symbols for the plt header.  SymbianOS does not have a
-        plt header.  */
-      if (htab->vxworks_p)
+      /* Output mapping symbols for the plt header.  */
+      if (htab->root.target_os == is_vxworks)
        {
          /* VxWorks shared libraries have no PLT header.  */
          if (!bfd_link_pic (info))
            {
              if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
-               return FALSE;
+               return false;
              if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
-               return FALSE;
+               return false;
            }
        }
-      else if (htab->nacl_p)
+      else if (htab->root.target_os == is_nacl)
        {
          if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
-           return FALSE;
+           return false;
        }
-      else if (using_thumb_only (htab))
+      else if (using_thumb_only (htab) && !htab->fdpic_p)
        {
          if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 0))
-           return FALSE;
+           return false;
          if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
-           return FALSE;
+           return false;
          if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 16))
-           return FALSE;
+           return false;
        }
-      else if (!htab->symbian_p)
+      else if (!htab->fdpic_p)
        {
          if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
-           return FALSE;
+           return false;
 #ifndef FOUR_WORD_PLT
          if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 16))
-           return FALSE;
+           return false;
 #endif
        }
     }
-  if (htab->nacl_p && htab->root.iplt && htab->root.iplt->size > 0)
+  if (htab->root.target_os == is_nacl
+      && htab->root.iplt
+      && htab->root.iplt->size > 0)
     {
       /* NaCl uses a special first entry in .iplt too.  */
       osi.sec = htab->root.iplt;
       osi.sec_shndx = (_bfd_elf_section_from_bfd_section
                       (output_bfd, osi.sec->output_section));
       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
-       return FALSE;
+       return false;
     }
   if ((htab->root.splt && htab->root.splt->size > 0)
       || (htab->root.iplt && htab->root.iplt->size > 0))
@@ -17217,38 +18225,48 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
          if (local_iplt != NULL)
            {
              num_syms = elf_symtab_hdr (input_bfd).sh_info;
+             if (num_syms > elf32_arm_num_entries (input_bfd))
+               {
+                 _bfd_error_handler (_("\
+%pB: Number of symbols in input file has increased from %lu to %u\n"),
+                                     input_bfd,
+                                     (unsigned long) elf32_arm_num_entries (input_bfd),
+                                     num_syms);
+                 return false;
+               }
              for (i = 0; i < num_syms; i++)
                if (local_iplt[i] != NULL
-                   && !elf32_arm_output_plt_map_1 (&osi, TRUE,
+                   && !elf32_arm_output_plt_map_1 (&osi, true,
                                                    &local_iplt[i]->root,
                                                    &local_iplt[i]->arm))
-                 return FALSE;
+                 return false;
            }
        }
     }
-  if (htab->dt_tlsdesc_plt != 0)
+  if (htab->root.tlsdesc_plt != 0)
     {
       /* Mapping symbols for the lazy tls trampoline.  */
-      if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->dt_tlsdesc_plt))
-       return FALSE;
+      if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM,
+                                    htab->root.tlsdesc_plt))
+       return false;
 
       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA,
-                                    htab->dt_tlsdesc_plt + 24))
-       return FALSE;
+                                    htab->root.tlsdesc_plt + 24))
+       return false;
     }
   if (htab->tls_trampoline != 0)
     {
       /* Mapping symbols for the tls trampoline.  */
       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->tls_trampoline))
-       return FALSE;
+       return false;
 #ifdef FOUR_WORD_PLT
       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA,
                                     htab->tls_trampoline + 12))
-       return FALSE;
+       return false;
 #endif
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Filter normal symbols of CMSE entry functions of ABFD to include in
@@ -17274,6 +18292,8 @@ elf32_arm_filter_cmse_symbols (bfd *abfd ATTRIBUTE_UNUSED,
 
   maxnamelen = 128;
   cmse_name = (char *) bfd_malloc (maxnamelen);
+  BFD_ASSERT (cmse_name);
+
   for (src_count = 0; src_count < symcount; src_count++)
     {
       struct elf32_arm_link_hash_entry *cmse_hash;
@@ -17300,7 +18320,7 @@ elf32_arm_filter_cmse_symbols (bfd *abfd ATTRIBUTE_UNUSED,
        }
       snprintf (cmse_name, maxnamelen, "%s%s", CMSE_PREFIX, name);
       cmse_hash = (struct elf32_arm_link_hash_entry *)
-       elf_link_hash_lookup (&(htab)->root, cmse_name, FALSE, FALSE, TRUE);
+       elf_link_hash_lookup (&(htab)->root, cmse_name, false, false, true);
 
       if (!cmse_hash
          || (cmse_hash->root.root.type != bfd_link_hash_defined
@@ -17308,9 +18328,6 @@ elf32_arm_filter_cmse_symbols (bfd *abfd ATTRIBUTE_UNUSED,
          || cmse_hash->root.type != STT_FUNC)
        continue;
 
-      if (!ARM_GET_SYM_CMSE_SPCL (cmse_hash->root.target_internal))
-       continue;
-
       syms[dst_count++] = sym;
     }
   free (cmse_name);
@@ -17346,17 +18363,17 @@ elf32_arm_filter_implib_symbols (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Allocate target specific section data.  */
 
-static bfd_boolean
+static bool
 elf32_arm_new_section_hook (bfd *abfd, asection *sec)
 {
   if (!sec->used_by_bfd)
     {
       _arm_elf_section_data *sdata;
-      bfd_size_type amt = sizeof (*sdata);
+      size_t amt = sizeof (*sdata);
 
       sdata = (_arm_elf_section_data *) bfd_zalloc (abfd, amt);
       if (sdata == NULL)
-       return FALSE;
+       return false;
       sec->used_by_bfd = sdata;
     }
 
@@ -17429,7 +18446,7 @@ struct a8_branch_to_stub_data
 /* Helper to insert branches to Cortex-A8 erratum stubs in the right
    places for a particular section.  */
 
-static bfd_boolean
+static bool
 make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
                       void *in_arg)
 {
@@ -17447,7 +18464,7 @@ make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
 
   if (stub_entry->target_section != data->writing_section
       || stub_entry->stub_type < arm_stub_a8_veneer_lwm)
-    return TRUE;
+    return true;
 
   contents = data->contents;
 
@@ -17474,9 +18491,9 @@ make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
      This check is just to be on the safe side...  */
   if ((veneered_insn_loc & ~0xfff) == (veneer_entry_loc & ~0xfff))
     {
-      _bfd_error_handler (_("%B: error: Cortex-A8 erratum stub is "
+      _bfd_error_handler (_("%pB: error: Cortex-A8 erratum stub is "
                            "allocated in unsafe location"), abfd);
-      return FALSE;
+      return false;
     }
 
   switch (stub_entry->stub_type)
@@ -17501,9 +18518,9 @@ make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
          {
            /* There's not much we can do apart from complain if this
               happens.  */
-           _bfd_error_handler (_("%B: error: Cortex-A8 erratum stub out "
+           _bfd_error_handler (_("%pB: error: Cortex-A8 erratum stub out "
                                  "of range (input file too large)"), abfd);
-           return FALSE;
+           return false;
          }
 
        /* i1 = not(j1 eor s), so:
@@ -17525,13 +18542,13 @@ make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
 
     default:
       BFD_FAIL ();
-      return FALSE;
+      return false;
     }
 
   bfd_put_16 (abfd, (branch_insn >> 16) & 0xffff, &contents[loc]);
   bfd_put_16 (abfd, branch_insn & 0xffff, &contents[loc + 2]);
 
-  return TRUE;
+  return true;
 }
 
 /* Beginning of stm32l4xx work-around.  */
@@ -17702,10 +18719,10 @@ push_thumb2_insn16 (struct elf32_arm_link_hash_table * htab,
 
 static bfd_byte *
 stm32l4xx_fill_stub_udf (struct elf32_arm_link_hash_table * htab,
-                        bfd *                   output_bfd,
-                        const bfd_byte * const  base_stub_contents,
-                        bfd_byte * const        from_stub_contents,
-                        const bfd_byte * const  end_stub_contents)
+                        bfd *                   output_bfd,
+                        const bfd_byte * const  base_stub_contents,
+                        bfd_byte * const        from_stub_contents,
+                        const bfd_byte * const  end_stub_contents)
 {
   bfd_byte *current_stub_contents = from_stub_contents;
 
@@ -18128,7 +19145,7 @@ stm32l4xx_create_replacing_stub_vldm (struct elf32_arm_link_hash_table * htab,
                                      const bfd_byte *const initial_insn_addr,
                                      bfd_byte *const base_stub_contents)
 {
-  int num_words = ((unsigned int) initial_insn << 24) >> 24;
+  int num_words = initial_insn & 0xff;
   bfd_byte *current_stub_contents = base_stub_contents;
 
   BFD_ASSERT (is_thumb2_vldm (initial_insn));
@@ -18151,13 +19168,13 @@ stm32l4xx_create_replacing_stub_vldm (struct elf32_arm_link_hash_table * htab,
     }
   else
     {
-      bfd_boolean is_dp = /* DP encoding.  */
+      bool is_dp = /* DP encoding.  */
        (initial_insn & 0xfe100f00) == 0xec100b00;
-      bfd_boolean is_ia_nobang = /* (IA without !).  */
+      bool is_ia_nobang = /* (IA without !).  */
        (((initial_insn << 7) >> 28) & 0xd) == 0x4;
-      bfd_boolean is_ia_bang = /* (IA with !) - includes VPOP.  */
+      bool is_ia_bang = /* (IA with !) - includes VPOP.  */
        (((initial_insn << 7) >> 28) & 0xd) == 0x5;
-      bfd_boolean is_db_bang = /* (DB with !).  */
+      bool is_db_bang = /* (DB with !).  */
        (((initial_insn << 7) >> 28) & 0xd) == 0x9;
       int base_reg = ((unsigned int) initial_insn << 12) >> 28;
       /* d = UInt (Vd:D);.  */
@@ -18269,7 +19286,7 @@ stm32l4xx_create_replacing_stub (struct elf32_arm_link_hash_table * htab,
 /* Do code byteswapping.  Return FALSE afterwards so that the section is
    written out as normal.  */
 
-static bfd_boolean
+static bool
 elf32_arm_write_section (bfd *output_bfd,
                         struct bfd_link_info *link_info,
                         asection *sec,
@@ -18288,13 +19305,13 @@ elf32_arm_write_section (bfd *output_bfd,
   unsigned int i;
 
   if (globals == NULL)
-    return FALSE;
+    return false;
 
   /* If this section has not been allocated an _arm_elf_section_data
      structure then we cannot record anything.  */
   arm_data = get_arm_elf_section_data (sec);
   if (arm_data == NULL)
-    return FALSE;
+    return false;
 
   mapcount = arm_data->mapcount;
   map = arm_data->map;
@@ -18328,7 +19345,7 @@ elf32_arm_write_section (bfd *output_bfd,
 
                if ((signed) branch_to_veneer < -(1 << 25)
                    || (signed) branch_to_veneer >= (1 << 25))
-                 _bfd_error_handler (_("%B: error: VFP11 veneer out of "
+                 _bfd_error_handler (_("%pB: error: VFP11 veneer out of "
                                        "range"), output_bfd);
 
                insn |= (branch_to_veneer >> 2) & 0xffffff;
@@ -18350,7 +19367,7 @@ elf32_arm_write_section (bfd *output_bfd,
 
                if ((signed) branch_from_veneer < -(1 << 25)
                    || (signed) branch_from_veneer >= (1 << 25))
-                 _bfd_error_handler (_("%B: error: VFP11 veneer out of "
+                 _bfd_error_handler (_("%pB: error: VFP11 veneer out of "
                                        "range"), output_bfd);
 
                /* Original instruction.  */
@@ -18401,12 +19418,13 @@ elf32_arm_write_section (bfd *output_bfd,
                      branch_to_veneer - (1 << 24) : 0;
 
                    _bfd_error_handler
-                     (_("%B(%#Lx): error: Cannot create STM32L4XX veneer. "
-                        "Jump out of range by %Ld bytes. "
-                        "Cannot encode branch instruction. "),
+                     (_("%pB(%#" PRIx64 "): error: "
+                        "cannot create STM32L4XX veneer; "
+                        "jump out of range by %" PRId64 " bytes; "
+                        "cannot encode branch instruction"),
                       output_bfd,
-                      stm32l4xx_errnode->vma - 4,
-                      out_of_range);
+                      (uint64_t) (stm32l4xx_errnode->vma - 4),
+                      (int64_t) out_of_range);
                    continue;
                  }
 
@@ -18439,8 +19457,8 @@ elf32_arm_write_section (bfd *output_bfd,
                              STM32L4XX_ERRATUM_LDM_VENEER_SIZE) < -(1 << 24)
                    || (signed) (veneer_r - veneer) >= (1 << 24))
                  {
-                   _bfd_error_handler (_("%B: error: Cannot create STM32L4XX "
-                                         "veneer."), output_bfd);
+                   _bfd_error_handler (_("%pB: error: cannot create STM32L4XX "
+                                         "veneer"), output_bfd);
                     continue;
                  }
 
@@ -18471,6 +19489,8 @@ elf32_arm_write_section (bfd *output_bfd,
       unsigned int in_index, out_index;
       bfd_vma add_to_offsets = 0;
 
+      if (edited_contents == NULL)
+       return false;
       for (in_index = 0, out_index = 0; in_index * 8 < input_size || edit_node;)
        {
          if (edit_node)
@@ -18551,7 +19571,7 @@ elf32_arm_write_section (bfd *output_bfd,
                                  edited_contents,
                                  (file_ptr) sec->output_offset, sec->size);
 
-      return TRUE;
+      return true;
     }
 
   /* Fix code to point to Cortex-A8 erratum stubs.  */
@@ -18567,7 +19587,7 @@ elf32_arm_write_section (bfd *output_bfd,
     }
 
   if (mapcount == 0)
-    return FALSE;
+    return false;
 
   if (globals->byteswap_code)
     {
@@ -18621,22 +19641,19 @@ elf32_arm_write_section (bfd *output_bfd,
   arm_data->mapsize = 0;
   arm_data->map = NULL;
 
-  return FALSE;
+  return false;
 }
 
 /* Mangle thumb function symbols as we read them in.  */
 
-static bfd_boolean
+static bool
 elf32_arm_swap_symbol_in (bfd * abfd,
                          const void *psrc,
                          const void *pshn,
                          Elf_Internal_Sym *dst)
 {
-  Elf_Internal_Shdr *symtab_hdr;
-  const char *name = NULL;
-
   if (!bfd_elf32_swap_symbol_in (abfd, psrc, pshn, dst))
-    return FALSE;
+    return false;
   dst->st_target_internal = 0;
 
   /* New EABI objects mark thumb function symbols by setting the low bit of
@@ -18663,14 +19680,7 @@ elf32_arm_swap_symbol_in (bfd * abfd,
   else
     ARM_SET_SYM_BRANCH_TYPE (dst->st_target_internal, ST_BRANCH_UNKNOWN);
 
-  /* Mark CMSE special symbols.  */
-  symtab_hdr = & elf_symtab_hdr (abfd);
-  if (symtab_hdr->sh_size)
-    name = bfd_elf_sym_name (abfd, symtab_hdr, dst, NULL);
-  if (name && CONST_STRNEQ (name, CMSE_PREFIX))
-    ARM_SET_SYM_CMSE_SPCL (dst->st_target_internal);
-
-  return TRUE;
+  return true;
 }
 
 
@@ -18713,7 +19723,7 @@ elf32_arm_swap_symbol_out (bfd *abfd,
 
 /* Add the PT_ARM_EXIDX program header.  */
 
-static bfd_boolean
+static bool
 elf32_arm_modify_segment_map (bfd *abfd,
                              struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
@@ -18734,7 +19744,7 @@ elf32_arm_modify_segment_map (bfd *abfd,
          m = (struct elf_segment_map *)
              bfd_zalloc (abfd, sizeof (struct elf_segment_map));
          if (m == NULL)
-           return FALSE;
+           return false;
          m->p_type = PT_ARM_EXIDX;
          m->count = 1;
          m->sections[0] = sec;
@@ -18744,7 +19754,7 @@ elf32_arm_modify_segment_map (bfd *abfd,
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* We may add a PT_ARM_EXIDX program header.  */
@@ -18765,25 +19775,20 @@ elf32_arm_additional_program_headers (bfd *abfd,
 /* Hook called by the linker routine which adds symbols from an object
    file.  */
 
-static bfd_boolean
+static bool
 elf32_arm_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
                           Elf_Internal_Sym *sym, const char **namep,
                           flagword *flagsp, asection **secp, bfd_vma *valp)
 {
-  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
-      && (abfd->flags & DYNAMIC) == 0
-      && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
-    elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
-
   if (elf32_arm_hash_table (info) == NULL)
-    return FALSE;
+    return false;
 
-  if (elf32_arm_hash_table (info)->vxworks_p
+  if (elf32_arm_hash_table (info)->root.target_os == is_vxworks
       && !elf_vxworks_add_symbol_hook (abfd, info, sym, namep,
                                       flagsp, secp, valp))
-    return FALSE;
+    return false;
 
-  return TRUE;
+  return true;
 }
 
 /* We use this to override swap_symbol_in and swap_symbol_out.  */
@@ -18877,7 +19882,7 @@ elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset)
   /* Respect Thumb stub if necessary.  */
   if (read_code16 (abfd, addr) == elf32_arm_plt_thumb_stub[0])
     {
-      plt_size += 2 * ARRAY_SIZE(elf32_arm_plt_thumb_stub);
+      plt_size += 2 * ARRAY_SIZE (elf32_arm_plt_thumb_stub);
     }
 
   /* Strip immediate from first add.  */
@@ -18941,15 +19946,15 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
   if (plt == NULL)
     return 0;
 
-  if (!elf32_arm_size_info.slurp_reloc_table (abfd, relplt, dynsyms, TRUE))
+  if (!elf32_arm_size_info.slurp_reloc_table (abfd, relplt, dynsyms, true))
     return -1;
 
   data = plt->contents;
   if (data == NULL)
     {
-      if (!bfd_get_full_section_contents(abfd, (asection *) plt, &data) || data == NULL)
+      if (!bfd_get_full_section_contents (abfd, (asection *) plt, &data) || data == NULL)
        return -1;
-      bfd_cache_section_contents((asection *) plt, data);
+      bfd_cache_section_contents ((asection *) plt, data);
     }
 
   count = relplt->size / hdr->sh_entsize;
@@ -19016,12 +20021,12 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
   return n;
 }
 
-static bfd_boolean
-elf32_arm_section_flags (flagword *flags, const Elf_Internal_Shdr * hdr)
+static bool
+elf32_arm_section_flags (const Elf_Internal_Shdr *hdr)
 {
   if (hdr->sh_flags & SHF_ARM_PURECODE)
-    *flags |= SEC_ELF_PURECODE;
-  return TRUE;
+    hdr->bfd_section->flags |= SEC_ELF_PURECODE;
+  return true;
 }
 
 static flagword
@@ -19047,7 +20052,7 @@ elf32_arm_count_additional_relocs (asection *sec)
    FALSE otherwise.  ISECTION is the best guess matching section from the
    input bfd IBFD, but it might be NULL.  */
 
-static bfd_boolean
+static bool
 elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
                                       bfd *obfd ATTRIBUTE_UNUSED,
                                       const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
@@ -19114,7 +20119,7 @@ elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
               then the index section should be too.  */
            if (oheaders[i]->sh_flags & SHF_GROUP)
              osection->sh_flags |= SHF_GROUP;
-           return TRUE;
+           return true;
          }
       }
       break;
@@ -19130,7 +20135,7 @@ elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
       break;
     }
 
-  return FALSE;
+  return false;
 }
 
 /* Returns TRUE if NAME is an ARM mapping symbol.
@@ -19140,7 +20145,7 @@ elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
    Other tools might also produce $b (Thumb BL), $f, $p, $m and $v, but we do
    not support them here.  $t.x indicates the start of ThumbEE instructions.  */
 
-static bfd_boolean
+static bool
 is_arm_mapping_symbol (const char * name)
 {
   return name != NULL /* Paranoia.  */
@@ -19184,49 +20189,49 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym)
 #define ELF_MINPAGESIZE                        0x1000
 #define ELF_COMMONPAGESIZE             0x1000
 
-#define bfd_elf32_mkobject                     elf32_arm_mkobject
+#define bfd_elf32_mkobject                     elf32_arm_mkobject
 
 #define bfd_elf32_bfd_copy_private_bfd_data    elf32_arm_copy_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   elf32_arm_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags                elf32_arm_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data   elf32_arm_print_private_bfd_data
-#define bfd_elf32_bfd_link_hash_table_create    elf32_arm_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create   elf32_arm_link_hash_table_create
 #define bfd_elf32_bfd_reloc_type_lookup                elf32_arm_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup                elf32_arm_reloc_name_lookup
-#define bfd_elf32_find_nearest_line            elf32_arm_find_nearest_line
-#define bfd_elf32_find_inliner_info            elf32_arm_find_inliner_info
+#define bfd_elf32_find_inliner_info            elf32_arm_find_inliner_info
 #define bfd_elf32_new_section_hook             elf32_arm_new_section_hook
 #define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
 #define bfd_elf32_bfd_final_link               elf32_arm_final_link
-#define bfd_elf32_get_synthetic_symtab  elf32_arm_get_synthetic_symtab
+#define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab
 
-#define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
-#define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
+#define elf_backend_get_symbol_type            elf32_arm_get_symbol_type
+#define elf_backend_maybe_function_sym         elf32_arm_maybe_function_sym
+#define elf_backend_gc_mark_hook               elf32_arm_gc_mark_hook
 #define elf_backend_gc_mark_extra_sections     elf32_arm_gc_mark_extra_sections
-#define elf_backend_check_relocs                elf32_arm_check_relocs
+#define elf_backend_check_relocs               elf32_arm_check_relocs
 #define elf_backend_update_relocs              elf32_arm_update_relocs
 #define elf_backend_relocate_section           elf32_arm_relocate_section
 #define elf_backend_write_section              elf32_arm_write_section
 #define elf_backend_adjust_dynamic_symbol      elf32_arm_adjust_dynamic_symbol
-#define elf_backend_create_dynamic_sections     elf32_arm_create_dynamic_sections
+#define elf_backend_create_dynamic_sections    elf32_arm_create_dynamic_sections
 #define elf_backend_finish_dynamic_symbol      elf32_arm_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections    elf32_arm_finish_dynamic_sections
 #define elf_backend_size_dynamic_sections      elf32_arm_size_dynamic_sections
 #define elf_backend_always_size_sections       elf32_arm_always_size_sections
 #define elf_backend_init_index_section         _bfd_elf_init_2_index_sections
-#define elf_backend_post_process_headers       elf32_arm_post_process_headers
+#define elf_backend_init_file_header           elf32_arm_init_file_header
 #define elf_backend_reloc_type_class           elf32_arm_reloc_type_class
 #define elf_backend_object_p                   elf32_arm_object_p
-#define elf_backend_fake_sections              elf32_arm_fake_sections
-#define elf_backend_section_from_shdr                  elf32_arm_section_from_shdr
-#define elf_backend_final_write_processing      elf32_arm_final_write_processing
-#define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
+#define elf_backend_fake_sections              elf32_arm_fake_sections
+#define elf_backend_section_from_shdr          elf32_arm_section_from_shdr
+#define elf_backend_final_write_processing     elf32_arm_final_write_processing
+#define elf_backend_copy_indirect_symbol       elf32_arm_copy_indirect_symbol
 #define elf_backend_size_info                  elf32_arm_size_info
 #define elf_backend_modify_segment_map         elf32_arm_modify_segment_map
-#define elf_backend_additional_program_headers  elf32_arm_additional_program_headers
-#define elf_backend_output_arch_local_syms      elf32_arm_output_arch_local_syms
+#define elf_backend_additional_program_headers elf32_arm_additional_program_headers
+#define elf_backend_output_arch_local_syms     elf32_arm_output_arch_local_syms
 #define elf_backend_filter_implib_symbols      elf32_arm_filter_implib_symbols
-#define elf_backend_begin_write_processing      elf32_arm_begin_write_processing
+#define elf_backend_begin_write_processing     elf32_arm_begin_write_processing
 #define elf_backend_add_symbol_hook            elf32_arm_add_symbol_hook
 #define elf_backend_count_additional_relocs    elf32_arm_count_additional_relocs
 #define elf_backend_symbol_processing          elf32_arm_backend_symbol_processing
@@ -19245,23 +20250,23 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym)
 #define elf_backend_got_header_size    12
 #define elf_backend_extern_protected_data 1
 
-#undef  elf_backend_obj_attrs_vendor
+#undef elf_backend_obj_attrs_vendor
 #define elf_backend_obj_attrs_vendor           "aeabi"
-#undef  elf_backend_obj_attrs_section
+#undef elf_backend_obj_attrs_section
 #define elf_backend_obj_attrs_section          ".ARM.attributes"
-#undef  elf_backend_obj_attrs_arg_type
+#undef elf_backend_obj_attrs_arg_type
 #define elf_backend_obj_attrs_arg_type         elf32_arm_obj_attrs_arg_type
-#undef  elf_backend_obj_attrs_section_type
+#undef elf_backend_obj_attrs_section_type
 #define elf_backend_obj_attrs_section_type     SHT_ARM_ATTRIBUTES
 #define elf_backend_obj_attrs_order            elf32_arm_obj_attrs_order
-#define elf_backend_obj_attrs_handle_unknown   elf32_arm_obj_attrs_handle_unknown
+#define elf_backend_obj_attrs_handle_unknown   elf32_arm_obj_attrs_handle_unknown
 
-#undef  elf_backend_section_flags
+#undef elf_backend_section_flags
 #define elf_backend_section_flags              elf32_arm_section_flags
-#undef  elf_backend_lookup_section_flags_hook
-#define elf_backend_lookup_section_flags_hook   elf32_arm_lookup_section_flags
+#undef elf_backend_lookup_section_flags_hook
+#define elf_backend_lookup_section_flags_hook  elf32_arm_lookup_section_flags
 
-#define elf_backend_linux_prpsinfo32_ugid16    TRUE
+#define elf_backend_linux_prpsinfo32_ugid16    true
 
 #include "elf32-target.h"
 
@@ -19290,8 +20295,6 @@ elf32_arm_nacl_link_hash_table_create (bfd *abfd)
       struct elf32_arm_link_hash_table *htab
        = (struct elf32_arm_link_hash_table *) ret;
 
-      htab->nacl_p = 1;
-
       htab->plt_header_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt0_entry);
       htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt_entry);
     }
@@ -19302,18 +20305,18 @@ elf32_arm_nacl_link_hash_table_create (bfd *abfd)
    really need to use elf32_arm_modify_segment_map.  But we do it
    anyway just to reduce gratuitous differences with the stock ARM backend.  */
 
-static bfd_boolean
+static bool
 elf32_arm_nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
 {
   return (elf32_arm_modify_segment_map (abfd, info)
          && nacl_modify_segment_map (abfd, info));
 }
 
-static void
-elf32_arm_nacl_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bool
+elf32_arm_nacl_final_write_processing (bfd *abfd)
 {
-  elf32_arm_final_write_processing (abfd, linker);
-  nacl_final_write_processing (abfd, linker);
+  arm_final_write_processing (abfd);
+  return nacl_final_write_processing (abfd);
 }
 
 static bfd_vma
@@ -19334,8 +20337,8 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #define elf_backend_plt_alignment              4
 #undef elf_backend_modify_segment_map
 #define        elf_backend_modify_segment_map          elf32_arm_nacl_modify_segment_map
-#undef elf_backend_modify_program_headers
-#define        elf_backend_modify_program_headers      nacl_modify_program_headers
+#undef elf_backend_modify_headers
+#define        elf_backend_modify_headers              nacl_modify_headers
 #undef  elf_backend_final_write_processing
 #define elf_backend_final_write_processing     elf32_arm_nacl_final_write_processing
 #undef bfd_elf32_get_synthetic_symtab
@@ -19346,6 +20349,8 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #undef ELF_MINPAGESIZE
 #undef ELF_COMMONPAGESIZE
 
+#undef ELF_TARGET_OS
+#define ELF_TARGET_OS                          is_nacl
 
 #include "elf32-target.h"
 
@@ -19353,7 +20358,7 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #undef elf_backend_plt_alignment
 #undef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map         elf32_arm_modify_segment_map
-#undef elf_backend_modify_program_headers
+#undef elf_backend_modify_headers
 #undef  elf_backend_final_write_processing
 #define elf_backend_final_write_processing     elf32_arm_final_write_processing
 #undef ELF_MINPAGESIZE
@@ -19362,16 +20367,90 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #define ELF_COMMONPAGESIZE             0x1000
 
 
-/* VxWorks Targets.  */
+/* FDPIC Targets.  */
 
 #undef  TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM               arm_elf32_vxworks_le_vec
+#define TARGET_LITTLE_SYM              arm_elf32_fdpic_le_vec
 #undef  TARGET_LITTLE_NAME
-#define TARGET_LITTLE_NAME              "elf32-littlearm-vxworks"
+#define TARGET_LITTLE_NAME             "elf32-littlearm-fdpic"
 #undef  TARGET_BIG_SYM
-#define TARGET_BIG_SYM                  arm_elf32_vxworks_be_vec
+#define TARGET_BIG_SYM                 arm_elf32_fdpic_be_vec
 #undef  TARGET_BIG_NAME
-#define TARGET_BIG_NAME                 "elf32-bigarm-vxworks"
+#define TARGET_BIG_NAME                        "elf32-bigarm-fdpic"
+#undef elf_match_priority
+#define elf_match_priority             128
+#undef ELF_OSABI
+#define ELF_OSABI              ELFOSABI_ARM_FDPIC
+
+/* Like elf32_arm_link_hash_table_create -- but overrides
+   appropriately for FDPIC.  */
+
+static struct bfd_link_hash_table *
+elf32_arm_fdpic_link_hash_table_create (bfd *abfd)
+{
+  struct bfd_link_hash_table *ret;
+
+  ret = elf32_arm_link_hash_table_create (abfd);
+  if (ret)
+    {
+      struct elf32_arm_link_hash_table *htab = (struct elf32_arm_link_hash_table *) ret;
+
+      htab->fdpic_p = 1;
+    }
+  return ret;
+}
+
+/* We need dynamic symbols for every section, since segments can
+   relocate independently.  */
+static bool
+elf32_arm_fdpic_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+                                   struct bfd_link_info *info
+                                   ATTRIBUTE_UNUSED,
+                                   asection *p ATTRIBUTE_UNUSED)
+{
+  switch (elf_section_data (p)->this_hdr.sh_type)
+    {
+    case SHT_PROGBITS:
+    case SHT_NOBITS:
+      /* If sh_type is yet undecided, assume it could be
+        SHT_PROGBITS/SHT_NOBITS.  */
+    case SHT_NULL:
+      return false;
+
+      /* There shouldn't be section relative relocations
+        against any other section.  */
+    default:
+      return true;
+    }
+}
+
+#undef  elf32_bed
+#define elf32_bed                              elf32_arm_fdpic_bed
+
+#undef  bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create   elf32_arm_fdpic_link_hash_table_create
+
+#undef elf_backend_omit_section_dynsym
+#define elf_backend_omit_section_dynsym                elf32_arm_fdpic_omit_section_dynsym
+
+#undef ELF_TARGET_OS
+
+#include "elf32-target.h"
+
+#undef elf_match_priority
+#undef ELF_OSABI
+#undef elf_backend_omit_section_dynsym
+
+/* VxWorks Targets.  */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM              arm_elf32_vxworks_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME             "elf32-littlearm-vxworks"
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM                 arm_elf32_vxworks_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME                        "elf32-bigarm-vxworks"
 
 /* Like elf32_arm_link_hash_table_create -- but overrides
    appropriately for VxWorks.  */
@@ -19387,16 +20466,15 @@ elf32_arm_vxworks_link_hash_table_create (bfd *abfd)
       struct elf32_arm_link_hash_table *htab
        = (struct elf32_arm_link_hash_table *) ret;
       htab->use_rel = 0;
-      htab->vxworks_p = 1;
     }
   return ret;
 }
 
-static void
-elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bool
+elf32_arm_vxworks_final_write_processing (bfd *abfd)
 {
-  elf32_arm_final_write_processing (abfd, linker);
-  elf_vxworks_final_write_processing (abfd, linker);
+  arm_final_write_processing (abfd);
+  return elf_vxworks_final_write_processing (abfd);
 }
 
 #undef  elf32_bed
@@ -19419,6 +20497,8 @@ elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
 #define elf_backend_want_plt_sym       1
 #undef  ELF_MAXPAGESIZE
 #define ELF_MAXPAGESIZE                        0x1000
+#undef ELF_TARGET_OS
+#define ELF_TARGET_OS                  is_vxworks
 
 #include "elf32-target.h"
 
@@ -19426,24 +20506,24 @@ elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
-static bfd_boolean
+static bool
 elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
   bfd *obfd = info->output_bfd;
   flagword out_flags;
   flagword in_flags;
-  bfd_boolean flags_compatible = TRUE;
+  bool flags_compatible = true;
   asection *sec;
 
   /* Check if we have the same endianness.  */
   if (! _bfd_generic_verify_endian_match (ibfd, info))
-    return FALSE;
+    return false;
 
   if (! is_arm_elf (ibfd) || ! is_arm_elf (obfd))
-    return TRUE;
+    return true;
 
   if (!elf32_arm_merge_eabi_attributes (ibfd, info))
-    return FALSE;
+    return false;
 
   /* The input BFD must have had its flags initialised.  */
   /* The following seems bogus to me -- The flags are initialized in
@@ -19461,9 +20541,9 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
       && !(ibfd->flags & DYNAMIC)
       && (in_flags & EF_ARM_BE8))
     {
-      _bfd_error_handler (_("error: %B is already in final BE8 format"),
+      _bfd_error_handler (_("error: %pB is already in final BE8 format"),
                          ibfd);
-      return FALSE;
+      return false;
     }
 
   if (!elf_flags_init (obfd))
@@ -19476,26 +20556,26 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         to the default values.  */
       if (bfd_get_arch_info (ibfd)->the_default
          && elf_elfheader (ibfd)->e_flags == 0)
-       return TRUE;
+       return true;
 
-      elf_flags_init (obfd) = TRUE;
+      elf_flags_init (obfd) = true;
       elf_elfheader (obfd)->e_flags = in_flags;
 
       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
          && bfd_get_arch_info (obfd)->the_default)
        return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
 
-      return TRUE;
+      return true;
     }
 
   /* Determine what should happen if the input ARM architecture
      does not match the output ARM architecture.  */
   if (! bfd_arm_merge_machines (ibfd, obfd))
-    return FALSE;
+    return false;
 
   /* Identical flags must be compatible.  */
   if (in_flags == out_flags)
-    return TRUE;
+    return true;
 
   /* Check to see if the input BFD actually contains any sections.  If
      not, its flags may not have been initialised either, but it
@@ -19509,8 +20589,8 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
     in data sections ?  */
   if (!(ibfd->flags & DYNAMIC))
     {
-      bfd_boolean null_input_bfd = TRUE;
-      bfd_boolean only_data_sections = TRUE;
+      bool null_input_bfd = true;
+      bool only_data_sections = true;
 
       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
        {
@@ -19518,18 +20598,18 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
          if (strcmp (sec->name, ".glue_7")
              && strcmp (sec->name, ".glue_7t"))
            {
-             if ((bfd_get_section_flags (ibfd, sec)
+             if ((bfd_section_flags (sec)
                   & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
                  == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
-               only_data_sections = FALSE;
+               only_data_sections = false;
 
-             null_input_bfd = FALSE;
+             null_input_bfd = false;
              break;
            }
        }
 
       if (null_input_bfd || only_data_sections)
-       return TRUE;
+       return true;
     }
 
   /* Complain about various flag mismatches.  */
@@ -19537,10 +20617,10 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
                                      EF_ARM_EABI_VERSION (out_flags)))
     {
       _bfd_error_handler
-       (_("error: Source object %B has EABI version %d, but target %B has EABI version %d"),
+       (_("error: source object %pB has EABI version %d, but target %pB has EABI version %d"),
         ibfd, (in_flags & EF_ARM_EABIMASK) >> 24,
         obfd, (out_flags & EF_ARM_EABIMASK) >> 24);
-      return FALSE;
+      return false;
     }
 
   /* Not sure what needs to be checked for EABI versions >= 1.  */
@@ -19552,52 +20632,52 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
        {
          _bfd_error_handler
-           (_("error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
+           (_("error: %pB is compiled for APCS-%d, whereas target %pB uses APCS-%d"),
             ibfd, in_flags & EF_ARM_APCS_26 ? 26 : 32,
             obfd, out_flags & EF_ARM_APCS_26 ? 26 : 32);
-         flags_compatible = FALSE;
+         flags_compatible = false;
        }
 
       if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
        {
          if (in_flags & EF_ARM_APCS_FLOAT)
            _bfd_error_handler
-             (_("error: %B passes floats in float registers, whereas %B passes them in integer registers"),
+             (_("error: %pB passes floats in float registers, whereas %pB passes them in integer registers"),
               ibfd, obfd);
          else
            _bfd_error_handler
-             (_("error: %B passes floats in integer registers, whereas %B passes them in float registers"),
+             (_("error: %pB passes floats in integer registers, whereas %pB passes them in float registers"),
               ibfd, obfd);
 
-         flags_compatible = FALSE;
+         flags_compatible = false;
        }
 
       if ((in_flags & EF_ARM_VFP_FLOAT) != (out_flags & EF_ARM_VFP_FLOAT))
        {
          if (in_flags & EF_ARM_VFP_FLOAT)
            _bfd_error_handler
-             (_("error: %B uses VFP instructions, whereas %B does not"),
-              ibfd, obfd);
+             (_("error: %pB uses %s instructions, whereas %pB does not"),
+              ibfd, "VFP", obfd);
          else
            _bfd_error_handler
-             (_("error: %B uses FPA instructions, whereas %B does not"),
-              ibfd, obfd);
+             (_("error: %pB uses %s instructions, whereas %pB does not"),
+              ibfd, "FPA", obfd);
 
-         flags_compatible = FALSE;
+         flags_compatible = false;
        }
 
       if ((in_flags & EF_ARM_MAVERICK_FLOAT) != (out_flags & EF_ARM_MAVERICK_FLOAT))
        {
          if (in_flags & EF_ARM_MAVERICK_FLOAT)
            _bfd_error_handler
-             (_("error: %B uses Maverick instructions, whereas %B does not"),
-              ibfd, obfd);
+             (_("error: %pB uses %s instructions, whereas %pB does not"),
+              ibfd, "Maverick", obfd);
          else
            _bfd_error_handler
-             (_("error: %B does not use Maverick instructions, whereas %B does"),
-              ibfd, obfd);
+             (_("error: %pB does not use %s instructions, whereas %pB does"),
+              ibfd, "Maverick", obfd);
 
-         flags_compatible = FALSE;
+         flags_compatible = false;
        }
 
 #ifdef EF_ARM_SOFT_FLOAT
@@ -19613,14 +20693,14 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
            {
              if (in_flags & EF_ARM_SOFT_FLOAT)
                _bfd_error_handler
-                 (_("error: %B uses software FP, whereas %B uses hardware FP"),
+                 (_("error: %pB uses software FP, whereas %pB uses hardware FP"),
                   ibfd, obfd);
              else
                _bfd_error_handler
-                 (_("error: %B uses hardware FP, whereas %B uses software FP"),
+                 (_("error: %pB uses hardware FP, whereas %pB uses software FP"),
                   ibfd, obfd);
 
-             flags_compatible = FALSE;
+             flags_compatible = false;
            }
        }
 #endif
@@ -19631,13 +20711,13 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
          if (in_flags & EF_ARM_INTERWORK)
            {
              _bfd_error_handler
-               (_("Warning: %B supports interworking, whereas %B does not"),
+               (_("warning: %pB supports interworking, whereas %pB does not"),
                 ibfd, obfd);
            }
          else
            {
              _bfd_error_handler
-               (_("Warning: %B does not support interworking, whereas %B does"),
+               (_("warning: %pB does not support interworking, whereas %pB does"),
                 ibfd, obfd);
            }
        }
@@ -19645,166 +20725,3 @@ elf32_arm_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 
   return flags_compatible;
 }
-
-
-/* Symbian OS Targets.  */
-
-#undef  TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM               arm_elf32_symbian_le_vec
-#undef  TARGET_LITTLE_NAME
-#define TARGET_LITTLE_NAME              "elf32-littlearm-symbian"
-#undef  TARGET_BIG_SYM
-#define TARGET_BIG_SYM                  arm_elf32_symbian_be_vec
-#undef  TARGET_BIG_NAME
-#define TARGET_BIG_NAME                 "elf32-bigarm-symbian"
-
-/* Like elf32_arm_link_hash_table_create -- but overrides
-   appropriately for Symbian OS.  */
-
-static struct bfd_link_hash_table *
-elf32_arm_symbian_link_hash_table_create (bfd *abfd)
-{
-  struct bfd_link_hash_table *ret;
-
-  ret = elf32_arm_link_hash_table_create (abfd);
-  if (ret)
-    {
-      struct elf32_arm_link_hash_table *htab
-       = (struct elf32_arm_link_hash_table *)ret;
-      /* There is no PLT header for Symbian OS.  */
-      htab->plt_header_size = 0;
-      /* The PLT entries are each one instruction and one word.  */
-      htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_symbian_plt_entry);
-      htab->symbian_p = 1;
-      /* Symbian uses armv5t or above, so use_blx is always true.  */
-      htab->use_blx = 1;
-      htab->root.is_relocatable_executable = 1;
-    }
-  return ret;
-}
-
-static const struct bfd_elf_special_section
-elf32_arm_symbian_special_sections[] =
-{
-  /* In a BPABI executable, the dynamic linking sections do not go in
-     the loadable read-only segment.  The post-linker may wish to
-     refer to these sections, but they are not part of the final
-     program image.  */
-  { STRING_COMMA_LEN (".dynamic"),       0, SHT_DYNAMIC,  0 },
-  { STRING_COMMA_LEN (".dynstr"),        0, SHT_STRTAB,   0 },
-  { STRING_COMMA_LEN (".dynsym"),        0, SHT_DYNSYM,   0 },
-  { STRING_COMMA_LEN (".got"),           0, SHT_PROGBITS, 0 },
-  { STRING_COMMA_LEN (".hash"),          0, SHT_HASH,     0 },
-  /* These sections do not need to be writable as the SymbianOS
-     postlinker will arrange things so that no dynamic relocation is
-     required.  */
-  { STRING_COMMA_LEN (".init_array"),    0, SHT_INIT_ARRAY,    SHF_ALLOC },
-  { STRING_COMMA_LEN (".fini_array"),    0, SHT_FINI_ARRAY,    SHF_ALLOC },
-  { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC },
-  { NULL,                             0, 0, 0,                 0 }
-};
-
-static void
-elf32_arm_symbian_begin_write_processing (bfd *abfd,
-                                         struct bfd_link_info *link_info)
-{
-  /* BPABI objects are never loaded directly by an OS kernel; they are
-     processed by a postlinker first, into an OS-specific format.  If
-     the D_PAGED bit is set on the file, BFD will align segments on
-     page boundaries, so that an OS can directly map the file.  With
-     BPABI objects, that just results in wasted space.  In addition,
-     because we clear the D_PAGED bit, map_sections_to_segments will
-     recognize that the program headers should not be mapped into any
-     loadable segment.  */
-  abfd->flags &= ~D_PAGED;
-  elf32_arm_begin_write_processing (abfd, link_info);
-}
-
-static bfd_boolean
-elf32_arm_symbian_modify_segment_map (bfd *abfd,
-                                     struct bfd_link_info *info)
-{
-  struct elf_segment_map *m;
-  asection *dynsec;
-
-  /* BPABI shared libraries and executables should have a PT_DYNAMIC
-     segment.  However, because the .dynamic section is not marked
-     with SEC_LOAD, the generic ELF code will not create such a
-     segment.  */
-  dynsec = bfd_get_section_by_name (abfd, ".dynamic");
-  if (dynsec)
-    {
-      for (m = elf_seg_map (abfd); m != NULL; m = m->next)
-       if (m->p_type == PT_DYNAMIC)
-         break;
-
-      if (m == NULL)
-       {
-         m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
-         m->next = elf_seg_map (abfd);
-         elf_seg_map (abfd) = m;
-       }
-    }
-
-  /* Also call the generic arm routine.  */
-  return elf32_arm_modify_segment_map (abfd, info);
-}
-
-/* Return address for Ith PLT stub in section PLT, for relocation REL
-   or (bfd_vma) -1 if it should not be included.  */
-
-static bfd_vma
-elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt,
-                              const arelent *rel ATTRIBUTE_UNUSED)
-{
-  return plt->vma + 4 * ARRAY_SIZE (elf32_arm_symbian_plt_entry) * i;
-}
-
-#undef  elf32_bed
-#define elf32_bed elf32_arm_symbian_bed
-
-/* The dynamic sections are not allocated on SymbianOS; the postlinker
-   will process them and then discard them.  */
-#undef  ELF_DYNAMIC_SEC_FLAGS
-#define ELF_DYNAMIC_SEC_FLAGS \
-  (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
-
-#undef elf_backend_emit_relocs
-
-#undef  bfd_elf32_bfd_link_hash_table_create
-#define bfd_elf32_bfd_link_hash_table_create   elf32_arm_symbian_link_hash_table_create
-#undef  elf_backend_special_sections
-#define elf_backend_special_sections           elf32_arm_symbian_special_sections
-#undef  elf_backend_begin_write_processing
-#define elf_backend_begin_write_processing     elf32_arm_symbian_begin_write_processing
-#undef  elf_backend_final_write_processing
-#define elf_backend_final_write_processing     elf32_arm_final_write_processing
-
-#undef  elf_backend_modify_segment_map
-#define elf_backend_modify_segment_map elf32_arm_symbian_modify_segment_map
-
-/* There is no .got section for BPABI objects, and hence no header.  */
-#undef  elf_backend_got_header_size
-#define elf_backend_got_header_size 0
-
-/* Similarly, there is no .got.plt section.  */
-#undef  elf_backend_want_got_plt
-#define elf_backend_want_got_plt 0
-
-#undef  elf_backend_plt_sym_val
-#define elf_backend_plt_sym_val                elf32_arm_symbian_plt_sym_val
-
-#undef  elf_backend_may_use_rel_p
-#define elf_backend_may_use_rel_p      1
-#undef  elf_backend_may_use_rela_p
-#define elf_backend_may_use_rela_p     0
-#undef  elf_backend_default_use_rela_p
-#define elf_backend_default_use_rela_p 0
-#undef  elf_backend_want_plt_sym
-#define elf_backend_want_plt_sym       0
-#undef  elf_backend_dtrel_excludes_plt
-#define elf_backend_dtrel_excludes_plt 0
-#undef  ELF_MAXPAGESIZE
-#define ELF_MAXPAGESIZE                        0x8000
-
-#include "elf32-target.h"
This page took 0.246067 seconds and 4 git commands to generate.