]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
readelf section reading
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index 0feeed9831d2500cd2117611062c4c127e2e591b..52d5302d07b59d19d747f5ccfd09621032b3dfb4 100644 (file)
@@ -1,5 +1,5 @@
 /* readelf.c -- display contents of an ELF format file
-   Copyright (C) 1998-2020 Free Software Foundation, Inc.
+   Copyright (C) 1998-2021 Free Software Foundation, Inc.
 
    Originally developed by Eric Youngdale <eric@andante.jic.com>
    Modifications by Nick Clifton <nickc@redhat.com>
@@ -44,9 +44,7 @@
 #include <assert.h>
 #include <time.h>
 #include <zlib.h>
-#ifdef HAVE_WCHAR_H
 #include <wchar.h>
-#endif
 
 #if __GNUC__ >= 2
 /* Define BFD64 here, even if our default architecture is 32 bit ELF
@@ -61,6 +59,7 @@
 #include "elfcomm.h"
 #include "dwarf.h"
 #include "ctf-api.h"
+#include "demangle.h"
 
 #include "elf/common.h"
 #include "elf/external.h"
@@ -211,30 +210,35 @@ static struct dump_list_entry * dump_sects_byname;
 
 char * program_name = "readelf";
 
-static bfd_boolean show_name = FALSE;
-static bfd_boolean do_dynamic = FALSE;
-static bfd_boolean do_syms = FALSE;
-static bfd_boolean do_dyn_syms = FALSE;
-static bfd_boolean do_reloc = FALSE;
-static bfd_boolean do_sections = FALSE;
-static bfd_boolean do_section_groups = FALSE;
-static bfd_boolean do_section_details = FALSE;
-static bfd_boolean do_segments = FALSE;
-static bfd_boolean do_unwind = FALSE;
-static bfd_boolean do_using_dynamic = FALSE;
-static bfd_boolean do_header = FALSE;
-static bfd_boolean do_dump = FALSE;
-static bfd_boolean do_version = FALSE;
-static bfd_boolean do_histogram = FALSE;
-static bfd_boolean do_debugging = FALSE;
-static bfd_boolean do_ctf = FALSE;
-static bfd_boolean do_arch = FALSE;
-static bfd_boolean do_notes = FALSE;
-static bfd_boolean do_archive_index = FALSE;
-static bfd_boolean check_all = FALSE;
-static bfd_boolean is_32bit_elf = FALSE;
-static bfd_boolean decompress_dumps = FALSE;
-static bfd_boolean do_not_show_symbol_truncation = FALSE;
+static bool show_name = false;
+static bool do_dynamic = false;
+static bool do_syms = false;
+static bool do_dyn_syms = false;
+static bool do_lto_syms = false;
+static bool do_reloc = false;
+static bool do_sections = false;
+static bool do_section_groups = false;
+static bool do_section_details = false;
+static bool do_segments = false;
+static bool do_unwind = false;
+static bool do_using_dynamic = false;
+static bool do_header = false;
+static bool do_dump = false;
+static bool do_version = false;
+static bool do_histogram = false;
+static bool do_debugging = false;
+static bool do_ctf = false;
+static bool do_arch = false;
+static bool do_notes = false;
+static bool do_archive_index = false;
+static bool check_all = false;
+static bool is_32bit_elf = false;
+static bool decompress_dumps = false;
+static bool do_not_show_symbol_truncation = false;
+static bool do_demangle = false;       /* Pretty print C++ symbol names.  */
+static bool process_links = false;
+static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
+static int sym_base = 0;
 
 static char *dump_ctf_parent_name;
 static char *dump_ctf_symtab_name;
@@ -255,6 +259,7 @@ struct group
 typedef struct filedata
 {
   const char *         file_name;
+  bool                 is_separate;
   FILE *               handle;
   bfd_size_type        file_size;
   Elf_Internal_Ehdr    file_header;
@@ -288,7 +293,7 @@ typedef struct filedata
   bfd_vma *            gnuchains;
   bfd_vma *            mipsxlat;
   bfd_vma              gnusymidx;
-  char                 program_interpreter[PATH_MAX];
+  char *               program_interpreter;
   bfd_vma              dynamic_info[DT_ENCODING];
   bfd_vma              dynamic_info_DT_GNU_HASH;
   bfd_vma              dynamic_info_DT_MIPS_XHASH;
@@ -308,12 +313,17 @@ typedef struct filedata
 typedef enum print_mode
 {
   HEX,
+  HEX_5,
   DEC,
   DEC_5,
   UNSIGNED,
+  UNSIGNED_5,
   PREFIX_HEX,
+  PREFIX_HEX_5,
   FULL_HEX,
-  LONG_HEX
+  LONG_HEX,
+  OCTAL,
+  OCTAL_5
 }
 print_mode;
 
@@ -326,22 +336,26 @@ enum versioned_symbol_info
 };
 
 static const char * get_symbol_version_string
-  (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
+  (Filedata *, bool, const char *, unsigned long, unsigned,
    Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
 
 #define UNKNOWN -1
 
-#define SECTION_NAME(X)                                                \
-  ((X) == NULL ? _("<none>")                                   \
-   : filedata->string_table == NULL ? _("<no-strings>")                \
-   : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>")   \
-  : filedata->string_table + (X)->sh_name))
+#define SECTION_NAME(X) \
+  (filedata->string_table + (X)->sh_name)
 
-#define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order!  */
+#define SECTION_NAME_VALID(X) \
+  ((X) != NULL                                                         \
+   && filedata->string_table != NULL                                   \
+   && (X)->sh_name < filedata->string_table_length)
 
-#define GET_ELF_SYMBOLS(file, section, sym_count)                      \
-  (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count)     \
-   : get_64bit_elf_symbols (file, section, sym_count))
+#define SECTION_NAME_PRINT(X) \
+  ((X) == NULL ? _("<none>")                                           \
+   : filedata->string_table == NULL ? _("<no-strings>")                        \
+   : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>")    \
+   : filedata->string_table + (X)->sh_name)
+
+#define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order!  */
 
 #define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
    (strtab != NULL && offset < strtab_size)
@@ -517,18 +531,34 @@ print_vma (bfd_vma vma, print_mode mode)
     case HEX:
       return nc + printf ("%" BFD_VMA_FMT "x", vma);
 
+    case PREFIX_HEX_5:
+      nc = printf ("0x");
+      /* Fall through.  */
+    case HEX_5:
+      return nc + printf ("%05" BFD_VMA_FMT "x", vma);
+
     case DEC:
       return printf ("%" BFD_VMA_FMT "d", vma);
 
     case UNSIGNED:
       return printf ("%" BFD_VMA_FMT "u", vma);
 
+    case UNSIGNED_5:
+      return printf ("%5" BFD_VMA_FMT "u", vma);
+
+    case OCTAL:
+      return printf ("%" BFD_VMA_FMT "o", vma);
+
+    case OCTAL_5:
+      return printf ("%5" BFD_VMA_FMT "o", vma);
+
     default:
       /* FIXME: Report unrecognised mode ?  */
       return 0;
     }
 }
 
+
 /* Display a symbol on stdout.  Handles the display of control characters and
    multibye characters (assuming the host environment supports them).
 
@@ -545,19 +575,20 @@ print_vma (bfd_vma vma, print_mode mode)
 static unsigned int
 print_symbol (signed int width, const char * symbol)
 {
-  bfd_boolean extra_padding = FALSE;
-  bfd_boolean do_dots = FALSE;
+  bool extra_padding = false;
+  bool do_dots = false;
   signed int num_printed = 0;
 #ifdef HAVE_MBSTATE_T
   mbstate_t state;
 #endif
   unsigned int width_remaining;
+  const void * alloced_symbol = NULL;
 
   if (width < 0)
     {
       /* Keep the width positive.  This helps the code below.  */
       width = - width;
-      extra_padding = TRUE;
+      extra_padding = true;
     }
   else if (width == 0)
     return 0;
@@ -575,7 +606,7 @@ print_symbol (signed int width, const char * symbol)
          width_remaining -= 5;
          if ((int) width_remaining < 0)
            width_remaining = 0;
-         do_dots = TRUE;
+         do_dots = true;
        }
     }
 
@@ -584,6 +615,14 @@ print_symbol (signed int width, const char * symbol)
   memset (& state, 0, sizeof (state));
 #endif
 
+  if (do_demangle && *symbol)
+    {
+      const char * res = cplus_demangle (symbol, demangle_flags);
+
+      if (res != NULL)
+       alloced_symbol = symbol = res;
+    }
+
   while (width_remaining)
     {
       size_t  n;
@@ -643,6 +682,7 @@ print_symbol (signed int width, const char * symbol)
       num_printed = width;
     }
 
+  free ((void *) alloced_symbol);
   return num_printed;
 }
 
@@ -653,9 +693,9 @@ print_symbol (signed int width, const char * symbol)
 static const char *
 printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
 {
-#define MAX_PRINT_SEC_NAME_LEN 128
+#define MAX_PRINT_SEC_NAME_LEN 256
   static char  sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
-  const char * name = SECTION_NAME (sec);
+  const char * name = SECTION_NAME_PRINT (sec);
   char *       buf = sec_name_buf;
   char         c;
   unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
@@ -717,7 +757,8 @@ find_section (Filedata * filedata, const char * name)
     return NULL;
 
   for (i = 0; i < filedata->file_header.e_shnum; i++)
-    if (streq (SECTION_NAME (filedata->section_headers + i), name))
+    if (SECTION_NAME_VALID (filedata->section_headers + i)
+       && streq (SECTION_NAME (filedata->section_headers + i), name))
       return filedata->section_headers + i;
 
   return NULL;
@@ -783,7 +824,8 @@ find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
          if (i >= filedata->file_header.e_shnum)
            continue; /* FIXME: Should we issue an error message ?  */
 
-         if (streq (SECTION_NAME (filedata->section_headers + i), name))
+         if (SECTION_NAME_VALID (filedata->section_headers + i)
+             && streq (SECTION_NAME (filedata->section_headers + i), name))
            return filedata->section_headers + i;
        }
     }
@@ -795,7 +837,7 @@ find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
    This OS has so many departures from the ELF standard that we test it at
    many places.  */
 
-static inline bfd_boolean
+static inline bool
 is_ia64_vms (Filedata * filedata)
 {
   return filedata->file_header.e_machine == EM_IA_64
@@ -804,7 +846,7 @@ is_ia64_vms (Filedata * filedata)
 
 /* Guess the relocation size commonly used by the specific machines.  */
 
-static bfd_boolean
+static bool
 guess_is_rela (unsigned int e_machine)
 {
   switch (e_machine)
@@ -824,7 +866,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_XGATE:
     case EM_NFP:
     case EM_BPF:
-      return FALSE;
+      return false;
 
       /* Targets that use RELA relocations.  */
     case EM_68K:
@@ -905,7 +947,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_MICROBLAZE:
     case EM_MICROBLAZE_OLD:
     case EM_WEBASSEMBLY:
-      return TRUE;
+      return true;
 
     case EM_68HC05:
     case EM_68HC08:
@@ -926,7 +968,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_TINYJ:
     default:
       warn (_("Don't know about relocations on this machine architecture\n"));
-      return FALSE;
+      return false;
     }
 }
 
@@ -936,7 +978,7 @@ guess_is_rela (unsigned int e_machine)
    and the number of relocs loaded is placed in *NRELASP.  It is the caller's
    responsibility to free the allocated buffer.  */
 
