Make bfd_byte an int8_t, flagword a uint32_t
[binutils-gdb.git] / bfd / peicode.h
index 4fcbac6704061986da0c5b6f3eb6948b8edba051..e2e2be65b5d1c097b1718f9f58d91b1ff9c7bb2c 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of PE/PEI, for BFD.
-   Copyright (C) 1995-2021 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.
@@ -56,7 +56,7 @@
 
 #include "libpei.h"
 
-static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
+static bool (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
 #ifndef coff_bfd_print_private_bfd_data
      NULL;
 #else
@@ -64,10 +64,10 @@ static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
 #undef coff_bfd_print_private_bfd_data
 #endif
 
-static bfd_boolean                     pe_print_private_bfd_data (bfd *, void *);
+static bool pe_print_private_bfd_data (bfd *, void *);
 #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
 
-static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
+static bool (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
 #ifndef coff_bfd_copy_private_bfd_data
      NULL;
 #else
@@ -75,7 +75,7 @@ static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
 #undef coff_bfd_copy_private_bfd_data
 #endif
 
-static bfd_boolean                    pe_bfd_copy_private_bfd_data (bfd *, bfd *);
+static bool pe_bfd_copy_private_bfd_data (bfd *, bfd *);
 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
 
 #define coff_mkobject     pe_mkobject
@@ -191,6 +191,8 @@ coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
 
 #ifdef COFF_IMAGE_WITH_PE
 # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
+#elif defined COFF_WITH_peAArch64
+# define coff_swap_filehdr_out _bfd_XX_only_swap_filehdr_out
 #elif defined COFF_WITH_pex64
 # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
 #elif defined COFF_WITH_pep
@@ -231,7 +233,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
     {
       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
       /* Do not cut upper 32-bits for 64-bit vma.  */
-#ifndef COFF_WITH_pex64
+#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
       scnhdr_int->s_vaddr &= 0xffffffff;
 #endif
     }
@@ -253,7 +255,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
 #endif
 }
 
-static bfd_boolean
+static bool
 pe_mkobject (bfd * abfd)
 {
   pe_data_type *pe;
@@ -262,7 +264,7 @@ pe_mkobject (bfd * abfd)
   abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
 
   if (abfd->tdata.pe_obj_data == 0)
-    return FALSE;
+    return false;
 
   pe = pe_data (abfd);
 
@@ -290,7 +292,11 @@ pe_mkobject (bfd * abfd)
   pe->dos_message[15] = 0x0;
 
   memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
-  return TRUE;
+
+  bfd_coff_long_section_names (abfd)
+    = coff_backend_info (abfd)->_bfd_coff_long_section_names;
+
+  return true;
 }
 
 /* Create the COFF backend specific information.  */
@@ -349,16 +355,16 @@ pe_mkobject_hook (bfd * abfd,
   return (void *) pe;
 }
 
-static bfd_boolean
+static bool
 pe_print_private_bfd_data (bfd *abfd, void * vfile)
 {
   FILE *file = (FILE *) vfile;
 
   if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
-    return FALSE;
+    return false;
 
   if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
-    return TRUE;
+    return true;
 
   fputc ('\n', file);
 
@@ -368,7 +374,7 @@ pe_print_private_bfd_data (bfd *abfd, void * vfile)
 /* Copy any private info we understand from the input bfd
    to the output bfd.  */
 
-static bfd_boolean
+static bool
 pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   /* PR binutils/716: Copy the large address aware flag.
@@ -380,12 +386,12 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
 
   if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
-    return FALSE;
+    return false;
 
   if (pe_saved_coff_bfd_copy_private_bfd_data)
     return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
 
-  return TRUE;
+  return true;
 }
 
 #define coff_bfd_copy_private_section_data \
@@ -395,11 +401,11 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 
 #ifdef COFF_IMAGE_WITH_PE
 \f
-/* Code to handle Microsoft's Image Library Format.
+/* Code to handle Microsoft's Import Library Format.
    Also known as LINK6 format.
    Documentation about this format can be found at:
 
-   http://msdn.microsoft.com/library/specs/pecoff_section8.htm  */
+   https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-library-format  */
 
 /* The following constants specify the sizes of the various data
    structures that we have to create in order to build a bfd describing
@@ -438,7 +444,7 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 #define SIZEOF_IDATA2          (5 * 4)
 
 /* For PEx64 idata4 & 5 have thumb size of 8 bytes.  */
-#ifdef COFF_WITH_pex64
+#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
 #define SIZEOF_IDATA4          (2 * 4)
 #define SIZEOF_IDATA5          (2 * 4)
 #else
@@ -489,7 +495,7 @@ pe_ILF_make_a_symbol_reloc (pe_ILF_vars *           vars,
 
   internal->r_vaddr  = address;
   internal->r_symndx = sym_index;
-  internal->r_type   = entry->howto->type;
+  internal->r_type   = entry->howto ? entry->howto->type : 0;
 
   vars->relcount ++;
 
@@ -520,7 +526,6 @@ pe_ILF_save_relocs (pe_ILF_vars * vars,
     abort ();
 
   coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
-  coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
 
   sec->relocation  = vars->reltab;
   sec->reloc_count = vars->relcount;
@@ -571,7 +576,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   esym = vars->esym_ptr;
 
   /* Copy the symbol's name into the string table.  */
-  sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
+  int len = sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
 
   if (section == NULL)
     section = bfd_und_section_ptr;
@@ -588,8 +593,8 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   /* Initialise the internal symbol structure.  */
   ent->u.syment.n_sclass         = sclass;
   ent->u.syment.n_scnum                  = section->target_index;
-  ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
-  ent->is_sym = TRUE;
+  ent->u.syment._n._n_n._n_offset = (uintptr_t) sym;
+  ent->is_sym = true;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
@@ -607,7 +612,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   vars->table_ptr ++;
   vars->native_ptr ++;
   vars->esym_ptr ++;
-  vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
+  vars->string_ptr += len + 1;
 
   BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
 }
@@ -738,6 +743,16 @@ static const jump_table jtab[] =
   },
 #endif
 
+#ifdef AARCH64MAGIC
+/* We don't currently support jumping to DLLs, so if
+   someone does try emit a runtime trap.  Through UDF #0.  */
+  { AARCH64MAGIC,
+    { 0x00, 0x00, 0x00, 0x00 },
+    4, 0
+  },
+
+#endif
+
 #ifdef  ARMPEMAGIC
   { ARMPEMAGIC,
     { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
@@ -753,6 +768,17 @@ static const jump_table jtab[] =
     16, 12
   },
 #endif
+
+#ifdef LOONGARCH64MAGIC
+/* We don't currently support jumping to DLLs, so if
+   someone does try emit a runtime trap.  Through BREAK 0.  */
+  { LOONGARCH64MAGIC,
+    { 0x00, 0x00, 0x2a, 0x00 },
+    4, 0
+  },
+
+#endif
+
   { 0, { 0 }, 0, 0 }
 };
 
@@ -762,7 +788,7 @@ static const jump_table jtab[] =
 
 /* Build a full BFD from the information supplied in a ILF object.  */
 
-static bfd_boolean
+static bool
 pe_ILF_build_a_bfd (bfd *          abfd,
                    unsigned int    magic,
                    char *          symbol_name,
@@ -795,13 +821,13 @@ pe_ILF_build_a_bfd (bfd *     abfd,
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unhandled import type; %x"),
                          abfd, import_type);
-      return FALSE;
+      return false;
 
     default:
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unrecognized import type; %x"),
                          abfd, import_type);
-      return FALSE;
+      return false;
     }
 
   switch (import_name_type)
@@ -816,7 +842,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
                          abfd, import_name_type);
