]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/peXXigen.c
2.41 Release sources
[thirdparty/binutils-gdb.git] / bfd / peXXigen.c
index c33c495a0f6a4e4ac741d0b77d7a50a7e1c721a1..da53f349dd03792978e15a99393f62b9874d806e 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI; the common executable parts.
-   Copyright (C) 1995-2020 Free Software Foundation, Inc.
+   Copyright (C) 1995-2023 Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -60,8 +60,9 @@
    on this code has a chance of getting something accomplished without
    wasting too much time.  */
 
-/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
-   depending on whether we're compiling for straight PE or PE+.  */
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64,
+   COFF_WITH_peAArch64 or COFF_WITH_peLoongArch64 depending on whether we're
+   compiling for straight PE or PE+.  */
 #define COFF_WITH_XX
 
 #include "sysdep.h"
 #include "coff/internal.h"
 #include "bfdver.h"
 #include "libiberty.h"
-#ifdef HAVE_WCHAR_H
 #include <wchar.h>
-#endif
-#ifdef HAVE_WCTYPE_H
 #include <wctype.h>
-#endif
 
 /* NOTE: it's strange to be including an architecture specific header
    in what's supposed to be general (to PE/PEI) code.  However, that's
 # include "coff/x86_64.h"
 #elif defined COFF_WITH_pep
 # include "coff/ia64.h"
+#elif defined COFF_WITH_peAArch64
+# include "coff/aarch64.h"
+#elif defined COFF_WITH_peLoongArch64
+# include "coff/loongarch64.h"
 #else
 # include "coff/i386.h"
 #endif
@@ -96,7 +97,7 @@
 #include "libpei.h"
 #include "safe-ctype.h"
 
-#if defined COFF_WITH_pep || defined COFF_WITH_pex64
+#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64
 # undef AOUTSZ
 # define AOUTSZ                PEPAOUTSZ
 # define PEAOUTHDR     PEPAOUTHDR
 #define HighBitSet(val)      ((val) & 0x80000000)
 #define SetHighBit(val)      ((val) | 0x80000000)
 #define WithoutHighBit(val)  ((val) & 0x7fffffff)
-
-/* FIXME: This file has various tests of POWERPC_LE_PE.  Those tests
-   worked when the code was in peicode.h, but no longer work now that
-   the code is in peigen.c.  PowerPC NT is said to be dead.  If
-   anybody wants to revive the code, you will have to figure out how
-   to handle those issues.  */
 \f
 void
 _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
@@ -194,7 +189,8 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
            }
          memcpy (sec_name, name, name_len);
 
-         flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
+         flags = (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD
+                  | SEC_LINKER_CREATED);
          sec = bfd_make_section_anyway_with_flags (abfd, sec_name, flags);
          if (sec == NULL)
            {
@@ -203,18 +199,7 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
              return;
            }
 
-         sec->vma = 0;
-         sec->lma = 0;
-         sec->size = 0;
-         sec->filepos = 0;
-         sec->rel_filepos = 0;
-         sec->reloc_count = 0;
-         sec->line_filepos = 0;
-         sec->lineno_count = 0;
-         sec->userdata = NULL;
-         sec->next = NULL;
          sec->alignment_power = 2;
-
          sec->target_index = unused_section_number;
 
          in->n_scnum = unused_section_number;
@@ -222,15 +207,9 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
       in->n_sclass = C_STAT;
     }
 #endif
-
-#ifdef coff_swap_sym_in_hook
-  /* This won't work in peigen.c, but since it's for PPC PE, it's not
-     worth fixing.  */
-  coff_swap_sym_in_hook (abfd, ext1, in1);
-#endif
 }
 
-static bfd_boolean
+static bool
 abs_finder (bfd * abfd ATTRIBUTE_UNUSED, asection * sec, void * data)
 {
   bfd_vma abs_val = * (bfd_vma *) data;
@@ -314,11 +293,11 @@ _bfd_XXi_swap_aux_in (bfd *       abfd,
     case C_FILE:
       if (ext->x_file.x_fname[0] == 0)
        {
-         in->x_file.x_n.x_zeroes = 0;
-         in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
+         in->x_file.x_n.x_n.x_zeroes = 0;
+         in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
        }
       else
-       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+       memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
       return;
 
     case C_STAT:
@@ -337,14 +316,14 @@ _bfd_XXi_swap_aux_in (bfd *       abfd,
       break;
     }
 
-  in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
+  in->x_sym.x_tagndx.u32 = H_GET_32 (abfd, ext->x_sym.x_tagndx);
   in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
 
   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
       || ISTAG (in_class))
     {
       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
-      in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
+      in->x_sym.x_fcnary.x_fcn.x_endndx.u32 = GET_FCN_ENDNDX (abfd, ext);
     }
   else
     {
@@ -386,13 +365,13 @@ _bfd_XXi_swap_aux_out (bfd *  abfd,
   switch (in_class)
     {
     case C_FILE:
-      if (in->x_file.x_fname[0] == 0)
+      if (in->x_file.x_n.x_fname[0] == 0)
        {
          H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
-         H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
+         H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
        }
       else
-       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
+       memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, sizeof (ext->x_file.x_fname));
 
       return AUXESZ;
 
@@ -412,14 +391,14 @@ _bfd_XXi_swap_aux_out (bfd *  abfd,
       break;
     }
 
-  H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+  H_PUT_32 (abfd, in->x_sym.x_tagndx.u32, ext->x_sym.x_tagndx);
   H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
 
   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
       || ISTAG (in_class))
     {
       PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,  ext);
-      PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+      PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.u32, ext);
     }
   else
     {
@@ -485,7 +464,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   aouthdr_int->text_start =
     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
   /* PE32+ does not have data_start member!  */
   aouthdr_int->data_start =
     GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
@@ -528,50 +507,31 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
   a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
 
-  {
-    unsigned idx;
-
-    /* PR 17512: Corrupt PE binaries can cause seg-faults.  */
-    if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
-      {
-       /* xgettext:c-format */
-       _bfd_error_handler
-         (_("%pB: aout header specifies an invalid number of"
-            " data-directory entries: %u"), abfd, a->NumberOfRvaAndSizes);
-       bfd_set_error (bfd_error_bad_value);
-
-       /* Paranoia: If the number is corrupt, then assume that the
-          actual entries themselves might be corrupt as well.  */
-       a->NumberOfRvaAndSizes = 0;
-      }
-
-    for (idx = 0; idx < a->NumberOfRvaAndSizes; idx++)
-      {
-       /* If data directory is empty, rva also should be 0.  */
-       int size =
-         H_GET_32 (abfd, src->DataDirectory[idx][1]);
-
-       a->DataDirectory[idx].Size = size;
+  /* PR 17512: Don't blindly trust NumberOfRvaAndSizes.  */
+  unsigned idx;
+  for (idx = 0;
+       idx < a->NumberOfRvaAndSizes && idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+       idx++)
+    {
+      /* If data directory is empty, rva also should be 0.  */
+      int size = H_GET_32 (abfd, src->DataDirectory[idx][1]);
+      int vma = size ? H_GET_32 (abfd, src->DataDirectory[idx][0]) : 0;
 
-       if (size)
-         a->DataDirectory[idx].VirtualAddress =
-           H_GET_32 (abfd, src->DataDirectory[idx][0]);
-       else
-         a->DataDirectory[idx].VirtualAddress = 0;
-      }
+      a->DataDirectory[idx].Size = size;
+      a->DataDirectory[idx].VirtualAddress = vma;
+    }
 
-    while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
-      {
-       a->DataDirectory[idx].Size = 0;
-       a->DataDirectory[idx].VirtualAddress = 0;
-       idx ++;
-      }
-  }
+  while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+    {
+      a->DataDirectory[idx].Size = 0;
+      a->DataDirectory[idx].VirtualAddress = 0;
+      idx++;
+    }
 
   if (aouthdr_int->entry)
     {
       aouthdr_int->entry += a->ImageBase;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       aouthdr_int->entry &= 0xffffffff;
 #endif
     }
@@ -579,12 +539,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
   if (aouthdr_int->tsize)
     {
       aouthdr_int->text_start += a->ImageBase;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       aouthdr_int->text_start &= 0xffffffff;
 #endif
     }
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
   /* PE32+ does not have data_start member!  */
   if (aouthdr_int->dsize)
     {
@@ -592,15 +552,6 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
       aouthdr_int->data_start &= 0xffffffff;
     }
 #endif
-
-#ifdef POWERPC_LE_PE
-  /* These three fields are normally set up by ppc_relocate_section.
-     In the case of reading a file in, we can pick them up from the
-     DataDirectory.  */
-  first_thunk_address = a->DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress;
-  thunk_size = a->DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size;
-  import_table_size = a->DataDirectory[PE_IMPORT_TABLE].Size;
-#endif
 }
 
 /* A support function for below.  */