-static bfd_boolean
+static bool
 slurp_rela_relocs (Filedata *            filedata,
                   unsigned long         rel_offset,
                   unsigned long         rel_size,
@@ -954,7 +996,7 @@ slurp_rela_relocs (Filedata *            filedata,
       erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
                                                  rel_size, _("32-bit relocation data"));
       if (!erelas)
-       return FALSE;
+       return false;
 
       nrelas = rel_size / sizeof (Elf32_External_Rela);
 
@@ -965,7 +1007,7 @@ slurp_rela_relocs (Filedata *            filedata,
        {
          free (erelas);
          error (_("out of memory parsing relocs\n"));
-         return FALSE;
+         return false;
        }
 
       for (i = 0; i < nrelas; i++)
@@ -984,7 +1026,7 @@ slurp_rela_relocs (Filedata *            filedata,
       erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
                                                  rel_size, _("64-bit relocation data"));
       if (!erelas)
-       return FALSE;
+       return false;
 
       nrelas = rel_size / sizeof (Elf64_External_Rela);
 
@@ -995,7 +1037,7 @@ slurp_rela_relocs (Filedata *            filedata,
        {
          free (erelas);
          error (_("out of memory parsing relocs\n"));
-         return FALSE;
+         return false;
        }
 
       for (i = 0; i < nrelas; i++)
@@ -1032,7 +1074,7 @@ slurp_rela_relocs (Filedata *            filedata,
 
   *relasp = relas;
   *nrelasp = nrelas;
-  return TRUE;
+  return true;
 }
 
 /* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
@@ -1041,7 +1083,7 @@ slurp_rela_relocs (Filedata *            filedata,
    and the number of relocs loaded is placed in *NRELSP.  It is the caller's
    responsibility to free the allocated buffer.  */
 
-static bfd_boolean
+static bool
 slurp_rel_relocs (Filedata *            filedata,
                  unsigned long         rel_offset,
                  unsigned long         rel_size,
@@ -1059,7 +1101,7 @@ slurp_rel_relocs (Filedata *            filedata,
       erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
                                                rel_size, _("32-bit relocation data"));
       if (!erels)
-       return FALSE;
+       return false;
 
       nrels = rel_size / sizeof (Elf32_External_Rel);
 
@@ -1069,7 +1111,7 @@ slurp_rel_relocs (Filedata *            filedata,
        {
          free (erels);
          error (_("out of memory parsing relocs\n"));
-         return FALSE;
+         return false;
        }
 
       for (i = 0; i < nrels; i++)
@@ -1088,7 +1130,7 @@ slurp_rel_relocs (Filedata *            filedata,
       erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
                                                rel_size, _("64-bit relocation data"));
       if (!erels)
-       return FALSE;
+       return false;
 
       nrels = rel_size / sizeof (Elf64_External_Rel);
 
@@ -1098,7 +1140,7 @@ slurp_rel_relocs (Filedata *            filedata,
        {
          free (erels);
          error (_("out of memory parsing relocs\n"));
-         return FALSE;
+         return false;
        }
 
       for (i = 0; i < nrels; i++)
@@ -1135,7 +1177,7 @@ slurp_rel_relocs (Filedata *            filedata,
 
   *relsp = rels;
   *nrelsp = nrels;
-  return TRUE;
+  return true;
 }
 
 /* Returns the reloc type extracted from the reloc info field.  */
@@ -1168,7 +1210,7 @@ get_reloc_symindex (bfd_vma reloc_info)
   return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
 }
 
-static inline bfd_boolean
+static inline bool
 uses_msp430x_relocs (Filedata * filedata)
 {
   return
@@ -1182,7 +1224,7 @@ uses_msp430x_relocs (Filedata * filedata)
 /* Display the contents of the relocation data found at the specified
    offset.  */
 
-static bfd_boolean
+static bool
 dump_relocations (Filedata *          filedata,
                  unsigned long       rel_offset,
                  unsigned long       rel_size,
@@ -1191,11 +1233,11 @@ dump_relocations (Filedata *          filedata,
                  char *              strtab,
                  unsigned long       strtablen,
                  int                 is_rela,
-                 bfd_boolean         is_dynsym)
+                 bool                is_dynsym)
 {
   unsigned long i;
   Elf_Internal_Rela * rels;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (is_rela == UNKNOWN)
     is_rela = guess_is_rela (filedata->file_header.e_machine);
@@ -1203,12 +1245,12 @@ dump_relocations (Filedata *          filedata,
   if (is_rela)
     {
       if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
-       return FALSE;
+       return false;
     }
   else
     {
       if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
-       return FALSE;
+       return false;
     }
 
   if (is_32bit_elf)
@@ -1268,32 +1310,10 @@ dump_relocations (Filedata *          filedata,
        }
       else
        {
-#if BFD_HOST_64BIT_LONG
-         printf (do_wide
-                 ? "%16.16lx  %16.16lx "
-                 : "%12.12lx  %12.12lx ",
-                 offset, inf);
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-         printf (do_wide
-                 ? "%16.16llx  %16.16llx "
-                 : "%12.12llx  %12.12llx ",
-                 offset, inf);
-#else
          printf (do_wide
-                 ? "%16.16I64x  %16.16I64x "
-                 : "%12.12I64x  %12.12I64x ",
+                 ? "%16.16" BFD_VMA_FMT "x  %16.16" BFD_VMA_FMT "x "
+                 : "%12.12" BFD_VMA_FMT "x  %12.12" BFD_VMA_FMT "x ",
                  offset, inf);
-#endif
-#else
-         printf (do_wide
-                 ? "%8.8lx%8.8lx  %8.8lx%8.8lx "
-                 : "%4.4lx%8.8lx  %4.4lx%8.8lx ",
-                 _bfd_int64_high (offset),
-                 _bfd_int64_low (offset),
-                 _bfd_int64_high (inf),
-                 _bfd_int64_low (inf));
-#endif
        }
 
       switch (filedata->file_header.e_machine)
@@ -1663,7 +1683,7 @@ dump_relocations (Filedata *          filedata,
              putchar (' ');
              printf (_("<unknown addend: %lx>"),
                      (unsigned long) rels[i].r_addend);
-             res = FALSE;
+             res = false;
            }
        }
       else if (symtab_index)
@@ -1672,7 +1692,7 @@ dump_relocations (Filedata *          filedata,
            {
              error (_(" bad symbol index: %08lx in reloc\n"),
                     (unsigned long) symtab_index);
-             res = FALSE;
+             res = false;
            }
          else
            {
@@ -1737,7 +1757,8 @@ dump_relocations (Filedata *          filedata,
                  if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
                    {
                      if (psym->st_shndx < filedata->file_header.e_shnum)
-                       sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
+                       sec_name = SECTION_NAME_PRINT (filedata->section_headers
+                                                      + psym->st_shndx);
                      else if (psym->st_shndx == SHN_ABS)
                        sec_name = "ABS";
                      else if (psym->st_shndx == SHN_COMMON)
@@ -1777,7 +1798,7 @@ dump_relocations (Filedata *          filedata,
                {
                  error (_("<corrupt string table index: %3ld>\n"),
                         psym->st_name);
-                 res = FALSE;
+                 res = false;
                }
              else
                {
@@ -2229,6 +2250,7 @@ get_dynamic_type (Filedata * filedata, unsigned long type)
     case DT_GNU_LIBLIST: return "GNU_LIBLIST";
     case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
     case DT_GNU_HASH:  return "GNU_HASH";
+    case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
 
     default:
       if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
@@ -2543,6 +2565,7 @@ get_machine_name (unsigned e_machine)
     case EM_BA2:               return "Beyond BA2 CPU architecture";
     case EM_XCORE:             return "XMOS xCORE processor family";
     case EM_MCHP_PIC:          return "Microchip 8-bit PIC(r) family";
+    case EM_INTELGT:           return "Intel Graphics Technology";
       /* 210 */
     case EM_KM32:              return "KM211 KM32 32-bit processor";
     case EM_KMX32:             return "KM211 KMX32 32-bit processor";
@@ -2560,10 +2583,26 @@ get_machine_name (unsigned e_machine)
     case EM_FT32:               return "FTDI Chip FT32";
     case EM_MOXIE:              return "Moxie";
     case EM_AMDGPU:            return "AMD GPU";
+      /* 230 (all reserved) */
+      /* 240 */
     case EM_RISCV:             return "RISC-V";
     case EM_LANAI:             return "Lanai 32-bit processor";
+    case EM_CEVA:              return "CEVA Processor Architecture Family";
+    case EM_CEVA_X2:           return "CEVA X2 Processor Family";
     case EM_BPF:               return "Linux BPF";
+    case EM_GRAPHCORE_IPU:     return "Graphcore Intelligent Processing Unit";
+    case EM_IMG1:              return "Imagination Technologies";
+      /* 250 */
     case EM_NFP:               return "Netronome Flow Processor";
+    case EM_VE:                        return "NEC Vector Engine";
+    case EM_CSKY:              return "C-SKY";
+    case EM_ARC_COMPACT3_64:   return "Synopsys ARCv2.3 64-bit";
+    case EM_MCS6502:           return "MOS Technology MCS 6502 processor";
+    case EM_ARC_COMPACT3:      return "Synopsys ARCv2.3 32-bit";
+    case EM_KVX:               return "Kalray VLIW core of the MPPA processor family";
+    case EM_65816:             return "WDC 65816/65C816";
+    case EM_LOONGARCH:         return "LoongArch";
+    case EM_KF32:              return "ChipON KungFu32";
 
       /* Large numbers...  */
     case EM_MT:                 return "Morpho Techologies MT processor";
@@ -2578,7 +2617,6 @@ get_machine_name (unsigned e_machine)
     case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
     case EM_CYGNUS_FRV:                return "Fujitsu FR-V";
     case EM_S12Z:               return "Freescale S12Z";
-    case EM_CSKY:              return "C-SKY";
 
     default:
       snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
@@ -2590,7 +2628,7 @@ static void
 decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
 {
   /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2.  Some
-     other compilers don't a specific architecture type in the e_flags, and
+     other compilers don't specify an architecture type in the e_flags, and
      instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
      architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
      architectures.
@@ -2660,7 +2698,7 @@ static void
 decode_ARM_machine_flags (unsigned e_flags, char buf[])
 {
   unsigned eabi;
-  bfd_boolean unknown = FALSE;
+  bool unknown = false;
 
   eabi = EF_ARM_EABI_VERSION (e_flags);
   e_flags &= ~ EF_ARM_EABIMASK;
@@ -2684,7 +2722,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
     default:
       strcat (buf, ", <unrecognized EABI>");
       if (e_flags)
-       unknown = TRUE;
+       unknown = true;
       break;
 
     case EF_ARM_EABI_VER1:
@@ -2704,7 +2742,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
              break;
 
            default:
-             unknown = TRUE;
+             unknown = true;
              break;
            }
        }
@@ -2735,7 +2773,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
              break;
 
            default:
-             unknown = TRUE;
+             unknown = true;
              break;
            }
        }
@@ -2766,7 +2804,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
              break;
 
            default:
-             unknown = TRUE;
+             unknown = true;
              break;
            }
        }
@@ -2801,7 +2839,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
              break;
 
            default:
-             unknown = TRUE;
+             unknown = true;
              break;
            }
        }
@@ -2860,7 +2898,7 @@ decode_ARM_machine_flags (unsigned e_flags, char buf[])
              break;
 
            default:
-             unknown = TRUE;
+             unknown = true;
              break;
            }
        }
@@ -2948,7 +2986,7 @@ decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
   unsigned arch;
   unsigned config;
   unsigned version;
-  bfd_boolean has_fpu = FALSE;
+  bool has_fpu = false;
   unsigned int r = 0;
 
   static const char *ABI_STRINGS[] =
@@ -3085,19 +3123,19 @@ decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
 
   if (config & E_NDS32_HAS_FPU_INST)
     {
-      has_fpu = TRUE;
+      has_fpu = true;
       r += snprintf (buf + r, size -r, ", FPU_SP");
     }
 
   if (config & E_NDS32_HAS_FPU_DP_INST)
     {
-      has_fpu = TRUE;
+      has_fpu = true;
       r += snprintf (buf + r, size -r, ", FPU_DP");
     }
 
   if (config & E_NDS32_HAS_FPU_MAC_INST)
     {
-      has_fpu = TRUE;
+      has_fpu = true;
       r += snprintf (buf + r, size -r, ", FPU_MAC");
     }
 
@@ -4039,6 +4077,10 @@ get_segment_type (Filedata * filedata, unsigned long p_type)
     case PT_GNU_RELRO:  return "GNU_RELRO";
     case PT_GNU_PROPERTY: return "GNU_PROPERTY";
 
+    case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
+    case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
+    case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
+
     default:
       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
        {
@@ -4272,7 +4314,7 @@ get_tic6x_section_type_name (unsigned int sh_type)
 }
 
 static const char *
-get_msp430x_section_type_name (unsigned int sh_type)
+get_msp430_section_type_name (unsigned int sh_type)
 {
   switch (sh_type)
     {
@@ -4319,6 +4361,16 @@ get_riscv_section_type_name (unsigned int sh_type)
     }
 }
 
+static const char *
+get_csky_section_type_name (unsigned int sh_type)
+{
+  switch (sh_type)
+    {
+    case SHT_CSKY_ATTRIBUTES:  return "CSKY_ATTRIBUTES";
+    default:  return NULL;
+    }
+}
+
 static const char *
 get_section_type_name (Filedata * filedata, unsigned int sh_type)
 {
@@ -4389,7 +4441,7 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type)
              result = get_tic6x_section_type_name (sh_type);
              break;
            case EM_MSP430:
-             result = get_msp430x_section_type_name (sh_type);
+             result = get_msp430_section_type_name (sh_type);
              break;
            case EM_NFP:
              result = get_nfp_section_type_name (sh_type);
@@ -4402,6 +4454,9 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type)
            case EM_RISCV:
              result = get_riscv_section_type_name (sh_type);
              break;
+           case EM_CSKY:
+             result = get_csky_section_type_name (sh_type);
+             break;
            default:
              result = NULL;
              break;
@@ -4471,67 +4526,81 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type)
     }
 }
 
-#define OPTION_DEBUG_DUMP      512
-#define OPTION_DYN_SYMS                513
-#define OPTION_DWARF_DEPTH     514
-#define OPTION_DWARF_START     515
-#define OPTION_DWARF_CHECK     516
-#define OPTION_CTF_DUMP                517
-#define OPTION_CTF_PARENT      518
-#define OPTION_CTF_SYMBOLS     519
-#define OPTION_CTF_STRINGS     520
+enum long_option_values
+{
+  OPTION_DEBUG_DUMP = 512,
+  OPTION_DYN_SYMS,
+  OPTION_LTO_SYMS,
+  OPTION_DWARF_DEPTH,
+  OPTION_DWARF_START,
+  OPTION_DWARF_CHECK,
+  OPTION_CTF_DUMP,
+  OPTION_CTF_PARENT,
+  OPTION_CTF_SYMBOLS,
+  OPTION_CTF_STRINGS,
+  OPTION_WITH_SYMBOL_VERSIONS,
+  OPTION_RECURSE_LIMIT,
+  OPTION_NO_RECURSE_LIMIT,
+  OPTION_NO_DEMANGLING,
+  OPTION_SYM_BASE
+};
 
 static struct option options[] =
 {
+ /* Note - This table is alpha-sorted on the 'val'
+    field in order to make adding new options easier.  */
+  {"arch-specific",    no_argument, 0, 'A'},
   {"all",             no_argument, 0, 'a'},
-  {"file-header",      no_argument, 0, 'h'},
-  {"program-headers",  no_argument, 0, 'l'},
+  {"demangle",         optional_argument, 0, 'C'},
+  {"archive-index",    no_argument, 0, 'c'},
+  {"use-dynamic",      no_argument, 0, 'D'},
+  {"dynamic",         no_argument, 0, 'd'},
   {"headers",         no_argument, 0, 'e'},
+  {"section-groups",   no_argument, 0, 'g'},
+  {"help",            no_argument, 0, 'H'},
+  {"file-header",      no_argument, 0, 'h'},
   {"histogram",               no_argument, 0, 'I'},
+  {"lint",             no_argument, 0, 'L'},
+  {"enable-checks",    no_argument, 0, 'L'},
+  {"program-headers",  no_argument, 0, 'l'},
   {"segments",        no_argument, 0, 'l'},
-  {"sections",        no_argument, 0, 'S'},
-  {"section-headers",  no_argument, 0, 'S'},
-  {"section-groups",   no_argument, 0, 'g'},
-  {"section-details",  no_argument, 0, 't'},
   {"full-section-name",no_argument, 0, 'N'},
+  {"notes",           no_argument, 0, 'n'},
+  {"process-links",    no_argument, 0, 'P'},
+  {"string-dump",      required_argument, 0, 'p'},
+  {"relocated-dump",   required_argument, 0, 'R'},
+  {"relocs",          no_argument, 0, 'r'},
+  {"section-headers",  no_argument, 0, 'S'},
+  {"sections",        no_argument, 0, 'S'},
   {"symbols",         no_argument, 0, 's'},
   {"syms",            no_argument, 0, 's'},
-  {"dyn-syms",        no_argument, 0, OPTION_DYN_SYMS},
-  {"relocs",          no_argument, 0, 'r'},
-  {"notes",           no_argument, 0, 'n'},
-  {"dynamic",         no_argument, 0, 'd'},
-  {"lint",             no_argument, 0, 'L'},
-  {"enable-checks",    no_argument, 0, 'L'},
-  {"arch-specific",    no_argument, 0, 'A'},
-  {"version-info",     no_argument, 0, 'V'},
-  {"use-dynamic",      no_argument, 0, 'D'},
+  {"silent-truncation",no_argument, 0, 'T'},
+  {"section-details",  no_argument, 0, 't'},
   {"unwind",          no_argument, 0, 'u'},
-  {"archive-index",    no_argument, 0, 'c'},
+  {"version-info",     no_argument, 0, 'V'},
+  {"version",         no_argument, 0, 'v'},
+  {"wide",            no_argument, 0, 'W'},
   {"hex-dump",        required_argument, 0, 'x'},
-  {"relocated-dump",   required_argument, 0, 'R'},
-  {"string-dump",      required_argument, 0, 'p'},
   {"decompress",       no_argument, 0, 'z'},
-#ifdef SUPPORT_DISASSEMBLY
-  {"instruction-dump", required_argument, 0, 'i'},
-#endif
-  {"debug-dump",       optional_argument, 0, OPTION_DEBUG_DUMP},
 
+  {"no-demangle",      no_argument, 0, OPTION_NO_DEMANGLING},
+  {"recurse-limit",    no_argument, NULL, OPTION_RECURSE_LIMIT},
+  {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
+  {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
+  {"dyn-syms",        no_argument, 0, OPTION_DYN_SYMS},
+  {"lto-syms",         no_argument, 0, OPTION_LTO_SYMS},
+  {"debug-dump",       optional_argument, 0, OPTION_DEBUG_DUMP},
   {"dwarf-depth",      required_argument, 0, OPTION_DWARF_DEPTH},
   {"dwarf-start",      required_argument, 0, OPTION_DWARF_START},
   {"dwarf-check",      no_argument, 0, OPTION_DWARF_CHECK},
-
 #ifdef ENABLE_LIBCTF
   {"ctf",             required_argument, 0, OPTION_CTF_DUMP},
-
   {"ctf-symbols",      required_argument, 0, OPTION_CTF_SYMBOLS},
   {"ctf-strings",      required_argument, 0, OPTION_CTF_STRINGS},
   {"ctf-parent",       required_argument, 0, OPTION_CTF_PARENT},
 #endif
+  {"sym-base",        optional_argument, 0, OPTION_SYM_BASE},
 
-  {"version",         no_argument, 0, 'v'},
-  {"wide",            no_argument, 0, 'W'},
-  {"silent-truncation",no_argument, 0, 'T'},
-  {"help",            no_argument, 0, 'H'},
   {0,                 no_argument, 0, 0}
 };
 
@@ -4540,54 +4609,123 @@ usage (FILE * stream)
 {
   fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
   fprintf (stream, _(" Display information about the contents of ELF format files\n"));
-  fprintf (stream, _(" Options are:\n\
-  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n\
-  -h --file-header       Display the ELF file header\n\
-  -l --program-headers   Display the program headers\n\
-     --segments          An alias for --program-headers\n\
-  -S --section-headers   Display the sections' header\n\
-     --sections          An alias for --section-headers\n\
-  -g --section-groups    Display the section groups\n\
-  -t --section-details   Display the section details\n\
-  -e --headers           Equivalent to: -h -l -S\n\
-  -s --syms              Display the symbol table\n\
-     --symbols           An alias for --syms\n\
-     --dyn-syms          Display the dynamic symbol table\n\
-  -n --notes             Display the core notes (if present)\n\
-  -r --relocs            Display the relocations (if present)\n\
-  -u --unwind            Display the unwind info (if present)\n\
-  -d --dynamic           Display the dynamic section (if present)\n\
-  -V --version-info      Display the version sections (if present)\n\
-  -A --arch-specific     Display architecture specific information (if any)\n\
-  -c --archive-index     Display the symbol/file index in an archive\n\
-  -D --use-dynamic       Use the dynamic section info when displaying symbols\n\
-  -L --lint|--enable-checks  Display warning messages for possible problems\n\
+  fprintf (stream, _(" Options are:\n"));
+  fprintf (stream, _("\
+  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
+  fprintf (stream, _("\
+  -h --file-header       Display the ELF file header\n"));
+  fprintf (stream, _("\
+  -l --program-headers   Display the program headers\n"));
+  fprintf (stream, _("\
+     --segments          An alias for --program-headers\n"));
+  fprintf (stream, _("\
+  -S --section-headers   Display the sections' header\n"));
+  fprintf (stream, _("\
+     --sections          An alias for --section-headers\n"));
+  fprintf (stream, _("\
+  -g --section-groups    Display the section groups\n"));
+  fprintf (stream, _("\
+  -t --section-details   Display the section details\n"));
+  fprintf (stream, _("\
+  -e --headers           Equivalent to: -h -l -S\n"));
+  fprintf (stream, _("\
+  -s --syms              Display the symbol table\n"));
+  fprintf (stream, _("\
+     --symbols           An alias for --syms\n"));
+  fprintf (stream, _("\
+     --dyn-syms          Display the dynamic symbol table\n"));
+  fprintf (stream, _("\
+     --lto-syms          Display LTO symbol tables\n"));
+  fprintf (stream, _("\
+     --sym-base=[0|8|10|16] \n\
+                         Force base for symbol sizes.  The options are \n\
+                         mixed (the default), octal, decimal, hexadecimal.\n"));
+  fprintf (stream, _("\
+  -C --demangle[=STYLE]  Decode low-level symbol names into user-level names\n\
+                          The STYLE, if specified, can be `auto' (the default),\n\
+                          `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
+                          or `gnat'\n"));
+  fprintf (stream, _("\
+     --no-demangle       Do not demangle low-level symbol names.  (default)\n"));
+  fprintf (stream, _("\
+     --recurse-limit     Enable a demangling recursion limit.  (default)\n"));
+  fprintf (stream, _("\
+     --no-recurse-limit  Disable a demangling recursion limit\n"));
+  fprintf (stream, _("\
+  -n --notes             Display the core notes (if present)\n"));
+  fprintf (stream, _("\
+  -r --relocs            Display the relocations (if present)\n"));
+  fprintf (stream, _("\
+  -u --unwind            Display the unwind info (if present)\n"));
+  fprintf (stream, _("\
+  -d --dynamic           Display the dynamic section (if present)\n"));
+  fprintf (stream, _("\
+  -V --version-info      Display the version sections (if present)\n"));
+  fprintf (stream, _("\
+  -A --arch-specific     Display architecture specific information (if any)\n"));
+  fprintf (stream, _("\
+  -c --archive-index     Display the symbol/file index in an archive\n"));
+  fprintf (stream, _("\
+  -D --use-dynamic       Use the dynamic section info when displaying symbols\n"));
+  fprintf (stream, _("\
+  -L --lint|--enable-checks\n\
+                         Display warning messages for possible problems\n"));
+  fprintf (stream, _("\
   -x --hex-dump=<number|name>\n\
-                         Dump the contents of section <number|name> as bytes\n\
+                         Dump the contents of section <number|name> as bytes\n"));
+  fprintf (stream, _("\
   -p --string-dump=<number|name>\n\
-                         Dump the contents of section <number|name> as strings\n\
+                         Dump the contents of section <number|name> as strings\n"));
+  fprintf (stream, _("\
   -R --relocated-dump=<number|name>\n\
-                         Dump the contents of section <number|name> as relocated bytes\n\
-  -z --decompress        Decompress section before dumping it\n\
-  -w[lLiaprmfFsoORtUuTgAckK] or\n\
-  --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
-               =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
-               =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
-               =addr,=cu_index,=links,=follow-links]\n\
+                         Dump the relocated contents of section <number|name>\n"));
+  fprintf (stream, _("\
+  -z --decompress        Decompress section before dumping it\n"));
+  fprintf (stream, _("\
+  -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
+                  f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
+                  m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
+                  s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
+                  U/=trace_info]\n\
                          Display the contents of DWARF debug sections\n"));
   fprintf (stream, _("\
-  --dwarf-depth=N        Do not display DIEs at depth N or greater\n\
-  --dwarf-start=N        Display DIEs starting with N, at the same depth\n\
-                         or deeper\n"));
+  -wk --debug-dump=links Display the contents of sections that link to separate\n\
+                          debuginfo files\n"));
+  fprintf (stream, _("\
+  -P --process-links     Display the contents of non-debug sections in separate\n\
+                          debuginfo files.  (Implies -wK)\n"));
+#if DEFAULT_FOR_FOLLOW_LINKS
+  fprintf (stream, _("\
+  -wK --debug-dump=follow-links\n\
+                         Follow links to separate debug info files (default)\n"));
+  fprintf (stream, _("\
+  -wN --debug-dump=no-follow-links\n\
+                         Do not follow links to separate debug info files\n"));
+#else
+  fprintf (stream, _("\
+  -wK --debug-dump=follow-links\n\
+                         Follow links to separate debug info files\n"));
+  fprintf (stream, _("\
+  -wN --debug-dump=no-follow-links\n\
+                         Do not follow links to separate debug info files\n\
+                          (default)\n"));
+#endif
+  fprintf (stream, _("\
+  --dwarf-depth=N        Do not display DIEs at depth N or greater\n"));
+  fprintf (stream, _("\
+  --dwarf-start=N        Display DIEs starting at offset N\n"));
 #ifdef ENABLE_LIBCTF
   fprintf (stream, _("\
-  --ctf=<number|name>    Display CTF info from section <number|name>\n\
+  --ctf=<number|name>    Display CTF info from section <number|name>\n"));
+  fprintf (stream, _("\
   --ctf-parent=<number|name>\n\
-                         Use section <number|name> as the CTF parent\n\n\
+                         Use section <number|name> as the CTF parent\n"));
+  fprintf (stream, _("\
   --ctf-symbols=<number|name>\n\
-                         Use section <number|name> as the CTF external symtab\n\n\
+                         Use section <number|name> as the CTF external symtab\n"));
+  fprintf (stream, _("\
   --ctf-strings=<number|name>\n\
-                         Use section <number|name> as the CTF external strtab\n\n"));
+                         Use section <number|name> as the CTF external strtab\n"));
 #endif
 
 #ifdef SUPPORT_DISASSEMBLY
@@ -4596,11 +4734,16 @@ usage (FILE * stream)
                          Disassemble the contents of section <number|name>\n"));
 #endif
   fprintf (stream, _("\
-  -I --histogram         Display histogram of bucket list lengths\n\
-  -W --wide              Allow output width to exceed 80 characters\n\
-  -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
-  @<file>                Read options from <file>\n\
-  -H --help              Display this information\n\
+  -I --histogram         Display histogram of bucket list lengths\n"));
+  fprintf (stream, _("\
+  -W --wide              Allow output width to exceed 80 characters\n"));
+  fprintf (stream, _("\
+  -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
+  fprintf (stream, _("\
+  @<file>                Read options from <file>\n"));
+  fprintf (stream, _("\
+  -H --help              Display this information\n"));
+  fprintf (stream, _("\
   -v --version           Display the version number of readelf\n"));
 
   if (REPORT_BUGS_TO[0] && stream == stdout)
@@ -4675,7 +4818,7 @@ request_dump (struct dump_data *dumpdata, dump_type type)
   int section;
   char * cp;
 
-  do_dump++;
+  do_dump = true;
   section = strtoul (optarg, & cp, 0);
 
   if (! *cp && section >= 0)
@@ -4693,7 +4836,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
     usage (stderr);
 
   while ((c = getopt_long
-         (argc, argv, "ADHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
+         (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
     {
       switch (c)
        {
@@ -4705,70 +4848,75 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
          break;
 
        case 'a':
-         do_syms = TRUE;
-         do_reloc = TRUE;
-         do_unwind = TRUE;
-         do_dynamic = TRUE;
-         do_header = TRUE;
-         do_sections = TRUE;
-         do_section_groups = TRUE;
-         do_segments = TRUE;
-         do_version = TRUE;
-         do_histogram = TRUE;
-         do_arch = TRUE;
-         do_notes = TRUE;
+         do_syms = true;
+         do_reloc = true;
+         do_unwind = true;
+         do_dynamic = true;
+         do_header = true;
+         do_sections = true;
+         do_section_groups = true;
+         do_segments = true;
+         do_version = true;
+         do_histogram = true;
+         do_arch = true;
+         do_notes = true;
          break;
+
        case 'g':
-         do_section_groups = TRUE;
+         do_section_groups = true;
          break;
        case 't':
        case 'N':
-         do_sections = TRUE;
-         do_section_details = TRUE;
+         do_sections = true;
+         do_section_details = true;
          break;
        case 'e':
-         do_header = TRUE;
-         do_sections = TRUE;
-         do_segments = TRUE;
+         do_header = true;
+         do_sections = true;
+         do_segments = true;
          break;
        case 'A':
-         do_arch = TRUE;
+         do_arch = true;
          break;
        case 'D':
-         do_using_dynamic = TRUE;
+         do_using_dynamic = true;
          break;
        case 'r':
-         do_reloc = TRUE;
+         do_reloc = true;
          break;
        case 'u':
-         do_unwind = TRUE;
+         do_unwind = true;
          break;
        case 'h':
-         do_header = TRUE;
+         do_header = true;
          break;
        case 'l':
-         do_segments = TRUE;
+         do_segments = true;
          break;
        case 's':
-         do_syms = TRUE;
+         do_syms = true;
          break;
        case 'S':
-         do_sections = TRUE;
+         do_sections = true;
          break;
        case 'd':
-         do_dynamic = TRUE;
+         do_dynamic = true;
          break;
        case 'I':
-         do_histogram = TRUE;
+         do_histogram = true;
          break;
        case 'n':
-         do_notes = TRUE;
+         do_notes = true;
          break;
        case 'c':
-         do_archive_index = TRUE;
+         do_archive_index = true;
          break;
        case 'L':
-         do_checks = TRUE;
+         do_checks = true;
+         break;
+       case 'P':
+         process_links = true;
+         do_follow_links = true;
          break;
        case 'x':
          request_dump (dumpdata, HEX_DUMP);
@@ -4780,28 +4928,31 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
          request_dump (dumpdata, RELOC_DUMP);
          break;
        case 'z':
-         decompress_dumps = TRUE;
+         decompress_dumps = true;
          break;
        case 'w':
-         do_dump = TRUE;
-         if (optarg == 0)
+         do_dump = true;
+         if (optarg == NULL)
            {
-             do_debugging = TRUE;
+             do_debugging = true;
              dwarf_select_sections_all ();
            }
          else
            {
-             do_debugging = FALSE;
+             do_debugging = false;
              dwarf_select_sections_by_letters (optarg);
            }
          break;
        case OPTION_DEBUG_DUMP:
-         do_dump = TRUE;
-         if (optarg == 0)
-           do_debugging = TRUE;
+         do_dump = true;
+         if (optarg == NULL)
+           {
+             do_debugging = true;
+             dwarf_select_sections_all ();
+           }
          else
            {
-             do_debugging = FALSE;
+             do_debugging = false;
              dwarf_select_sections_by_names (optarg);
            }
          break;
@@ -4820,23 +4971,29 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
          }
          break;
        case OPTION_DWARF_CHECK:
-         dwarf_check = TRUE;
+         dwarf_check = true;
          break;
        case OPTION_CTF_DUMP:
-         do_ctf = TRUE;
+         do_ctf = true;
          request_dump (dumpdata, CTF_DUMP);
          break;
        case OPTION_CTF_SYMBOLS:
+         free (dump_ctf_symtab_name);
          dump_ctf_symtab_name = strdup (optarg);
          break;
        case OPTION_CTF_STRINGS:
+         free (dump_ctf_strtab_name);
          dump_ctf_strtab_name = strdup (optarg);
          break;
        case OPTION_CTF_PARENT:
+         free (dump_ctf_parent_name);
          dump_ctf_parent_name = strdup (optarg);
          break;
        case OPTION_DYN_SYMS:
-         do_dyn_syms = TRUE;
+         do_dyn_syms = true;
+         break;
+       case OPTION_LTO_SYMS:
+         do_lto_syms = true;
          break;
 #ifdef SUPPORT_DISASSEMBLY
        case 'i':
@@ -4847,14 +5004,60 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
          print_version (program_name);
          break;
        case 'V':
-         do_version = TRUE;
+         do_version = true;
          break;
        case 'W':
-         do_wide = TRUE;
+         do_wide = true;
          break;
        case 'T':
-         do_not_show_symbol_truncation = TRUE;
+         do_not_show_symbol_truncation = true;
+         break;
+       case 'C':
+         do_demangle = true;
+         if (optarg != NULL)
+           {
+             enum demangling_styles style;
+
+             style = cplus_demangle_name_to_style (optarg);
+             if (style == unknown_demangling)
+               error (_("unknown demangling style `%s'"), optarg);
+
+             cplus_demangle_set_style (style);
+           }
+         break;
+       case OPTION_NO_DEMANGLING:
+         do_demangle = false;
+         break;
+       case OPTION_RECURSE_LIMIT:
+         demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
+         break;
+       case OPTION_NO_RECURSE_LIMIT:
+         demangle_flags |= DMGL_NO_RECURSE_LIMIT;
+         break;
+       case OPTION_WITH_SYMBOL_VERSIONS:
+         /* Ignored for backward compatibility.  */
+         break;
+
+       case OPTION_SYM_BASE:
+         sym_base = 0;
+         if (optarg != NULL)
+           {
+             sym_base = strtoul (optarg, NULL, 0);
+             switch (sym_base)
+               {
+                 case 0:
+                 case 8:
+                 case 10:
+                 case 16:
+                   break;
+
+                 default:
+                   sym_base = 0;
+                   break;
+               }
+           }
          break;
+
        default:
          /* xgettext:c-format */
          error (_("Invalid option '-%c'\n"), c);
@@ -4868,15 +5071,16 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
       && !do_segments && !do_header && !do_dump && !do_version
       && !do_histogram && !do_debugging && !do_arch && !do_notes
       && !do_section_groups && !do_archive_index
-      && !do_dyn_syms)
+      && !do_dyn_syms && !do_lto_syms)
     {
       if (do_checks)
        {
-         check_all = TRUE;
-         do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
-         do_segments = do_header = do_dump = do_version = TRUE;
-         do_histogram = do_debugging = do_arch = do_notes = TRUE;
-         do_section_groups = do_archive_index = do_dyn_syms = TRUE;
+         check_all = true;
+         do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
+         do_segments = do_header = do_dump = do_version = true;
+         do_histogram = do_debugging = do_arch = do_notes = true;
+         do_section_groups = do_archive_index = do_dyn_syms = true;
+         do_lto_syms = true;
        }
       else
        usage (stderr);
@@ -4917,7 +5121,7 @@ get_data_encoding (unsigned int encoding)
 
 /* Decode the data held in 'filedata->file_header'.  */
 
-static bfd_boolean
+static bool
 process_file_header (Filedata * filedata)
 {
   Elf_Internal_Ehdr * header = & filedata->file_header;
@@ -4929,16 +5133,20 @@ process_file_header (Filedata * filedata)
     {
       error
        (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
-      return FALSE;
+      return false;
     }
 
-  init_dwarf_regnames_by_elf_machine_code (header->e_machine);
+  if (! filedata->is_separate)
+    init_dwarf_regnames_by_elf_machine_code (header->e_machine);
 
   if (do_header)
     {
       unsigned i;
 
-      printf (_("ELF Header:\n"));
+      if (filedata->is_separate)
+       printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
+      else
+       printf (_("ELF Header:\n"));
       printf (_("  Magic:   "));
       for (i = 0; i < EI_NIDENT; i++)
        printf ("%2.2x ", header->e_ident[i]);
@@ -5032,13 +5240,13 @@ process_file_header (Filedata * filedata)
       filedata->section_headers = NULL;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Read in the program headers from FILEDATA and store them in PHEADERS.
    Returns TRUE upon success, FALSE otherwise.  Loads 32-bit headers.  */
 
-static bfd_boolean
+static bool
 get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
 {
   Elf32_External_Phdr * phdrs;
@@ -5050,11 +5258,11 @@ get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
 
   /* PR binutils/17531: Cope with unexpected section header sizes.  */
   if (size == 0 || num == 0)
-    return FALSE;
+    return false;
   if (size < sizeof * phdrs)
     {
       error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
-      return FALSE;
+      return false;
     }
   if (size > sizeof * phdrs)
     warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
@@ -5062,7 +5270,7 @@ get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
   phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
                                             size, num, _("program headers"));
   if (phdrs == NULL)
-    return FALSE;
+    return false;
 
   for (i = 0, internal = pheaders, external = phdrs;
        i < filedata->file_header.e_phnum;
@@ -5079,13 +5287,13 @@ get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
     }
 
   free (phdrs);
-  return TRUE;
+  return true;
 }
 
 /* Read in the program headers from FILEDATA and store them in PHEADERS.
    Returns TRUE upon success, FALSE otherwise.  Loads 64-bit headers.  */
 
-static bfd_boolean
+static bool
 get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
 {
   Elf64_External_Phdr * phdrs;
@@ -5097,11 +5305,11 @@ get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
 
   /* PR binutils/17531: Cope with unexpected section header sizes.  */
   if (size == 0 || num == 0)
-    return FALSE;
+    return false;
   if (size < sizeof * phdrs)
     {
       error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
-      return FALSE;
+      return false;
     }
   if (size > sizeof * phdrs)
     warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
@@ -5109,7 +5317,7 @@ get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
   phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
                                             size, num, _("program headers"));
   if (!phdrs)
-    return FALSE;
+    return false;
 
   for (i = 0, internal = pheaders, external = phdrs;
        i < filedata->file_header.e_phnum;
@@ -5126,19 +5334,19 @@ get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
     }
 
   free (phdrs);
-  return TRUE;
+  return true;
 }
 
 /* Returns TRUE if the program headers were read into `program_headers'.  */
 
-static bfd_boolean
+static bool
 get_program_headers (Filedata * filedata)
 {
   Elf_Internal_Phdr * phdrs;
 
   /* Check cache of prior read.  */
   if (filedata->program_headers != NULL)
-    return TRUE;
+    return true;
 
   /* Be kind to memory checkers by looking for
      e_phnum values which we know must be invalid.  */
@@ -5148,7 +5356,7 @@ get_program_headers (Filedata * filedata)
     {
       error (_("Too many program headers - %#x - the file is not that big\n"),
             filedata->file_header.e_phnum);
-      return FALSE;
+      return false;
     }
 
   phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
@@ -5157,7 +5365,7 @@ get_program_headers (Filedata * filedata)
     {
       error (_("Out of memory reading %u program headers\n"),
             filedata->file_header.e_phnum);
-      return FALSE;
+      return false;
     }
 
   if (is_32bit_elf
@@ -5165,16 +5373,16 @@ get_program_headers (Filedata * filedata)
       : get_64bit_program_headers (filedata, phdrs))
     {
       filedata->program_headers = phdrs;
-      return TRUE;
+      return true;
     }
 
   free (phdrs);
-  return FALSE;
+  return false;
 }
 
 /* Returns TRUE if the program headers were loaded.  */
 
-static bfd_boolean
+static bool
 process_program_headers (Filedata * filedata)
 {
   Elf_Internal_Phdr * segment;
@@ -5191,16 +5399,27 @@ process_program_headers (Filedata * filedata)
        {
          warn (_("possibly corrupt ELF header - it has a non-zero program"
                  " header offset, but no program headers\n"));
-         return FALSE;
+         return false;
        }
       else if (do_segments)
-       printf (_("\nThere are no program headers in this file.\n"));
-      return TRUE;
+       {
+         if (filedata->is_separate)
+           printf (_("\nThere are no program headers in linked file '%s'.\n"),
+                   filedata->file_name);
+         else
+           printf (_("\nThere are no program headers in this file.\n"));
+       }
+      return true;
     }
 
   if (do_segments && !do_header)
     {
-      printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
+      if (filedata->is_separate)
+       printf ("\nIn linked file '%s' the ELF file type is %s\n",
+               filedata->file_name,
+               get_file_type (filedata->file_header.e_type));
+      else
+       printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
       printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
       printf (ngettext ("There is %d program header, starting at offset %s\n",
                        "There are %d program headers, starting at offset %s\n",
@@ -5210,7 +5429,7 @@ process_program_headers (Filedata * filedata)
     }
 
   if (! get_program_headers (filedata))
-    return TRUE;
+    return true;
 
   if (do_segments)
     {
@@ -5415,22 +5634,21 @@ the .dynamic section is not the same as the dynamic segment\n"));
          break;
 
        case PT_INTERP:
-         if (fseek (filedata->handle,
-                    filedata->archive_file_offset + (long) segment->p_offset,
-                    SEEK_SET))
+         if (segment->p_offset >= filedata->file_size
+             || segment->p_filesz > filedata->file_size - segment->p_offset
+             || segment->p_filesz - 1 >= (size_t) -2
+             || fseek (filedata->handle,
+                       filedata->archive_file_offset + (long) segment->p_offset,
+                       SEEK_SET))
            error (_("Unable to find program interpreter name\n"));
          else
            {
-             char fmt [32];
-             int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
-
-             if (ret >= (int) sizeof (fmt) || ret < 0)
-               error (_("Internal error: failed to create format string to display program interpreter\n"));
-
-             filedata->program_interpreter[0] = 0;
-             if (fscanf (filedata->handle, fmt,
-                         filedata->program_interpreter) <= 0)
-               error (_("Unable to read program interpreter name\n"));
+             size_t len = segment->p_filesz;
+             free (filedata->program_interpreter);
+             filedata->program_interpreter = xmalloc (len + 1);
+             len = fread (filedata->program_interpreter, 1, len,
+                          filedata->handle);
+             filedata->program_interpreter[len] = 0;
 
              if (do_segments)
                printf (_("      [Requesting program interpreter: %s]\n"),
@@ -5468,7 +5686,7 @@ the .dynamic section is not the same as the dynamic segment\n"));
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 
@@ -5507,8 +5725,8 @@ offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
    If PROBE is true, this is just a probe and we do not generate any error
    messages if the load fails.  */
 
-static bfd_boolean
-get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
+static bool
+get_32bit_section_headers (Filedata * filedata, bool probe)
 {
   Elf32_External_Shdr * shdrs;
   Elf_Internal_Shdr *   internal;
@@ -5518,12 +5736,12 @@ get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
 
   /* PR binutils/17531: Cope with unexpected section header sizes.  */
   if (size == 0 || num == 0)
-    return FALSE;
+    return false;
   if (size < sizeof * shdrs)
     {
       if (! probe)
        error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
-      return FALSE;
+      return false;
     }
   if (!probe && size > sizeof * shdrs)
     warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
@@ -5532,9 +5750,8 @@ get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
                                             size, num,
                                            probe ? NULL : _("section headers"));
   if (shdrs == NULL)
-    return FALSE;
+    return false;
 
-  free (filedata->section_headers);
   filedata->section_headers = (Elf_Internal_Shdr *)
     cmalloc (num, sizeof (Elf_Internal_Shdr));
   if (filedata->section_headers == NULL)
@@ -5542,7 +5759,7 @@ get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
       if (!probe)
        error (_("Out of memory reading %u section headers\n"), num);
       free (shdrs);
-      return FALSE;
+      return false;
     }
 
   for (i = 0, internal = filedata->section_headers;
@@ -5566,13 +5783,13 @@ get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
     }
 
   free (shdrs);
-  return TRUE;
+  return true;
 }
 
 /* Like get_32bit_section_headers, except that it fetches 64-bit headers.  */
 
-static bfd_boolean
-get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
+static bool
+get_64bit_section_headers (Filedata * filedata, bool probe)
 {
   Elf64_External_Shdr *  shdrs;
   Elf_Internal_Shdr *    internal;
@@ -5582,13 +5799,13 @@ get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
 
   /* PR binutils/17531: Cope with unexpected section header sizes.  */
   if (size == 0 || num == 0)
-    return FALSE;
+    return false;
 
   if (size < sizeof * shdrs)
     {
       if (! probe)
        error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
-      return FALSE;
+      return false;
     }
 
   if (! probe && size > sizeof * shdrs)
@@ -5599,9 +5816,8 @@ get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
                                             size, num,
                                            probe ? NULL : _("section headers"));
   if (shdrs == NULL)
-    return FALSE;
+    return false;
 
-  free (filedata->section_headers);
   filedata->section_headers = (Elf_Internal_Shdr *)
     cmalloc (num, sizeof (Elf_Internal_Shdr));
   if (filedata->section_headers == NULL)
@@ -5609,7 +5825,7 @@ get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
       if (! probe)
        error (_("Out of memory reading %u section headers\n"), num);
       free (shdrs);
-      return FALSE;
+      return false;
     }
 
   for (i = 0, internal = filedata->section_headers;
@@ -5633,7 +5849,22 @@ get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
     }
 
   free (shdrs);
-  return TRUE;
+  return true;
+}
+
+static bool
+get_section_headers (Filedata *filedata, bool probe)
+{
+  if (filedata->section_headers != NULL)
+    return true;
+
+  if (filedata->file_header.e_shoff == 0)
+    return true;
+
+  if (is_32bit_elf)
+    return get_32bit_section_headers (filedata, probe);
+  else
+    return get_64bit_section_headers (filedata, probe);
 }
 
 static Elf_Internal_Sym *
@@ -5872,6 +6103,17 @@ get_64bit_elf_symbols (Filedata *           filedata,
   return isyms;
 }
 
+static Elf_Internal_Sym *
+get_elf_symbols (Filedata *filedata,
+                Elf_Internal_Shdr *section,
+                unsigned long *num_syms_return)
+{
+  if (is_32bit_elf)
+    return get_32bit_elf_symbols (filedata, section, num_syms_return);
+  else
+    return get_64bit_elf_symbols (filedata, section, num_syms_return);
+}
+
 static const char *
 get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
 {
@@ -5923,6 +6165,8 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
       /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
       /* VLE specific.  */
       /* 25 */ { STRING_COMMA_LEN ("VLE") },
+      /* GNU specific.  */
+      /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
     };
 
   if (do_section_details)
@@ -5955,7 +6199,6 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
            case SHF_TLS:               sindex = 9; break;
            case SHF_EXCLUDE:           sindex = 18; break;
            case SHF_COMPRESSED:        sindex = 20; break;
-           case SHF_GNU_MBIND:         sindex = 24; break;
 
            default:
              sindex = -1;
@@ -6007,10 +6250,28 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
                  if (flag == SHF_PPC_VLE)
                    sindex = 25;
                  break;
+               default:
+                 break;
+               }
 
+             switch (filedata->file_header.e_ident[EI_OSABI])
+               {
+               case ELFOSABI_GNU:
+               case ELFOSABI_FREEBSD:
+                 if (flag == SHF_GNU_RETAIN)
+                   sindex = 26;
+                 /* Fall through */
+               case ELFOSABI_NONE:
+                 if (flag == SHF_GNU_MBIND)
+                   /* We should not recognize SHF_GNU_MBIND for
+                      ELFOSABI_NONE, but binutils as of 2019-07-23 did
+                      not set the EI_OSABI header byte.  */
+                   sindex = 24;
+                 break;
                default:
                  break;
                }
+             break;
            }
 
          if (sindex != -1)
@@ -6053,7 +6314,6 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
            case SHF_TLS:               *p = 'T'; break;
            case SHF_EXCLUDE:           *p = 'E'; break;
            case SHF_COMPRESSED:        *p = 'C'; break;
-           case SHF_GNU_MBIND:         *p = 'D'; break;
 
            default:
              if ((filedata->file_header.e_machine == EM_X86_64
@@ -6063,14 +6323,37 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
                *p = 'l';
              else if (filedata->file_header.e_machine == EM_ARM
                       && flag == SHF_ARM_PURECODE)
-                 *p = 'y';
+               *p = 'y';
              else if (filedata->file_header.e_machine == EM_PPC
                       && flag == SHF_PPC_VLE)
-                 *p = 'v';
+               *p = 'v';
              else if (flag & SHF_MASKOS)
                {
-                 *p = 'o';
-                 sh_flags &= ~ SHF_MASKOS;
+                 switch (filedata->file_header.e_ident[EI_OSABI])
+                   {
+                   case ELFOSABI_GNU:
+                   case ELFOSABI_FREEBSD:
+                     if (flag == SHF_GNU_RETAIN)
+                       {
+                         *p = 'R';
+                         break;
+                       }
+                     /* Fall through */
+                   case ELFOSABI_NONE:
+                     if (flag == SHF_GNU_MBIND)
+                       {
+                         /* We should not recognize SHF_GNU_MBIND for
+                            ELFOSABI_NONE, but binutils as of 2019-07-23 did
+                            not set the EI_OSABI header byte.  */
+                         *p = 'D';
+                         break;
+                       }
+                     /* Fall through */
+                   default:
+                     *p = 'o';
+                     sh_flags &= ~SHF_MASKOS;
+                     break;
+                   }
                }
              else if (flag & SHF_MASKPROC)
                {
@@ -6182,29 +6465,12 @@ get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_ty
     }
 }
 
-static bfd_boolean
+static bool
 process_section_headers (Filedata * filedata)
 {
   Elf_Internal_Shdr * section;
   unsigned int i;
 
-  free (filedata->section_headers);
-  filedata->section_headers = NULL;
-  free (filedata->dynamic_symbols);
-  filedata->dynamic_symbols = NULL;
-  filedata->num_dynamic_syms = 0;
-  free (filedata->dynamic_strings);
-  filedata->dynamic_strings = NULL;
-  filedata->dynamic_strings_length = 0;
-  free (filedata->dynamic_syminfo);
-  filedata->dynamic_syminfo = NULL;
-  while (filedata->symtab_shndx_list != NULL)
-    {
-      elf_section_list *next = filedata->symtab_shndx_list->next;
-      free (filedata->symtab_shndx_list);
-      filedata->symtab_shndx_list = next;
-    }
-
   if (filedata->file_header.e_shnum == 0)
     {
       /* PR binutils/12467.  */
@@ -6212,34 +6478,31 @@ process_section_headers (Filedata * filedata)
        {
          warn (_("possibly corrupt ELF file header - it has a non-zero"
                  " section header offset, but no section headers\n"));
-         return FALSE;
+         return false;
        }
       else if (do_sections)
        printf (_("\nThere are no sections in this file.\n"));
 
-      return TRUE;
+      return true;
     }
 
   if (do_sections && !do_header)
-    printf (ngettext ("There is %d section header, "
-                     "starting at offset 0x%lx:\n",
-                     "There are %d section headers, "
-                     "starting at offset 0x%lx:\n",
-                     filedata->file_header.e_shnum),
-           filedata->file_header.e_shnum,
-           (unsigned long) filedata->file_header.e_shoff);
-
-  if (is_32bit_elf)
-    {
-      if (! get_32bit_section_headers (filedata, FALSE))
-       return FALSE;
-    }
-  else
     {
-      if (! get_64bit_section_headers (filedata, FALSE))
-       return FALSE;
+      if (filedata->is_separate && process_links)
+       printf (_("In linked file '%s': "), filedata->file_name);
+      if (! filedata->is_separate || process_links)
+       printf (ngettext ("There is %d section header, "
+                         "starting at offset 0x%lx:\n",
+                         "There are %d section headers, "
+                         "starting at offset 0x%lx:\n",
+                         filedata->file_header.e_shnum),
+               filedata->file_header.e_shnum,
+               (unsigned long) filedata->file_header.e_shoff);
     }
 
+  if (!get_section_headers (filedata, false))
+    return false;
+
   /* Read in the string table, so that we have names to display.  */
   if (filedata->file_header.e_shstrndx != SHN_UNDEF
        && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
@@ -6332,7 +6595,7 @@ process_section_headers (Filedata * filedata)
        i < filedata->file_header.e_shnum;
        i++, section++)
     {
-      char * name = SECTION_NAME (section);
+      char * name = SECTION_NAME_PRINT (section);
 
       /* Run some sanity checks on the headers and
         possibly fill in some file data as well.  */
@@ -6347,7 +6610,7 @@ process_section_headers (Filedata * filedata)
 
          CHECK_ENTSIZE (section, i, Sym);
          filedata->dynamic_symbols
-           = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
+           = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
          filedata->dynamic_symtab_section = section;
          break;
 
@@ -6415,10 +6678,11 @@ process_section_headers (Filedata * filedata)
       if ((do_debugging || do_debug_info || do_debug_abbrevs
           || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
           || do_debug_aranges || do_debug_frames || do_debug_macinfo
-          || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
+          || do_debug_str || do_debug_str_offsets || do_debug_loc
+          || do_debug_ranges
           || do_debug_addr || do_debug_cu_index || do_debug_links)
-         && (const_strneq (name, ".debug_")
-             || const_strneq (name, ".zdebug_")))
+         && (startswith (name, ".debug_")
+             || startswith (name, ".zdebug_")))
        {
           if (name[1] == 'z')
             name += sizeof (".zdebug_") - 1;
@@ -6426,34 +6690,35 @@ process_section_headers (Filedata * filedata)
             name += sizeof (".debug_") - 1;
 
          if (do_debugging
-             || (do_debug_info     && const_strneq (name, "info"))
-             || (do_debug_info     && const_strneq (name, "types"))
-             || (do_debug_abbrevs  && const_strneq (name, "abbrev"))
+             || (do_debug_info     && startswith (name, "info"))
+             || (do_debug_info     && startswith (name, "types"))
+             || (do_debug_abbrevs  && startswith (name, "abbrev"))
              || (do_debug_lines    && strcmp (name, "line") == 0)
-             || (do_debug_lines    && const_strneq (name, "line."))
-             || (do_debug_pubnames && const_strneq (name, "pubnames"))
-             || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
-             || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
-             || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
-             || (do_debug_aranges  && const_strneq (name, "aranges"))
-             || (do_debug_ranges   && const_strneq (name, "ranges"))
-             || (do_debug_ranges   && const_strneq (name, "rnglists"))
-             || (do_debug_frames   && const_strneq (name, "frame"))
-             || (do_debug_macinfo  && const_strneq (name, "macinfo"))
-             || (do_debug_macinfo  && const_strneq (name, "macro"))
-             || (do_debug_str      && const_strneq (name, "str"))
-             || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
-             || (do_debug_loc      && const_strneq (name, "loc"))
-             || (do_debug_loc      && const_strneq (name, "loclists"))
-             || (do_debug_addr     && const_strneq (name, "addr"))
-             || (do_debug_cu_index && const_strneq (name, "cu_index"))
-             || (do_debug_cu_index && const_strneq (name, "tu_index"))
+             || (do_debug_lines    && startswith (name, "line."))
+             || (do_debug_pubnames && startswith (name, "pubnames"))
+             || (do_debug_pubtypes && startswith (name, "pubtypes"))
+             || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
+             || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
+             || (do_debug_aranges  && startswith (name, "aranges"))
+             || (do_debug_ranges   && startswith (name, "ranges"))
+             || (do_debug_ranges   && startswith (name, "rnglists"))
+             || (do_debug_frames   && startswith (name, "frame"))
+             || (do_debug_macinfo  && startswith (name, "macinfo"))
+             || (do_debug_macinfo  && startswith (name, "macro"))
+             || (do_debug_str      && startswith (name, "str"))
+             || (do_debug_links    && startswith (name, "sup"))
+             || (do_debug_str_offsets && startswith (name, "str_offsets"))
+             || (do_debug_loc      && startswith (name, "loc"))
+             || (do_debug_loc      && startswith (name, "loclists"))
+             || (do_debug_addr     && startswith (name, "addr"))
+             || (do_debug_cu_index && startswith (name, "cu_index"))
+             || (do_debug_cu_index && startswith (name, "tu_index"))
              )
            request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
        }
       /* Linkonce section to be combined with .debug_info at link time.  */
       else if ((do_debugging || do_debug_info)
-              && const_strneq (name, ".gnu.linkonce.wi."))
+              && startswith (name, ".gnu.linkonce.wi."))
        request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
       else if (do_debug_frames && streq (name, ".eh_frame"))
        request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
@@ -6463,7 +6728,7 @@ process_section_headers (Filedata * filedata)
       /* Trace sections for Itanium VMS.  */
       else if ((do_debugging || do_trace_info || do_trace_abbrevs
                 || do_trace_aranges)
-              && const_strneq (name, ".trace_"))
+              && startswith (name, ".trace_"))
        {
           name += sizeof (".trace_") - 1;
 
@@ -6475,15 +6740,20 @@ process_section_headers (Filedata * filedata)
            request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
        }
       else if ((do_debugging || do_debug_links)
-              && (const_strneq (name, ".gnu_debuglink")
-                  || const_strneq (name, ".gnu_debugaltlink")))
+              && (startswith (name, ".gnu_debuglink")
+                  || startswith (name, ".gnu_debugaltlink")))
        request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
     }
 
   if (! do_sections)
-    return TRUE;
+    return true;
+
+  if (filedata->is_separate && ! process_links)
+    return true;
 
-  if (filedata->file_header.e_shnum > 1)
+  if (filedata->is_separate)
+    printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
+  else if (filedata->file_header.e_shnum > 1)
     printf (_("\nSection Headers:\n"));
   else
     printf (_("\nSection Header:\n"));
@@ -6668,7 +6938,7 @@ process_section_headers (Filedata * filedata)
       if (do_section_details)
        printf ("%s\n      ", printable_section_name (filedata, section));
       else
-       print_symbol (-17, SECTION_NAME (section));
+       print_symbol (-17, SECTION_NAME_PRINT (section));
 
       printf (do_wide ? " %-15s " : " %-15.15s ",
              get_section_type_name (filedata, section->sh_type));
@@ -6862,6 +7132,18 @@ process_section_headers (Filedata * filedata)
   W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
   L (link order), O (extra OS processing required), G (group), T (TLS),\n\
   C (compressed), x (unknown), o (OS specific), E (exclude),\n  "));
+      switch (filedata->file_header.e_ident[EI_OSABI])
+       {
+       case ELFOSABI_GNU:
+       case ELFOSABI_FREEBSD:
+         printf (_("R (retain), "));
+         /* Fall through */
+       case ELFOSABI_NONE:
+         printf (_("D (mbind), "));
+         break;
+       default:
+         break;
+       }
       if (filedata->file_header.e_machine == EM_X86_64
          || filedata->file_header.e_machine == EM_L1OM
          || filedata->file_header.e_machine == EM_K1OM)
@@ -6873,20 +7155,20 @@ process_section_headers (Filedata * filedata)
       printf ("p (processor specific)\n");
     }
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
            Elf_Internal_Sym **symtab, unsigned long *nsyms,
            char **strtab, unsigned long *strtablen)
 {
   *strtab = NULL;
   *strtablen = 0;
-  *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
+  *symtab = get_elf_symbols (filedata, symsec, nsyms);
 
   if (*symtab == NULL)
-    return FALSE;
+    return false;
 
   if (symsec->sh_link != 0)
     {
@@ -6898,7 +7180,7 @@ get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
          free (*symtab);
          *symtab = NULL;
          *nsyms = 0;
-         return FALSE;
+         return false;
        }
 
       strsec = filedata->section_headers + symsec->sh_link;
@@ -6910,11 +7192,11 @@ get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
          free (*symtab);
          *symtab = NULL;
          *nsyms = 0;
-         return FALSE;
+         return false;
        }
       *strtablen = strsec->sh_size;
     }
-  return TRUE;
+  return true;
 }
 
 static const char *
@@ -6937,7 +7219,7 @@ get_group_flags (unsigned int flags)
   return buff;
 }
 
-static bfd_boolean
+static bool
 process_section_groups (Filedata * filedata)
 {
   Elf_Internal_Shdr * section;
@@ -6952,21 +7234,26 @@ process_section_groups (Filedata * filedata)
 
   /* Don't process section groups unless needed.  */
   if (!do_unwind && !do_section_groups)
-    return TRUE;
+    return true;
 
   if (filedata->file_header.e_shnum == 0)
     {
       if (do_section_groups)
-       printf (_("\nThere are no sections to group in this file.\n"));
-
-      return TRUE;
+       {
+         if (filedata->is_separate)
+           printf (_("\nThere are no sections group in linked file '%s'.\n"),
+                   filedata->file_name);
+         else
+           printf (_("\nThere are no section groups in this file.\n"));
+       }
+      return true;
     }
 
   if (filedata->section_headers == NULL)
     {
       error (_("Section headers are not available!\n"));
       /* PR 13622: This can happen with a corrupt ELF header.  */
-      return FALSE;
+      return false;
     }
 
   filedata->section_headers_groups
@@ -6977,7 +7264,7 @@ process_section_groups (Filedata * filedata)
     {
       error (_("Out of memory reading %u section group headers\n"),
             filedata->file_header.e_shnum);
-      return FALSE;
+      return false;
     }
 
   /* Scan the sections for the group section.  */
@@ -6991,9 +7278,15 @@ process_section_groups (Filedata * filedata)
   if (filedata->group_count == 0)
     {
       if (do_section_groups)
-       printf (_("\nThere are no section groups in this file.\n"));
+       {
+         if (filedata->is_separate)
+           printf (_("\nThere are no section groups in linked file '%s'.\n"),
+                   filedata->file_name);
+         else
+           printf (_("\nThere are no section groups in this file.\n"));
+       }
 
-      return TRUE;
+      return true;
     }
 
   filedata->section_groups = (struct group *) calloc (filedata->group_count,
@@ -7003,7 +7296,7 @@ process_section_groups (Filedata * filedata)
     {
       error (_("Out of memory reading %lu groups\n"),
             (unsigned long) filedata->group_count);
-      return FALSE;
+      return false;
     }
 
   symtab_sec = NULL;
@@ -7012,6 +7305,10 @@ process_section_groups (Filedata * filedata)
   num_syms = 0;
   strtab = NULL;
   strtab_size = 0;
+
+  if (filedata->is_separate)
+    printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
+
   for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
        i < filedata->file_header.e_shnum;
        i++, section++)
@@ -7039,7 +7336,7 @@ process_section_groups (Filedata * filedata)
            {
              symtab_sec = sec;
              free (symtab);
-             symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
+             symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
            }
 
          if (symtab == NULL)
@@ -7065,7 +7362,8 @@ process_section_groups (Filedata * filedata)
                  continue;
                }
 
-             group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
+             group_name = SECTION_NAME_PRINT (filedata->section_headers
+                                              + sym->st_shndx);
              strtab_sec = NULL;
              free (strtab);
              strtab = NULL;
@@ -7169,12 +7467,12 @@ process_section_groups (Filedata * filedata)
                      /* Intel C/C++ compiler may put section 0 in a
                         section group.  We just warn it the first time
                         and ignore it afterwards.  */
-                     static bfd_boolean warned = FALSE;
+                     static bool warned = false;
                      if (!warned)
                        {
                          error (_("section 0 in group section [%5u]\n"),
                                 filedata->section_headers_groups [entry]->group_index);
-                         warned = TRUE;
+                         warned = true;
                        }
                    }
                }