-      return FALSE;
+      return false;
     }
 
   /* Initialise local variables.
@@ -829,7 +855,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
   vars.bim
     = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
   if (vars.bim == NULL)
-    return FALSE;
+    return false;
 
   ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
   vars.bim->buffer = ptr;
@@ -910,7 +936,7 @@ pe_ILF_build_a_bfd (bfd *       abfd,
        /* See PR 20907 for a reproducer.  */
        goto error_return;
 
-#ifdef COFF_WITH_pex64
+#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
       ((unsigned int *) id4->contents)[0] = ordinal;
       ((unsigned int *) id4->contents)[1] = 0x80000000;
       ((unsigned int *) id5->contents)[0] = ordinal;
@@ -1048,6 +1074,32 @@ pe_ILF_build_a_bfd (bfd *            abfd,
       abort ();
     }
 
+  /* Now create a symbol describing the imported value.  */
+  switch (import_type)
+    {
+    case IMPORT_CODE:
+      pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
+                           BSF_NOT_AT_END | BSF_FUNCTION);
+
+      break;
+
+    case IMPORT_DATA:
+      /* Nothing to do here.  */
+      break;
+
+    default:
+      /* XXX code not yet written.  */
+      abort ();
+    }
+
+  /* Create an import symbol for the DLL, without the .dll suffix.  */
+  ptr = (bfd_byte *) strrchr (source_dll, '.');
+  if (ptr)
+    * ptr = 0;
+  pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
+  if (ptr)
+    * ptr = '.';
+
   /* Initialise the bfd.  */
   memset (& internal_f, 0, sizeof (internal_f));
 