@@ -653,7 +604,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->tsize)
     {
       aouthdr_in->text_start -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       aouthdr_in->text_start &= 0xffffffff;
 #endif
     }
@@ -661,7 +612,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->dsize)
     {
       aouthdr_in->data_start -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       aouthdr_in->data_start &= 0xffffffff;
 #endif
     }
@@ -669,7 +620,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   if (aouthdr_in->entry)
     {
       aouthdr_in->entry -= ib;
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       aouthdr_in->entry &= 0xffffffff;
 #endif
     }
@@ -758,13 +709,23 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
 
   H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
 
+  if (extra->MajorLinkerVersion || extra->MinorLinkerVersion)
+    {
+      H_PUT_8 (abfd, extra->MajorLinkerVersion,
+              aouthdr_out->standard.vstamp);
+      H_PUT_8 (abfd, extra->MinorLinkerVersion,
+              aouthdr_out->standard.vstamp + 1);
+    }
+  else
+    {
 /* e.g. 219510000 is linker version 2.19  */
 #define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
 
-  /* This piece of magic sets the "linker version" field to
-     LINKER_VERSION.  */
-  H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
-           aouthdr_out->standard.vstamp);
+      /* This piece of magic sets the "linker version" field to
+        LINKER_VERSION.  */
+      H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
+               aouthdr_out->standard.vstamp);
+    }
 
   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
@@ -773,7 +734,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
                          aouthdr_out->standard.text_start);
 
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
   /* PE32+ does not have data_start member!  */
   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
                          aouthdr_out->standard.data_start);
@@ -954,11 +915,18 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
 
   memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
 
-  PUT_SCNHDR_VADDR (abfd,
-                   ((scnhdr_int->s_vaddr
-                     - pe_data (abfd)->pe_opthdr.ImageBase)
-                    & 0xffffffff),
-                   scnhdr_ext->s_vaddr);
+  ss = scnhdr_int->s_vaddr - pe_data (abfd)->pe_opthdr.ImageBase;
+  if (scnhdr_int->s_vaddr < pe_data (abfd)->pe_opthdr.ImageBase)
+    _bfd_error_handler (_("%pB:%.8s: section below image base"),
+                        abfd, scnhdr_int->s_name);
+  /* Do not compare lower 32-bits for 64-bit vma.  */
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
+  else if(ss != (ss & 0xffffffff))
+    _bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name);
+  PUT_SCNHDR_VADDR (abfd, ss & 0xffffffff, scnhdr_ext->s_vaddr);
+#else
+  PUT_SCNHDR_VADDR (abfd, ss, scnhdr_ext->s_vaddr);
+#endif
 
   /* NT wants the size data to be rounded up to the next
      NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
@@ -1010,7 +978,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
        (0x02000000).  Also, the resource data should also be read and
        writable.  */
 
-    /* FIXME: Alignment is also encoded in this field, at least on PPC and
+    /* FIXME: Alignment is also encoded in this field, at least on
        ARM-WINCE.  Although - how do we get the original alignment field
        back ?  */
 