@@ -7201,7 +7499,7 @@ process_section_groups (Filedata * filedata)
 
   free (symtab);
   free (strtab);
-  return TRUE;
+  return true;
 }
 
 /* Data used to display dynamic fixups.  */
@@ -7226,7 +7524,7 @@ struct ia64_vms_dynimgrela
 /* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
    library).  */
 
-static bfd_boolean
+static bool
 dump_ia64_vms_dynamic_fixups (Filedata *                  filedata,
                              struct ia64_vms_dynfixup *  fixup,
                               const char *                strtab,
@@ -7241,7 +7539,7 @@ dump_ia64_vms_dynamic_fixups (Filedata *                  filedata,
                   sizeof (*imfs), fixup->fixup_rela_cnt,
                   _("dynamic section image fixups"));
   if (!imfs)
-    return FALSE;
+    return false;
 
   if (fixup->needed < strtab_sz)
     lib_name = strtab + fixup->needed;
@@ -7275,12 +7573,12 @@ dump_ia64_vms_dynamic_fixups (Filedata *                  filedata,
     }
 
   free (imfs);
-  return TRUE;
+  return true;
 }
 
 /* Display IA-64 OpenVMS dynamic relocations (used to relocate an image).  */
 
-static bfd_boolean
+static bool
 dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
 {
   Elf64_External_VMS_IMAGE_RELA *imrs;
@@ -7291,7 +7589,7 @@ dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *i
                   sizeof (*imrs), imgrela->img_rela_cnt,
                   _("dynamic section image relocations"));
   if (!imrs)
-    return FALSE;
+    return false;
 
   printf (_("\nImage relocs\n"));
   printf
@@ -7318,12 +7616,12 @@ dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *i
     }
 
   free (imrs);
-  return TRUE;
+  return true;
 }
 
 /* Display IA-64 OpenVMS dynamic relocations and fixups.  */
 
-static bfd_boolean
+static bool
 process_ia64_vms_dynamic_relocs (Filedata * filedata)
 {
   struct ia64_vms_dynfixup fixup;
@@ -7332,7 +7630,7 @@ process_ia64_vms_dynamic_relocs (Filedata * filedata)
   bfd_vma strtab_off = 0;
   bfd_vma strtab_sz = 0;
   char *strtab = NULL;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   memset (&fixup, 0, sizeof (fixup));
   memset (&imgrela, 0, sizeof (imgrela));
@@ -7372,7 +7670,7 @@ process_ia64_vms_dynamic_relocs (Filedata * filedata)
         case DT_IA_64_VMS_FIXUP_RELA_OFF:
           fixup.fixup_rela_off = entry->d_un.d_val;
           if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
-           res = FALSE;
+           res = false;
           break;
         case DT_IA_64_VMS_IMG_RELA_CNT:
          imgrela.img_rela_cnt = entry->d_un.d_val;
@@ -7380,7 +7678,7 @@ process_ia64_vms_dynamic_relocs (Filedata * filedata)
         case DT_IA_64_VMS_IMG_RELA_OFF:
          imgrela.img_rela_off = entry->d_un.d_val;
           if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
-           res = FALSE;
+           res = false;
           break;
 
         default:
@@ -7402,30 +7700,30 @@ static struct
 }
   dynamic_relocations [] =
 {
-  { "REL", DT_REL, DT_RELSZ, FALSE },
-  { "RELA", DT_RELA, DT_RELASZ, TRUE },
+  { "REL", DT_REL, DT_RELSZ, false },
+  { "RELA", DT_RELA, DT_RELASZ, true },
   { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
 };
 
 /* Process the reloc section.  */
 
-static bfd_boolean
+static bool
 process_relocs (Filedata * filedata)
 {
   unsigned long rel_size;
   unsigned long rel_offset;
 
   if (!do_reloc)
-    return TRUE;
+    return true;
 
   if (do_using_dynamic)
     {
       int          is_rela;
       const char * name;
-      bfd_boolean  has_dynamic_reloc;
+      bool  has_dynamic_reloc;
       unsigned int i;
 
-      has_dynamic_reloc = FALSE;
+      has_dynamic_reloc = false;
 
       for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
        {
@@ -7435,7 +7733,7 @@ process_relocs (Filedata * filedata)
          rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
 
          if (rel_size)
-           has_dynamic_reloc = TRUE;
+           has_dynamic_reloc = true;
 
          if (is_rela == UNKNOWN)
            {
@@ -7443,19 +7741,24 @@ process_relocs (Filedata * filedata)
                switch (filedata->dynamic_info[DT_PLTREL])
                  {
                  case DT_REL:
-                   is_rela = FALSE;
+                   is_rela = false;
                    break;
                  case DT_RELA:
-                   is_rela = TRUE;
+                   is_rela = true;
                    break;
                  }
            }
 
          if (rel_size)
            {
-             printf
-               (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
-                name, rel_offset, rel_size);
+             if (filedata->is_separate)
+               printf
+                 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
+                  filedata->file_name, name, rel_offset, rel_size);
+             else
+               printf
+                 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
+                  name, rel_offset, rel_size);
 
              dump_relocations (filedata,
                                offset_from_vma (filedata, rel_offset, rel_size),
@@ -7464,22 +7767,28 @@ process_relocs (Filedata * filedata)
                                filedata->num_dynamic_syms,
                                filedata->dynamic_strings,
                                filedata->dynamic_strings_length,
-                               is_rela, TRUE /* is_dynamic */);
+                               is_rela, true /* is_dynamic */);
            }
        }
 
       if (is_ia64_vms (filedata))
         if (process_ia64_vms_dynamic_relocs (filedata))
-         has_dynamic_reloc = TRUE;
+         has_dynamic_reloc = true;
 
       if (! has_dynamic_reloc)
-       printf (_("\nThere are no dynamic relocations in this file.\n"));
+       {
+         if (filedata->is_separate)
+           printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
+                   filedata->file_name);
+         else
+           printf (_("\nThere are no dynamic relocations in this file.\n"));
+       }
     }
   else
     {
       Elf_Internal_Shdr * section;
       unsigned long i;
-      bfd_boolean found = FALSE;
+      bool found = false;
 
       for (i = 0, section = filedata->section_headers;
           i < filedata->file_header.e_shnum;
@@ -7497,7 +7806,11 @@ process_relocs (Filedata * filedata)
              int is_rela;
              unsigned long num_rela;
 
-             printf (_("\nRelocation section "));
+             if (filedata->is_separate)
+               printf (_("\nIn linked file '%s' relocation section "),
+                       filedata->file_name);
+             else
+               printf (_("\nRelocation section "));
 
              if (filedata->string_table == NULL)
                printf ("%d", section->sh_name);
@@ -7540,9 +7853,9 @@ process_relocs (Filedata * filedata)
              else
                dump_relocations (filedata, rel_offset, rel_size,
                                  NULL, 0, NULL, 0, is_rela,
-                                 FALSE /* is_dynamic */);
+                                 false /* is_dynamic */);
 
-             found = TRUE;
+             found = true;
            }
        }
 
@@ -7553,18 +7866,28 @@ process_relocs (Filedata * filedata)
            {
              if (filedata->dynamic_info[dynamic_relocations [i].size])
                {
-                 printf (_("\nThere are no static relocations in this file."));
+                 if (filedata->is_separate)
+                   printf (_("\nThere are no static relocations in linked file '%s'."),
+                           filedata->file_name);
+                 else
+                   printf (_("\nThere are no static relocations in this file."));
                  printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
 
                  break;
                }
            }
          if (i == ARRAY_SIZE (dynamic_relocations))
-           printf (_("\nThere are no relocations in this file.\n"));
+           {
+             if (filedata->is_separate)
+               printf (_("\nThere are no relocations in linked file '%s'.\n"),
+                       filedata->file_name);
+             else
+               printf (_("\nThere are no relocations in this file.\n"));
+           }
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* An absolute address consists of a section and an offset.  If the
@@ -7674,13 +7997,13 @@ struct ia64_unw_aux_info
   unsigned long                 strtab_size;   /* Size of string table.  */
 };
 
-static bfd_boolean
+static bool
 dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
 {
   struct ia64_unw_table_entry * tp;
   unsigned long j, nfuns;
   int in_body;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
   for (nfuns = 0, j = 0; j < aux->nsyms; j++)
@@ -7729,7 +8052,7 @@ dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
            {
              warn (_("Invalid section %u in table entry %ld\n"),
                    tp->info.section, (long) (tp - aux->table));
-             res = FALSE;
+             res = false;
              continue;
            }
          offset += filedata->section_headers[tp->info.section].sh_addr;
@@ -7741,7 +8064,7 @@ dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
        {
          warn (_("Invalid offset %lx in table entry %ld\n"),
                (long) tp->info.offset, (long) (tp - aux->table));
-         res = FALSE;
+         res = false;
          continue;
        }
 
@@ -7775,7 +8098,7 @@ dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
   return res;
 }
 
-static bfd_boolean
+static bool
 slurp_ia64_unwind_table (Filedata *                  filedata,
                         struct ia64_unw_aux_info *  aux,
                         Elf_Internal_Shdr *         sec)
@@ -7799,7 +8122,7 @@ slurp_ia64_unwind_table (Filedata *                  filedata,
   if (filedata->file_header.e_phnum)
     {
       if (! get_program_headers (filedata))
-         return FALSE;
+         return false;
 
       for (seg = filedata->program_headers;
           seg < filedata->program_headers + filedata->file_header.e_phnum;
@@ -7822,7 +8145,7 @@ slurp_ia64_unwind_table (Filedata *                  filedata,
   table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
                                       _("unwind table"));
   if (!table)
-    return FALSE;
+    return false;
 
   aux->table_len = size / (3 * eh_addr_size);
   aux->table = (struct ia64_unw_table_entry *)
@@ -7859,7 +8182,7 @@ slurp_ia64_unwind_table (Filedata *                  filedata,
          free (aux->table);
          aux->table = NULL;
          aux->table_len = 0;
-         return FALSE;
+         return false;
        }
 
       for (rp = rela; rp < rela + nrelas; ++rp)
@@ -7875,7 +8198,7 @@ slurp_ia64_unwind_table (Filedata *                  filedata,
              continue;
            }
 
-         if (! const_strneq (relname, "R_IA64_SEGREL"))
+         if (! startswith (relname, "R_IA64_SEGREL"))
            {
              warn (_("Skipping unexpected relocation type: %s\n"), relname);
              continue;
@@ -7921,17 +8244,17 @@ slurp_ia64_unwind_table (Filedata *                  filedata,
       free (rela);
     }
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 ia64_process_unwind (Filedata * filedata)
 {
   Elf_Internal_Shdr * sec;
   Elf_Internal_Shdr * unwsec = NULL;
   unsigned long i, unwcount = 0, unwstart = 0;
   struct ia64_unw_aux_info aux;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   memset (& aux, 0, sizeof (aux));
 
@@ -7949,7 +8272,7 @@ ia64_process_unwind (Filedata * filedata)
            }
          if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
                           &aux.strtab, &aux.strtab_size))
-           return FALSE;
+           return false;
        }
       else if (sec->sh_type == SHT_IA_64_UNWIND)
        unwcount++;
@@ -7993,7 +8316,8 @@ ia64_process_unwind (Filedata * filedata)
                {
                  sec = filedata->section_headers + g->section_index;
 
-                 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
+                 if (SECTION_NAME_VALID (sec)
+                     && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
                    break;
                }
 
@@ -8001,14 +8325,19 @@ ia64_process_unwind (Filedata * filedata)
                i = filedata->file_header.e_shnum;
            }
        }
-      else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
+      else if (SECTION_NAME_VALID (unwsec)
+              && startswith (SECTION_NAME (unwsec),
+                             ELF_STRING_ia64_unwind_once))
        {
          /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO.  */
          len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
          suffix = SECTION_NAME (unwsec) + len;
-         for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
+         for (i = 0, sec = filedata->section_headers;
+              i < filedata->file_header.e_shnum;
               ++i, ++sec)
-           if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
+           if (SECTION_NAME_VALID (sec)
+               && startswith (SECTION_NAME (sec),
+                              ELF_STRING_ia64_unwind_info_once)
                && streq (SECTION_NAME (sec) + len2, suffix))
              break;
        }
@@ -8019,11 +8348,14 @@ ia64_process_unwind (Filedata * filedata)
          len = sizeof (ELF_STRING_ia64_unwind) - 1;
          len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
          suffix = "";
-         if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
+         if (SECTION_NAME_VALID (unwsec)
+             && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
            suffix = SECTION_NAME (unwsec) + len;
-         for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
+         for (i = 0, sec = filedata->section_headers;
+              i < filedata->file_header.e_shnum;
               ++i, ++sec)
-           if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
+           if (SECTION_NAME_VALID (sec)
+               && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
                && streq (SECTION_NAME (sec) + len2, suffix))
              break;
        }
@@ -8123,12 +8455,12 @@ struct hppa_unw_aux_info
   unsigned long                  strtab_size;  /* Size of string table.  */
 };
 
-static bfd_boolean
+static bool
 dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
 {
   struct hppa_unw_table_entry * tp;
   unsigned long j, nfuns;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
   for (nfuns = 0, j = 0; j < aux->nsyms; j++)
@@ -8202,7 +8534,7 @@ dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
   return res;
 }
 
-static bfd_boolean
+static bool
 slurp_hppa_unwind_table (Filedata *                  filedata,
                         struct hppa_unw_aux_info *  aux,
                         Elf_Internal_Shdr *         sec)