@@ -1063,7 +1115,7 @@ pe_ILF_build_a_bfd (bfd *     abfd,
   if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
     goto error_return;
 
-  coff_data (abfd)->pe = 1;
+  obj_pe (abfd) = true;
 #ifdef THUMBPEMAGIC
   if (vars.magic == THUMBPEMAGIC)
     /* Stop some linker warnings about thumb code not supporting interworking.  */
@@ -1074,38 +1126,13 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   bfd_cache_close (abfd);
 
   abfd->iostream = (void *) vars.bim;
-  abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
+  abfd->flags |= BFD_IN_MEMORY | HAS_SYMS;
   abfd->iovec = &_bfd_memory_iovec;
   abfd->where = 0;
   abfd->origin = 0;
+  abfd->size = 0;
   obj_sym_filepos (abfd) = 0;
 
-  /* Now create a symbol describing the imported value.  */
-  switch (import_type)
-    {
-    case IMPORT_CODE:
-      pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
-                           BSF_NOT_AT_END | BSF_FUNCTION);
-
-      break;
-
-    case IMPORT_DATA:
-      /* Nothing to do here.  */
-      break;
-
-    default:
-      /* XXX code not yet written.  */
-      abort ();
-    }
-
-  /* Create an import symbol for the DLL, without the .dll suffix.  */
-  ptr = (bfd_byte *) strrchr (source_dll, '.');
-  if (ptr)
-    * ptr = 0;
-  pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
-  if (ptr)
-    * ptr = '.';
-
   /* Point the bfd at the symbol table.  */
   obj_symbols (abfd) = vars.sym_cache;
   abfd->symcount = vars.sym_index;
@@ -1114,25 +1141,35 @@ pe_ILF_build_a_bfd (bfd *           abfd,
   obj_raw_syment_count (abfd) = vars.sym_index;
 
   obj_coff_external_syms (abfd) = (void *) vars.esym_table;
-  obj_coff_keep_syms (abfd) = TRUE;
+  obj_coff_keep_syms (abfd) = true;
 
   obj_convert (abfd) = vars.sym_table;
   obj_conv_table_size (abfd) = vars.sym_index;
 
   obj_coff_strings (abfd) = vars.string_table;
-  obj_coff_keep_strings (abfd) = TRUE;
-
-  abfd->flags |= HAS_SYMS;
+  obj_coff_strings_len (abfd) = vars.string_ptr - vars.string_table;
+  obj_coff_keep_strings (abfd) = true;
 
-  return TRUE;
+  return true;
 
  error_return:
   free (vars.bim->buffer);
   free (vars.bim);
-  return FALSE;
+  return false;
 }
 
-/* We have detected a Image Library Format archive element.
+/* Cleanup function, returned from check_format hook.  */
+
+static void
+pe_ILF_cleanup (bfd *abfd)
+{
+  struct bfd_in_memory *bim = abfd->iostream;
+  free (bim->buffer);
+  free (bim);
+  abfd->iostream = NULL;
+}
+
+/* We have detected an Import Library Format archive element.
    Decode the element and return the appropriate target.  */
 
 static bfd_cleanup