@@ -1031,7 +999,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
        { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
        { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
        { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
-       { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+       { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
        { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
        { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
        { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
@@ -1144,18 +1112,25 @@ _bfd_XXi_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
 }
 
 CODEVIEW_INFO *
-_bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo)
+_bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo,
+                               char **pdb)
 {
   char buffer[256+1];
+  bfd_size_type nread;
 
   if (bfd_seek (abfd, where, SEEK_SET) != 0)
     return NULL;
 
-  if (bfd_bread (buffer, 256, abfd) < 4)
+  if (length <= sizeof (CV_INFO_PDB70) && length <= sizeof (CV_INFO_PDB20))
+    return NULL;
+  if (length > 256)
+    length = 256;
+  nread = bfd_bread (buffer, length, abfd);
+  if (length != nread)
     return NULL;
 
   /* Ensure null termination of filename.  */
-  buffer[256] = '\0';
+  memset (buffer + nread, 0, sizeof (buffer) - nread);
 
   cvinfo->CVSignature = H_GET_32 (abfd, buffer);
   cvinfo->Age = 0;
@@ -1176,7 +1151,10 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length
       memcpy (&(cvinfo->Signature[8]), &(cvinfo70->Signature[8]), 8);
 
       cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH;
-      // cvinfo->PdbFileName = cvinfo70->PdbFileName;
+      /* cvinfo->PdbFileName = cvinfo70->PdbFileName;  */
+
+      if (pdb)
+       *pdb = xstrdup (cvinfo70->PdbFileName);
 
       return cvinfo;
     }
@@ -1187,7 +1165,10 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length
       cvinfo->Age = H_GET_32(abfd, cvinfo20->Age);
       memcpy (cvinfo->Signature, cvinfo20->Signature, 4);
       cvinfo->SignatureLength = 4;
-      // cvinfo->PdbFileName = cvinfo20->PdbFileName;
+      /* cvinfo->PdbFileName = cvinfo20->PdbFileName;  */
+
+      if (pdb)
+       *pdb = xstrdup (cvinfo20->PdbFileName);
 
       return cvinfo;
     }
@@ -1196,9 +1177,11 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length
 }
 
 unsigned int
-_bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinfo)
+_bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinfo,
+                               const char *pdb)
 {
-  const bfd_size_type size = sizeof (CV_INFO_PDB70) + 1;
+  size_t pdb_len = pdb ? strlen (pdb) : 0;
+  const bfd_size_type size = sizeof (CV_INFO_PDB70) + pdb_len + 1;
   bfd_size_type written;
   CV_INFO_PDB70 *cvinfo70;
   char * buffer;
@@ -1221,7 +1204,11 @@ _bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinf
   memcpy (&(cvinfo70->Signature[8]), &(cvinfo->Signature[8]), 8);
 
   H_PUT_32 (abfd, cvinfo->Age, cvinfo70->Age);
-  cvinfo70->PdbFileName[0] = '\0';
+
+  if (pdb == NULL)
+    cvinfo70->PdbFileName[0] = '\0';
+  else
+    memcpy (cvinfo70->PdbFileName, pdb, pdb_len + 1);
 
   written = bfd_bwrite (buffer, size, abfd);
 
@@ -1250,26 +1237,31 @@ static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
   N_("Reserved")
 };
 
-#ifdef POWERPC_LE_PE
-/* The code for the PPC really falls in the "architecture dependent"
-   category.  However, it's not clear that anyone will ever care, so
-   we're ignoring the issue for now; if/when PPC matters, some of this
-   may need to go into peicode.h, or arguments passed to enable the
-   PPC- specific code.  */
-#endif
+static bool
+get_contents_sanity_check (bfd *abfd, asection *section,
+                          bfd_size_type dataoff, bfd_size_type datasize)
+{
+  if ((section->flags & SEC_HAS_CONTENTS) == 0)
+    return false;
+  if (dataoff > section->size
+      || datasize > section->size - dataoff)
+    return false;
+  ufile_ptr filesize = bfd_get_file_size (abfd);
+  if (filesize != 0
+      && ((ufile_ptr) section->filepos > filesize
+         || dataoff > filesize - section->filepos
+         || datasize > filesize - section->filepos - dataoff))
+    return false;
+  return true;
+}
 
-static bfd_boolean
+static bool
 pe_print_idata (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
   bfd_byte *data;
   asection *section;
   bfd_signed_vma adj;
-
-#ifdef POWERPC_LE_PE
-  asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
-#endif
-
   bfd_size_type datasize = 0;
   bfd_size_type dataoff;
   bfd_size_type i;
@@ -1286,13 +1278,13 @@ pe_print_idata (bfd * abfd, void * vfile)
     {
       /* Maybe the extra header isn't there.  Look for the section.  */
       section = bfd_get_section_by_name (abfd, ".idata");
-      if (section == NULL)
-       return TRUE;
+      if (section == NULL || (section->flags & SEC_HAS_CONTENTS) == 0)
+       return true;
 
       addr = section->vma;
       datasize = section->size;
       if (datasize == 0)
-       return TRUE;
+       return true;
     }
   else
     {
@@ -1308,14 +1300,14 @@ pe_print_idata (bfd * abfd, void * vfile)
        {
          fprintf (file,
                   _("\nThere is an import table, but the section containing it could not be found\n"));
-         return TRUE;
+         return true;
        }
       else if (!(section->flags & SEC_HAS_CONTENTS))
        {
          fprintf (file,
                   _("\nThere is an import table in %s, but that section has no contents\n"),
                   section->name);
-         return TRUE;
+         return true;
        }
     }
 
@@ -1325,56 +1317,6 @@ pe_print_idata (bfd * abfd, void * vfile)
 
   dataoff = addr - section->vma;
 
-#ifdef POWERPC_LE_PE
-  if (rel_section != 0 && rel_section->size != 0)
-    {
-      /* The toc address can be found by taking the starting address,
-        which on the PPC locates a function descriptor. The
-        descriptor consists of the function code starting address
-        followed by the address of the toc. The starting address we
-        get from the bfd, and the descriptor is supposed to be in the
-        .reldata section.  */
-
-      bfd_vma loadable_toc_address;
-      bfd_vma toc_address;
-      bfd_vma start_address;
-      bfd_byte *data;
-      bfd_vma offset;
-
-      if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
-       {
-         free (data);
-         return FALSE;
-       }
-
-      offset = abfd->start_address - rel_section->vma;
-
-      if (offset >= rel_section->size || offset + 8 > rel_section->size)
-       {
-         free (data);
-         return FALSE;
-       }
-
-      start_address = bfd_get_32 (abfd, data + offset);
-      loadable_toc_address = bfd_get_32 (abfd, data + offset + 4);
-      toc_address = loadable_toc_address - 32768;
-
-      fprintf (file,
-              _("\nFunction descriptor located at the start address: %04lx\n"),
-              (unsigned long int) (abfd->start_address));
-      fprintf (file,
-              /* xgettext:c-format */
-              _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
-              start_address, loadable_toc_address, toc_address);
-      free (data);
-    }
-  else
-    {
-      fprintf (file,
-              _("\nNo reldata section! Function descriptor not decoded.\n"));
-    }
-#endif
-
   fprintf (file,
           _("\nThe Import Tables (interpreted %s section contents)\n"),
           section->name);
@@ -1387,7 +1329,7 @@ pe_print_idata (bfd * abfd, void * vfile)
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   adj = section->vma - extra->ImageBase;
@@ -1479,6 +1421,9 @@ pe_print_idata (bfd * abfd, void * vfile)
                {
                  ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
                  ft_datasize = ft_section->size - ft_idx;
+                 if (!get_contents_sanity_check (abfd, ft_section,
+                                                 ft_idx, ft_datasize))
+                   continue;
                  ft_data = (bfd_byte *) bfd_malloc (ft_datasize);
                  if (ft_data == NULL)
                    continue;
@@ -1586,10 +1531,10 @@ pe_print_idata (bfd * abfd, void * vfile)
 
   free (data);
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 pe_print_edata (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
@@ -1626,13 +1571,13 @@ pe_print_edata (bfd * abfd, void * vfile)
       /* Maybe the extra header isn't there.  Look for the section.  */
       section = bfd_get_section_by_name (abfd, ".edata");
       if (section == NULL)
-       return TRUE;
+       return true;
 
       addr = section->vma;
       dataoff = 0;
       datasize = section->size;
       if (datasize == 0)
-       return TRUE;
+       return true;
     }
   else
     {
@@ -1646,26 +1591,11 @@ pe_print_edata (bfd * abfd, void * vfile)
        {
          fprintf (file,
                   _("\nThere is an export table, but the section containing it could not be found\n"));
-         return TRUE;
-       }
-      else if (!(section->flags & SEC_HAS_CONTENTS))
-       {
-         fprintf (file,
-                  _("\nThere is an export table in %s, but that section has no contents\n"),
-                  section->name);
-         return TRUE;
+         return true;
        }
 
       dataoff = addr - section->vma;
       datasize = extra->DataDirectory[PE_EXPORT_TABLE].Size;
-      if (dataoff > section->size
-         || datasize > section->size - dataoff)
-       {
-         fprintf (file,
-                  _("\nThere is an export table in %s, but it does not fit into that section\n"),
-                  section->name);
-         return TRUE;
-       }
     }
 
   /* PR 17512: Handle corrupt PE binaries.  */
@@ -1675,7 +1605,15 @@ pe_print_edata (bfd * abfd, void * vfile)
               /* xgettext:c-format */
               _("\nThere is an export table in %s, but it is too small (%d)\n"),
               section->name, (int) datasize);
-      return TRUE;
+      return true;
+    }
+
+  if (!get_contents_sanity_check (abfd, section, dataoff, datasize))
+    {
+      fprintf (file,
+              _("\nThere is an export table in %s, but contents cannot be read\n"),
+              section->name);
+      return true;
     }
 
   /* xgettext:c-format */
@@ -1684,11 +1622,14 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   data = (bfd_byte *) bfd_malloc (datasize);
   if (data == NULL)
-    return FALSE;
+    return false;
 
   if (! bfd_get_section_contents (abfd, section, data,
                                  (file_ptr) dataoff, datasize))
-    return FALSE;
+    {
+      free (data);
+      return false;
+    }
 
   /* Go get Export Directory Table.  */
   edt.export_flags   = bfd_get_32 (abfd, data +         0);
@@ -1862,7 +1803,7 @@ pe_print_edata (bfd * abfd, void * vfile)
 
   free (data);
 
-  return TRUE;
+  return true;
 }
 
 /* This really is architecture dependent.  On IA-64, a .pdata entry
@@ -1877,10 +1818,10 @@ pe_print_edata (bfd * abfd, void * vfile)
 
    This is the version for uncompressed data.  */
 
-static bfd_boolean
+static bool
 pe_print_pdata (bfd * abfd, void * vfile)
 {
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
 # define PDATA_ROW_SIZE        (3 * 8)
 #else
 # define PDATA_ROW_SIZE        (5 * 4)
@@ -1894,9 +1835,10 @@ pe_print_pdata (bfd * abfd, void * vfile)
   int onaline = PDATA_ROW_SIZE;
 
   if (section == NULL
+      || (section->flags & SEC_HAS_CONTENTS) == 0
       || coff_section_data (abfd, section) == NULL
       || pei_section_data (abfd, section) == NULL)
-    return TRUE;
+    return true;
 
   stop = pei_section_data (abfd, section)->virt_size;
   if ((stop % onaline) != 0)
@@ -1907,7 +1849,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 
   fprintf (file,
           _("\nThe Function Table (interpreted .pdata section contents)\n"));
-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
   fprintf (file,
           _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
 #else
@@ -1918,7 +1860,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
 
   datasize = section->size;
   if (datasize == 0)
-    return TRUE;
+    return true;
 
   /* PR 17512: file: 002-193900-0.004.  */
   if (datasize < stop)
@@ -1926,13 +1868,13 @@ pe_print_pdata (bfd * abfd, void * vfile)
       /* xgettext:c-format */
       fprintf (file, _("Virtual size of .pdata section (%ld) larger than real size (%ld)\n"),
               (long) stop, (long) datasize);
-      return FALSE;
+      return false;
     }
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   start = 0;
@@ -1944,7 +1886,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_vma eh_handler;
       bfd_vma eh_data;
       bfd_vma prolog_end_addr;
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
       int em_data;
 #endif
 
@@ -1962,7 +1904,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
        /* We are probably into the padding of the section now.  */
        break;
 
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
       em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
 #endif
       eh_handler &= ~(bfd_vma) 0x3;
@@ -1973,45 +1915,18 @@ pe_print_pdata (bfd * abfd, void * vfile)
       bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, eh_handler);
-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
       fputc (' ', file);
       bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
       bfd_fprintf_vma (abfd, file, prolog_end_addr);
       fprintf (file, "   %x", em_data);
 #endif