@@ -8223,7 +8555,7 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
   if (filedata->file_header.e_phnum)
     {
       if (! get_program_headers (filedata))
-       return FALSE;
+       return false;
 
       for (seg = filedata->program_headers;
           seg < filedata->program_headers + filedata->file_header.e_phnum;
@@ -8247,7 +8579,7 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
   table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
                                       _("unwind table"));
   if (!table)
-    return FALSE;
+    return false;
 
   unw_ent_size = 16;
   nentries = size / unw_ent_size;
@@ -8318,7 +8650,7 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
 
       if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
                              & rela, & nrelas))
-       return FALSE;
+       return false;
 
       for (rp = rela; rp < rela + nrelas; ++rp)
        {
@@ -8333,7 +8665,7 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
            }
 
          /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64.  */
-         if (! const_strneq (relname, "R_PARISC_SEGREL"))
+         if (! startswith (relname, "R_PARISC_SEGREL"))
            {
              warn (_("Skipping unexpected relocation type: %s\n"), relname);
              continue;
@@ -8373,20 +8705,20 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
       free (rela);
     }
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 hppa_process_unwind (Filedata * filedata)
 {
   struct hppa_unw_aux_info aux;
   Elf_Internal_Shdr * unwsec = NULL;
   Elf_Internal_Shdr * sec;
   unsigned long i;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (filedata->string_table == NULL)
-    return FALSE;
+    return false;
 
   memset (& aux, 0, sizeof (aux));
 
@@ -8404,9 +8736,10 @@ hppa_process_unwind (Filedata * filedata)
            }
          if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
                           &aux.strtab, &aux.strtab_size))
-           return FALSE;
+           return false;
        }
-      else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
+      else if (SECTION_NAME_VALID (sec)
+              && streq (SECTION_NAME (sec), ".PARISC.unwind"))
        unwsec = sec;
     }
 
@@ -8415,7 +8748,8 @@ hppa_process_unwind (Filedata * filedata)
 
   for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
     {
-      if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
+      if (SECTION_NAME_VALID (sec)
+         && streq (SECTION_NAME (sec), ".PARISC.unwind"))
        {
          unsigned long num_unwind = sec->sh_size / 16;
 
@@ -8429,12 +8763,12 @@ hppa_process_unwind (Filedata * filedata)
                  num_unwind);
 
           if (! slurp_hppa_unwind_table (filedata, &aux, sec))
-           res = FALSE;
+           res = false;
 
          if (res && aux.table_len > 0)
            {
              if (! dump_hppa_unwind (filedata, &aux))
-               res = FALSE;
+               res = false;
            }
 
          free ((char *) aux.table);
@@ -8518,7 +8852,7 @@ arm_free_section (struct arm_section *arm_sec)
       reloc was applied store -1 there.
    5) Return TRUE upon success, FALSE otherwise.  */
 
-static bfd_boolean
+static bool
 get_unwind_section_word (Filedata *                 filedata,
                         struct arm_unw_aux_info *  aux,
                         struct arm_section *       arm_sec,
@@ -8532,10 +8866,10 @@ get_unwind_section_word (Filedata *                 filedata,
   Elf_Internal_Sym *sym;
   const char * relname;
   unsigned int word;
-  bfd_boolean wrapped;
+  bool wrapped;
 
   if (sec == NULL || arm_sec == NULL)
-    return FALSE;
+    return false;
 
   addr->section = SHN_UNDEF;
   addr->offset = 0;
@@ -8573,14 +8907,14 @@ get_unwind_section_word (Filedata *                 filedata,
              if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
                                     relsec->sh_size,
                                     & arm_sec->rela, & arm_sec->nrelas))
-               return FALSE;
+               return false;
            }
          else /* relsec->sh_type == SHT_RELA */
            {
              if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
                                      relsec->sh_size,
                                      & arm_sec->rela, & arm_sec->nrelas))
-               return FALSE;
+               return false;
            }
          break;
        }
@@ -8590,14 +8924,14 @@ get_unwind_section_word (Filedata *                 filedata,
 
   /* If there is no unwind data we can do nothing.  */
   if (arm_sec->data == NULL)
-    return FALSE;
+    return false;
 
   /* If the offset is invalid then fail.  */
   if (/* PR 21343 *//* PR 18879 */
       sec->sh_size < 4
       || word_offset > (sec->sh_size - 4)
       || ((bfd_signed_vma) word_offset) < 0)
-    return FALSE;
+    return false;
 
   /* Get the word at the required offset.  */
   word = byte_get (arm_sec->data + word_offset, 4);
@@ -8606,11 +8940,11 @@ get_unwind_section_word (Filedata *                 filedata,
   if (arm_sec->rela == NULL)
     {
       * wordp = word;
-      return TRUE;
+      return true;
     }
 
   /* Look through the relocs to find the one that applies to the provided offset.  */
-  wrapped = FALSE;
+  wrapped = false;
   for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
     {
       bfd_vma prelval, offset;
@@ -8618,7 +8952,7 @@ get_unwind_section_word (Filedata *                 filedata,
       if (rp->r_offset > word_offset && !wrapped)
        {
          rp = arm_sec->rela;
-         wrapped = TRUE;
+         wrapped = true;
        }
       if (rp->r_offset > word_offset)
        break;
@@ -8724,7 +9058,7 @@ get_unwind_section_word (Filedata *                 filedata,
   *wordp = word;
   arm_sec->next_rela = rp;
 
-  return TRUE;
+  return true;
 }
 
 static const char *tic6x_unwind_regnames[16] =
@@ -8756,7 +9090,7 @@ decode_tic6x_unwind_regmask (unsigned int mask)
       data_offset += 4;                                                \
       if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec,    \
                                     data_offset, & word, & addr, NULL))        \
-       return FALSE;                                           \
+       return false;                                           \
       remaining = 4;                                           \
       more_words--;                                            \
     }                                                          \
@@ -8772,11 +9106,11 @@ decode_tic6x_unwind_regmask (unsigned int mask)
   else                                 \
     {                                  \
       printf (_("[Truncated opcode]\n"));      \
-      return FALSE;                    \
+      return false;                    \
     }                                  \
   printf ("0x%02x ", OP)
 
-static bfd_boolean
+static bool
 decode_arm_unwind_bytecode (Filedata *                 filedata,
                            struct arm_unw_aux_info *  aux,
                            unsigned int               word,
@@ -8787,7 +9121,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
                            struct arm_section *       data_arm_sec)
 {
   struct absaddr addr;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   /* Decode the unwinding instructions.  */
   while (1)
@@ -8823,7 +9157,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
          else
            {
              unsigned int mask = ((op & 0x0f) << 8) | op2;
-             bfd_boolean first = TRUE;
+             bool first = true;
              int i;
 
              printf ("pop {");
@@ -8831,7 +9165,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
                if (mask & (1 << i))
                  {
                    if (first)
-                     first = FALSE;
+                     first = false;
                    else
                      printf (", ");
                    printf ("r%d", 4 + i);
@@ -8849,14 +9183,14 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
       else if ((op & 0xf0) == 0xa0)
        {
          int end = 4 + (op & 0x07);
-         bfd_boolean first = TRUE;
+         bool first = true;
          int i;
 
          printf ("     pop {");
          for (i = 4; i <= end; i++)
            {
              if (first)
-               first = FALSE;
+               first = false;
              else
                printf (", ");
              printf ("r%d", i);
@@ -8879,7 +9213,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
          else
            {
              unsigned int mask = op2 & 0x0f;
-             bfd_boolean first = TRUE;
+             bool first = true;
              int i;
 
              printf ("pop {");
@@ -8887,7 +9221,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
                if (mask & (1 << i))
                  {
                    if (first)
-                     first = FALSE;
+                     first = false;
                    else
                      printf (", ");
                    printf ("r%d", i);
@@ -8910,11 +9244,11 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
          if (i == sizeof (buf))
            {
              error (_("corrupt change to vsp\n"));
-             res = FALSE;
+             res = false;
            }
          else
            {
-             offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
+             offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
              assert (len == i + 1);
              offset = offset * 4 + 0x204;
              printf ("vsp = vsp + %ld", offset);
@@ -8972,7 +9306,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
          else
            {
              unsigned int mask = op2 & 0x0f;
-             bfd_boolean first = TRUE;
+             bool first = true;
              int i;
 
              printf ("pop {");
@@ -8980,7 +9314,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
                if (mask & (1 << i))
                  {
                    if (first)
-                     first = FALSE;
+                     first = false;
                    else
                      printf (", ");
                    printf ("wCGR%d", i);
@@ -8991,7 +9325,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
       else
        {
          printf (_("     [unsupported opcode]"));
-         res = FALSE;
+         res = false;
        }
 
       printf ("\n");
@@ -9000,7 +9334,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
   return res;
 }
 
-static bfd_boolean
+static bool
 decode_tic6x_unwind_bytecode (Filedata *                 filedata,
                              struct arm_unw_aux_info *  aux,
                              unsigned int               word,
@@ -9130,10 +9464,10 @@ decode_tic6x_unwind_bytecode (Filedata *                 filedata,
          if (i == sizeof (buf))
            {
              warn (_("Corrupt stack pointer adjustment detected\n"));
-             return FALSE;
+             return false;
            }
 
-         offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
+         offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
          assert (len == i + 1);
          offset = offset * 8 + 0x408;
          printf (_("sp = sp + %ld"), offset);
@@ -9152,7 +9486,7 @@ decode_tic6x_unwind_bytecode (Filedata *                 filedata,
       putchar ('\n');
     }
 
-  return TRUE;
+  return true;
 }
 
 static bfd_vma
@@ -9170,7 +9504,7 @@ arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
   return offset + where;
 }
 
-static bfd_boolean
+static bool
 decode_arm_unwind (Filedata *                 filedata,
                   struct arm_unw_aux_info *  aux,
                   unsigned int               word,
@@ -9183,7 +9517,7 @@ decode_arm_unwind (Filedata *                 filedata,
   unsigned int more_words = 0;
   struct absaddr addr;
   bfd_vma sym_name = (bfd_vma) -1;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (remaining == 0)
     {
@@ -9194,7 +9528,7 @@ decode_arm_unwind (Filedata *                 filedata,
         the personality routine.  */
       if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
                                     & word, & addr, & sym_name))
-       return FALSE;
+       return false;
 
       remaining = 4;
     }
@@ -9233,10 +9567,10 @@ decode_arm_unwind (Filedata *                 filedata,
         encoding, starting with one byte giving the number of
         words.  */
       if (procname != NULL
-         && (const_strneq (procname, "__gcc_personality_v0")
-             || const_strneq (procname, "__gxx_personality_v0")
-             || const_strneq (procname, "__gcj_personality_v0")
-             || const_strneq (procname, "__gnu_objc_personality_v0")))
+         && (startswith (procname, "__gcc_personality_v0")
+             || startswith (procname, "__gxx_personality_v0")
+             || startswith (procname, "__gcj_personality_v0")
+             || startswith (procname, "__gnu_objc_personality_v0")))
        {
          remaining = 0;
          more_words = 1;
@@ -9244,7 +9578,7 @@ decode_arm_unwind (Filedata *                 filedata,
          if (!remaining)
            {
              printf (_("  [Truncated data]\n"));
-             return FALSE;
+             return false;
            }
          more_words = word >> 24;
          word <<= 8;
@@ -9252,7 +9586,7 @@ decode_arm_unwind (Filedata *                 filedata,
          per_index = -1;
        }
       else
-       return TRUE;
+       return true;
     }
   else
     {
@@ -9268,7 +9602,7 @@ decode_arm_unwind (Filedata *                 filedata,
          && (word & 0x70000000))
        {
          warn (_("Corrupt ARM compact model table entry: %x \n"), word);
-         res = FALSE;
+         res = false;
        }
 
       per_index = (word >> 24) & 0x7f;
@@ -9294,13 +9628,13 @@ decode_arm_unwind (Filedata *                 filedata,
        {
          if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
                                            data_offset, data_sec, data_arm_sec))
-           res = FALSE;
+           res = false;
        }
       else
        {
          warn (_("Unknown ARM compact model index encountered\n"));
          printf (_("  [reserved]\n"));
-         res = FALSE;
+         res = false;
        }
       break;
 
@@ -9309,7 +9643,7 @@ decode_arm_unwind (Filedata *                 filedata,
        {
          if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
                                              data_offset, data_sec, data_arm_sec))
-           res = FALSE;
+           res = false;
        }
       else if (per_index < 5)
        {
@@ -9332,7 +9666,7 @@ decode_arm_unwind (Filedata *                 filedata,
     default:
       error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
             filedata->file_header.e_machine);
-      res = FALSE;
+      res = false;
     }
 
   /* Decode the descriptors.  Not implemented.  */
@@ -9340,7 +9674,7 @@ decode_arm_unwind (Filedata *                 filedata,
   return res;
 }
 
-static bfd_boolean
+static bool
 dump_arm_unwind (Filedata *                 filedata,
                 struct arm_unw_aux_info *  aux,
                 Elf_Internal_Shdr *        exidx_sec)
@@ -9348,7 +9682,7 @@ dump_arm_unwind (Filedata *                 filedata,
   struct arm_section exidx_arm_sec, extab_arm_sec;
   unsigned int i, exidx_len;
   unsigned long j, nfuns;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
   memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
@@ -9377,7 +9711,7 @@ dump_arm_unwind (Filedata *                 filedata,
          free (aux->funtab);
          arm_free_section (& exidx_arm_sec);
          arm_free_section (& extab_arm_sec);
-         return FALSE;
+         return false;
        }
 
       /* ARM EHABI, Section 5:
@@ -9386,7 +9720,7 @@ dump_arm_unwind (Filedata *                 filedata,
       if (exidx_fn & 0x80000000)
        {
          warn (_("corrupt index table entry: %x\n"), exidx_fn);
-         res = FALSE;
+         res = false;
        }
 
       fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
@@ -9428,7 +9762,7 @@ dump_arm_unwind (Filedata *                 filedata,
                  warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
                        (unsigned long) table_offset,
                        printable_section_name (filedata, table_sec));
-                 res = FALSE;
+                 res = false;
                  continue;
                }
            }
@@ -9443,13 +9777,13 @@ dump_arm_unwind (Filedata *                 filedata,
            {
              warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
                    (unsigned long) table);
-             res = FALSE;
+             res = false;
              continue;
            }
 
          if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
                                   &extab_arm_sec))
-           res = FALSE;
+           res = false;
        }
     }
 
@@ -9464,7 +9798,7 @@ dump_arm_unwind (Filedata *                 filedata,
 
 /* Used for both ARM and C6X unwinding tables.  */
 
-static bfd_boolean
+static bool
 arm_process_unwind (Filedata * filedata)
 {
   struct arm_unw_aux_info aux;
@@ -9472,7 +9806,7 @@ arm_process_unwind (Filedata * filedata)
   Elf_Internal_Shdr *sec;
   unsigned long i;
   unsigned int sec_type;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   switch (filedata->file_header.e_machine)
     {
@@ -9487,11 +9821,11 @@ arm_process_unwind (Filedata * filedata)
     default:
       error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
             filedata->file_header.e_machine);
-      return FALSE;
+      return false;
     }
 
   if (filedata->string_table == NULL)
-    return FALSE;
+    return false;
 
   memset (& aux, 0, sizeof (aux));
   aux.filedata = filedata;
@@ -9510,7 +9844,7 @@ arm_process_unwind (Filedata * filedata)
            }
          if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
                           &aux.strtab, &aux.strtab_size))
-           return FALSE;
+           return false;
        }
       else if (sec->sh_type == sec_type)
        unwsec = sec;
@@ -9534,7 +9868,7 @@ arm_process_unwind (Filedata * filedata)
                    num_unwind);
 
            if (! dump_arm_unwind (filedata, &aux, sec))
-             res = FALSE;
+             res = false;
          }
       }
 
@@ -9544,25 +9878,34 @@ arm_process_unwind (Filedata * filedata)
   return res;
 }
 
-static bfd_boolean
+static bool
+no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
+{
+  printf (_("No processor specific unwind information to decode\n"));
+  return true;
+}
+
+static bool
 process_unwind (Filedata * filedata)
 {
   struct unwind_handler
   {
     unsigned int machtype;
-    bfd_boolean (* handler)(Filedata *);
+    bool (* handler)(Filedata *);
   } handlers[] =
   {
     { EM_ARM, arm_process_unwind },
     { EM_IA_64, ia64_process_unwind },
     { EM_PARISC, hppa_process_unwind },
     { EM_TI_C6000, arm_process_unwind },
+    { EM_386, no_processor_specific_unwind },
+    { EM_X86_64, no_processor_specific_unwind },
     { 0, NULL }
   };
   int i;
 
   if (!do_unwind)
-    return TRUE;
+    return true;
 
   for (i = 0; handlers[i].handler != NULL; i++)
     if (filedata->file_header.e_machine == handlers[i].machtype)
@@ -9570,7 +9913,7 @@ process_unwind (Filedata * filedata)
 
   printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
          get_machine_name (filedata->file_header.e_machine));
-  return TRUE;
+  return true;
 }
 
 static void
@@ -9607,13 +9950,13 @@ dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
            "RLD_ORDER_SAFE"
          };
          unsigned int cnt;
-         bfd_boolean first = TRUE;
+         bool first = true;
 
          for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
            if (entry->d_un.d_val & (1 << cnt))
              {
                printf ("%s%s", first ? "" : " ", opts[cnt]);
-               first = FALSE;
+               first = false;
              }
        }
       break;
@@ -9708,7 +10051,7 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
          { DT_HP_GROUP, "HP_GROUP" },
          { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
        };
-       bfd_boolean first = TRUE;
+       bool first = true;
        size_t cnt;
        bfd_vma val = entry->d_un.d_val;
 
@@ -9718,7 +10061,7 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
              if (! first)
                putchar (' ');
              fputs (flags[cnt].str, stdout);
-             first = FALSE;
+             first = false;
              val ^= flags[cnt].bit;
            }
 
@@ -9744,20 +10087,29 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
 
 #define VMS_EPOCH_OFFSET 35067168000000000LL
 #define VMS_GRANULARITY_FACTOR 10000000
+#ifndef INT64_MIN
+#define INT64_MIN (-9223372036854775807LL - 1)
+#endif
 
 /* Display a VMS time in a human readable format.  */
 
 static void
 print_vms_time (bfd_int64_t vmstime)
 {
-  struct tm *tm;
+  struct tm *tm = NULL;
   time_t unxtime;
 
-  unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
-  tm = gmtime (&unxtime);
-  printf ("%04u-%02u-%02uT%02u:%02u:%02u",
-          tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-          tm->tm_hour, tm->tm_min, tm->tm_sec);
+  if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
+    {
+      vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
+      unxtime = vmstime;
+      if (unxtime == vmstime)
+       tm = gmtime (&unxtime);
+    }
+  if (tm != NULL)
+    printf ("%04u-%02u-%02uT%02u:%02u:%02u",
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+           tm->tm_hour, tm->tm_min, tm->tm_sec);
 }
 #endif /* BFD64 */
 
@@ -9820,7 +10172,7 @@ dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
   putchar ('\n');
 }
 
-static bfd_boolean
+static bool
 get_32bit_dynamic_section (Filedata * filedata)
 {
   Elf32_External_Dyn * edyn;
@@ -9832,7 +10184,7 @@ get_32bit_dynamic_section (Filedata * filedata)
                                          filedata->dynamic_size,
                                          _("dynamic section"));
   if (!edyn)
-    return FALSE;
+    return false;
 
   /* SGI's ELF has more than one section in the DYNAMIC segment, and we
      might not have the luxury of section headers.  Look for the DT_NULL
@@ -9853,7 +10205,7 @@ get_32bit_dynamic_section (Filedata * filedata)
       error (_("Out of memory allocating space for %lu dynamic entries\n"),
             (unsigned long) filedata->dynamic_nent);
       free (edyn);
-      return FALSE;
+      return false;
     }
 
   for (ext = edyn, entry = filedata->dynamic_section;
@@ -9866,10 +10218,10 @@ get_32bit_dynamic_section (Filedata * filedata)
 
   free (edyn);
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 get_64bit_dynamic_section (Filedata * filedata)
 {
   Elf64_External_Dyn * edyn;
@@ -9882,7 +10234,7 @@ get_64bit_dynamic_section (Filedata * filedata)
                                          filedata->dynamic_size,
                                          _("dynamic section"));
   if (!edyn)
-    return FALSE;
+    return false;
 
   /* SGI's ELF has more than one section in the DYNAMIC segment, and we
      might not have the luxury of section headers.  Look for the DT_NULL
@@ -9904,7 +10256,7 @@ get_64bit_dynamic_section (Filedata * filedata)
       error (_("Out of memory allocating space for %lu dynamic entries\n"),
             (unsigned long) filedata->dynamic_nent);
       free (edyn);
-      return FALSE;
+      return false;
     }
 
   /* Convert from external to internal formats.  */
@@ -9918,13 +10270,25 @@ get_64bit_dynamic_section (Filedata * filedata)
 
   free (edyn);
 
-  return TRUE;
+  return true;
 }
 
-static void
+static bool
+get_dynamic_section (Filedata *filedata)
+{
+  if (filedata->dynamic_section)
+    return true;
+
+  if (is_32bit_elf)
+    return get_32bit_dynamic_section (filedata);
+  else
+    return get_64bit_dynamic_section (filedata);
+}
+
+static void
 print_dynamic_flags (bfd_vma flags)
 {
-  bfd_boolean first = TRUE;
+  bool first = true;
 
   while (flags)
     {
@@ -9934,7 +10298,7 @@ print_dynamic_flags (bfd_vma flags)
       flags &= ~ flag;
 
       if (first)
-       first = FALSE;
+       first = false;
       else
        putc (' ', stdout);
 
@@ -10245,7 +10609,7 @@ get_num_dynamic_syms (Filedata * filedata)
 
 /* Parse and display the contents of the dynamic section.  */
 
-static bfd_boolean
+static bool
 process_dynamic_section (Filedata * filedata)
 {
   Elf_Internal_Dyn * entry;
@@ -10253,21 +10617,19 @@ process_dynamic_section (Filedata * filedata)
   if (filedata->dynamic_size == 0)
     {
       if (do_dynamic)
-       printf (_("\nThere is no dynamic section in this file.\n"));
+       {
+         if (filedata->is_separate)
+           printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
+                   filedata->file_name);
+         else
+           printf (_("\nThere is no dynamic section in this file.\n"));
+       }
 
-      return TRUE;
+      return true;
     }
 
-  if (is_32bit_elf)
-    {
-      if (! get_32bit_dynamic_section (filedata))
-       return FALSE;
-    }
-  else
-    {
-      if (! get_64bit_dynamic_section (filedata))
-       return FALSE;
-    }
+  if (!get_dynamic_section (filedata))
+    return false;
 
   /* Find the appropriate symbol table.  */
   if (filedata->dynamic_symbols == NULL || do_histogram)
@@ -10307,7 +10669,7 @@ process_dynamic_section (Filedata * filedata)
            {
              error (_("Cannot interpret virtual addresses "
                       "without program headers.\n"));
-             return FALSE;
+             return false;
            }
 
          for (seg = filedata->program_headers;
@@ -10321,7 +10683,7 @@ process_dynamic_section (Filedata * filedata)
                {
                  /* See PR 21379 for a reproducer.  */
                  error (_("Invalid PT_LOAD entry\n"));
-                 return FALSE;
+                 return false;
                }
 
              if (vma >= (seg->p_vaddr & -seg->p_align)
@@ -10351,13 +10713,13 @@ the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
 
                  section.sh_name = filedata->string_table_length;
                  filedata->dynamic_symbols
-                   = GET_ELF_SYMBOLS (filedata, &section,
+                   = get_elf_symbols (filedata, &section,
                                       &filedata->num_dynamic_syms);
                  if (filedata->dynamic_symbols == NULL
                      || filedata->num_dynamic_syms != num_of_syms)
                    {
                      error (_("Corrupt DT_SYMTAB dynamic entry\n"));
-                     return FALSE;
+                     return false;
                    }
                  break;
                }
@@ -10446,7 +10808,7 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
            get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
                      1, syminsz, _("symbol information"));
          if (!extsyminfo)
-           return FALSE;
+           return false;
 
          if (filedata->dynamic_syminfo != NULL)
            {
@@ -10459,7 +10821,7 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
              error (_("Out of memory allocating %lu bytes "
                       "for dynamic symbol info\n"),
                     (unsigned long) syminsz);
-             return FALSE;
+             return false;
            }
 
          filedata->dynamic_syminfo_nent
@@ -10478,12 +10840,30 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
     }
 
   if (do_dynamic && filedata->dynamic_addr)
-    printf (ngettext ("\nDynamic section at offset 0x%lx "
-                     "contains %lu entry:\n",
-                     "\nDynamic section at offset 0x%lx "
-                     "contains %lu entries:\n",
-                     filedata->dynamic_nent),
-           filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
+    {
+      if (filedata->dynamic_nent == 1)
+       {
+         if (filedata->is_separate)
+           printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
+                   filedata->file_name,
+                   filedata->dynamic_addr);
+         else
+           printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
+                   filedata->dynamic_addr);
+       }
+      else
+       {
+         if (filedata->is_separate)
+           printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
+                   filedata->file_name,
+                   filedata->dynamic_addr,
+                   (unsigned long) filedata->dynamic_nent);
+         else
+           printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
+                   filedata->dynamic_addr,
+                   (unsigned long) filedata->dynamic_nent);
+       }
+    }
   if (do_dynamic)
     printf (_("  Tag        Type                         Name/Value\n"));
 
@@ -10820,7 +11200,8 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
                    case DT_NEEDED:
                      printf (_("Shared library: [%s]"), name);
 
-                     if (streq (name, filedata->program_interpreter))
+                     if (filedata->program_interpreter
+                         && streq (name, filedata->program_interpreter))
                        printf (_(" program interpreter"));
                      break;
 
@@ -10941,6 +11322,28 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
            }
          break;
 
+       case DT_GNU_FLAGS_1:
+         if (do_dynamic)
+           {
+             printf (_("Flags:"));
+             if (entry->d_un.d_val == 0)
+               printf (_(" None\n"));
+             else
+               {
+                 unsigned long int val = entry->d_un.d_val;
+
+                 if (val & DF_GNU_1_UNIQUE)
+                   {
+                     printf (" UNIQUE");
+                     val ^= DF_GNU_1_UNIQUE;
+                   }
+                 if (val != 0)
+                   printf (" %lx", val);
+                 puts ("");
+               }
+           }
+         break;
+
        default:
          if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
            filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
@@ -10972,7 +11375,7 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 static char *
@@ -11017,15 +11420,15 @@ get_ver_flags (unsigned int flags)
 
 /* Display the contents of the version sections.  */
 
-static bfd_boolean
+static bool
 process_version_sections (Filedata * filedata)
 {
   Elf_Internal_Shdr * section;
   unsigned i;
-  bfd_boolean found = FALSE;
+  bool found = false;
 
   if (! do_version)
-    return TRUE;
+    return true;
 
   for (i = 0, section = filedata->section_headers;
        i < filedata->file_header.e_shnum;
@@ -11040,15 +11443,23 @@ process_version_sections (Filedata * filedata)
            unsigned long cnt;
            char * endbuf;
 
-           found = TRUE;
+           found = true;
 
-           printf (ngettext ("\nVersion definition section '%s' "
-                             "contains %u entry:\n",
-                             "\nVersion definition section '%s' "
-                             "contains %u entries:\n",
-                             section->sh_info),
-                   printable_section_name (filedata, section),
-                   section->sh_info);
+           if (filedata->is_separate)
+             printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
+                               "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
+                               section->sh_info),
+                     filedata->file_name,
+                     printable_section_name (filedata, section),
+                     section->sh_info);
+           else
+             printf (ngettext ("\nVersion definition section '%s' "
+                               "contains %u entry:\n",
+                               "\nVersion definition section '%s' "
+                               "contains %u entries:\n",
+                               section->sh_info),
+                     printable_section_name (filedata, section),
+                     section->sh_info);
 
            printf (_(" Addr: 0x"));
            printf_vma (section->sh_addr);
@@ -11179,14 +11590,23 @@ process_version_sections (Filedata * filedata)
            unsigned long cnt;
            char * endbuf;
 
-           found = TRUE;
+           found = true;
 
-           printf (ngettext ("\nVersion needs section '%s' "
-                             "contains %u entry:\n",
-                             "\nVersion needs section '%s' "
-                             "contains %u entries:\n",
-                             section->sh_info),
-                   printable_section_name (filedata, section), section->sh_info);
+           if (filedata->is_separate)
+             printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
+                               "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
+                               section->sh_info),
+                     filedata->file_name,
+                     printable_section_name (filedata, section),
+                     section->sh_info);
+           else
+             printf (ngettext ("\nVersion needs section '%s' "
+                               "contains %u entry:\n",
+                               "\nVersion needs section '%s' "
+                               "contains %u entries:\n",
+                               section->sh_info),
+                     printable_section_name (filedata, section),
+                     section->sh_info);
 
            printf (_(" Addr: 0x"));
            printf_vma (section->sh_addr);
@@ -11278,7 +11698,7 @@ process_version_sections (Filedata * filedata)
                  }
 
                if (j < ent.vn_cnt)
-                 warn (_("Missing Version Needs auxillary information\n"));
+                 warn (_("Missing Version Needs auxiliary information\n"));
 
                if (ent.vn_next < sizeof (*entry)
                    && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
@@ -11321,9 +11741,9 @@ process_version_sections (Filedata * filedata)
            if (link_section->sh_link >= filedata->file_header.e_shnum)
              break;
 
-           found = TRUE;
+           found = true;
 
-           symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
+           symbols = get_elf_symbols (filedata, link_section, & num_syms);
            if (symbols == NULL)
              break;
 
@@ -11338,12 +11758,21 @@ process_version_sections (Filedata * filedata)
                break;
              }
 