@@ -1149,7 +1186,7 @@ pe_ILF_object_p (bfd * abfd)
   unsigned int   magic;
 
   /* Upon entry the first six bytes of the ILF header have
-      already been read.  Now read the rest of the header.  */
+     already been read.  Now read the rest of the header.  */
   if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14)
     return NULL;
 
@@ -1206,6 +1243,18 @@ pe_ILF_object_p (bfd * abfd)
 #endif
       break;
 
+    case IMAGE_FILE_MACHINE_ARM64:
+#ifdef AARCH64MAGIC
+      magic = AARCH64MAGIC;
+#endif
+      break;
+
+    case IMAGE_FILE_MACHINE_LOONGARCH64:
+#ifdef LOONGARCH64MAGIC
+      magic = LOONGARCH64MAGIC;
+#endif
+      break;
+
     case IMAGE_FILE_MACHINE_THUMB:
 #ifdef THUMBPEMAGIC
       {
@@ -1293,7 +1342,7 @@ pe_ILF_object_p (bfd * abfd)
       return NULL;
     }
 
-  return _bfd_no_cleanup;
+  return pe_ILF_cleanup;
 }
 
 static void
@@ -1367,7 +1416,7 @@ pe_bfd_read_buildid (bfd *abfd)
          */
          if (_bfd_XXi_slurp_codeview_record (abfd,
                                              (file_ptr) idd.PointerToRawData,
-                                             idd.SizeOfData, cvinfo))
+                                             idd.SizeOfData, cvinfo, NULL))
            {
              struct bfd_build_id* build_id = bfd_alloc (abfd,
                         sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
@@ -1474,7 +1523,7 @@ pe_bfd_object_p (bfd * abfd)
   if (opt_hdr_size != 0)
     {
       bfd_size_type amt = opt_hdr_size;
-      void * opthdr;
+      bfd_byte * opthdr;
 
       /* PR 17521 file: 230-131433-0.004.  */
       if (amt < sizeof (PEAOUTHDR))
@@ -1486,19 +1535,53 @@ pe_bfd_object_p (bfd * abfd)
       if (amt > opt_hdr_size)
        memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
 
-      bfd_set_error (bfd_error_no_error);
-      bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
-      if (bfd_get_error () != bfd_error_no_error)
-       return NULL;
-    }
+      bfd_coff_swap_aouthdr_in (abfd, opthdr, &internal_a);
 
+      struct internal_extra_pe_aouthdr *a = &internal_a.pe;
+
+#ifdef ARM
+      /* Use Subsystem to distinguish between pei-arm-little and
+        pei-arm-wince-little.  */
+#ifdef WINCE
+      if (a->Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CE_GUI)
+#else
+      if (a->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CE_GUI)
+#endif
+       {
+         bfd_set_error (bfd_error_wrong_format);
+         return NULL;
+       }
+#endif
+
+      if ((a->SectionAlignment & -a->SectionAlignment) != a->SectionAlignment
+         || a->SectionAlignment >= 0x80000000)
+       {
+         _bfd_error_handler (_("%pB: adjusting invalid SectionAlignment"),
+                               abfd);
+         a->SectionAlignment &= -a->SectionAlignment;
+         if (a->SectionAlignment >= 0x80000000)
+           a->SectionAlignment = 0x40000000;
+       }
+
+      if ((a->FileAlignment & -a->FileAlignment) != a->FileAlignment
+         || a->FileAlignment > a->SectionAlignment)
+       {
+         _bfd_error_handler (_("%pB: adjusting invalid FileAlignment"),
+                             abfd);
+         a->FileAlignment &= -a->FileAlignment;
+         if (a->FileAlignment > a->SectionAlignment)
+           a->FileAlignment = a->SectionAlignment;
+       }
+
+      if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+       _bfd_error_handler (_("%pB: invalid NumberOfRvaAndSizes"), abfd);
+    }
 
   result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
                               (opt_hdr_size != 0
                                ? &internal_a
                                : (struct internal_aouthdr *) NULL));
 
-
   if (result)
     {
       /* Now the whole header has been processed, see if there is a build-id */