-
-#ifdef POWERPC_LE_PE
-      if (eh_handler == 0 && eh_data != 0)
-       {
-         /* Special bits here, although the meaning may be a little
-            mysterious. The only one I know for sure is 0x03
-            Code Significance
-            0x00 None
-            0x01 Register Save Millicode
-            0x02 Register Restore Millicode
-            0x03 Glue Code Sequence.  */
-         switch (eh_data)
-           {
-           case 0x01:
-             fprintf (file, _(" Register save millicode"));
-             break;
-           case 0x02:
-             fprintf (file, _(" Register restore millicode"));
-             break;
-           case 0x03:
-             fprintf (file, _(" Glue code sequence"));
-             break;
-           default:
-             break;
-           }
-       }
-#endif
       fprintf (file, "\n");
     }
 
   free (data);
 
-  return TRUE;
+  return true;
 #undef PDATA_ROW_SIZE
 }
 
@@ -2076,7 +1991,7 @@ cleanup_syms (sym_cache *psc)
 
 /* This is the version for "compressed" pdata.  */
 
-bfd_boolean
+bool
 _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
 {
 # define PDATA_ROW_SIZE        (2 * 4)
@@ -2090,9 +2005,10 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
   struct sym_cache cache = {0, 0} ;
 
   if (section == NULL
+      || (section->flags & SEC_HAS_CONTENTS) == 0
       || coff_section_data (abfd, section) == NULL
       || pei_section_data (abfd, section) == NULL)
-    return TRUE;
+    return true;
 
   stop = pei_section_data (abfd, section)->virt_size;
   if ((stop % onaline) != 0)
@@ -2110,15 +2026,17 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
 
   datasize = section->size;
   if (datasize == 0)
-    return TRUE;
+    return true;
 
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   start = 0;
+  if (stop > datasize)
+    stop = datasize;
 
   for (i = start; i < stop; i += onaline)
     {
@@ -2190,7 +2108,7 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
 
   cleanup_syms (& cache);
 
-  return TRUE;
+  return true;
 #undef PDATA_ROW_SIZE
 }
 
@@ -2213,7 +2131,7 @@ static const char * const tbl[] =
   "UNKNOWN",   /* MUST be last.  */
 };
 