-           printf (ngettext ("\nVersion symbols section '%s' "
-                             "contains %lu entry:\n",
-                             "\nVersion symbols section '%s' "
-                             "contains %lu entries:\n",
-                             total),
-                   printable_section_name (filedata, section), (unsigned long) total);
+           if (filedata->is_separate)
+             printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
+                               "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
+                               total),
+                     filedata->file_name,
+                     printable_section_name (filedata, section),
+                     (unsigned long) total);
+           else
+             printf (ngettext ("\nVersion symbols section '%s' "
+                               "contains %lu entry:\n",
+                               "\nVersion symbols section '%s' "
+                               "contains %lu entries:\n",
+                               total),
+                     printable_section_name (filedata, section),
+                     (unsigned long) total);
 
            printf (_(" Addr: 0x"));
            printf_vma (section->sh_addr);
@@ -11546,9 +11975,15 @@ process_version_sections (Filedata * filedata)
     }
 
   if (! found)
-    printf (_("\nNo version information found in this file.\n"));
+    {
+      if (filedata->is_separate)
+       printf (_("\nNo version information found in linked file '%s'.\n"),
+               filedata->file_name);
+      else
+       printf (_("\nNo version information found in this file.\n"));
+    }
 
-  return TRUE;
+  return true;
 }
 
 static const char *
@@ -11872,7 +12307,7 @@ get_symbol_index_type (Filedata * filedata, unsigned int type)
 
 static const char *
 get_symbol_version_string (Filedata *                   filedata,
-                          bfd_boolean                  is_dynsym,
+                          bool                         is_dynsym,
                           const char *                 strtab,
                           unsigned long int            strtab_size,
                           unsigned int                 si,
@@ -12044,6 +12479,28 @@ get_symbol_version_string (Filedata *                   filedata,
   return NULL;
 }
 
+/* Display a symbol size on stdout.  Format is based on --sym-base setting.  */
+
+static unsigned int
+print_dynamic_symbol_size (bfd_vma vma, int base)
+{
+  switch (base)
+    {
+    case 8:
+      return print_vma (vma, OCTAL_5);
+
+    case 10:
+      return print_vma (vma, UNSIGNED_5);
+
+    case 16:
+      return print_vma (vma, PREFIX_HEX_5);
+
+    case 0:
+    default:
+      return print_vma (vma, DEC_5);
+    }
+}
+
 static void
 print_dynamic_symbol (Filedata *filedata, unsigned long si,
                      Elf_Internal_Sym *symtab,
@@ -12053,12 +12510,14 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
   const char *version_string;
   enum versioned_symbol_info sym_info;
   unsigned short vna_other;
+  bool is_valid;
+  const char * sstr;
   Elf_Internal_Sym *psym = symtab + si;
-  
+
   printf ("%6ld: ", si);
   print_vma (psym->st_value, LONG_HEX);
   putchar (' ');
-  print_vma (psym->st_size, DEC_5);
+  print_dynamic_symbol_size (psym->st_size, sym_base);
   printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
   printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
   if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
@@ -12076,9 +12535,20 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
     }
   printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
 
-  bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
-                                           psym->st_name);
-  const char * sstr = is_valid  ? strtab + psym->st_name : _("<corrupt>");
+  if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
+      && psym->st_shndx < filedata->file_header.e_shnum
+      && psym->st_name == 0)
+    {
+      is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
+      sstr = is_valid ?
+       SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
+       : _("<corrupt>");
+    }
+  else
+    {
+      is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
+      sstr = is_valid  ? strtab + psym->st_name : _("<corrupt>");
+    }
 
   version_string
     = get_symbol_version_string (filedata,
@@ -12086,7 +12556,7 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
                                  || section->sh_type == SHT_DYNSYM),
                                 strtab, strtab_size, si,
                                 psym, &sym_info, &vna_other);
-  
+
   int len_avail = 21;
   if (! do_wide && version_string != NULL)
     {
@@ -12101,7 +12571,7 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
     }
 
   print_symbol (len_avail, sstr);
-    
+
   if (version_string)
     {
       if (sym_info == symbol_undefined)
@@ -12125,14 +12595,274 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
          si, printable_section_name (filedata, section), section->sh_info);
 }
 
+static const char *
+get_lto_kind (unsigned int kind)
+{
+  switch (kind)
+    {
+    case 0: return "DEF";
+    case 1: return "WEAKDEF";
+    case 2: return "UNDEF";
+    case 3: return "WEAKUNDEF";
+    case 4: return "COMMON";
+    default:
+      break;
+    }
+
+  static char buffer[30];
+  error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
+  sprintf (buffer, "<unknown: %u>", kind);
+  return buffer;
+}
+
+static const char *
+get_lto_visibility (unsigned int visibility)
+{
+  switch (visibility)
+    {
+    case 0: return "DEFAULT";
+    case 1: return "PROTECTED";
+    case 2: return "INTERNAL";
+    case 3: return "HIDDEN";
+    default:
+      break;
+    }
+
+  static char buffer[30];
+  error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
+  sprintf (buffer, "<unknown: %u>", visibility);
+  return buffer;
+}
+
+static const char *
+get_lto_sym_type (unsigned int sym_type)
+{
+  switch (sym_type)
+    {
+    case 0: return "UNKNOWN";
+    case 1: return "FUNCTION";
+    case 2: return "VARIABLE";
+    default:
+      break;
+    }
+
+  static char buffer[30];
+  error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
+  sprintf (buffer, "<unknown: %u>", sym_type);
+  return buffer;
+}
+
+/* Display an LTO format symbol table.
+   FIXME: The format of LTO symbol tables is not formalized.
+   So this code could need changing in the future.  */
+
+static bool
+display_lto_symtab (Filedata *           filedata,
+                   Elf_Internal_Shdr *  section)
+{
+  if (section->sh_size == 0)
+    {
+      if (filedata->is_separate)
+       printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
+               printable_section_name (filedata, section),
+               filedata->file_name);
+      else
+       printf (_("\nLTO Symbol table '%s' is empty!\n"),
+               printable_section_name (filedata, section));
+
+      return true;
+    }
+
+  if (section->sh_size > filedata->file_size)
+    {
+      error (_("Section %s has an invalid sh_size of 0x%lx\n"),
+            printable_section_name (filedata, section),
+            (unsigned long) section->sh_size);
+      return false;
+    }
+
+  void * alloced_data = get_data (NULL, filedata, section->sh_offset,
+                                 section->sh_size, 1, _("LTO symbols"));
+  if (alloced_data == NULL)
+    return false;
+
+  /* Look for extended data for the symbol table.  */
+  Elf_Internal_Shdr * ext;
+  void * ext_data_orig = NULL;
+  char * ext_data = NULL;
+  char * ext_data_end = NULL;
+  char * ext_name = NULL;
+
+  if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
+               SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
+      && ext_name != NULL /* Paranoia.  */
+      && (ext = find_section (filedata, ext_name)) != NULL)
+    {
+      if (ext->sh_size < 3)
+       error (_("LTO Symbol extension table '%s' is empty!\n"),
+              printable_section_name (filedata, ext));
+      else
+       {
+         ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
+                                              ext->sh_size, 1,
+                                              _("LTO ext symbol data"));
+         if (ext_data != NULL)
+           {
+             ext_data_end = ext_data + ext->sh_size;
+             if (* ext_data++ != 1)
+               error (_("Unexpected version number in symbol extension table\n"));
+           }
+       }
+    }
+
+  const unsigned char * data = (const unsigned char *) alloced_data;
+  const unsigned char * end = data + section->sh_size;
+
+  if (filedata->is_separate)
+    printf (_("\nIn linked file '%s': "), filedata->file_name);
+  else
+    printf ("\n");
+
+  if (ext_data_orig != NULL)
+    {
+      if (do_wide)
+       printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
+               printable_section_name (filedata, section),
+               printable_section_name (filedata, ext));
+      else
+       {
+         printf (_("LTO Symbol table '%s'\n"),
+                 printable_section_name (filedata, section));
+         printf (_(" and extension table '%s' contain:\n"),
+                 printable_section_name (filedata, ext));
+       }
+    }
+  else
+    printf (_("LTO Symbol table '%s' contains:\n"),
+           printable_section_name (filedata, section));
+
+  /* FIXME: Add a wide version.  */
+  if (ext_data_orig != NULL)
+    printf (_("  Comdat_Key       Kind  Visibility     Size      Slot      Type  Section Name\n"));
+  else
+    printf (_("  Comdat_Key       Kind  Visibility     Size      Slot Name\n"));
+
+  /* FIXME: We do not handle style prefixes.  */
+
+  while (data < end)
+    {
+      const unsigned char * sym_name = data;
+      data += strnlen ((const char *) sym_name, end - data) + 1;
+      if (data >= end)
+       goto fail;
+
+      const unsigned char * comdat_key = data;
+      data += strnlen ((const char *) comdat_key, end - data) + 1;
+      if (data >= end)
+       goto fail;
+
+      if (data + 2 + 8 + 4 > end)
+       goto fail;
+
+      unsigned int kind = *data++;
+      unsigned int visibility = *data++;
+
+      elf_vma size = byte_get (data, 8);
+      data += 8;
+
+      elf_vma slot = byte_get (data, 4);
+      data += 4;
+
+      if (ext_data != NULL)
+       {
+         if (ext_data < (ext_data_end - 1))
+           {
+             unsigned int sym_type = * ext_data ++;
+             unsigned int sec_kind = * ext_data ++;
+
+             printf ("  %10s %10s %11s %08lx  %08lx %9s %08lx _",
+                     * comdat_key == 0 ? "-" : (char *) comdat_key,
+                     get_lto_kind (kind),
+                     get_lto_visibility (visibility),
+                     (long) size,
+                     (long) slot,
+                     get_lto_sym_type (sym_type),
+                     (long) sec_kind);
+             print_symbol (6, (const char *) sym_name);
+           }
+         else
+           {
+             error (_("Ran out of LTO symbol extension data\n"));
+             ext_data = NULL;
+             /* FIXME: return FAIL result ?  */
+           }
+       }
+      else
+       {
+         printf ("  %10s %10s %11s %08lx  %08lx _",
+                 * comdat_key == 0 ? "-" : (char *) comdat_key,
+                 get_lto_kind (kind),
+                 get_lto_visibility (visibility),
+                 (long) size,
+                 (long) slot);
+         print_symbol (21, (const char *) sym_name);
+       }
+      putchar ('\n');
+    }
+
+  if (ext_data != NULL && ext_data < ext_data_end)
+    {
+      error (_("Data remains in the LTO symbol extension table\n"));
+      goto fail;
+    }
+
+  free (alloced_data);
+  free (ext_data_orig);
+  free (ext_name);
+  return true;
+
+ fail:
+  error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
+  free (alloced_data);
+  free (ext_data_orig);
+  free (ext_name);
+  return false;
+}
+
+/* Display LTO symbol tables.  */
+
+static bool
+process_lto_symbol_tables (Filedata * filedata)
+{
+  Elf_Internal_Shdr * section;
+  unsigned int i;
+  bool res = true;
+
+  if (!do_lto_syms)
+    return true;
+
+  if (filedata->section_headers == NULL)
+    return true;
+
+  for (i = 0, section = filedata->section_headers;
+       i < filedata->file_header.e_shnum;
+       i++, section++)
+    if (SECTION_NAME_VALID (section)
+       && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
+      res &= display_lto_symtab (filedata, section);
+
+  return res;
+}
+
 /* Dump the symbol table.  */
-static bfd_boolean
+
+static bool
 process_symbol_table (Filedata * filedata)
 {
   Elf_Internal_Shdr * section;
 
   if (!do_syms && !do_dyn_syms && !do_histogram)
-    return TRUE;
+    return true;
 
   if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
       && do_syms
@@ -12142,10 +12872,21 @@ process_symbol_table (Filedata * filedata)
     {
       unsigned long si;
 
-      printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
-                       "\nSymbol table for image contains %lu entries:\n",
-                       filedata->num_dynamic_syms),
-             filedata->num_dynamic_syms);
+      if (filedata->is_separate)
+       {
+         printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
+                           "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
+                           filedata->num_dynamic_syms),
+                 filedata->file_name,
+                 filedata->num_dynamic_syms);
+       }
+      else
+       {
+         printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
+                           "\nSymbol table for image contains %lu entries:\n",
+                           filedata->num_dynamic_syms),
+                 filedata->num_dynamic_syms);
+       }
       if (is_32bit_elf)
        printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
       else
@@ -12184,18 +12925,27 @@ process_symbol_table (Filedata * filedata)
            }
 
          num_syms = section->sh_size / section->sh_entsize;
-         printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
-                           "\nSymbol table '%s' contains %lu entries:\n",
-                           num_syms),
-                 printable_section_name (filedata, section),
-                 num_syms);
+
+         if (filedata->is_separate)
+           printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
+                             "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
+                             num_syms),
+                   filedata->file_name,
+                   printable_section_name (filedata, section),
+                   num_syms);
+         else
+           printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
+                             "\nSymbol table '%s' contains %lu entries:\n",
+                             num_syms),
+                   printable_section_name (filedata, section),
+                   num_syms);
 
          if (is_32bit_elf)
            printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
          else
            printf (_("   Num:    Value          Size Type    Bind   Vis      Ndx Name\n"));
 
-         symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
+         symtab = get_elf_symbols (filedata, section, & num_syms);
          if (symtab == NULL)
            continue;
 
@@ -12390,7 +13140,7 @@ process_symbol_table (Filedata * filedata)
   filedata->ngnuchains = 0;
   free (filedata->mipsxlat);
   filedata->mipsxlat = NULL;
-  return TRUE;
+  return true;
 
  err_out:
   free (filedata->gnubuckets);
@@ -12406,30 +13156,38 @@ process_symbol_table (Filedata * filedata)
   filedata->nbuckets = 0;
   free (filedata->chains);
   filedata->chains = NULL;
-  return FALSE;
+  return false;
 }
 
-static bfd_boolean
-process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
+static bool
+process_syminfo (Filedata * filedata)
 {
   unsigned int i;
 
   if (filedata->dynamic_syminfo == NULL
       || !do_dynamic)
     /* No syminfo, this is ok.  */
-    return TRUE;
+    return true;
 
   /* There better should be a dynamic symbol section.  */
   if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
-    return FALSE;
+    return false;
 
-  if (filedata->dynamic_addr)
+  if (filedata->is_separate)
+    printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
+                     "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
+                     filedata->dynamic_syminfo_nent),
+           filedata->file_name,
+           filedata->dynamic_syminfo_offset,
+           filedata->dynamic_syminfo_nent);
+  else
     printf (ngettext ("\nDynamic info segment at offset 0x%lx "
                      "contains %d entry:\n",
                      "\nDynamic info segment at offset 0x%lx "
                      "contains %d entries:\n",
                      filedata->dynamic_syminfo_nent),
-           filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
+           filedata->dynamic_syminfo_offset,
+           filedata->dynamic_syminfo_nent);
 
   printf (_(" Num: Name                           BoundTo     Flags\n"));
   for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
@@ -12481,7 +13239,7 @@ process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
       puts ("");
     }
 
-  return TRUE;
+  return true;
 }
 
 /* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
@@ -12499,7 +13257,7 @@ process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
    for the current section has finished, and any saved state should be
    discarded.  */
 
-static bfd_boolean
+static bool
 target_specific_reloc_handling (Filedata *           filedata,
                                Elf_Internal_Rela *  reloc,
                                unsigned char *      start,
@@ -12526,23 +13284,25 @@ target_specific_reloc_handling (Filedata *           filedata,
        if (reloc == NULL)
          {
            saved_sym = NULL;
-           return TRUE;
+           return true;
          }
 
        switch (reloc_type)
          {
          case 10: /* R_MSP430_SYM_DIFF */
+         case 12: /* R_MSP430_GNU_SUB_ULEB128 */
            if (uses_msp430x_relocs (filedata))
              break;
            /* Fall through.  */
          case 21: /* R_MSP430X_SYM_DIFF */
+         case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
            /* PR 21139.  */
            if (sym_index >= num_syms)
              error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
                     sym_index);
            else
              saved_sym = symtab + sym_index;
-           return TRUE;
+           return true;
 
          case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
          case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
@@ -12550,12 +13310,14 @@ target_specific_reloc_handling (Filedata *           filedata,
 
          case 5: /* R_MSP430_16_BYTE */
          case 9: /* R_MSP430_8 */
+         case 11: /* R_MSP430_GNU_SET_ULEB128 */
            if (uses_msp430x_relocs (filedata))
              break;
            goto handle_sym_diff;
 
          case 2: /* R_MSP430_ABS16 */
          case 15: /* R_MSP430X_ABS16 */
+         case 22: /* R_MSP430X_GNU_SET_ULEB128 */
            if (! uses_msp430x_relocs (filedata))
              break;
            goto handle_sym_diff;
@@ -12563,10 +13325,30 @@ target_specific_reloc_handling (Filedata *           filedata,
          handle_sym_diff:
            if (saved_sym != NULL)
              {
-               int reloc_size = reloc_type == 1 ? 4 : 2;
                bfd_vma value;
+               unsigned int reloc_size = 0;
+               int leb_ret = 0;
+               switch (reloc_type)
+                 {
+                 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
+                   reloc_size = 4;
+                   break;
+                 case 11: /* R_MSP430_GNU_SET_ULEB128 */
+                 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
+                   if (reloc->r_offset < (size_t) (end - start))
+                     read_leb128 (start + reloc->r_offset, end, false,
+                                  &reloc_size, &leb_ret);
+                   break;
+                 default:
+                   reloc_size = 2;
+                   break;
+                 }
 
-               if (sym_index >= num_syms)
+               if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
+                 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
+                          "ULEB128 value\n"),
+                        (long) reloc->r_offset);
+               else if (sym_index >= num_syms)
                  error (_("MSP430 reloc contains invalid symbol index %lu\n"),
                         sym_index);
                else
@@ -12583,7 +13365,7 @@ target_specific_reloc_handling (Filedata *           filedata,
                  }
 
                saved_sym = NULL;
-               return TRUE;
+               return true;
              }
            break;
 
@@ -12603,20 +13385,20 @@ target_specific_reloc_handling (Filedata *           filedata,
        if (reloc == NULL)
          {
            saved_sym = NULL;
-           return TRUE;
+           return true;
          }
 
        switch (reloc_type)
          {
          case 34: /* R_MN10300_ALIGN */
-           return TRUE;
+           return true;
          case 33: /* R_MN10300_SYM_DIFF */
            if (sym_index >= num_syms)
              error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
                     sym_index);
            else
              saved_sym = symtab + sym_index;
-           return TRUE;
+           return true;
 
          case 1: /* R_MN10300_32 */
          case 2: /* R_MN10300_16 */
@@ -12641,7 +13423,7 @@ target_specific_reloc_handling (Filedata *           filedata,
                  }
 
                saved_sym = NULL;
-               return TRUE;
+               return true;
              }
            break;
          default:
@@ -12661,7 +13443,7 @@ target_specific_reloc_handling (Filedata *           filedata,
        if (reloc == NULL)
          {
            saved_sym1 = saved_sym2 = 0;
-           return TRUE;
+           return true;
          }
 
        switch (reloc_type)
@@ -12676,12 +13458,12 @@ target_specific_reloc_handling (Filedata *           filedata,
                saved_sym2 = symtab[sym_index].st_value;
                saved_sym2 += reloc->r_addend;
              }
-           return TRUE;
+           return true;
 
          case 0x83: /* R_RL78_OPsub.  */
            value = saved_sym1 - saved_sym2;
            saved_sym2 = saved_sym1 = 0;
-           return TRUE;
+           return true;
            break;
 
          case 0x41: /* R_RL78_ABS32.  */
@@ -12691,7 +13473,7 @@ target_specific_reloc_handling (Filedata *           filedata,
              error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
                     (long) reloc->r_offset);
            value = 0;
-           return TRUE;
+           return true;
 
          case 0x43: /* R_RL78_ABS16.  */
            if (IN_RANGE (start, end, start + reloc->r_offset, 2))
@@ -12700,7 +13482,7 @@ target_specific_reloc_handling (Filedata *           filedata,
              error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
                     (long) reloc->r_offset);
            value = 0;
-           return TRUE;
+           return true;
 
          default:
            break;
@@ -12709,7 +13491,7 @@ target_specific_reloc_handling (Filedata *           filedata,
       }
     }
 
-  return FALSE;
+  return false;
 }
 
 /* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
@@ -12723,7 +13505,7 @@ target_specific_reloc_handling (Filedata *           filedata,
    the reloc-macros.h header, in the same way that it already creates the
    reloc naming functions.  */
 
-static bfd_boolean
+static bool
 is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -12919,7 +13701,7 @@ is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
          error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
                 filedata->file_header.e_machine);
        prev_warn = filedata->file_header.e_machine;
-       return FALSE;
+       return false;
       }
     }
 }
@@ -12927,7 +13709,7 @@ is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 32-bit pc-relative RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -12996,14 +13778,14 @@ is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
         have already tested for target coverage in is_32bit_abs_reloc.  A
         more helpful warning message will be generated by apply_relocations
         anyway, so just return.  */
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 64-bit absolute RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13038,14 +13820,14 @@ is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_MIPS:
       return reloc_type == 18; /* R_MIPS_64.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
    a 64-bit pc-relative RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13075,14 +13857,14 @@ is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_TILEGX:
       return reloc_type == 5;  /* R_TILEGX_64_PCREL.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 24-bit absolute RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13095,14 +13877,14 @@ is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_Z80:
       return reloc_type == 5; /* R_Z80_24. */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 16-bit absolute RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13168,14 +13950,14 @@ is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_Z80:
       return reloc_type == 4; /* R_Z80_16.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 8-bit absolute RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13185,14 +13967,14 @@ is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_Z80:
       return reloc_type == 1;  /* R_Z80_8.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 6-bit absolute RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13200,14 +13982,14 @@ is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 53; /* R_RISCV_SET6.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 32-bit inplace add RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13216,14 +13998,14 @@ is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 35; /* R_RISCV_ADD32.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 32-bit inplace sub RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13232,14 +14014,14 @@ is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 39; /* R_RISCV_SUB32.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 64-bit inplace add RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13248,14 +14030,14 @@ is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 36; /* R_RISCV_ADD64.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 64-bit inplace sub RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13264,14 +14046,14 @@ is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 40; /* R_RISCV_SUB64.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 16-bit inplace add RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13280,14 +14062,14 @@ is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 34; /* R_RISCV_ADD16.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 16-bit inplace sub RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13296,14 +14078,14 @@ is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 38; /* R_RISCV_SUB16.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 8-bit inplace add RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13312,14 +14094,14 @@ is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 33; /* R_RISCV_ADD8.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 8-bit inplace sub RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
@@ -13328,14 +14110,14 @@ is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 37; /* R_RISCV_SUB8.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 6-bit inplace sub RELA relocation used in DWARF debug sections.  */
 
-static bfd_boolean
+static bool
 is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13343,14 +14125,14 @@ is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_RISCV:
       return reloc_type == 52; /* R_RISCV_SUB6.  */
     default:
-      return FALSE;
+      return false;
     }
 }
 
 /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
    relocation entries (possibly formerly used for SHT_GROUP sections).  */
 
-static bfd_boolean
+static bool
 is_none_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
@@ -13429,28 +14211,28 @@ is_none_reloc (Filedata * filedata, unsigned int reloc_type)
              || reloc_type == 61  /* R_XTENSA_NDIFF16.  */
              || reloc_type == 62  /* R_XTENSA_NDIFF32.  */);
     }
-  return FALSE;
+  return false;
 }
 
 /* Returns TRUE if there is a relocation against
    section NAME at OFFSET bytes.  */
 
-bfd_boolean
+bool
 reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
 {
   Elf_Internal_Rela * relocs;
   Elf_Internal_Rela * rp;
 
   if (dsec == NULL || dsec->reloc_info == NULL)
-    return FALSE;
+    return false;
 
   relocs = (Elf_Internal_Rela *) dsec->reloc_info;
 
   for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
     if (rp->r_offset == offset)
-      return TRUE;
+      return true;
 
-   return FALSE;
+   return false;
 }
 
 /* Apply relocations to a section.
@@ -13463,7 +14245,7 @@ reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
    which can be found in debug sections. FIXME: Add support for
    more relocations ?  */
 
-static bfd_boolean
+static bool
 apply_relocations (Filedata *                 filedata,
                   const Elf_Internal_Shdr *  section,
                   unsigned char *            start,
@@ -13482,14 +14264,14 @@ apply_relocations (Filedata *                 filedata,
 
   if (filedata->file_header.e_type != ET_REL)
     /* No relocs to apply.  */
-    return TRUE;
+    return true;
 
   /* Find the reloc section associated with the section.  */
   for (relsec = filedata->section_headers;
        relsec < filedata->section_headers + filedata->file_header.e_shnum;
        ++relsec)
     {
-      bfd_boolean is_rela;
+      bool is_rela;
       unsigned long num_relocs;
       Elf_Internal_Rela * relocs;
       Elf_Internal_Rela * rp;
@@ -13508,7 +14290,7 @@ apply_relocations (Filedata *                 filedata,
       symsec = filedata->section_headers + relsec->sh_link;
       if (symsec->sh_type != SHT_SYMTAB
          && symsec->sh_type != SHT_DYNSYM)
-       return FALSE;
+       return false;
 
       is_rela = relsec->sh_type == SHT_RELA;
 
@@ -13516,30 +14298,30 @@ apply_relocations (Filedata *                 filedata,
        {
          if (!slurp_rela_relocs (filedata, relsec->sh_offset,
                                   relsec->sh_size, & relocs, & num_relocs))
-           return FALSE;
+           return false;
        }
       else
        {
          if (!slurp_rel_relocs (filedata, relsec->sh_offset,
                                  relsec->sh_size, & relocs, & num_relocs))
-           return FALSE;
+           return false;
        }
 
       /* SH uses RELA but uses in place value instead of the addend field.  */
       if (filedata->file_header.e_machine == EM_SH)
-       is_rela = FALSE;
+       is_rela = false;
 
-      symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
+      symtab = get_elf_symbols (filedata, symsec, & num_syms);
 
       for (rp = relocs; rp < relocs + num_relocs; ++rp)
        {
-         bfd_vma         addend;
-         unsigned int    reloc_type;
-         unsigned int    reloc_size;
-         bfd_boolean     reloc_inplace = FALSE;
-         bfd_boolean     reloc_subtract = FALSE;
-         unsigned char * rloc;
-         unsigned long   sym_index;
+         bfd_vma addend;
+         unsigned int reloc_type;
+         unsigned int reloc_size;
+         bool reloc_inplace = false;
+         bool reloc_subtract = false;
+         unsigned char *rloc;
+         unsigned long sym_index;
 
          reloc_type = get_reloc_type (filedata, rp->r_info);
 
@@ -13565,34 +14347,34 @@ apply_relocations (Filedata *                 filedata,
                   || is_32bit_inplace_add_reloc (filedata, reloc_type))
            {
              reloc_size = 4;
-             reloc_inplace = TRUE;
+             reloc_inplace = true;
            }
          else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
                                                                 reloc_type))
                   || is_64bit_inplace_add_reloc (filedata, reloc_type))
            {
              reloc_size = 8;
-             reloc_inplace = TRUE;
+             reloc_inplace = true;
            }
          else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
                                                                 reloc_type))
                   || is_16bit_inplace_add_reloc (filedata, reloc_type))
            {
              reloc_size = 2;
-             reloc_inplace = TRUE;
+             reloc_inplace = true;
            }
          else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
                                                                reloc_type))
                   || is_8bit_inplace_add_reloc (filedata, reloc_type))
            {
              reloc_size = 1;
-             reloc_inplace = TRUE;
+             reloc_inplace = true;
            }
          else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
                                                                reloc_type)))
            {
              reloc_size = 1;
-             reloc_inplace = TRUE;
+             reloc_inplace = true;
            }
          else
            {
@@ -13710,18 +14492,18 @@ apply_relocations (Filedata *                 filedata,
       break;
     }
 
-  return TRUE;
+  return true;
 }
 
 #ifdef SUPPORT_DISASSEMBLY
-static bfd_boolean
+static bool
 disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
 {
   printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
 
   /* FIXME: XXX -- to be done --- XXX */
 
-  return TRUE;
+  return true;
 }
 #endif
 
@@ -13746,7 +14528,7 @@ get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
 
 /* Uncompresses a section that was compressed using zlib, in place.  */
 
-static bfd_boolean
+static bool
 uncompress_section_contents (unsigned char **   buffer,
                             dwarf_size_type    uncompressed_size,
                             dwarf_size_type *  size)
@@ -13774,49 +14556,55 @@ uncompress_section_contents (unsigned char **   buffer,
   while (strm.avail_in > 0)
     {
       if (rc != Z_OK)
-        goto fail;
+        break;
       strm.next_out = ((Bytef *) uncompressed_buffer
                        + (uncompressed_size - strm.avail_out));
       rc = inflate (&strm, Z_FINISH);
       if (rc != Z_STREAM_END)
-        goto fail;
+        break;
       rc = inflateReset (& strm);
     }
-  rc = inflateEnd (& strm);
-  if (rc != Z_OK
+  if (inflateEnd (& strm) != Z_OK
+      || rc != Z_OK
       || strm.avail_out != 0)
     goto fail;
 
   *buffer = uncompressed_buffer;
   *size = uncompressed_size;
-  return TRUE;
+  return true;
 
  fail:
   free (uncompressed_buffer);
   /* Indicate decompression failure.  */
   *buffer = NULL;
-  return FALSE;
+  return false;
 }
 
-static bfd_boolean
+static bool
 dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
 {
-  Elf_Internal_Shdr *  relsec;
-  bfd_size_type        num_bytes;
-  unsigned char *      data;
-  unsigned char *      end;
-  unsigned char *      real_start;
-  unsigned char *      start;
-  bfd_boolean          some_strings_shown;
+  Elf_Internal_Shdr *relsec;
+  bfd_size_type num_bytes;
+  unsigned char *data;
+  unsigned char *end;
+  unsigned char *real_start;
+  unsigned char *start;
+  bool some_strings_shown;
 
   real_start = start = (unsigned char *) get_section_contents (section, filedata);
   if (start == NULL)
     /* PR 21820: Do not fail if the section was empty.  */
-    return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
+    return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
 
   num_bytes = section->sh_size;
 
-  printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
+  if (filedata->is_separate)
+    printf (_("\nString dump of section '%s' in linked file %s:\n"),
+           printable_section_name (filedata, section),
+           filedata->file_name);
+  else
+    printf (_("\nString dump of section '%s':\n"),
+           printable_section_name (filedata, section));
 
   if (decompress_dumps)
     {
@@ -13899,7 +14687,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
 
   data = start;
   end  = start + num_bytes;
-  some_strings_shown = FALSE;
+  some_strings_shown = false;
 
 #ifdef HAVE_MBSTATE_T
   mbstate_t state;
@@ -13907,7 +14695,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
   memset (& state, 0, sizeof (state));
 #endif
 
-  bfd_boolean continuing = FALSE;
+  bool continuing = false;
 
   while (data < end)
     {
@@ -13922,22 +14710,16 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
          if (continuing)
            {
              printf ("            ");
-             continuing = FALSE;
+             continuing = false;
            }
          else
            {
-#ifndef __MSVCRT__
-             /* PR 11128: Use two separate invocations in order to work
-                around bugs in the Solaris 8 implementation of printf.  */
-             printf ("  [%6tx]  ", data - start);
-#else
-             printf ("  [%6Ix]  ", (size_t) (data - start));
-#endif
+             printf ("  [%6lx]  ", (unsigned long) (data - start));
            }
 
          if (maxlen > 0)
            {
-             char c;
+             char c = 0;
 
              while (maxlen)
                {
@@ -13951,7 +14733,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
                    {
                      printf ("\\n\n");
                      if (*data != 0)
-                       continuing = TRUE;
+                       continuing = true;
                      break;
                    }
 
@@ -13995,7 +14777,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
              printf (_("<corrupt>\n"));
              data = end;
            }
-         some_strings_shown = TRUE;
+         some_strings_shown = true;
        }
     }
 
@@ -14005,17 +14787,17 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
   free (real_start);
 
   putchar ('\n');
-  return TRUE;
+  return true;
 
 error_out:
   free (real_start);
-  return FALSE;
+  return false;
 }
 
-static bfd_boolean
-dump_section_as_bytes (Elf_Internal_Shdr *  section,
-                      Filedata *           filedata,
-                      bfd_boolean          relocate)
+static bool
+dump_section_as_bytes (Elf_Internal_Shdr *section,
+                      Filedata *filedata,
+                      bool relocate)
 {
   Elf_Internal_Shdr * relsec;
   bfd_size_type       bytes;
@@ -14028,11 +14810,17 @@ dump_section_as_bytes (Elf_Internal_Shdr *  section,
   real_start = start = (unsigned char *) get_section_contents (section, filedata);
   if (start == NULL)
     /* PR 21820: Do not fail if the section was empty.  */
-    return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
+    return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
 
   section_size = section->sh_size;
 
-  printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
+  if (filedata->is_separate)
+    printf (_("\nHex dump of section '%s' in linked file %s:\n"),
+           printable_section_name (filedata, section),
+           filedata->file_name);
+  else
+    printf (_("\nHex dump of section '%s':\n"),
+           printable_section_name (filedata, section));
 
   if (decompress_dumps)
     {
@@ -14168,18 +14956,18 @@ dump_section_as_bytes (Elf_Internal_Shdr *  section,
   free (real_start);
 
   putchar ('\n');
-  return TRUE;
+  return true;
 
  error_out:
   free (real_start);
-  return FALSE;
+  return false;
 }
 
 #ifdef ENABLE_LIBCTF
 static ctf_sect_t *
 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
 {
-  buf->cts_name = SECTION_NAME (shdr);
+  buf->cts_name = SECTION_NAME_PRINT (shdr);
   buf->cts_size = shdr->sh_size;
   buf->cts_entsize = shdr->sh_entsize;
 
@@ -14202,17 +14990,38 @@ dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
   return new_s;
 }
 
+/* Dump CTF errors/warnings.  */
+static void
+dump_ctf_errs (ctf_dict_t *fp)
+{
+  ctf_next_t *it = NULL;
+  char *errtext;
+  int is_warning;
+  int err;
+
+  /* Dump accumulated errors and warnings.  */
+  while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
+    {
+      error (_("%s: %s"), is_warning ? _("warning"): _("error"),
+            errtext);
+      free (errtext);
+    }
+  if (err != ECTF_NEXT_END)
+    error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
+}
+
 /* Dump one CTF archive member.  */
 
 static int
-dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
+dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
 {
-  ctf_file_t *parent = (ctf_file_t *) arg;
+  ctf_dict_t *parent = (ctf_dict_t *) arg;
   const char *things[] = {"Header", "Labels", "Data objects",
                          "Function objects", "Variables", "Types", "Strings",
                          ""};
   const char **thing;
   size_t i;
+  int err = 0;
 
   /* Only print out the name of non-default-named archive members.
      The name .ctf appears everywhere, even for things that aren't
@@ -14245,13 +15054,17 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
        {
          error (_("Iteration failed: %s, %s\n"), *thing,
                 ctf_errmsg (ctf_errno (ctf)));
-         return 1;
+         err = 1;
+         goto out;
        }
     }
-  return 0;
+
+ out:
+  dump_ctf_errs (ctf);
+  return err;
 }
 
-static bfd_boolean
+static bool
 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
 {
   Elf_Internal_Shdr *  parent_sec = NULL;
@@ -14266,20 +15079,20 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
   ctf_sect_t *        strsectp = NULL;
   ctf_archive_t *      ctfa = NULL;
   ctf_archive_t *      parenta = NULL, *lookparent;
-  ctf_file_t *         parent = NULL;
+  ctf_dict_t *         parent = NULL;
 
   int err;
-  bfd_boolean ret = FALSE;
+  bool ret = false;
 
   shdr_to_ctf_sect (&ctfsect, section, filedata);
   data = get_section_contents (section, filedata);
   ctfsect.cts_data = data;
 
   if (!dump_ctf_symtab_name)
-    dump_ctf_symtab_name = strdup (".symtab");
+    dump_ctf_symtab_name = strdup (".dynsym");
 
   if (!dump_ctf_strtab_name)
-    dump_ctf_strtab_name = strdup (".strtab");
+    dump_ctf_strtab_name = strdup (".dynstr");
 
   if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
     {
@@ -14296,7 +15109,8 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
       symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
       symsect.cts_data = symdata;
     }
-  if (dump_ctf_strtab_name && dump_ctf_symtab_name[0] != 0)
+
+  if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
     {
       if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
        {
@@ -14312,6 +15126,7 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
       strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
       strsect.cts_data = strdata;
     }
+
   if (dump_ctf_parent_name)
     {
       if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
@@ -14334,15 +15149,20 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
 
   if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
     {
+      dump_ctf_errs (NULL);
       error (_("CTF open failure: %s\n"), ctf_errmsg (err));
       goto fail;
     }
 
+  ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
+                             != ELFDATA2MSB);
+
   if (parentdata)
     {
       if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
                                      &err)) == NULL)
        {
+         dump_ctf_errs (NULL);
          error (_("CTF open failure: %s\n"), ctf_errmsg (err));
          goto fail;
        }
@@ -14354,22 +15174,32 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
   /* Assume that the applicable parent archive member is the default one.
      (This is what all known implementations are expected to do, if they
      put CTFs and their parents in archives together.)  */
-  if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
+  if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
     {
+      dump_ctf_errs (NULL);
       error (_("CTF open failure: %s\n"), ctf_errmsg (err));
       goto fail;
     }
 
-  ret = TRUE;
+  ret = true;
 
-  printf (_("\nDump of CTF section '%s':\n"),
-         printable_section_name (filedata, section));
+  if (filedata->is_separate)
+    printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
+           printable_section_name (filedata, section),
+           filedata->file_name);
+  else
+    printf (_("\nDump of CTF section '%s':\n"),
+           printable_section_name (filedata, section));
 
-  if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
-    ret = FALSE;
+  if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
+    {
+      dump_ctf_errs (NULL);
+      error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
+      ret = false;
+    }
 
  fail:
-  ctf_file_close (parent);
+  ctf_dict_close (parent);
   ctf_close (ctfa);
   ctf_close (parenta);
   free (parentdata);
@@ -14380,7 +15210,7 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
 }
 #endif
 
-static bfd_boolean
+static bool
 load_specific_debug_section (enum dwarf_section_display_enum  debug,
                             const Elf_Internal_Shdr *        sec,
                             void *                           data)
@@ -14393,13 +15223,12 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
     {
       /* If it is already loaded, do nothing.  */
       if (streq (section->filename, filedata->file_name))
-       return TRUE;
+       return true;
       free (section->start);
     }
 
   snprintf (buf, sizeof (buf), _("%s section data"), section->name);
   section->address = sec->sh_addr;
-  section->user_data = NULL;
   section->filename = filedata->file_name;
   section->start = (unsigned char *) get_data (NULL, filedata,
                                                sec->sh_offset, 1,
@@ -14423,20 +15252,20 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
            {
              warn (_("compressed section %s is too small to contain a compression header\n"),
                    section->name);
-             return FALSE;
+             return false;
            }
 
          compression_header_size = get_compression_header (&chdr, start, size);
          if (compression_header_size == 0)
            /* An error message will have already been generated
               by get_compression_header.  */
-           return FALSE;
+           return false;
 
          if (chdr.ch_type != ELFCOMPRESS_ZLIB)
            {
              warn (_("section '%s' has unsupported compress type: %d\n"),
                    section->name, chdr.ch_type);
-             return FALSE;
+             return false;
            }
          uncompressed_size = chdr.ch_size;
          start += compression_header_size;
@@ -14473,7 +15302,7 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
            {
              error (_("Unable to decompress section %s\n"),
                     printable_section_name (filedata, sec));
-             return FALSE;
+             return false;
            }
        }
 
@@ -14481,13 +15310,13 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
     }
 
   if (section->start == NULL)
-    return FALSE;
+    return false;
 
   if (debug_displays [debug].relocate)
     {
       if (! apply_relocations (filedata, sec, section->start, section->size,
                               & section->reloc_info, & section->num_relocs))
-       return FALSE;
+       return false;
     }
   else
     {
@@ -14495,7 +15324,7 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
       section->num_relocs = 0;
     }
 
-  return TRUE;
+  return true;
 }
 
 #if HAVE_LIBDEBUGINFOD
@@ -14503,7 +15332,7 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
 unsigned char *
 get_build_id (void * data)
 {
-  Filedata * filedata = (Filedata *)data;
+  Filedata * filedata = (Filedata *) data;
   Elf_Internal_Shdr * shdr;
   unsigned long i;
 
@@ -14609,7 +15438,7 @@ malformed note encountered in section %s whilst scanning for build-id note\n"),
       /* Check if this is the build-id note. If so then convert the build-id
          bytes to a hex string.  */
       if (inote.namesz > 0
-          && const_strneq (inote.namedata, "GNU")
+          && startswith (inote.namedata, "GNU")
           && inote.type == NT_GNU_BUILD_ID)
         {
           unsigned long j;
@@ -14640,7 +15469,7 @@ malformed note encountered in section %s whilst scanning for build-id note\n"),
    within the list of sections given here.  */
 static unsigned int * section_subset = NULL;
 
-bfd_boolean
+bool
 load_debug_section (enum dwarf_section_display_enum debug, void * data)
 {
   struct dwarf_section * section = &debug_displays [debug].section;
@@ -14649,7 +15478,7 @@ load_debug_section (enum dwarf_section_display_enum debug, void * data)
 
   /* Without section headers we cannot find any sections.  */
   if (filedata->section_headers == NULL)
-    return FALSE;
+    return false;
 
   if (filedata->string_table == NULL
       && filedata->file_header.e_shstrndx != SHN_UNDEF
@@ -14682,7 +15511,7 @@ load_debug_section (enum dwarf_section_display_enum debug, void * data)
        section->name = section->compressed_name;
     }
   if (sec == NULL)
-    return FALSE;
+    return false;
 
   /* If we're loading from a subset of sections, and we've loaded
      a section matching this name before, it's likely that it's a
@@ -14711,20 +15540,20 @@ free_debug_section (enum dwarf_section_display_enum debug)
   section->num_relocs = 0;
 }
 
-static bfd_boolean
+static bool
 display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
 {
-  char * name = SECTION_NAME (section);
+  char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
   const char * print_name = printable_section_name (filedata, section);
   bfd_size_type length;
-  bfd_boolean result = TRUE;
+  bool result = true;
   int i;
 
   length = section->sh_size;
   if (length == 0)
     {
       printf (_("\nSection '%s' has no debugging data.\n"), print_name);
-      return TRUE;
+      return true;
     }
   if (section->sh_type == SHT_NOBITS)
     {
@@ -14734,10 +15563,10 @@ display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * fileda
         stripped with the --only-keep-debug command line option.  */
       printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
              print_name);
-      return FALSE;
+      return false;
     }
 
-  if (const_strneq (name, ".gnu.linkonce.wi."))
+  if (startswith (name, ".gnu.linkonce.wi."))
     name = ".debug_info";
 
   /* See if we know how to display the contents of this section.  */
@@ -14748,15 +15577,15 @@ display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * fileda
       struct dwarf_section *           sec = & display->section;
 
       if (streq (sec->uncompressed_name, name)
-         || (id == line && const_strneq (name, ".debug_line."))
+         || (id == line && startswith (name, ".debug_line."))
          || streq (sec->compressed_name, name))
        {
-         bfd_boolean secondary = (section != find_section (filedata, name));
+         bool secondary = (section != find_section (filedata, name));
 
          if (secondary)
            free_debug_section (id);
 
-         if (i == line && const_strneq (name, ".debug_line."))
+         if (i == line && startswith (name, ".debug_line."))
            sec->name = name;
          else if (streq (sec->uncompressed_name, name))
            sec->name = sec->uncompressed_name;
@@ -14773,7 +15602,7 @@ display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * fileda
 
              section_subset = NULL;
 
-             if (secondary || (id != info && id != abbrev))
+             if (secondary || (id != info && id != abbrev && id != debug_addr))
                free_debug_section (id);
            }
          break;
@@ -14783,7 +15612,7 @@ display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * fileda
   if (i == max)
     {
       printf (_("Unrecognized debug section: %s\n"), print_name);
-      result = FALSE;
+      result = false;
     }
 
   return result;
@@ -14800,30 +15629,31 @@ initialise_dumps_byname (Filedata * filedata)
   for (cur = dump_sects_byname; cur; cur = cur->next)
     {
       unsigned int i;
-      bfd_boolean any = FALSE;
+      bool any = false;
 
       for (i = 0; i < filedata->file_header.e_shnum; i++)
-       if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
+       if (SECTION_NAME_VALID (filedata->section_headers + i)
+           && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
          {
            request_dump_bynumber (&filedata->dump, i, cur->type);
-           any = TRUE;
+           any = true;
          }
 
-      if (!any)
-       warn (_("Section '%s' was not dumped because it does not exist!\n"),
+      if (!any && !filedata->is_separate)
+       warn (_("Section '%s' was not dumped because it does not exist\n"),
              cur->name);
     }
 }
 
-static bfd_boolean
+static bool
 process_section_contents (Filedata * filedata)
 {
   Elf_Internal_Shdr * section;
   unsigned int i;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (! do_dump)
-    return TRUE;
+    return true;
 
   initialise_dumps_byname (filedata);
 
@@ -14833,56 +15663,59 @@ process_section_contents (Filedata * filedata)
     {
       dump_type dump = filedata->dump.dump_sects[i];
 
+      if (filedata->is_separate && ! process_links)
+       dump &= DEBUG_DUMP;
+
 #ifdef SUPPORT_DISASSEMBLY
       if (dump & DISASS_DUMP)
        {
          if (! disassemble_section (section, filedata))
-           res = FALSE;
+           res = false;
        }
 #endif
       if (dump & HEX_DUMP)
        {
-         if (! dump_section_as_bytes (section, filedata, FALSE))
-           res = FALSE;
+         if (! dump_section_as_bytes (section, filedata, false))
+           res = false;
        }
 
       if (dump & RELOC_DUMP)
        {
-         if (! dump_section_as_bytes (section, filedata, TRUE))
-           res = FALSE;
+         if (! dump_section_as_bytes (section, filedata, true))
+           res = false;
        }
 
       if (dump & STRING_DUMP)
        {
          if (! dump_section_as_strings (section, filedata))
-           res = FALSE;
+           res = false;
        }
 
       if (dump & DEBUG_DUMP)
        {
          if (! display_debug_section (i, section, filedata))
-           res = FALSE;
+           res = false;
        }
 
 #ifdef ENABLE_LIBCTF
       if (dump & CTF_DUMP)
        {
          if (! dump_section_as_ctf (section, filedata))
-           res = FALSE;
+           res = false;
        }
 #endif
     }
 
-  /* Check to see if the user requested a
-     dump of a section that does not exist.  */
-  while (i < filedata->dump.num_dump_sects)
+  if (! filedata->is_separate)
     {
-      if (filedata->dump.dump_sects[i])
-       {
-         warn (_("Section %d was not dumped because it does not exist!\n"), i);
-         res = FALSE;
-       }
-      i++;
+      /* Check to see if the user requested a
+        dump of a section that does not exist.  */
+      for (; i < filedata->dump.num_dump_sects; i++)
+       if (filedata->dump.dump_sects[i])
+         {
+           warn (_("Section %d was not dumped because it does not exist!\n"), i);
+           res = false;
+         }
     }
 
   return res;
@@ -14893,16 +15726,16 @@ process_mips_fpe_exception (int mask)
 {
   if (mask)
     {
-      bfd_boolean first = TRUE;
+      bool first = true;
 
       if (mask & OEX_FPU_INEX)
-       fputs ("INEX", stdout), first = FALSE;
+       fputs ("INEX", stdout), first = false;
       if (mask & OEX_FPU_UFLO)
-       printf ("%sUFLO", first ? "" : "|"), first = FALSE;
+       printf ("%sUFLO", first ? "" : "|"), first = false;
       if (mask & OEX_FPU_OFLO)
-       printf ("%sOFLO", first ? "" : "|"), first = FALSE;
+       printf ("%sOFLO", first ? "" : "|"), first = false;
       if (mask & OEX_FPU_DIV0)
-       printf ("%sDIV0", first ? "" : "|"), first = FALSE;
+       printf ("%sDIV0", first ? "" : "|"), first = false;
       if (mask & OEX_FPU_INVAL)
        printf ("%sINVAL", first ? "" : "|");
     }
@@ -15140,77 +15973,77 @@ typedef struct
   const char * name;
   /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup.  */
   unsigned int type;
-  const char *table;
+  const char *const *table;
 } arm_attr_public_tag;
 
-static const char * arm_attr_tag_CPU_arch[] =
+static const char *const arm_attr_tag_CPU_arch[] =
   {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
    "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
    "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
-static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
-static const char * arm_attr_tag_THUMB_ISA_use[] =
+static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
+static const char *const arm_attr_tag_THUMB_ISA_use[] =
   {"No", "Thumb-1", "Thumb-2", "Yes"};
-static const char * arm_attr_tag_FP_arch[] =
+static const char *const arm_attr_tag_FP_arch[] =
   {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
    "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
-static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
-static const char * arm_attr_tag_Advanced_SIMD_arch[] =
+static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
+static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
   {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
    "NEON for ARMv8.1"};
-static const char * arm_attr_tag_PCS_config[] =
+static const char *const arm_attr_tag_PCS_config[] =
   {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
    "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
-static const char * arm_attr_tag_ABI_PCS_R9_use[] =
+static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
   {"V6", "SB", "TLS", "Unused"};
-static const char * arm_attr_tag_ABI_PCS_RW_data[] =
+static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
   {"Absolute", "PC-relative", "SB-relative", "None"};
-static const char * arm_attr_tag_ABI_PCS_RO_data[] =
+static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
   {"Absolute", "PC-relative", "None"};
-static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
+static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
   {"None", "direct", "GOT-indirect"};
-static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
+static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
   {"None", "??? 1", "2", "??? 3", "4"};
-static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
-static const char * arm_attr_tag_ABI_FP_denormal[] =
+static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
+static const char *const arm_attr_tag_ABI_FP_denormal[] =
   {"Unused", "Needed", "Sign only"};
-static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
-static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
-static const char * arm_attr_tag_ABI_FP_number_model[] =
+static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
+static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
+static const char *const arm_attr_tag_ABI_FP_number_model[] =
   {"Unused", "Finite", "RTABI", "IEEE 754"};
-static const char * arm_attr_tag_ABI_enum_size[] =
+static const char *const arm_attr_tag_ABI_enum_size[] =
   {"Unused", "small", "int", "forced to int"};
-static const char * arm_attr_tag_ABI_HardFP_use[] =
+static const char *const arm_attr_tag_ABI_HardFP_use[] =
   {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
-static const char * arm_attr_tag_ABI_VFP_args[] =
+static const char *const arm_attr_tag_ABI_VFP_args[] =
   {"AAPCS", "VFP registers", "custom", "compatible"};
-static const char * arm_attr_tag_ABI_WMMX_args[] =
+static const char *const arm_attr_tag_ABI_WMMX_args[] =
   {"AAPCS", "WMMX registers", "custom"};
-static const char * arm_attr_tag_ABI_optimization_goals[] =
+static const char *const arm_attr_tag_ABI_optimization_goals[] =
   {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
     "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
-static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
+static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
   {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
     "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
-static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
-static const char * arm_attr_tag_FP_HP_extension[] =
+static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
+static const char *const arm_attr_tag_FP_HP_extension[] =
   {"Not Allowed", "Allowed"};
-static const char * arm_attr_tag_ABI_FP_16bit_format[] =
+static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
   {"None", "IEEE 754", "Alternative Format"};
-static const char * arm_attr_tag_DSP_extension[] =
+static const char *const arm_attr_tag_DSP_extension[] =
   {"Follow architecture", "Allowed"};
-static const char * arm_attr_tag_MPextension_use[] =
+static const char *const arm_attr_tag_MPextension_use[] =
   {"Not Allowed", "Allowed"};
-static const char * arm_attr_tag_DIV_use[] =
+static const char *const arm_attr_tag_DIV_use[] =
   {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
     "Allowed in v7-A with integer division extension"};
-static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
-static const char * arm_attr_tag_Virtualization_use[] =
+static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
+static const char *const arm_attr_tag_Virtualization_use[] =
   {"Not Allowed", "TrustZone", "Virtualization Extensions",
     "TrustZone and Virtualization Extensions"};
-static const char * arm_attr_tag_MPextension_use_legacy[] =
+static const char *const arm_attr_tag_MPextension_use_legacy[] =
   {"Not Allowed", "Allowed"};
 
-static const char * arm_attr_tag_MVE_arch[] =
+static const char *const arm_attr_tag_MVE_arch[] =
   {"No MVE", "MVE Integer only", "MVE Integer and FP"};
 
 #define LOOKUP(id, name) \
@@ -15651,40 +16484,40 @@ display_sparc_hwcaps (unsigned int mask)
 {
   if (mask)
     {
-      bfd_boolean first = TRUE;
+      bool first = true;
 
       if (mask & ELF_SPARC_HWCAP_MUL32)
-       fputs ("mul32", stdout), first = FALSE;
+       fputs ("mul32", stdout), first = false;
       if (mask & ELF_SPARC_HWCAP_DIV32)
-       printf ("%sdiv32", first ? "" : "|"), first = FALSE;
+       printf ("%sdiv32", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_FSMULD)
-       printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
+       printf ("%sfsmuld", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_V8PLUS)
-       printf ("%sv8plus", first ? "" : "|"), first = FALSE;
+       printf ("%sv8plus", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_POPC)
-       printf ("%spopc", first ? "" : "|"), first = FALSE;
+       printf ("%spopc", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_VIS)
-       printf ("%svis", first ? "" : "|"), first = FALSE;
+       printf ("%svis", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_VIS2)
-       printf ("%svis2", first ? "" : "|"), first = FALSE;
+       printf ("%svis2", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
-       printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
+       printf ("%sASIBlkInit", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_FMAF)
-       printf ("%sfmaf", first ? "" : "|"), first = FALSE;
+       printf ("%sfmaf", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_VIS3)
-       printf ("%svis3", first ? "" : "|"), first = FALSE;
+       printf ("%svis3", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_HPC)
-       printf ("%shpc", first ? "" : "|"), first = FALSE;
+       printf ("%shpc", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_RANDOM)
-       printf ("%srandom", first ? "" : "|"), first = FALSE;
+       printf ("%srandom", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_TRANS)
-       printf ("%strans", first ? "" : "|"), first = FALSE;
+       printf ("%strans", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_FJFMAU)
-       printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
+       printf ("%sfjfmau", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_IMA)
-       printf ("%sima", first ? "" : "|"), first = FALSE;
+       printf ("%sima", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
-       printf ("%scspare", first ? "" : "|"), first = FALSE;
+       printf ("%scspare", first ? "" : "|"), first = false;
     }
   else
     fputc ('0', stdout);
@@ -15696,30 +16529,30 @@ display_sparc_hwcaps2 (unsigned int mask)
 {
   if (mask)
     {
-      bfd_boolean first = TRUE;
+      bool first = true;
 
       if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
-       fputs ("fjathplus", stdout), first = FALSE;
+       fputs ("fjathplus", stdout), first = false;
       if (mask & ELF_SPARC_HWCAP2_VIS3B)
-       printf ("%svis3b", first ? "" : "|"), first = FALSE;
+       printf ("%svis3b", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_ADP)
-       printf ("%sadp", first ? "" : "|"), first = FALSE;
+       printf ("%sadp", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_SPARC5)
-       printf ("%ssparc5", first ? "" : "|"), first = FALSE;
+       printf ("%ssparc5", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_MWAIT)
-       printf ("%smwait", first ? "" : "|"), first = FALSE;
+       printf ("%smwait", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_XMPMUL)
-       printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
+       printf ("%sxmpmul", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_XMONT)
-       printf ("%sxmont2", first ? "" : "|"), first = FALSE;
+       printf ("%sxmont2", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_NSEC)
-       printf ("%snsec", first ? "" : "|"), first = FALSE;
+       printf ("%snsec", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
-       printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
+       printf ("%sfjathhpc", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_FJDES)
-       printf ("%sfjdes", first ? "" : "|"), first = FALSE;
+       printf ("%sfjdes", first ? "" : "|"), first = false;
       if (mask & ELF_SPARC_HWCAP2_FJAES)
-       printf ("%sfjaes", first ? "" : "|"), first = FALSE;
+       printf ("%sfjaes", first ? "" : "|"), first = false;
     }
   else
     fputc ('0', stdout);
@@ -16111,7 +16944,7 @@ display_raw_attribute (unsigned char * p, unsigned char const * const end)
 }
 
 static unsigned char *
-display_msp430x_attribute (unsigned char * p,
+display_msp430_attribute (unsigned char * p,
                           const unsigned char * const end)
 {
   unsigned int val;
@@ -16295,33 +17128,137 @@ display_riscv_attribute (unsigned char *p,
   return p;
 }
 
-static bfd_boolean
-process_attributes (Filedata * filedata,
-                   const char * public_name,
-                   unsigned int proc_type,
-                   unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
-                   unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
+static unsigned char *
+display_csky_attribute (unsigned char * p,
+                       const unsigned char * const end)
 {
-  Elf_Internal_Shdr * sect;
-  unsigned i;
-  bfd_boolean res = TRUE;
+  unsigned int tag;
+  unsigned int val;
+  READ_ULEB (tag, p, end);
 
-  /* Find the section header so that we get the size.  */
-  for (i = 0, sect = filedata->section_headers;
-       i < filedata->file_header.e_shnum;
-       i++, sect++)
+  if (tag >= Tag_CSKY_MAX)
     {
-      unsigned char * contents;
-      unsigned char * p;
+      return display_tag_value (-1, p, end);
+    }
 
-      if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
-       continue;
+  switch (tag)
+    {
+    case Tag_CSKY_ARCH_NAME:
+      printf ("  Tag_CSKY_ARCH_NAME:\t\t");
+      return display_tag_value (-1, p, end);
+    case Tag_CSKY_CPU_NAME:
+      printf ("  Tag_CSKY_CPU_NAME:\t\t");
+      return display_tag_value (-1, p, end);
+
+    case Tag_CSKY_ISA_FLAGS:
+      printf ("  Tag_CSKY_ISA_FLAGS:\t\t");
+      return display_tag_value (0, p, end);
+    case Tag_CSKY_ISA_EXT_FLAGS:
+      printf ("  Tag_CSKY_ISA_EXT_FLAGS:\t");
+      return display_tag_value (0, p, end);
+
+    case Tag_CSKY_DSP_VERSION:
+      printf ("  Tag_CSKY_DSP_VERSION:\t\t");
+      READ_ULEB (val, p, end);
+      if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
+       printf ("DSP Extension\n");
+      else if (val == VAL_CSKY_DSP_VERSION_2)
+       printf ("DSP 2.0\n");
+      break;
+
+    case Tag_CSKY_VDSP_VERSION:
+      printf ("  Tag_CSKY_VDSP_VERSION:\t");
+      READ_ULEB (val, p, end);
+      printf ("VDSP Version %d\n", val);
+      break;
+
+    case Tag_CSKY_FPU_VERSION:
+      printf ("  Tag_CSKY_FPU_VERSION:\t\t");
+      READ_ULEB (val, p, end);
+      if (val == VAL_CSKY_FPU_VERSION_1)
+       printf ("ABIV1 FPU Version 1\n");
+      else if (val == VAL_CSKY_FPU_VERSION_2)
+       printf ("FPU Version 2\n");
+      break;
+
+    case Tag_CSKY_FPU_ABI:
+      printf ("  Tag_CSKY_FPU_ABI:\t\t");
+      READ_ULEB (val, p, end);
+      if (val == VAL_CSKY_FPU_ABI_HARD)
+       printf ("Hard\n");
+      else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
+       printf ("SoftFP\n");
+      else if (val == VAL_CSKY_FPU_ABI_SOFT)
+       printf ("Soft\n");
+      break;
+    case Tag_CSKY_FPU_ROUNDING:
+      READ_ULEB (val, p, end);
+      if (val == 1) {
+       printf ("  Tag_CSKY_FPU_ROUNDING:\t");
+       printf ("Needed\n");
+      }
+      break;
+    case Tag_CSKY_FPU_DENORMAL:
+      READ_ULEB (val, p, end);
+      if (val == 1) {
+       printf ("  Tag_CSKY_FPU_DENORMAL:\t");
+       printf ("Needed\n");
+      }
+      break;
+    case Tag_CSKY_FPU_Exception:
+      READ_ULEB (val, p, end);
+      if (val == 1) {
+       printf ("  Tag_CSKY_FPU_Exception:\t");
+       printf ("Needed\n");
+      }
+      break;
+    case Tag_CSKY_FPU_NUMBER_MODULE:
+      printf ("  Tag_CSKY_FPU_NUMBER_MODULE:\t");
+      return display_tag_value (-1, p, end);
+    case Tag_CSKY_FPU_HARDFP:
+      printf ("  Tag_CSKY_FPU_HARDFP:\t\t");
+      READ_ULEB (val, p, end);
+      if (val & VAL_CSKY_FPU_HARDFP_HALF)
+       printf (" Half");
+      if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
+       printf (" Single");
+      if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
+       printf (" Double");
+      printf ("\n");
+      break;
+    default:
+      return display_tag_value (tag, p, end);
+     }
+  return p;
+}
+
+static bool
+process_attributes (Filedata * filedata,
+                   const char * public_name,
+                   unsigned int proc_type,
+                   unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
+                   unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
+{
+  Elf_Internal_Shdr * sect;
+  unsigned i;
+  bool res = true;
+
+  /* Find the section header so that we get the size.  */
+  for (i = 0, sect = filedata->section_headers;
+       i < filedata->file_header.e_shnum;
+       i++, sect++)
+    {
+      unsigned char * contents;
+      unsigned char * p;
+
+      if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
+       continue;
 
       contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
                                              sect->sh_size, _("attributes"));
       if (contents == NULL)
        {
-         res = FALSE;
+         res = false;
          continue;
        }
 
@@ -16331,7 +17268,7 @@ process_attributes (Filedata * filedata,
       if (*p != 'A')
        {
          printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
-         res = FALSE;
+         res = false;
        }
       else
        {
@@ -16344,13 +17281,13 @@ process_attributes (Filedata * filedata,
            {
              bfd_vma attr_len;
              unsigned int namelen;
-             bfd_boolean public_section;
-             bfd_boolean gnu_section;
+             bool public_section;
+             bool gnu_section;
 
              if (section_len <= 4)
                {
                  error (_("Tag section ends prematurely\n"));
-                 res = FALSE;
+                 res = false;
                  break;
                }
              attr_len = byte_get (p, 4);
@@ -16361,13 +17298,13 @@ process_attributes (Filedata * filedata,
                  error (_("Bad attribute length (%u > %u)\n"),
                          (unsigned) attr_len, (unsigned) section_len);
                  attr_len = section_len;
-                 res = FALSE;
+                 res = false;
                }
              /* PR 17531: file: 001-101425-0.004  */
              else if (attr_len < 5)
                {
                  error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
-                 res = FALSE;
+                 res = false;
                  break;
                }
 
@@ -16378,7 +17315,7 @@ process_attributes (Filedata * filedata,
              if (namelen == 0 || namelen >= attr_len)
                {
                  error (_("Corrupt attribute section name\n"));
-                 res = FALSE;
+                 res = false;
                  break;
                }
 
@@ -16387,14 +17324,14 @@ process_attributes (Filedata * filedata,
              putchar ('\n');
 
              if (public_name && streq ((char *) p, public_name))
-               public_section = TRUE;
+               public_section = true;
              else
-               public_section = FALSE;
+               public_section = false;
 
              if (streq ((char *) p, "gnu"))
-               gnu_section = TRUE;
+               gnu_section = true;
              else
-               gnu_section = FALSE;
+               gnu_section = false;
 
              p += namelen;
              attr_len -= namelen;
@@ -16410,7 +17347,7 @@ process_attributes (Filedata * filedata,
                  if (attr_len < 6)
                    {
                      error (_("Unused bytes at end of section\n"));
-                     res = FALSE;
+                     res = false;
                      section_len = 0;
                      break;
                    }
@@ -16421,7 +17358,7 @@ process_attributes (Filedata * filedata,
                    {
                      error (_("Bad subsection length (%u > %u)\n"),
                              (unsigned) size, (unsigned) attr_len);
-                     res = FALSE;
+                     res = false;
                      size = attr_len;
                    }
                  /* PR binutils/17531: Safe handling of corrupt files.  */
@@ -16429,7 +17366,7 @@ process_attributes (Filedata * filedata,
                    {
                      error (_("Bad subsection length (%u < 6)\n"),
                              (unsigned) size);
-                     res = FALSE;
+                     res = false;
                      section_len = 0;
                      break;
                    }
@@ -16462,7 +17399,7 @@ process_attributes (Filedata * filedata,
                      break;
                    default:
                      printf (_("Unknown tag: %d\n"), tag);
-                     public_section = FALSE;
+                     public_section = false;
                      break;
                    }
 
@@ -16690,7 +17627,7 @@ get_mips_reg_size (int reg_size)
         : -1;
 }
 
-static bfd_boolean
+static bool
 process_mips_specific (Filedata * filedata)
 {
   Elf_Internal_Dyn * entry;
@@ -16708,11 +17645,11 @@ process_mips_specific (Filedata * filedata)
   bfd_vma local_gotno = 0;
   bfd_vma gotsym = 0;
   bfd_vma symtabno = 0;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
                            display_mips_gnu_attribute))
-    res = FALSE;
+    res = false;
 
   sect = find_section (filedata, ".MIPS.abiflags");
 
@@ -16724,7 +17661,7 @@ process_mips_specific (Filedata * filedata)
       if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
        {
          error (_("Corrupt MIPS ABI Flags section.\n"));
-         res = FALSE;
+         res = false;
        }
       else
        {
@@ -16993,7 +17930,7 @@ process_mips_specific (Filedata * filedata)
          free (elib);
        }
       else
-       res = FALSE;
+       res = false;
     }
 
   if (options_offset != 0)
@@ -17009,13 +17946,13 @@ process_mips_specific (Filedata * filedata)
       if (sect == NULL)
        {
          error (_("No MIPS_OPTIONS header found\n"));
-         return FALSE;
+         return false;
        }
       /* PR 24243  */
       if (sect->sh_size < sizeof (* eopt))
        {
          error (_("The MIPS options section is too small.\n"));
-         return FALSE;
+         return false;
        }
 
       eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
@@ -17041,7 +17978,7 @@ process_mips_specific (Filedata * filedata)
                  error (_("Invalid size (%u) for MIPS option\n"),
                         optsize);
                  free (eopt);
-                 return FALSE;
+                 return false;
                }
              offset += optsize;
              ++cnt;
@@ -17243,7 +18180,7 @@ process_mips_specific (Filedata * filedata)
          free (eopt);
        }
       else
-       res = FALSE;
+       res = false;
     }
 
   if (conflicts_offset != 0 && conflictsno != 0)
@@ -17254,7 +18191,7 @@ process_mips_specific (Filedata * filedata)
       if (filedata->dynamic_symbols == NULL)
        {
          error (_("conflict list found without a dynamic symbol table\n"));
-         return FALSE;
+         return false;
        }
 
       /* PR 21345 - print a slightly more helpful error message
@@ -17263,14 +18200,14 @@ process_mips_specific (Filedata * filedata)
        {
          error (_("Overlarge number of conflicts detected: %lx\n"),
                 (long) conflictsno);
-         return FALSE;
+         return false;
        }
 
       iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
       if (iconf == NULL)
        {
          error (_("Out of memory allocating space for dynamic conflicts\n"));
-         return FALSE;
+         return false;
        }
 
       if (is_32bit_elf)
@@ -17283,7 +18220,7 @@ process_mips_specific (Filedata * filedata)
          if (!econf32)
            {
              free (iconf);
-             return FALSE;
+             return false;
            }
 
          for (cnt = 0; cnt < conflictsno; ++cnt)
@@ -17301,7 +18238,7 @@ process_mips_specific (Filedata * filedata)
          if (!econf64)
            {
              free (iconf);
-             return FALSE;
+             return false;
            }
 
          for (cnt = 0; cnt < conflictsno; ++cnt)
@@ -17357,7 +18294,7 @@ process_mips_specific (Filedata * filedata)
        {
          error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
                 (unsigned long) gotsym, (unsigned long) symtabno);
-         return FALSE;
+         return false;
        }
 
       global_end = local_end + (symtabno - gotsym) * addr_size;
@@ -17365,7 +18302,7 @@ process_mips_specific (Filedata * filedata)
       if (global_end < local_end)
        {
          error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
-         return FALSE;
+         return false;
        }
 
       offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
@@ -17488,12 +18425,12 @@ process_mips_specific (Filedata * filedata)
       if (pltrel == DT_RELA)
        {
          if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
-           return FALSE;
+           return false;
        }
       else
        {
          if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
-           return FALSE;
+           return false;
        }
 
       ent = mips_pltgot;
@@ -17504,7 +18441,10 @@ process_mips_specific (Filedata * filedata)
       data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
                                          1, _("Procedure Linkage Table data"));
       if (data == NULL)
-       return FALSE;
+       {
+         free (rels);
+         return false;
+       }
 
       printf ("\nPLT GOT:\n\n");
       printf (_(" Reserved entries:\n"));
@@ -17556,7 +18496,7 @@ process_mips_specific (Filedata * filedata)
   return res;
 }
 
-static bfd_boolean
+static bool
 process_nds32_specific (Filedata * filedata)
 {
   Elf_Internal_Shdr *sect = NULL;
@@ -17572,7 +18512,7 @@ process_nds32_specific (Filedata * filedata)
                      _("NDS32 elf flags section"));
 
       if (buf == NULL)
-       return FALSE;
+       return false;
 
       flag = byte_get (buf, 4);
       free (buf);
@@ -17593,10 +18533,10 @@ process_nds32_specific (Filedata * filedata)
        }
     }
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 process_gnu_liblist (Filedata * filedata)
 {
   Elf_Internal_Shdr * section;
@@ -17607,10 +18547,10 @@ process_gnu_liblist (Filedata * filedata)
   size_t cnt;
   unsigned long num_liblist;
   unsigned i;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (! do_arch)
-    return TRUE;
+    return true;
 
   for (i = 0, section = filedata->section_headers;
        i < filedata->file_header.e_shnum;
@@ -17628,7 +18568,7 @@ process_gnu_liblist (Filedata * filedata)
 
          if (elib == NULL)
            {
-             res = FALSE;
+             res = false;
              break;
            }
 
@@ -17641,7 +18581,7 @@ process_gnu_liblist (Filedata * filedata)
            {
              free (elib);
              free (strtab);
-             res = FALSE;
+             res = false;
              break;
            }
          strtab_size = string_sec->sh_size;
@@ -17712,6 +18652,8 @@ get_note_type (Filedata * filedata, unsigned e_type)
        return _("NT_PRPSINFO (prpsinfo structure)");
       case NT_TASKSTRUCT:
        return _("NT_TASKSTRUCT (task structure)");
+      case NT_GDB_TDESC:
+        return _("NT_GDB_TDESC (GDB XML target description)");
       case NT_PRXFPREG:
        return _("NT_PRXFPREG (user_xfpregs structure)");
       case NT_PPC_VMX:
@@ -17750,6 +18692,8 @@ get_note_type (Filedata * filedata, unsigned e_type)
        return _("NT_386_IOPERM (x86 I/O permissions)");
       case NT_X86_XSTATE:
        return _("NT_X86_XSTATE (x86 XSAVE extended state)");
+      case NT_X86_CET:
+       return _("NT_X86_CET (x86 CET state)");
       case NT_S390_HIGH_GPRS:
        return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
       case NT_S390_TIMER:
@@ -17784,8 +18728,16 @@ get_note_type (Filedata * filedata, unsigned e_type)
        return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
       case NT_ARM_HW_WATCH:
        return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
+      case NT_ARM_SVE:
+       return _("NT_ARM_SVE (AArch SVE registers)");
+      case NT_ARM_PAC_MASK:
+       return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
+      case NT_ARM_TAGGED_ADDR_CTRL:
+       return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
       case NT_ARC_V2:
        return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
+      case NT_RISCV_CSR:
+       return _("NT_RISCV_CSR (RISC-V control and status registers)");
       case NT_PSTATUS:
        return _("NT_PSTATUS (pstatus structure)");
       case NT_FPREGS:
@@ -17802,6 +18754,8 @@ get_note_type (Filedata * filedata, unsigned e_type)
        return _("NT_SIGINFO (siginfo_t data)");
       case NT_FILE:
        return _("NT_FILE (mapped files)");
+      case NT_MEMTAG:
+       return _("NT_MEMTAG (memory tags)");
       default:
        break;
       }
@@ -17824,7 +18778,7 @@ get_note_type (Filedata * filedata, unsigned e_type)
   return buff;
 }
 
-static bfd_boolean
+static bool
 print_core_note (Elf_Internal_Note *pnote)
 {
   unsigned int addr_size = is_32bit_elf ? 4 : 8;
@@ -17835,7 +18789,7 @@ print_core_note (Elf_Internal_Note *pnote)
     {
       if (do_wide)
        printf ("\n");
-      return TRUE;
+      return true;
     }
 
 #ifndef BFD64
@@ -17843,14 +18797,14 @@ print_core_note (Elf_Internal_Note *pnote)
     {
       printf (_("    Cannot decode 64-bit note in 32-bit build\n"));
       /* Still "successful".  */
-      return TRUE;
+      return true;
     }
 #endif
 
   if (pnote->descsz < 2 * addr_size)
     {
       error (_("    Malformed note - too short for header\n"));
-      return FALSE;
+      return false;
     }
 
   descdata = (unsigned char *) pnote->descdata;
@@ -17859,7 +18813,7 @@ print_core_note (Elf_Internal_Note *pnote)
   if (descdata[pnote->descsz - 1] != '\0')
     {
       error (_("    Malformed note - does not end with \\0\n"));
-      return FALSE;
+      return false;
     }
 
   count = byte_get (descdata, addr_size);
@@ -17872,7 +18826,7 @@ print_core_note (Elf_Internal_Note *pnote)
       || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
     {
       error (_("    Malformed note - too short for supplied file count\n"));
-      return FALSE;
+      return false;
     }
 
   printf (_("    Page size: "));
@@ -17891,7 +18845,7 @@ print_core_note (Elf_Internal_Note *pnote)
       if (filenames == descend)
        {
          error (_("    Malformed note - filenames end too early\n"));
-         return FALSE;
+         return false;
        }
 
       start = byte_get (descdata, addr_size);
@@ -17912,7 +18866,7 @@ print_core_note (Elf_Internal_Note *pnote)
       filenames += 1 + strlen ((char *) filenames);
     }
 
-  return TRUE;
+  return true;
 }
 
 static const char *
@@ -18019,7 +18973,7 @@ decode_x86_compat_isa (unsigned int bitmask)
 }
 
 static void
-decode_x86_isa (unsigned int bitmask)
+decode_x86_compat_2_isa (unsigned int bitmask)
 {
   if (!bitmask)
     {
@@ -18034,79 +18988,79 @@ decode_x86_isa (unsigned int bitmask)
       bitmask &= ~ bit;
       switch (bit)
        {
-       case GNU_PROPERTY_X86_ISA_1_CMOV:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
          printf ("CMOV");
          break;
-       case GNU_PROPERTY_X86_ISA_1_SSE:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
          printf ("SSE");
          break;
-       case GNU_PROPERTY_X86_ISA_1_SSE2:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
          printf ("SSE2");
          break;
-       case GNU_PROPERTY_X86_ISA_1_SSE3:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
          printf ("SSE3");
          break;
-       case GNU_PROPERTY_X86_ISA_1_SSSE3:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
          printf ("SSSE3");
          break;
-       case GNU_PROPERTY_X86_ISA_1_SSE4_1:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
          printf ("SSE4_1");
          break;
-       case GNU_PROPERTY_X86_ISA_1_SSE4_2:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
          printf ("SSE4_2");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
          printf ("AVX");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX2:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
          printf ("AVX2");
          break;
-       case GNU_PROPERTY_X86_ISA_1_FMA:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
          printf ("FMA");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512F:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
          printf ("AVX512F");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512CD:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
          printf ("AVX512CD");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512ER:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
          printf ("AVX512ER");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512PF:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
          printf ("AVX512PF");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512VL:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
          printf ("AVX512VL");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
          printf ("AVX512DQ");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512BW:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
          printf ("AVX512BW");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
          printf ("AVX512_4FMAPS");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
          printf ("AVX512_4VNNIW");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
          printf ("AVX512_BITALG");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
          printf ("AVX512_IFMA");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
          printf ("AVX512_VBMI");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
          printf ("AVX512_VBMI2");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
          printf ("AVX512_VNNI");
          break;
-       case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
+       case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
          printf ("AVX512_BF16");
          break;
        default:
@@ -18118,6 +19072,37 @@ decode_x86_isa (unsigned int bitmask)
     }
 }
 
+static void
+decode_x86_isa (unsigned int bitmask)
+{
+  while (bitmask)
+    {
+      unsigned int bit = bitmask & (- bitmask);
+
+      bitmask &= ~ bit;
+      switch (bit)
+       {
+       case GNU_PROPERTY_X86_ISA_1_BASELINE:
+         printf ("x86-64-baseline");
+         break;
+       case GNU_PROPERTY_X86_ISA_1_V2:
+         printf ("x86-64-v2");
+         break;
+       case GNU_PROPERTY_X86_ISA_1_V3:
+         printf ("x86-64-v3");
+         break;
+       case GNU_PROPERTY_X86_ISA_1_V4:
+         printf ("x86-64-v4");
+         break;
+       default:
+         printf (_("<unknown: %x>"), bit);
+         break;
+       }
+      if (bitmask)
+       printf (", ");
+    }
+}
+
 static void
 decode_x86_feature_1 (unsigned int bitmask)
 {
@@ -18140,6 +19125,12 @@ decode_x86_feature_1 (unsigned int bitmask)
        case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
          printf ("SHSTK");
          break;
+       case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
+         printf ("LAM_U48");
+         break;
+       case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
+         printf ("LAM_U57");
+         break;
        default:
          printf (_("<unknown: %x>"), bit);
          break;
@@ -18183,6 +19174,12 @@ decode_x86_feature_2 (unsigned int bitmask)
        case GNU_PROPERTY_X86_FEATURE_2_ZMM:
          printf ("ZMM");
          break;
+       case GNU_PROPERTY_X86_FEATURE_2_TMM:
+         printf ("TMM");
+         break;
+       case GNU_PROPERTY_X86_FEATURE_2_MASK:
+         printf ("MASK");
+         break;
        case GNU_PROPERTY_X86_FEATURE_2_FXSR:
          printf ("FXSR");
          break;
@@ -18361,6 +19358,28 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
                    }
                  goto next;
 
+               case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
+                 if (datasz != 4)
+                   printf (_("x86 ISA used: <corrupt length: %#x> "),
+                           datasz);
+                 else
+                   {
+                     printf ("x86 ISA used: ");
+                     decode_x86_compat_2_isa (bitmask);
+                   }
+                 goto next;
+
+               case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
+                 if (datasz != 4)
+                   printf (_("x86 ISA needed: <corrupt length: %#x> "),
+                           datasz);
+                 else
+                   {
+                     printf ("x86 ISA needed: ");
+                     decode_x86_compat_2_isa (bitmask);
+                   }
+                 goto next;
+
                default:
                  break;
                }
@@ -18404,7 +19423,7 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
       if (type < GNU_PROPERTY_LOPROC)
        printf (_("<unknown type %#x data: "), type);
       else if (type < GNU_PROPERTY_LOUSER)
-       printf (_("<procesor-specific type %#x data: "), type);
+       printf (_("<processor-specific type %#x data: "), type);
       else
        printf (_("<application-specific type %#x data: "), type);
       for (j = 0; j < datasz; ++j)
@@ -18425,7 +19444,7 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
   printf ("\n");
 }
 
-static bfd_boolean
+static bool
 print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
 {
   /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type ().  */
@@ -18516,7 +19535,7 @@ print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
        if (pnote->descsz < 8)
          {
            error (_("<corrupt GNU_HWCAP>\n"));
-           return FALSE;
+           return false;
          }
        num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
        mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
@@ -18544,7 +19563,7 @@ print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
       break;
     }
 
-  return TRUE;
+  return true;
 }
 
 static const char *
@@ -18566,20 +19585,20 @@ get_v850_elf_note_type (enum v850_notes n_type)
     }
 }
 
-static bfd_boolean
+static bool
 print_v850_note (Elf_Internal_Note * pnote)
 {
   unsigned int val;
 
   if (pnote->descsz != 4)
-    return FALSE;
+    return false;
 
   val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
 
   if (val == 0)
     {
       printf (_("not set\n"));
-      return TRUE;
+      return true;
     }
 
   switch (pnote->type)
@@ -18587,24 +19606,24 @@ print_v850_note (Elf_Internal_Note * pnote)
     case V850_NOTE_ALIGNMENT:
       switch (val)
        {
-       case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
-       case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
+       case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
+       case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
        }
       break;
 
     case V850_NOTE_DATA_SIZE:
       switch (val)
        {
-       case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
-       case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
+       case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
+       case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
        }
       break;
 
     case V850_NOTE_FPU_INFO:
       switch (val)
        {
-       case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
-       case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
+       case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
+       case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
        }
       break;
 
@@ -18614,7 +19633,7 @@ print_v850_note (Elf_Internal_Note * pnote)
       if (val == EF_RH850_SIMD)
        {
          printf (_("yes\n"));
-         return TRUE;
+         return true;
        }
       break;
 
@@ -18624,10 +19643,10 @@ print_v850_note (Elf_Internal_Note * pnote)
     }
 
   printf (_("unknown value: %x\n"), val);
-  return FALSE;
+  return false;
 }
 
-static bfd_boolean
+static bool
 process_netbsd_elf_note (Elf_Internal_Note * pnote)
 {
   unsigned int version;
@@ -18647,14 +19666,13 @@ process_netbsd_elf_note (Elf_Internal_Note * pnote)
        printf ("  NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
                version, version / 100000000, (version / 1000000) % 100,
                (version / 100) % 100);
-      return TRUE;
+      return true;
 
     case NT_NETBSD_MARCH:
       printf ("  NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
              pnote->descdata);
-      return TRUE;
+      return true;
 
-#ifdef   NT_NETBSD_PAX
     case NT_NETBSD_PAX:
       if (pnote->descsz < 1)
        break;
@@ -18666,13 +19684,12 @@ process_netbsd_elf_note (Elf_Internal_Note * pnote)
              ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
              ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
              ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
-      return TRUE;
-#endif
+      return true;
     }
 
   printf ("  NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
          pnote->descsz, pnote->type);
-  return FALSE;
+  return false;
 }
 
 static const char *
@@ -18717,15 +19734,11 @@ get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
       /* NetBSD core "procinfo" structure.  */
       return _("NetBSD procinfo structure");
 
-#ifdef NT_NETBSDCORE_AUXV
     case NT_NETBSDCORE_AUXV:
       return _("NetBSD ELF auxiliary vector data");
-#endif
 
-#ifdef NT_NETBSDCORE_LWPSTATUS
     case NT_NETBSDCORE_LWPSTATUS:
       return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
-#endif
 
     default:
       /* As of Jan 2020 there are no other machine-independent notes
@@ -18816,7 +19829,7 @@ get_stapsdt_note_type (unsigned e_type)
   return buff;
 }
 
-static bfd_boolean
+static bool
 print_stapsdt_note (Elf_Internal_Note *pnote)
 {
   size_t len, maxlen;
@@ -18890,7 +19903,7 @@ print_stapsdt_note (Elf_Internal_Note *pnote)
  stapdt_note_too_small:
   printf (_("  <corrupt - note is too small>\n"));
   error (_("corrupt stapdt note - the data size is too small\n"));
-  return FALSE;
+  return false;
 }
 
 static const char *
@@ -18934,7 +19947,7 @@ get_ia64_vms_note_type (unsigned e_type)
     }
 }
 
-static bfd_boolean
+static bool
 print_ia64_vms_note (Elf_Internal_Note * pnote)
 {
   int maxlen = pnote->descsz;
@@ -19040,15 +20053,15 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
       break;
 
     default:
-      return FALSE;
+      return false;
     }
 
-  return TRUE;
+  return true;
 
  desc_size_fail:
   printf (_("  <corrupt - data size is too small>\n"));
   error (_("corrupt IA64 note: data size is too small\n"));
-  return FALSE;
+  return false;
 }
 
 struct build_attr_cache {
@@ -19065,10 +20078,10 @@ struct build_attr_cache {
    symbol could not be found.  */
 
 static Elf_Internal_Sym *
-get_symbol_for_build_attribute (Filedata *       filedata,
-                               unsigned long    offset,
-                               bfd_boolean      is_open_attr,
-                               const char **    pname)
+get_symbol_for_build_attribute (Filedata *filedata,
+                               unsigned long offset,
+                               bool is_open_attr,
+                               const char **pname)
 {
   Elf_Internal_Sym *saved_sym = NULL;
   Elf_Internal_Sym *sym;
@@ -19179,7 +20192,7 @@ get_symbol_for_build_attribute (Filedata *       filedata,
 
 /* Returns true iff addr1 and addr2 are in the same section.  */
 
-static bfd_boolean
+static bool
 same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
 {
   Elf_Internal_Shdr * a1;
@@ -19191,20 +20204,20 @@ same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
   return a1 == a2 && a1 != NULL;
 }
 
-static bfd_boolean
+static bool
 print_gnu_build_attribute_description (Elf_Internal_Note *  pnote,
                                       Filedata *           filedata)
 {
-  static unsigned long  global_offset = 0;
-  static unsigned long  global_end = 0;
-  static unsigned long  func_offset = 0;
-  static unsigned long  func_end = 0;
+  static unsigned long global_offset = 0;
+  static unsigned long global_end = 0;
+  static unsigned long func_offset = 0;
+  static unsigned long func_end = 0;
 
-  Elf_Internal_Sym *    sym;
-  const char *          name;
-  unsigned long         start;
-  unsigned long         end;
-  bfd_boolean           is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
+  Elf_Internal_Sym *sym;
+  const char *name;
+  unsigned long start;
+  unsigned long end;
+  bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
 
   switch (pnote->descsz)
     {
@@ -19226,7 +20239,7 @@ print_gnu_build_attribute_description (Elf_Internal_Note *  pnote,
          else
            printf (_("    Applies to region from %#lx\n"), func_offset);
        }
-      return TRUE;
+      return true;
 
     case 4:
       start = byte_get ((unsigned char *) pnote->descdata, 4);
@@ -19234,17 +20247,8 @@ print_gnu_build_attribute_description (Elf_Internal_Note *  pnote,
       break;
 
     case 8:
-      if (is_32bit_elf)
-       {
-         /* FIXME: We should check that version 3+ notes are being used here...  */
-         start = byte_get ((unsigned char *) pnote->descdata, 4);
-         end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
-       }
-      else
-       {
-         start = byte_get ((unsigned char *) pnote->descdata, 8);
-         end = 0;
-       }
+      start = byte_get ((unsigned char *) pnote->descdata, 4);
+      end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
       break;
 
     case 16:
@@ -19255,7 +20259,7 @@ print_gnu_build_attribute_description (Elf_Internal_Note *  pnote,
     default:
       error (_("    <invalid description size: %lx>\n"), pnote->descsz);
       printf (_("    <invalid descsz>"));
-      return FALSE;
+      return false;
     }
 
   name = NULL;
@@ -19308,10 +20312,10 @@ print_gnu_build_attribute_description (Elf_Internal_Note *  pnote,
     printf (_(" (%s)"), name);
 
   printf ("\n");
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
 {
   static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
@@ -19328,7 +20332,7 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
     {
       error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
       print_symbol (-20, _("  <corrupt name>"));
-      return FALSE;
+      return false;
     }
 
   if (do_wide)
@@ -19343,7 +20347,7 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
        {
          error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
          print_symbol (-20, _("  <corrupt name>"));
-         return FALSE;
+         return false;
        }
 
       printf ("GA");
@@ -19363,7 +20367,7 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
     default:
       error (_("unrecognised attribute type in name field: %d\n"), name_type);
       print_symbol (-20, _("<unknown name type>"));
-      return FALSE;
+      return false;
     }
 
   ++ name;
@@ -19446,11 +20450,11 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
       error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
             (unsigned long) pnote->namesz,
             (long) (name - pnote->namedata));
-      return FALSE;
+      return false;
     }
 
   if (left < 1 && ! do_wide)
-    return TRUE;
+    return true;
 
   switch (name_type)
     {
@@ -19479,7 +20483,7 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
 
        while (bytes --)
          {
-           unsigned long byte = (* name ++) & 0xff;
+           unsigned long long byte = *name++ & 0xff;
 
            val |= byte << shift;
            shift += 8;
@@ -19547,7 +20551,7 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
   if (do_wide && left > 0)
     printf ("%-*s", left, " ");
 
-  return TRUE;
+  return true;
 }
 
 /* Note that by the ELF standard, the name field is already null byte
@@ -19556,7 +20560,7 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
 
    If the value of namesz is zero, there is no name present.  */
 
-static bfd_boolean
+static bool
 process_note (Elf_Internal_Note *  pnote,
              Filedata *           filedata)
 {
@@ -19568,38 +20572,38 @@ process_note (Elf_Internal_Note *  pnote,
        note type strings.  */
     nt = get_note_type (filedata, pnote->type);
 
-  else if (const_strneq (pnote->namedata, "GNU"))
+  else if (startswith (pnote->namedata, "GNU"))
     /* GNU-specific object file notes.  */
     nt = get_gnu_elf_note_type (pnote->type);
 
-  else if (const_strneq (pnote->namedata, "FreeBSD"))
+  else if (startswith (pnote->namedata, "FreeBSD"))
     /* FreeBSD-specific core file notes.  */
     nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
 
-  else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
+  else if (startswith (pnote->namedata, "NetBSD-CORE"))
     /* NetBSD-specific core file notes.  */
     nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
 
-  else if (const_strneq (pnote->namedata, "NetBSD"))
+  else if (startswith (pnote->namedata, "NetBSD"))
     /* NetBSD-specific core file notes.  */
     return process_netbsd_elf_note (pnote);
 
-  else if (const_strneq (pnote->namedata, "PaX"))
+  else if (startswith (pnote->namedata, "PaX"))
     /* NetBSD-specific core file notes.  */
     return process_netbsd_elf_note (pnote);
 
-  else if (strneq (pnote->namedata, "SPU/", 4))
+  else if (startswith (pnote->namedata, "SPU/"))
     {
       /* SPU-specific core file notes.  */
       nt = pnote->namedata + 4;
       name = "SPU";
     }
 
-  else if (const_strneq (pnote->namedata, "IPF/VMS"))
+  else if (startswith (pnote->namedata, "IPF/VMS"))
     /* VMS/ia64-specific file notes.  */
     nt = get_ia64_vms_note_type (pnote->type);
 
-  else if (const_strneq (pnote->namedata, "stapsdt"))
+  else if (startswith (pnote->namedata, "stapsdt"))
     nt = get_stapsdt_note_type (pnote->type);
 
   else
@@ -19609,7 +20613,7 @@ process_note (Elf_Internal_Note *  pnote,
 
   printf ("  ");
 
-  if (((const_strneq (pnote->namedata, "GA")
+  if (((startswith (pnote->namedata, "GA")
        && strchr ("*$!+", pnote->namedata[2]) != NULL)
        || strchr ("*$!+", pnote->namedata[0]) != NULL)
       && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
@@ -19623,15 +20627,15 @@ process_note (Elf_Internal_Note *  pnote,
   else
     printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
 
-  if (const_strneq (pnote->namedata, "IPF/VMS"))
+  if (startswith (pnote->namedata, "IPF/VMS"))
     return print_ia64_vms_note (pnote);
-  else if (const_strneq (pnote->namedata, "GNU"))
+  else if (startswith (pnote->namedata, "GNU"))
     return print_gnu_note (filedata, pnote);
-  else if (const_strneq (pnote->namedata, "stapsdt"))
+  else if (startswith (pnote->namedata, "stapsdt"))
     return print_stapsdt_note (pnote);
-  else if (const_strneq (pnote->namedata, "CORE"))
+  else if (startswith (pnote->namedata, "CORE"))
     return print_core_note (pnote);
-  else if (((const_strneq (pnote->namedata, "GA")
+  else if (((startswith (pnote->namedata, "GA")
             && strchr ("*$!+", pnote->namedata[2]) != NULL)
            || strchr ("*$!+", pnote->namedata[0]) != NULL)
           && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
@@ -19652,23 +20656,23 @@ process_note (Elf_Internal_Note *  pnote,
   if (do_wide)
     printf ("\n");
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 process_notes_at (Filedata *           filedata,
                  Elf_Internal_Shdr *  section,
                  bfd_vma              offset,
                  bfd_vma              length,
                  bfd_vma              align)
 {
-  Elf_External_Note * pnotes;
-  Elf_External_Note * external;
-  char *              end;
-  bfd_boolean         res = TRUE;
+  Elf_External_Note *pnotes;
+  Elf_External_Note *external;
+  char *end;
+  bool res = true;
 
   if (length <= 0)
-    return FALSE;
+    return false;
 
   if (section)
     {
@@ -19678,7 +20682,7 @@ process_notes_at (Filedata *           filedata,
          if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
            {
              free (pnotes);
-             return FALSE;
+             return false;
            }
        }
     }
@@ -19687,14 +20691,18 @@ process_notes_at (Filedata *           filedata,
                                             _("notes"));
 
   if (pnotes == NULL)
-    return FALSE;
+    return false;
 
   external = pnotes;
 
+  if (filedata->is_separate)
+    printf (_("In linked file '%s': "), filedata->file_name);
+  else
+    printf ("\n");
   if (section)
-    printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
+    printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
   else
-    printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
+    printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
            (unsigned long) offset, (unsigned long) length);
 
   /* NB: Some note sections may have alignment value of 0 or 1.  gABI
@@ -19709,7 +20717,7 @@ process_notes_at (Filedata *           filedata,
       warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
            (long) align);
       free (pnotes);
-      return FALSE;
+      return false;
     }
 
   printf (_("  %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
@@ -19808,7 +20816,7 @@ process_notes_at (Filedata *           filedata,
              if (temp == NULL)
                {
                  error (_("Out of memory allocating space for inote name\n"));
-                 res = FALSE;
+                 res = false;
                  break;
                }
 
@@ -19819,7 +20827,7 @@ process_notes_at (Filedata *           filedata,
        }
 
       if (! process_note (& inote, filedata))
-       res = FALSE;
+       res = false;
 
       free (temp);
       temp = NULL;
@@ -19830,15 +20838,15 @@ process_notes_at (Filedata *           filedata,
   return res;
 }
 
-static bfd_boolean
+static bool
 process_corefile_note_segments (Filedata * filedata)
 {
-  Elf_Internal_Phdr * segment;
+  Elf_Internal_Phdr *segment;
   unsigned int i;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (! get_program_headers (filedata))
-    return TRUE;
+    return true;
 
   for (i = 0, segment = filedata->program_headers;
        i < filedata->file_header.e_phnum;
@@ -19849,27 +20857,27 @@ process_corefile_note_segments (Filedata * filedata)
                                (bfd_vma) segment->p_offset,
                                (bfd_vma) segment->p_filesz,
                                (bfd_vma) segment->p_align))
-         res = FALSE;
+         res = false;
     }
 
   return res;
 }
 
-static bfd_boolean
+static bool
 process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
 {
   Elf_External_Note * pnotes;
   Elf_External_Note * external;
   char * end;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   if (length <= 0)
-    return FALSE;
+    return false;
 
   pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
                                            _("v850 notes"));
   if (pnotes == NULL)
-    return FALSE;
+    return false;
 
   external = pnotes;
   end = (char*) pnotes + length;
@@ -19925,7 +20933,7 @@ process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
 
       if (! print_v850_note (& inote))
        {
-         res = FALSE;
+         res = false;
          printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
                  inote.namesz, inote.descsz);
        }
@@ -19936,13 +20944,13 @@ process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
   return res;
 }
 
-static bfd_boolean
+static bool
 process_note_sections (Filedata * filedata)
 {
-  Elf_Internal_Shdr * section;
+  Elf_Internal_Shdr *section;
   unsigned long i;
   unsigned int n = 0;
-  bfd_boolean res = TRUE;
+  bool res = true;
 
   for (i = 0, section = filedata->section_headers;
        i < filedata->file_header.e_shnum && section != NULL;
@@ -19954,7 +20962,7 @@ process_note_sections (Filedata * filedata)
                                  (bfd_vma) section->sh_offset,
                                  (bfd_vma) section->sh_size,
                                  (bfd_vma) section->sh_addralign))
-           res = FALSE;
+           res = false;
          n++;
        }
 
@@ -19966,7 +20974,7 @@ process_note_sections (Filedata * filedata)
          if (! process_v850_notes (filedata,
                                    (bfd_vma) section->sh_offset,
                                    (bfd_vma) section->sh_size))
-           res = FALSE;
+           res = false;
          n++;
        }
     }
@@ -19978,12 +20986,12 @@ process_note_sections (Filedata * filedata)
   return res;
 }
 
-static bfd_boolean
+static bool
 process_notes (Filedata * filedata)
 {
   /* If we have not been asked to display the notes then do nothing.  */
   if (! do_notes)
-    return TRUE;
+    return true;
 
   if (filedata->file_header.e_type != ET_CORE)
     return process_note_sections (filedata);
@@ -19992,8 +21000,13 @@ process_notes (Filedata * filedata)
   if (filedata->file_header.e_phnum > 0)
     return process_corefile_note_segments (filedata);
 
-  printf (_("No note segments present in the core file.\n"));
-  return TRUE;
+  if (filedata->is_separate)
+    printf (_("No notes found in linked file '%s'.\n"),
+           filedata->file_name);
+  else
+    printf (_("No notes found file.\n"));
+
+  return true;
 }
 
 static unsigned char *
@@ -20019,11 +21032,11 @@ display_generic_attribute (unsigned char * start,
   return display_tag_value (tag, start, end);
 }
 
-static bfd_boolean
+static bool
 process_arch_specific (Filedata * filedata)
 {
   if (! do_arch)
-    return TRUE;
+    return true;
 
   switch (filedata->file_header.e_machine)
     {
@@ -20044,7 +21057,7 @@ process_arch_specific (Filedata * filedata)
 
     case EM_MSP430:
      return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
-                               display_msp430x_attribute,
+                               display_msp430_attribute,
                                display_msp430_gnu_attribute);
 
     case EM_RISCV:
@@ -20080,6 +21093,10 @@ process_arch_specific (Filedata * filedata)
                                 display_tic6x_attribute,
                                 display_generic_attribute);
 
+    case EM_CSKY:
+      return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
+                                display_csky_attribute, NULL);
+
     default:
       return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
                                 display_public_gnu_attributes,
@@ -20087,12 +21104,12 @@ process_arch_specific (Filedata * filedata)
     }
 }
 
-static bfd_boolean
+static bool
 get_file_header (Filedata * filedata)
 {
   /* Read in the identity array.  */
   if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
-    return FALSE;
+    return false;
 
   /* Determine how to read the rest of the header.  */
   switch (filedata->file_header.e_ident[EI_DATA])
@@ -20118,7 +21135,7 @@ get_file_header (Filedata * filedata)
       Elf32_External_Ehdr ehdr32;
 
       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
-       return FALSE;
+       return false;
 
       filedata->file_header.e_type      = BYTE_GET (ehdr32.e_type);
       filedata->file_header.e_machine   = BYTE_GET (ehdr32.e_machine);
@@ -20146,11 +21163,11 @@ get_file_header (Filedata * filedata)
        {
          error (_("This instance of readelf has been built without support for a\n\
 64 bit data type and so it cannot read 64 bit ELF files.\n"));
-         return FALSE;
+         return false;
        }
 
       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
-       return FALSE;
+       return false;
 
       filedata->file_header.e_type      = BYTE_GET (ehdr64.e_type);
       filedata->file_header.e_machine   = BYTE_GET (ehdr64.e_machine);
@@ -20167,17 +21184,71 @@ get_file_header (Filedata * filedata)
       filedata->file_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
     }
 
-  if (filedata->file_header.e_shoff)
+  return true;
+}
+
+static void
+free_filedata (Filedata *filedata)
+{
+  free (filedata->program_interpreter);
+  filedata->program_interpreter = NULL;
+
+  free (filedata->program_headers);
+  filedata->program_headers = NULL;
+
+  free (filedata->section_headers);
+  filedata->section_headers = NULL;
+
+  free (filedata->string_table);
+  filedata->string_table = NULL;
+  filedata->string_table_length = 0;
+
+  free (filedata->dump.dump_sects);
+  filedata->dump.dump_sects = NULL;
+  filedata->dump.num_dump_sects = 0;
+
+  free (filedata->dynamic_strings);
+  filedata->dynamic_strings = NULL;
+  filedata->dynamic_strings_length = 0;
+
+  free (filedata->dynamic_symbols);
+  filedata->dynamic_symbols = NULL;
+  filedata->num_dynamic_syms = 0;
+
+  free (filedata->dynamic_syminfo);
+  filedata->dynamic_syminfo = NULL;
+
+  free (filedata->dynamic_section);
+  filedata->dynamic_section = NULL;
+
+  while (filedata->symtab_shndx_list != NULL)
     {
-      /* There may be some extensions in the first section header.  Don't
-        bomb if we can't read it.  */
-      if (is_32bit_elf)
-       get_32bit_section_headers (filedata, TRUE);
-      else
-       get_64bit_section_headers (filedata, TRUE);
+      elf_section_list *next = filedata->symtab_shndx_list->next;
+      free (filedata->symtab_shndx_list);
+      filedata->symtab_shndx_list = next;
     }
 
-  return TRUE;
+  free (filedata->section_headers_groups);
+  filedata->section_headers_groups = NULL;
+
+  if (filedata->section_groups)
+    {
+      size_t i;
+      struct group_list * g;
+      struct group_list * next;
+
+      for (i = 0; i < filedata->group_count; i++)
+       {
+         for (g = filedata->section_groups [i].root; g != NULL; g = next)
+           {
+             next = g->next;
+             free (g);
+           }
+       }
+
+      free (filedata->section_groups);
+      filedata->section_groups = NULL;
+    }
 }
 
 static void
@@ -20194,11 +21265,12 @@ close_file (Filedata * filedata)
 void
 close_debug_file (void * data)
 {
+  free_filedata ((Filedata *) data);
   close_file ((Filedata *) data);
 }
 
 static Filedata *
-open_file (const char * pathname)
+open_file (const char * pathname, bool is_separate)
 {
   struct stat  statbuf;
   Filedata *   filedata = NULL;
@@ -20217,23 +21289,13 @@ open_file (const char * pathname)
 
   filedata->file_size = (bfd_size_type) statbuf.st_size;
   filedata->file_name = pathname;
+  filedata->is_separate = is_separate;
 
   if (! get_file_header (filedata))
     goto fail;
 
-  if (filedata->file_header.e_shoff)
-    {
-      bfd_boolean res;
-
-      /* Read the section headers again, this time for real.  */
-      if (is_32bit_elf)
-       res = get_32bit_section_headers (filedata, FALSE);
-      else
-       res = get_64bit_section_headers (filedata, FALSE);
-
-      if (!res)
-       goto fail;
-    }
+  if (!get_section_headers (filedata, false))
+    goto fail;
 
   return filedata;
 
@@ -20250,7 +21312,30 @@ open_file (const char * pathname)
 void *
 open_debug_file (const char * pathname)
 {
-  return open_file (pathname);
+  return open_file (pathname, true);
+}
+
+static void
+initialise_dump_sects (Filedata * filedata)
+{
+  /* Initialise the dump_sects array from the cmdline_dump_sects array.
+     Note we do this even if cmdline_dump_sects is empty because we
+     must make sure that the dump_sets array is zeroed out before each
+     object file is processed.  */
+  if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
+    memset (filedata->dump.dump_sects, 0,
+           filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
+
+  if (cmdline.num_dump_sects > 0)
+    {
+      if (filedata->dump.num_dump_sects == 0)
+       /* A sneaky way of allocating the dump_sects array.  */
+       request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
+
+      assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
+      memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
+             cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
+    }
 }
 
 /* Process one ELF object file according to the command line options.
@@ -20258,17 +21343,17 @@ open_debug_file (const char * pathname)
    positioned at the start of the ELF object.  Returns TRUE if no
    problems were encountered, FALSE otherwise.  */
 
-static bfd_boolean
+static bool
 process_object (Filedata * filedata)
 {
-  bfd_boolean  have_separate_files;
+  bool have_separate_files;
   unsigned int i;
-  bfd_boolean res;
+  bool res;
 
   if (! get_file_header (filedata))
     {
       error (_("%s: Failed to read file header\n"), filedata->file_name);
-      return FALSE;
+      return false;
     }
 
   /* Initialise per file variables.  */
@@ -20284,67 +21369,60 @@ process_object (Filedata * filedata)
   if (show_name)
     printf (_("\nFile: %s\n"), filedata->file_name);
 
-  /* Initialise the dump_sects array from the cmdline_dump_sects array.
-     Note we do this even if cmdline_dump_sects is empty because we
-     must make sure that the dump_sets array is zeroed out before each
-     object file is processed.  */
-  if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
-    memset (filedata->dump.dump_sects, 0,
-           filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
-
-  if (cmdline.num_dump_sects > 0)
-    {
-      if (filedata->dump.num_dump_sects == 0)
-       /* A sneaky way of allocating the dump_sects array.  */
-       request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
+  initialise_dump_sects (filedata);
 
-      assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
-      memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
-             cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
-    }
+  /* There may be some extensions in the first section header.  Don't
+     bomb if we can't read it.  */
+  get_section_headers (filedata, true);
 
   if (! process_file_header (filedata))
-    return FALSE;
+    {
+      res = false;
+      goto out;
+    }
 
   if (! process_section_headers (filedata))
     {
       /* Without loaded section headers we cannot process lots of things.  */
-      do_unwind = do_version = do_dump = do_arch = FALSE;
+      do_unwind = do_version = do_dump = do_arch = false;
 
       if (! do_using_dynamic)
-       do_syms = do_dyn_syms = do_reloc = FALSE;
+       do_syms = do_dyn_syms = do_reloc = false;
     }
 
   if (! process_section_groups (filedata))
     /* Without loaded section groups we cannot process unwind.  */
-    do_unwind = FALSE;
+    do_unwind = false;
 
   res = process_program_headers (filedata);
   if (res)
     res = process_dynamic_section (filedata);
 
   if (! process_relocs (filedata))
-    res = FALSE;
+    res = false;
 
   if (! process_unwind (filedata))
-    res = FALSE;
+    res = false;
 
   if (! process_symbol_table (filedata))
-    res = FALSE;
+    res = false;
+
+  if (! process_lto_symbol_tables (filedata))
+    res = false;
 
   if (! process_syminfo (filedata))
-    res = FALSE;
+    res = false;
 
   if (! process_version_sections (filedata))
-    res = FALSE;
+    res = false;
 
   if (filedata->file_header.e_shstrndx != SHN_UNDEF)
     have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
   else
-    have_separate_files = FALSE;
+    have_separate_files = false;
 
   if (! process_section_contents (filedata))
-    res = FALSE;
+    res = false;
 
   if (have_separate_files)
     {
@@ -20352,79 +21430,53 @@ process_object (Filedata * filedata)
 
       for (d = first_separate_info; d != NULL; d = d->next)
        {
-         if (! process_section_headers (d->handle))
-           res = FALSE;
+         initialise_dump_sects (d->handle);
+
+         if (process_links && ! process_file_header (d->handle))
+           res = false;
+         else if (! process_section_headers (d->handle))
+           res = false;
          else if (! process_section_contents (d->handle))
-           res = FALSE;
+           res = false;
+         else if (process_links)
+           {
+             if (! process_section_groups (d->handle))
+               res = false;
+             if (! process_program_headers (d->handle))
+               res = false;
+             if (! process_dynamic_section (d->handle))
+               res = false;
+             if (! process_relocs (d->handle))
+               res = false;
+             if (! process_unwind (d->handle))
+               res = false;
+             if (! process_symbol_table (d->handle))
+               res = false;
+             if (! process_lto_symbol_tables (d->handle))
+               res = false;
+             if (! process_syminfo (d->handle))
+               res = false;
+             if (! process_version_sections (d->handle))
+               res = false;
+             if (! process_notes (d->handle))
+               res = false;
+           }
        }
 
       /* The file handles are closed by the call to free_debug_memory() below.  */
     }
 
   if (! process_notes (filedata))
-    res = FALSE;
+    res = false;
 
   if (! process_gnu_liblist (filedata))
-    res = FALSE;
+    res = false;
 
   if (! process_arch_specific (filedata))
-    res = FALSE;
-
-  free (filedata->program_headers);
-  filedata->program_headers = NULL;
-
-  free (filedata->section_headers);
-  filedata->section_headers = NULL;
-
-  free (filedata->string_table);
-  filedata->string_table = NULL;
-  filedata->string_table_length = 0;
-
-  free (filedata->dump.dump_sects);
-  filedata->dump.dump_sects = NULL;
-  filedata->dump.num_dump_sects = 0;
-
-  free (filedata->dynamic_strings);
-  filedata->dynamic_strings = NULL;
-  filedata->dynamic_strings_length = 0;
-
-  free (filedata->dynamic_symbols);
-  filedata->dynamic_symbols = NULL;
-  filedata->num_dynamic_syms = 0;
-
-  free (filedata->dynamic_syminfo);
-  filedata->dynamic_syminfo = NULL;
-
-  free (filedata->dynamic_section);
-  filedata->dynamic_section = NULL;
-
-  while (filedata->symtab_shndx_list != NULL)
-    {
-      elf_section_list *next = filedata->symtab_shndx_list->next;
-      free (filedata->symtab_shndx_list);
-      filedata->symtab_shndx_list = next;
-    }
-
-  free (filedata->section_headers_groups);
-  filedata->section_headers_groups = NULL;
-
-  if (filedata->section_groups)
-    {
-      struct group_list * g;
-      struct group_list * next;
-
-      for (i = 0; i < filedata->group_count; i++)
-       {
-         for (g = filedata->section_groups [i].root; g != NULL; g = next)
-           {
-             next = g->next;
-             free (g);
-           }
-       }
+    res = false;
 
-      free (filedata->section_groups);
-      filedata->section_groups = NULL;
-    }
+ out:
+  free_filedata (filedata);
 
   free_debug_memory ();
 
@@ -20435,15 +21487,15 @@ process_object (Filedata * filedata)
    On entry the file is positioned just after the ARMAG string.
    Returns TRUE upon success, FALSE otherwise.  */
 
-static bfd_boolean
-process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
+static bool
+process_archive (Filedata * filedata, bool is_thin_archive)
 {
   struct archive_info arch;
   struct archive_info nested_arch;
   size_t got;
-  bfd_boolean ret = TRUE;
+  bool ret = true;
 
-  show_name = TRUE;
+  show_name = true;
 
   /* The ARCH structure is used to hold information about this archive.  */
   arch.file_name = NULL;
@@ -20465,7 +21517,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
                     filedata->file_size, is_thin_archive,
                     do_archive_index) != 0)
     {
-      ret = FALSE;
+      ret = false;
       goto out;
     }
 
@@ -20518,7 +21570,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
                  error (_("%s: end of the symbol table reached "
                           "before the end of the index\n"),
                         filedata->file_name);
-                 ret = FALSE;
+                 ret = false;
                  break;
                }
              /* PR 17531: file: 0b6630b2.  */
@@ -20542,7 +21594,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
                               "the index table\n",
                               arch.sym_size - l),
                     filedata->file_name, arch.sym_size - l);
-             ret = FALSE;
+             ret = false;
            }
 
          if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
@@ -20550,7 +21602,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
              error (_("%s: failed to seek back to start of object files "
                       "in the archive\n"),
                     filedata->file_name);
-             ret = FALSE;
+             ret = false;
              goto out;
            }
        }
@@ -20560,7 +21612,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
          && !do_histogram && !do_debugging && !do_arch && !do_notes
          && !do_section_groups && !do_dyn_syms)
        {
-         ret = TRUE; /* Archive index only.  */
+         ret = true; /* Archive index only.  */
          goto out;
        }
     }
@@ -20576,7 +21628,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
        {
          error (_("%s: failed to seek to next archive header\n"),
                 arch.file_name);
-         ret = FALSE;
+         ret = false;
          break;
        }
       got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
@@ -20588,14 +21640,14 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
             have already been freed.  */
          error (_("%s: failed to read archive header\n"), arch.file_name);
 
-         ret = FALSE;
+         ret = false;
          break;
        }
       if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
        {
          error (_("%s: did not find a valid archive header\n"),
                 arch.file_name);
-         ret = FALSE;
+         ret = false;
          break;
        }
 
@@ -20609,7 +21661,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
       if (name == NULL)
        {
          error (_("%s: bad archive file name\n"), arch.file_name);
-         ret = FALSE;
+         ret = false;
          break;
        }
       namelen = strlen (name);
@@ -20619,7 +21671,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
        {
          error (_("%s: bad archive file name\n"), arch.file_name);
          free (name);
-         ret = FALSE;
+         ret = false;
          break;
        }
 
@@ -20634,17 +21686,17 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
          if (member_file_name == NULL)
            {
              free (qualified_name);
-             ret = FALSE;
+             ret = false;
              break;
            }
 
-         member_filedata = open_file (member_file_name);
+         member_filedata = open_file (member_file_name, false);
          if (member_filedata == NULL)
            {
              error (_("Input file '%s' is not readable.\n"), member_file_name);
              free (member_file_name);
              free (qualified_name);
-             ret = FALSE;
+             ret = false;
              break;
            }
 
@@ -20652,7 +21704,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
          member_filedata->file_name = qualified_name;
 
          if (! process_object (member_filedata))
-           ret = FALSE;
+           ret = false;
 
          close_file (member_filedata);
          free (member_file_name);
@@ -20670,7 +21722,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
                     qualified_name, name);
              free (qualified_name);
              free (name);
-             ret = FALSE;
+             ret = false;
              break;
            }
          free (name);
@@ -20687,7 +21739,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
              error (_("%s: failed to seek to archive member.\n"),
                     nested_arch.file_name);
              free (qualified_name);
-             ret = FALSE;
+             ret = false;
              break;
            }
 
@@ -20695,7 +21747,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
          thin_filedata.file_name = qualified_name;
 
          if (! process_object (& thin_filedata))
-           ret = FALSE;
+           ret = false;
        }
       else
        {
@@ -20703,7 +21755,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
          filedata->archive_file_offset = arch.next_arhdr_offset;
          filedata->file_name = qualified_name;
          if (! process_object (filedata))
-           ret = FALSE;
+           ret = false;
          arch.next_arhdr_offset += filedata->archive_file_size;
          /* Stop looping with "negative" archive_file_size.  */
          if (arch.next_arhdr_offset < filedata->archive_file_size)
@@ -20722,13 +21774,13 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
   return ret;
 }
 
-static bfd_boolean
+static bool
 process_file (char * file_name)
 {
   Filedata * filedata = NULL;
   struct stat statbuf;
   char armag[SARMAG];
-  bfd_boolean ret = TRUE;
+  bool ret = true;
 
   if (stat (file_name, &statbuf) < 0)
     {
@@ -20737,20 +21789,20 @@ process_file (char * file_name)
       else
        error (_("Could not locate '%s'.  System error message: %s\n"),
               file_name, strerror (errno));
-      return FALSE;
+      return false;
     }
 
   if (! S_ISREG (statbuf.st_mode))
     {
       error (_("'%s' is not an ordinary file\n"), file_name);
-      return FALSE;
+      return false;
     }
 
   filedata = calloc (1, sizeof * filedata);
   if (filedata == NULL)
     {
       error (_("Out of memory allocating file data structure\n"));
-      return FALSE;
+      return false;
     }
 
   filedata->file_name = file_name;
@@ -20759,7 +21811,7 @@ process_file (char * file_name)
     {
       error (_("Input file '%s' is not readable.\n"), file_name);
       free (filedata);
-      return FALSE;
+      return false;
     }
 
   if (fread (armag, SARMAG, 1, filedata->handle) != 1)
@@ -20767,20 +21819,21 @@ process_file (char * file_name)
       error (_("%s: Failed to read file's magic number\n"), file_name);
       fclose (filedata->handle);
       free (filedata);
-      return FALSE;
+      return false;
     }
 
   filedata->file_size = (bfd_size_type) statbuf.st_size;
+  filedata->is_separate = false;
 
   if (memcmp (armag, ARMAG, SARMAG) == 0)
     {
-      if (! process_archive (filedata, FALSE))
-       ret = FALSE;
+      if (! process_archive (filedata, false))
+       ret = false;
     }
   else if (memcmp (armag, ARMAGT, SARMAG) == 0)
     {
-      if ( ! process_archive (filedata, TRUE))
-       ret = FALSE;
+      if ( ! process_archive (filedata, true))
+       ret = false;
     }
   else
     {
@@ -20792,7 +21845,7 @@ process_file (char * file_name)
       filedata->archive_file_size = filedata->archive_file_offset = 0;
 
       if (! process_object (filedata))
-       ret = FALSE;
+       ret = false;
     }
 
   fclose (filedata->handle);
@@ -20836,12 +21889,10 @@ main (int argc, char ** argv)
 {
   int err;
 
-#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+#ifdef HAVE_LC_MESSAGES
   setlocale (LC_MESSAGES, "");
 #endif
-#if defined (HAVE_SETLOCALE)
   setlocale (LC_CTYPE, "");
-#endif
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
@@ -20852,20 +21903,20 @@ main (int argc, char ** argv)
   if (optind < (argc - 1))
     /* When displaying information for more than one file,
        prefix the information with the file name.  */
-    show_name = TRUE;
+    show_name = true;
   else if (optind >= argc)
     {
       /* Ensure that the warning is always displayed.  */
-      do_checks = TRUE;
+      do_checks = true;
 
       warn (_("Nothing to do.\n"));
       usage (stderr);
     }
 
-  err = FALSE;
+  err = false;
   while (optind < argc)
     if (! process_file (argv[optind++]))
-      err = TRUE;
+      err = true;
 
   free (cmdline.dump_sects);