-static bfd_boolean
+static bool
 pe_print_reloc (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
@@ -2221,8 +2139,10 @@ pe_print_reloc (bfd * abfd, void * vfile)
   asection *section = bfd_get_section_by_name (abfd, ".reloc");
   bfd_byte *p, *end;
 
-  if (section == NULL || section->size == 0 || !(section->flags & SEC_HAS_CONTENTS))
-    return TRUE;
+  if (section == NULL
+      || section->size == 0
+      || (section->flags & SEC_HAS_CONTENTS) == 0)
+    return true;
 
   fprintf (file,
           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
@@ -2230,7 +2150,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
   if (! bfd_malloc_and_get_section (abfd, section, &data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   p = data;
@@ -2293,7 +2213,7 @@ pe_print_reloc (bfd * abfd, void * vfile)
 
   free (data);
 
-  return TRUE;
+  return true;
 }
 \f
 /* A data structure describing the regions of a .rsrc section.
@@ -2318,13 +2238,13 @@ rsrc_print_resource_directory (FILE * , bfd *, unsigned int, bfd_byte *,
    or section_end + 1 upon failure.  */
 
 static bfd_byte *
-rsrc_print_resource_entries (FILE *        file,
-                            bfd *          abfd,
-                            unsigned int   indent,
-                            bfd_boolean    is_name,
-                            bfd_byte *     data,
-                            rsrc_regions * regions,
-                            bfd_vma        rva_bias)
+rsrc_print_resource_entries (FILE *file,
+                            bfd *abfd,
+                            unsigned int indent,
+                            bool is_name,
+                            bfd_byte *data,
+                            rsrc_regions *regions,
+                            bfd_vma rva_bias)
 {
   unsigned long entry, addr, size;
   bfd_byte * leaf;
@@ -2480,7 +2400,7 @@ rsrc_print_resource_directory (FILE *           file,
     {
       bfd_byte * entry_end;
 
-      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, TRUE,
+      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, true,
                                               data, regions, rva_bias);
       data += 8;
       highest_data = max (highest_data, entry_end);
@@ -2492,7 +2412,7 @@ rsrc_print_resource_directory (FILE *           file,
     {
       bfd_byte * entry_end;
 
-      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, FALSE,
+      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, false,
                                               data, regions, rva_bias);
       data += 8;
       highest_data = max (highest_data, entry_end);
@@ -2507,7 +2427,7 @@ rsrc_print_resource_directory (FILE *           file,
    reproduce the resources, windres does that.  Instead we dump
    the tables in a human readable format.  */
 
-static bfd_boolean
+static bool
 rsrc_print_section (bfd * abfd, void * vfile)
 {
   bfd_vma rva_bias;
@@ -2520,24 +2440,24 @@ rsrc_print_section (bfd * abfd, void * vfile)
 
   pe = pe_data (abfd);
   if (pe == NULL)
-    return TRUE;
+    return true;
 
   section = bfd_get_section_by_name (abfd, ".rsrc");
   if (section == NULL)
-    return TRUE;
+    return true;
   if (!(section->flags & SEC_HAS_CONTENTS))
-    return TRUE;
+    return true;
 
   datasize = section->size;
   if (datasize == 0)
-    return TRUE;
+    return true;
 
   rva_bias = section->vma - pe->pe_opthdr.ImageBase;
 
   if (! bfd_malloc_and_get_section (abfd, section, & data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   regions.section_start = data;
@@ -2592,7 +2512,7 @@ rsrc_print_section (bfd * abfd, void * vfile)
             (int) (regions.resource_start - regions.section_start));
 
   free (regions.section_start);
-  return TRUE;
+  return true;
 }
 
 #define IMAGE_NUMBEROF_DEBUG_TYPES 17
@@ -2618,7 +2538,7 @@ static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] =
   "Repro",
 };
 
-static bfd_boolean
+static bool
 pe_print_debugdata (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
@@ -2633,7 +2553,7 @@ pe_print_debugdata (bfd * abfd, void * vfile)
   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
 
   if (size == 0)
-    return TRUE;
+    return true;
 
   addr += extra->ImageBase;
   for (section = abfd->sections; section != NULL; section = section->next)
@@ -2646,21 +2566,21 @@ pe_print_debugdata (bfd * abfd, void * vfile)
     {
       fprintf (file,
               _("\nThere is a debug directory, but the section containing it could not be found\n"));
-      return TRUE;
+      return true;
     }
   else if (!(section->flags & SEC_HAS_CONTENTS))
     {
       fprintf (file,
               _("\nThere is a debug directory in %s, but that section has no contents\n"),
               section->name);
-      return TRUE;
+      return true;
     }
   else if (section->size < size)
     {
       fprintf (file,
               _("\nError: section %s contains the debug data starting address but it is too small\n"),
               section->name);
-      return FALSE;
+      return false;
     }
 
   fprintf (file, _("\nThere is a debug directory in %s at 0x%lx\n\n"),
@@ -2671,7 +2591,7 @@ pe_print_debugdata (bfd * abfd, void * vfile)
   if (size > (section->size - dataoff))
     {
       fprintf (file, _("The debug data size field in the data directory is too big for the section"));
-      return FALSE;
+      return false;
     }
 
   fprintf (file,
@@ -2681,7 +2601,7 @@ pe_print_debugdata (bfd * abfd, void * vfile)
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
@@ -2709,22 +2629,25 @@ pe_print_debugdata (bfd * abfd, void * vfile)
             We need to use a 32-bit aligned buffer
             to safely read in a codeview record.  */
          char buffer[256 + 1] ATTRIBUTE_ALIGNED_ALIGNOF (CODEVIEW_INFO);
+         char *pdb;
 
          CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
 
          /* The debug entry doesn't have to have to be in a section,
             in which case AddressOfRawData is 0, so always use PointerToRawData.  */
          if (!_bfd_XXi_slurp_codeview_record (abfd, (file_ptr) idd.PointerToRawData,
-                                              idd.SizeOfData, cvinfo))
+                                              idd.SizeOfData, cvinfo, &pdb))
            continue;
 
          for (j = 0; j < cvinfo->SignatureLength; j++)
            sprintf (&signature[j*2], "%02x", cvinfo->Signature[j] & 0xff);
 
          /* xgettext:c-format */
-         fprintf (file, _("(format %c%c%c%c signature %s age %ld)\n"),
+         fprintf (file, _("(format %c%c%c%c signature %s age %ld pdb %s)\n"),
                   buffer[0], buffer[1], buffer[2], buffer[3],
-                  signature, cvinfo->Age);
+                  signature, cvinfo->Age, pdb[0] ? pdb : "(none)");
+
+         free (pdb);
        }
     }
 
@@ -2734,10 +2657,10 @@ pe_print_debugdata (bfd * abfd, void * vfile)
     fprintf (file,
            _("The debug directory size is not a multiple of the debug directory entry size\n"));
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 pe_is_repro (bfd * abfd)
 {
   pe_data_type *pe = pe_data (abfd);
@@ -2746,13 +2669,13 @@ pe_is_repro (bfd * abfd)
   bfd_byte *data = 0;
   bfd_size_type dataoff;
   unsigned int i;
-  bfd_boolean res = FALSE;
+  bool res = false;
 
   bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
   bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
 
   if (size == 0)
-    return FALSE;
+    return false;
 
   addr += extra->ImageBase;
   for (section = abfd->sections; section != NULL; section = section->next)
@@ -2765,20 +2688,20 @@ pe_is_repro (bfd * abfd)
       || (!(section->flags & SEC_HAS_CONTENTS))
       || (section->size < size))
     {
-      return FALSE;
+      return false;
     }
 
   dataoff = addr - section->vma;
 
   if (size > (section->size - dataoff))
     {
-      return FALSE;
+      return false;
     }
 
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
       free (data);
-      return FALSE;
+      return false;
     }
 
   for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
@@ -2791,7 +2714,7 @@ pe_is_repro (bfd * abfd)
 
       if (idd.Type == PE_IMAGE_DEBUG_TYPE_REPRO)
         {
-          res = TRUE;
+          res = true;
           break;
         }
     }
@@ -2803,7 +2726,7 @@ pe_is_repro (bfd * abfd)
 
 /* Print out the program headers.  */
 
-bfd_boolean
+bool
 _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
@@ -2827,8 +2750,11 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
   PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
   PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
+  PF (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, "copy to swap file if on removable media");
+  PF (IMAGE_FILE_NET_RUN_FROM_SWAP, "copy to swap file if on network media");
   PF (IMAGE_FILE_SYSTEM, "system file");
   PF (IMAGE_FILE_DLL, "DLL");
+  PF (IMAGE_FILE_UP_SYSTEM_ONLY, "run only on uniprocessor machine");
   PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
 #undef PF
 
@@ -2888,7 +2814,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
   fprintf (file, "\nBaseOfCode\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfCode);
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
   /* PE32+ does not have BaseOfData member!  */
   fprintf (file, "\nBaseOfData\t\t");
   bfd_fprintf_vma (abfd, file, i->BaseOfData);
@@ -2929,7 +2855,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
       subsystem_name = "Wince CUI";
       break;
-    // These are from UEFI Platform Initialization Specification 1.1.
+    /* These are from UEFI Platform Initialization Specification 1.1.  */
     case IMAGE_SUBSYSTEM_EFI_APPLICATION:
       subsystem_name = "EFI application";
       break;
@@ -2942,11 +2868,11 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
     case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
       subsystem_name = "SAL runtime driver";
       break;
-    // This is from revision 8.0 of the MS PE/COFF spec
+    /* This is from revision 8.0 of the MS PE/COFF spec  */
     case IMAGE_SUBSYSTEM_XBOX:
       subsystem_name = "XBOX";
       break;
-    // Added default case for clarity - subsystem_name is NULL anyway.
+    /* Added default case for clarity - subsystem_name is NULL anyway.  */
     default:
       subsystem_name = NULL;
     }
@@ -2955,6 +2881,34 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   if (subsystem_name)
     fprintf (file, "\t(%s)", subsystem_name);
   fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
+  if (i->DllCharacteristics)
+    {
+      unsigned short dllch = i->DllCharacteristics;
+      const char *indent = "\t\t\t\t\t";
+
+      if (dllch & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA)
+       fprintf (file, "%sHIGH_ENTROPY_VA\n", indent);
+      if (dllch & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)
+       fprintf (file, "%sDYNAMIC_BASE\n", indent);
+      if (dllch & IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY)
+       fprintf (file, "%sFORCE_INTEGRITY\n", indent);
+      if (dllch & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
+       fprintf (file, "%sNX_COMPAT\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)
+       fprintf (file, "%sNO_ISOLATION\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_SEH)
+       fprintf (file, "%sNO_SEH\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_BIND)
+       fprintf (file, "%sNO_BIND\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_APPCONTAINER)
+       fprintf (file, "%sAPPCONTAINER\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)
+       fprintf (file, "%sWDM_DRIVER\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_GUARD_CF)
+       fprintf (file, "%sGUARD_CF\n", indent);
+      if (dllch & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)
+       fprintf (file, "%sTERMINAL_SERVICE_AWARE\n", indent);
+    }
   fprintf (file, "SizeOfStackReserve\t");
   bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
   fprintf (file, "\nSizeOfStackCommit\t");
@@ -2987,10 +2941,10 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
 
   rsrc_print_section (abfd, vfile);
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
 {
   bfd_vma addr = * (bfd_vma *) obj;
@@ -3006,15 +2960,16 @@ find_section_by_vma (bfd *abfd, bfd_vma addr)
 /* Copy any private info we understand from the input bfd
    to the output bfd.  */
 
-bfd_boolean
+bool
 _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
 {
   pe_data_type *ipe, *ope;
+  bfd_size_type size;
 
   /* One day we may try to grok other private data.  */
   if (ibfd->xvec->flavour != bfd_target_coff_flavour
       || obfd->xvec->flavour != bfd_target_coff_flavour)
-    return TRUE;
+    return true;
 
   ipe = pe_data (ibfd);
   ope = pe_data (obfd);
@@ -3044,76 +2999,94 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
   memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
 
   /* The file offsets contained in the debug directory need rewriting.  */
-  if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0)
+  size = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size;
+  if (size != 0)
     {
       bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
        + ope->pe_opthdr.ImageBase;
-      asection *section = find_section_by_vma (obfd, addr);
-      bfd_byte *data;
-
-      if (section && bfd_malloc_and_get_section (obfd, section, &data))
+      /* In particular a .buildid section may overlap (in VA space) with
+        whatever section comes ahead of it (largely because of section->size
+        representing s_size, not virt_size).  Therefore don't look for the
+        section containing the first byte, but for that covering the last
+        one.  */
+      bfd_vma last = addr + size - 1;
+      asection *section = find_section_by_vma (obfd, last);
+
+      if (section != NULL)
        {
-         unsigned int i;
-         struct external_IMAGE_DEBUG_DIRECTORY *dd =
-           (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
+         bfd_byte *data;
+         bfd_vma dataoff = addr - section->vma;
 
          /* PR 17512: file: 0f15796a.  */
-         if ((unsigned long) ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
-             > section->size - (addr - section->vma))
+         if (addr < section->vma
+             || section->size < dataoff
+             || section->size - dataoff < size)
            {
              /* xgettext:c-format */
              _bfd_error_handler
-               (_("%pB: Data Directory size (%lx) "
-                  "exceeds space left in section (%" PRIx64 ")"),
+               (_("%pB: Data Directory (%lx bytes at %" PRIx64 ") "
+                  "extends across section boundary at %" PRIx64),
                 obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
-                (uint64_t) (section->size - (addr - section->vma)));
-             free (data);
-             return FALSE;
+                (uint64_t) addr, (uint64_t) section->vma);
+             return false;
            }
 
-         for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
-                / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
+         if ((section->flags & SEC_HAS_CONTENTS) != 0
+             && bfd_malloc_and_get_section (obfd, section, &data))
            {
-             asection *ddsection;
-             struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
-             struct internal_IMAGE_DEBUG_DIRECTORY idd;
+             unsigned int i;
+             struct external_IMAGE_DEBUG_DIRECTORY *dd =
+               (struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff);
 
-             _bfd_XXi_swap_debugdir_in (obfd, edd, &idd);
+             for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
+                    / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
+               {
+                 asection *ddsection;
+                 struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
+                 struct internal_IMAGE_DEBUG_DIRECTORY idd;
+                 bfd_vma idd_vma;
 
-             if (idd.AddressOfRawData == 0)
-               continue; /* RVA 0 means only offset is valid, not handled yet.  */
+                 _bfd_XXi_swap_debugdir_in (obfd, edd, &idd);
 
-             ddsection = find_section_by_vma (obfd, idd.AddressOfRawData + ope->pe_opthdr.ImageBase);
-             if (!ddsection)
-               continue; /* Not in a section! */
+                 /* RVA 0 means only offset is valid, not handled yet.  */
+                 if (idd.AddressOfRawData == 0)
+                   continue;
 
-             idd.PointerToRawData = ddsection->filepos + (idd.AddressOfRawData
-                                                          + ope->pe_opthdr.ImageBase) - ddsection->vma;
+                 idd_vma = idd.AddressOfRawData + ope->pe_opthdr.ImageBase;
+                 ddsection = find_section_by_vma (obfd, idd_vma);
+                 if (!ddsection)
+                   continue; /* Not in a section! */
 
-             _bfd_XXi_swap_debugdir_out (obfd, &idd, edd);
-           }
+                 idd.PointerToRawData
+                   = ddsection->filepos + idd_vma - ddsection->vma;
+                 _bfd_XXi_swap_debugdir_out (obfd, &idd, edd);
+               }
 
-         if (!bfd_set_section_contents (obfd, section, data, 0, section->size))
-           {
-             _bfd_error_handler (_("failed to update file offsets in debug directory"));
+             if (!bfd_set_section_contents (obfd, section, data, 0,
+                                            section->size))
+               {
+                 _bfd_error_handler (_("failed to update file offsets"
+                                       " in debug directory"));
+                 free (data);
+                 return false;
+               }
              free (data);
-             return FALSE;
            }
-         free (data);
-       }
-      else if (section)
-       {
-         _bfd_error_handler (_("%pB: failed to read debug data section"), obfd);
-         return FALSE;
+         else
+           {
+             _bfd_error_handler (_("%pB: failed to read "
+                                   "debug data section"), obfd);
+             return false;
+           }
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Copy private section data.  */
 
-bfd_boolean
+bool
 _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
                                       asection *isec,
                                       bfd *obfd,
@@ -3121,7 +3094,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
 {
   if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
       || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
-    return TRUE;
+    return true;
 
   if (coff_section_data (ibfd, isec) != NULL
       && pei_section_data (ibfd, isec) != NULL)
@@ -3131,7 +3104,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
          size_t amt = sizeof (struct coff_section_tdata);
          osec->used_by_bfd = bfd_zalloc (obfd, amt);
          if (osec->used_by_bfd == NULL)
-           return FALSE;
+           return false;
        }
 
       if (pei_section_data (obfd, osec) == NULL)
@@ -3139,7 +3112,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
          size_t amt = sizeof (struct pei_section_tdata);
          coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
          if (coff_section_data (obfd, osec)->tdata == NULL)
-           return FALSE;
+           return false;
        }
 
       pei_section_data (obfd, osec)->virt_size =
@@ -3148,7 +3121,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
        pei_section_data (ibfd, isec)->pe_flags;
     }
 
-  return TRUE;
+  return true;
 }
 
 void
@@ -3157,7 +3130,7 @@ _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
   coff_get_symbol_info (abfd, symbol, ret);
 }
 
-#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64))
 static int
 sort_x64_pdata (const void *l, const void *r)
 {
@@ -3182,12 +3155,12 @@ static bfd_byte *
 rsrc_count_directory (bfd *, bfd_byte *, bfd_byte *, bfd_byte *, bfd_vma);
 
 static bfd_byte *
-rsrc_count_entries (bfd *         abfd,
-                   bfd_boolean    is_name,
-                   bfd_byte *     datastart,
-                   bfd_byte *     data,
-                   bfd_byte *     dataend,
-                   bfd_vma        rva_bias)
+rsrc_count_entries (bfd *abfd,
+                   bool is_name,
+                   bfd_byte *datastart,
+                   bfd_byte *data,
+                   bfd_byte *dataend,
+                   bfd_vma rva_bias)
 {
   unsigned long entry, addr, size;
 
@@ -3304,14 +3277,14 @@ typedef struct rsrc_leaf
 
 typedef struct rsrc_entry
 {
-  bfd_boolean is_name;
+  bool is_name;
   union
   {
     unsigned int         id;
     struct rsrc_string   name;
   } name_id;
 
-  bfd_boolean is_dir;
+  bool is_dir;
   union
   {
     struct rsrc_directory * directory;
@@ -3327,14 +3300,14 @@ rsrc_parse_directory (bfd *, rsrc_directory *, bfd_byte *,
                      bfd_byte *, bfd_byte *, bfd_vma, rsrc_entry *);
 
 static bfd_byte *
-rsrc_parse_entry (bfd *                   abfd,
-                 bfd_boolean      is_name,
-                 rsrc_entry *     entry,
-                 bfd_byte *       datastart,
-                 bfd_byte *       data,
-                 bfd_byte *       dataend,
-                 bfd_vma          rva_bias,
-                 rsrc_directory * parent)
+rsrc_parse_entry (bfd *abfd,
+                 bool is_name,
+                 rsrc_entry *entry,
+                 bfd_byte *datastart,
+                 bfd_byte * data,
+                 bfd_byte *dataend,
+                 bfd_vma rva_bias,
+                 rsrc_directory *parent)
 {
   unsigned long val, addr, size;
 
@@ -3371,8 +3344,8 @@ rsrc_parse_entry (bfd *              abfd,
 
   if (HighBitSet (val))
     {
-      entry->is_dir = TRUE;
-      entry->value.directory = bfd_malloc (sizeof * entry->value.directory);
+      entry->is_dir = true;
+      entry->value.directory = bfd_malloc (sizeof (*entry->value.directory));
       if (entry->value.directory == NULL)
        return dataend;
 
@@ -3382,13 +3355,13 @@ rsrc_parse_entry (bfd *            abfd,
                                   dataend, rva_bias, entry);
     }
 
-  entry->is_dir = FALSE;
-  entry->value.leaf = bfd_malloc (sizeof * entry->value.leaf);
+  entry->is_dir = false;
+  entry->value.leaf = bfd_malloc (sizeof (*entry->value.leaf));
   if (entry->value.leaf == NULL)
     return dataend;
 
   data = datastart + val;
-  if (data < datastart || data >= dataend)
+  if (data < datastart || data + 12 > dataend)
     return dataend;
 
   addr = bfd_get_32 (abfd, data);
@@ -3396,6 +3369,8 @@ rsrc_parse_entry (bfd *              abfd,
   entry->value.leaf->codepage = bfd_get_32 (abfd, data + 8);
   /* FIXME: We assume that the reserved field (data + 12) is OK.  */
 
+  if (size > dataend - datastart - (addr - rva_bias))
+    return dataend;
   entry->value.leaf->data = bfd_malloc (size);
   if (entry->value.leaf->data == NULL)
     return dataend;
@@ -3405,15 +3380,15 @@ rsrc_parse_entry (bfd *            abfd,
 }
 
 static bfd_byte *
-rsrc_parse_entries (bfd *           abfd,
-                   rsrc_dir_chain * chain,
-                   bfd_boolean      is_name,
-                   bfd_byte *       highest_data,
-                   bfd_byte *       datastart,
-                   bfd_byte *       data,
-                   bfd_byte *       dataend,
-                   bfd_vma          rva_bias,
-                   rsrc_directory * parent)
+rsrc_parse_entries (bfd *abfd,
+                   rsrc_dir_chain *chain,
+                   bool is_name,
+                   bfd_byte *highest_data,
+                   bfd_byte *datastart,
+                   bfd_byte *data,
+                   bfd_byte *dataend,
+                   bfd_vma rva_bias,
+                   rsrc_directory *parent)
 {
   unsigned int i;
   rsrc_entry * entry;
@@ -3424,7 +3399,7 @@ rsrc_parse_entries (bfd *      abfd,
       return highest_data;
     }
 
-  entry = bfd_malloc (sizeof * entry);
+  entry = bfd_malloc (sizeof (*entry));
   if (entry == NULL)
     return dataend;
 
@@ -3443,7 +3418,7 @@ rsrc_parse_entries (bfd *      abfd,
 
       if (i)
        {
-         entry->next_entry = bfd_malloc (sizeof * entry);
+         entry->next_entry = bfd_malloc (sizeof (*entry));
          entry = entry->next_entry;
          if (entry == NULL)
            return dataend;
@@ -3481,11 +3456,11 @@ rsrc_parse_directory (bfd *            abfd,
 
   data += 16;
 
-  highest_data = rsrc_parse_entries (abfd, & table->names, TRUE, data,
+  highest_data = rsrc_parse_entries (abfd, & table->names, true, data,
                                     datastart, data, dataend, rva_bias, table);
   data += table->names.num_entries * 8;
 
-  highest_data = rsrc_parse_entries (abfd, & table->ids, FALSE, highest_data,
+  highest_data = rsrc_parse_entries (abfd, & table->ids, false, highest_data,
                                     datastart, data, dataend, rva_bias, table);
   data += table->ids.num_entries * 8;
 
@@ -3647,16 +3622,12 @@ rsrc_write_directory (rsrc_write_data * data,
   BFD_ASSERT (nt == next_entry);
 }
 
-#if defined HAVE_WCHAR_H && ! defined __CYGWIN__ && ! defined __MINGW32__
+#if ! defined __CYGWIN__ && ! defined __MINGW32__
 /* Return the length (number of units) of the first character in S,
    putting its 'ucs4_t' representation in *PUC.  */
 
 static unsigned int
-#if defined HAVE_WCTYPE_H
 u16_mbtouc (wint_t * puc, const unsigned short * s, unsigned int n)
-#else
-u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n)
-#endif
 {
   unsigned short c = * s;
 
@@ -3688,11 +3659,11 @@ u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n)
   *puc = 0xfffd;
   return 1;
 }
-#endif /* HAVE_WCHAR_H and not Cygwin/Mingw */
+#endif /* not Cygwin/Mingw */
 
 /* Perform a comparison of two entries.  */
 static signed int
-rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
+rsrc_cmp (bool is_name, rsrc_entry * a, rsrc_entry * b)
 {
   signed int    res;
   bfd_byte *    astring;
@@ -3725,20 +3696,15 @@ rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
   res = rscpcmp ((const wchar_t *) astring, (const wchar_t *) bstring,
                 min (alen, blen));
 
-#elif defined HAVE_WCHAR_H
+#else
   {
     unsigned int  i;
 
     res = 0;
     for (i = min (alen, blen); i--; astring += 2, bstring += 2)
       {
-#if defined HAVE_WCTYPE_H
        wint_t awc;
        wint_t bwc;
-#else
-       wchar_t awc;
-       wchar_t bwc;
-#endif
 
        /* Convert UTF-16 unicode characters into wchar_t characters
           so that we can then perform a case insensitive comparison.  */
@@ -3748,21 +3714,14 @@ rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
        if (Alen != Blen)
          return Alen - Blen;
 
-#ifdef HAVE_WCTYPE_H
        awc = towlower (awc);
        bwc = towlower (bwc);
 
        res = awc - bwc;
-#else
-       res = wcsncasecmp (& awc, & bwc, 1);
-#endif
        if (res)
          break;
       }
   }
-#else
-  /* Do the best we can - a case sensitive, untranslated comparison.  */
-  res = memcmp (astring, bstring, min (alen, blen) * 2);
 #endif
 
   if (res == 0)
@@ -3782,10 +3741,9 @@ rsrc_print_name (char * buffer, rsrc_string string)
 }
 
 static const char *
-rsrc_resource_name (rsrc_entry * entry, rsrc_directory * dir)
+rsrc_resource_name (rsrc_entry *entry, rsrc_directory *dir, char *buffer)
 {
-  static char buffer [256];
-  bfd_boolean is_string = FALSE;
+  bool is_string = false;
 
   buffer[0] = 0;
 
@@ -3808,7 +3766,7 @@ rsrc_resource_name (rsrc_entry * entry, rsrc_directory * dir)
            case 3: strcat (buffer, " (ICON)"); break;
            case 4: strcat (buffer, " (MENU)"); break;
            case 5: strcat (buffer, " (DIALOG)"); break;
-           case 6: strcat (buffer, " (STRING)"); is_string = TRUE; break;
+           case 6: strcat (buffer, " (STRING)"); is_string = true; break;
            case 7: strcat (buffer, " (FONTDIR)"); break;
            case 8: strcat (buffer, " (FONT)"); break;
            case 9: strcat (buffer, " (ACCELERATOR)"); break;
@@ -3872,7 +3830,7 @@ rsrc_resource_name (rsrc_entry * entry, rsrc_directory * dir)
    them and return FALSE.  Otherwise we copy any strings from B into A and
    then return TRUE.  */
 
-static bfd_boolean
+static bool
 rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
                           rsrc_entry * b ATTRIBUTE_UNUSED)
 {
@@ -3921,11 +3879,11 @@ rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
          && !a->parent->entry->is_name)
        _bfd_error_handler (_(".rsrc merge failure: duplicate string resource: %d"),
                            ((a->parent->entry->name_id.id - 1) << 4) + i);
-      return FALSE;
+      return false;
     }
 
   if (copy_needed == 0)
-    return TRUE;
+    return true;
 
   /* If we reach here then A and B must both have non-colliding strings.
      (We never get string resources with fully empty string tables).
@@ -3933,7 +3891,7 @@ rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
      in B's strings.  */
   new_data = bfd_malloc (a->value.leaf->size + copy_needed);
   if (new_data == NULL)
-    return FALSE;
+    return false;
 
   nstring = new_data;
   astring = a->value.leaf->data;
@@ -3970,7 +3928,7 @@ rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
   a->value.leaf->data = new_data;
   a->value.leaf->size += copy_needed;
 
-  return TRUE;
+  return true;
 }
 
 static void rsrc_merge (rsrc_entry *, rsrc_entry *);
@@ -3980,21 +3938,21 @@ static void rsrc_merge (rsrc_entry *, rsrc_entry *);
    with lists and we want to handle matches specially.  */
 
 static void
-rsrc_sort_entries (rsrc_dir_chain *  chain,
-                  bfd_boolean       is_name,
-                  rsrc_directory *  dir)
+rsrc_sort_entries (rsrc_dir_chain *chain,
+                  bool is_name,
+                  rsrc_directory *dir)
 {
   rsrc_entry * entry;
   rsrc_entry * next;
   rsrc_entry ** points_to_entry;
-  bfd_boolean swapped;
+  bool swapped;
 
   if (chain->num_entries < 2)
     return;
 
   do
     {
-      swapped = FALSE;
+      swapped = false;
       points_to_entry = & chain->first_entry;
       entry = * points_to_entry;
       next  = entry->next_entry;
@@ -4010,7 +3968,7 @@ rsrc_sort_entries (rsrc_dir_chain *  chain,
              * points_to_entry = next;
              points_to_entry = & next->next_entry;
              next = entry->next_entry;
-             swapped = TRUE;
+             swapped = true;
            }
          else if (cmp == 0)
            {
@@ -4050,7 +4008,7 @@ rsrc_sort_entries (rsrc_dir_chain *  chain,
                          * points_to_entry = next;
                          points_to_entry = & next->next_entry;
                          next = entry->next_entry;
-                         swapped = TRUE;
+                         swapped = true;
                        }
                      else
                        {
@@ -4116,8 +4074,12 @@ rsrc_sort_entries (rsrc_dir_chain *  chain,
                          || dir->entry->parent->entry == NULL)
                        _bfd_error_handler (_(".rsrc merge failure: duplicate leaf"));
                      else
-                       _bfd_error_handler (_(".rsrc merge failure: duplicate leaf: %s"),
-                                           rsrc_resource_name (entry, dir));
+                       {
+                         char buff[256];
+
+                         _bfd_error_handler (_(".rsrc merge failure: duplicate leaf: %s"),
+                                             rsrc_resource_name (entry, dir, buff));
+                       }
                      bfd_set_error (bfd_error_file_truncated);
                      return;
                    }
@@ -4201,8 +4163,8 @@ rsrc_merge (struct rsrc_entry * a, struct rsrc_entry * b)
   rsrc_attach_chain (& adir->ids, & bdir->ids);
 
   /* Now sort A's entries.  */
-  rsrc_sort_entries (& adir->names, TRUE, adir);
-  rsrc_sort_entries (& adir->ids, FALSE, adir);
+  rsrc_sort_entries (& adir->names, true, adir);
+  rsrc_sort_entries (& adir->ids, false, adir);
 }
 
 /* Check the .rsrc section.  If it contains multiple concatenated
@@ -4244,13 +4206,7 @@ rsrc_process_section (bfd * abfd,
 
   rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
 
-  data = bfd_malloc (size);
-  if (data == NULL)
-    return;
-
-  datastart = data;
-
-  if (! bfd_get_section_contents (abfd, sec, data, 0, size))
+  if (! bfd_malloc_and_get_section (abfd, sec, &datastart))
     goto end;
 
   /* Step zero: Scan the input bfds looking for .rsrc sections and record
@@ -4262,7 +4218,8 @@ rsrc_process_section (bfd * abfd,
      at the end of a variable amount.  (It does not appear to be based upon
      the section alignment or the file alignment).  We need to skip any
      padding bytes when parsing the input .rsrc sections.  */
-  rsrc_sizes = bfd_malloc (max_num_input_rsrc * sizeof * rsrc_sizes);
+  data = datastart;
+  rsrc_sizes = bfd_malloc (max_num_input_rsrc * sizeof (*rsrc_sizes));
   if (rsrc_sizes == NULL)
     goto end;
 
@@ -4279,7 +4236,7 @@ rsrc_process_section (bfd * abfd,
            {
              max_num_input_rsrc += 10;
              rsrc_sizes = bfd_realloc (rsrc_sizes, max_num_input_rsrc
-                                       * sizeof * rsrc_sizes);
+                                       * sizeof (*rsrc_sizes));
              if (rsrc_sizes == NULL)
                goto end;
            }
@@ -4332,7 +4289,7 @@ rsrc_process_section (bfd * abfd,
   data = datastart;
   rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
 
-  type_tables = bfd_malloc (num_resource_sets * sizeof * type_tables);
+  type_tables = bfd_malloc (num_resource_sets * sizeof (*type_tables));
   if (type_tables == NULL)
     goto end;
 
@@ -4369,7 +4326,7 @@ rsrc_process_section (bfd * abfd,
   for (indx = 0; indx < num_resource_sets; indx++)
     rsrc_attach_chain (& new_table.names, & type_tables[indx].names);
 
-  rsrc_sort_entries (& new_table.names, TRUE, & new_table);
+  rsrc_sort_entries (& new_table.names, true, & new_table);
 
   /* Chain the ID entries onto the table.  */
   new_table.ids.first_entry = NULL;
@@ -4378,7 +4335,7 @@ rsrc_process_section (bfd * abfd,
   for (indx = 0; indx < num_resource_sets; indx++)
     rsrc_attach_chain (& new_table.ids, & type_tables[indx].ids);
 
-  rsrc_sort_entries (& new_table.ids, FALSE, & new_table);
+  rsrc_sort_entries (& new_table.ids, false, & new_table);
 
   /* Step four: Create new contents for the .rsrc section.  */
   /* Step four point one: Compute the size of each region of the .rsrc section.
@@ -4420,12 +4377,12 @@ rsrc_process_section (bfd * abfd,
 /* Handle the .idata section and other things that need symbol table
    access.  */
 
-bfd_boolean
+bool
 _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 {
   struct coff_link_hash_entry *h1;
   struct bfd_link_info *info = pfinfo->info;
-  bfd_boolean result = TRUE;
+  bool result = true;
 
   /* There are a few fields that need to be filled in now while we
      have symbol table access.
@@ -4436,7 +4393,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
   /* The import directory.  This is the address of .idata$2, with size
      of .idata$2 + .idata$3.  */
   h1 = coff_link_hash_lookup (coff_hash_table (info),
-                             ".idata$2", FALSE, FALSE, TRUE);
+                             ".idata$2", false, false, true);
   if (h1 != NULL)
     {
       /* PR ld/2729: We cannot rely upon all the output sections having been
@@ -4455,11 +4412,11 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          _bfd_error_handler
            (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"),
             abfd);
-         result = FALSE;
+         result = false;
        }
 
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 ".idata$4", FALSE, FALSE, TRUE);
+                                 ".idata$4", false, false, true);
       if (h1 != NULL
          && (h1->root.type == bfd_link_hash_defined
           || h1->root.type == bfd_link_hash_defweak)
@@ -4475,13 +4432,13 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          _bfd_error_handler
            (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"),
             abfd);
-         result = FALSE;
+         result = false;
        }
 
       /* The import address table.  This is the size/address of
         .idata$5.  */
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 ".idata$5", FALSE, FALSE, TRUE);
+                                 ".idata$5", false, false, true);
       if (h1 != NULL
          && (h1->root.type == bfd_link_hash_defined
           || h1->root.type == bfd_link_hash_defweak)
@@ -4496,11 +4453,11 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          _bfd_error_handler
            (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"),
             abfd);
-         result = FALSE;
+         result = false;
        }
 
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 ".idata$6", FALSE, FALSE, TRUE);
+                                 ".idata$6", false, false, true);
       if (h1 != NULL
          && (h1->root.type == bfd_link_hash_defined
           || h1->root.type == bfd_link_hash_defweak)
@@ -4516,13 +4473,13 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          _bfd_error_handler
            (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
             abfd);
-         result = FALSE;
+         result = false;
        }
     }
   else
     {
       h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                 "__IAT_start__", FALSE, FALSE, TRUE);
+                                 "__IAT_start__", false, false, true);
       if (h1 != NULL
          && (h1->root.type == bfd_link_hash_defined
           || h1->root.type == bfd_link_hash_defweak)
@@ -4537,7 +4494,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
             + h1->root.u.def.section->output_offset);
 
          h1 = coff_link_hash_lookup (coff_hash_table (info),
-                                     "__IAT_end__", FALSE, FALSE, TRUE);
+                                     "__IAT_end__", false, false, true);
          if (h1 != NULL
              && (h1->root.type == bfd_link_hash_defined
               || h1->root.type == bfd_link_hash_defweak)
@@ -4558,7 +4515,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
              _bfd_error_handler
                (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
                   " because .idata$6 is missing"), abfd);
-             result = FALSE;
+             result = false;
            }
        }
     }
@@ -4566,7 +4523,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
   h1 = coff_link_hash_lookup (coff_hash_table (info),
                              (bfd_get_symbol_leading_char (abfd) != 0
                               ? "__tls_used" : "_tls_used"),
-                             FALSE, FALSE, TRUE);
+                             false, false, true);
   if (h1 != NULL)
     {
       if ((h1->root.type == bfd_link_hash_defined
@@ -4583,13 +4540,13 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
          _bfd_error_handler
            (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"),
             abfd);
-         result = FALSE;
+         result = false;
        }
      /* According to PECOFF sepcifications by Microsoft version 8.2
        the TLS data directory consists of 4 pointers, followed
        by two 4-byte integer. This implies that the total size
        is different for 32-bit and 64-bit executables.  */
-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
 #else
       pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
@@ -4598,32 +4555,26 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 
 /* If there is a .pdata section and we have linked pdata finally, we
      need to sort the entries ascending.  */
-#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64))
   {
     asection *sec = bfd_get_section_by_name (abfd, ".pdata");
 
     if (sec)
       {
        bfd_size_type x = sec->rawsize;
-       bfd_byte *tmp_data = NULL;
-
-       if (x)
-         tmp_data = bfd_malloc (x);
+       bfd_byte *tmp_data;
 
-       if (tmp_data != NULL)
+       if (bfd_malloc_and_get_section (abfd, sec, &tmp_data))
          {
-           if (bfd_get_section_contents (abfd, sec, tmp_data, 0, x))
-             {
-               qsort (tmp_data,
-                      (size_t) (x / 12),
-                      12, sort_x64_pdata);
-               bfd_set_section_contents (pfinfo->output_bfd, sec,
-                                         tmp_data, 0, x);
-             }
+           qsort (tmp_data,
+                  (size_t) (x / 12),
+                  12, sort_x64_pdata);
+           bfd_set_section_contents (pfinfo->output_bfd, sec,
+                                     tmp_data, 0, x);
            free (tmp_data);
          }
        else
-         result = FALSE;
+         result = false;
       }
   }
 #endif