Make bfd_byte an int8_t, flagword a uint32_t
[binutils-gdb.git] / bfd / compress.c
index 5ea7cd95f3a7d9cc819237e81d2bf84510496a69..844328b27a965f71295adb6d510b402cfdb565fa 100644 (file)
@@ -1,5 +1,5 @@
 /* Compressed section support (intended for debug sections).
-   Copyright (C) 2008-2022 Free Software Foundation, Inc.
+   Copyright (C) 2008-2023 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #include "elf-bfd.h"
 #include "libbfd.h"
 #include "safe-ctype.h"
+#include "libiberty.h"
 
 #define MAX_COMPRESSION_HEADER_SIZE 24
 
 /*
 CODE_FRAGMENT
+.{* Types of compressed DWARF debug sections.  *}
+.enum compressed_debug_section_type
+.{
+.  COMPRESS_DEBUG_NONE = 0,
+.  COMPRESS_DEBUG_GNU_ZLIB = 1 << 1,
+.  COMPRESS_DEBUG_GABI_ZLIB = 1 << 2,
+.  COMPRESS_DEBUG_ZSTD = 1 << 3,
+.  COMPRESS_UNKNOWN = 1 << 4
+.};
+.
+.{* Tuple for compressed_debug_section_type and their name.  *}
+.struct compressed_type_tuple
+.{
+.  enum compressed_debug_section_type type;
+.  const char *name;
+.};
+.
+.{* Compression header ch_type values.  *}
 .enum compression_type
 .{
 .  ch_none = 0,
@@ -66,6 +85,54 @@ CODE_FRAGMENT
 .
 */
 
+/* Display texts for type of compressed DWARF debug sections.  */
+static const struct compressed_type_tuple compressed_debug_section_names[] =
+{
+  { COMPRESS_DEBUG_NONE, "none" },
+  { COMPRESS_DEBUG_GABI_ZLIB, "zlib" },
+  { COMPRESS_DEBUG_GNU_ZLIB, "zlib-gnu" },
+  { COMPRESS_DEBUG_GABI_ZLIB, "zlib-gabi" },
+  { COMPRESS_DEBUG_ZSTD, "zstd" },
+};
+
+/*
+FUNCTION
+       bfd_get_compression_algorithm
+SYNOPSIS
+       enum compressed_debug_section_type
+         bfd_get_compression_algorithm (const char *name);
+DESCRIPTION
+       Return compressed_debug_section_type from a string representation.
+*/
+enum compressed_debug_section_type
+bfd_get_compression_algorithm (const char *name)
+{
+  for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i)
+    if (strcasecmp (compressed_debug_section_names[i].name, name) == 0)
+      return compressed_debug_section_names[i].type;
+
+  return COMPRESS_UNKNOWN;
+}
+
+/*
+FUNCTION
+       bfd_get_compression_algorithm_name
+SYNOPSIS
+       const char *bfd_get_compression_algorithm_name
+         (enum compressed_debug_section_type type);
+DESCRIPTION
+       Return compression algorithm name based on the type.
+*/
+const char *
+bfd_get_compression_algorithm_name (enum compressed_debug_section_type type)
+{
+  for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i)
+    if (type == compressed_debug_section_names[i].type)
+      return compressed_debug_section_names[i].name;
+
+  return NULL;
+}
+
 /*
 FUNCTION
        bfd_update_compression_header
@@ -196,9 +263,6 @@ SYNOPSIS
 
 DESCRIPTION
        Return the size of the compression header of SEC in ABFD.
-
-RETURNS
-       Return the size of the compression header in bytes.
 */
 
 int
@@ -249,7 +313,7 @@ bfd_convert_section_setup (bfd *ibfd, asection *isec, bfd *obfd,
     {
       const char *name = *new_name;
 
-      if ((ibfd->flags & (BFD_DECOMPRESS | BFD_COMPRESS_GABI)) != 0)
+      if ((obfd->flags & (BFD_DECOMPRESS | BFD_COMPRESS_GABI)) != 0)
        {
          /* When we decompress or compress with SHF_COMPRESSED,
             convert section name from .zdebug_* to .debug_*.  */
@@ -615,7 +679,8 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec)
   if (compressed_size >= uncompressed_size)
     {
       memcpy (buffer, input_buffer, uncompressed_size);
-      elf_section_flags (sec) &= ~SHF_COMPRESSED;
+      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+       elf_section_flags (sec) &= ~SHF_COMPRESSED;
       sec->compress_status = COMPRESS_SECTION_NONE;
     }
   else
@@ -652,7 +717,8 @@ DESCRIPTION
 bool
 bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
 {
-  bfd_size_type sz = bfd_get_section_limit_octets (abfd, sec);
+  bfd_size_type readsz = bfd_get_section_limit_octets (abfd, sec);
+  bfd_size_type allocsz = bfd_get_section_alloc_size (abfd, sec);
   bfd_byte *p = *ptr;
   bool ret;
   bfd_size_type save_size;
@@ -661,7 +727,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
   unsigned int compression_header_size;
   const unsigned int compress_status = sec->compress_status;
 
-  if (sz == 0)
+  if (allocsz == 0)
     {
       *ptr = NULL;
       return true;
@@ -676,7 +742,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
-        abfd, sec, (uint64_t) sz);
+        abfd, sec, (uint64_t) readsz);
       return false;
     }
 
@@ -685,7 +751,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
     case COMPRESS_SECTION_NONE:
       if (p == NULL)
        {
-         p = (bfd_byte *) bfd_malloc (sz);
+         p = (bfd_byte *) bfd_malloc (allocsz);
          if (p == NULL)
            {
              /* PR 20801: Provide a more helpful error message.  */
@@ -693,12 +759,12 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
                _bfd_error_handler
                  /* xgettext:c-format */
                  (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
-                 abfd, sec, (uint64_t) sz);
+                 abfd, sec, (uint64_t) allocsz);
              return false;
            }
        }
 
-      if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
+      if (!bfd_get_section_contents (abfd, sec, p, 0, readsz))
        {
          if (*ptr != p)
            free (p);
@@ -731,7 +797,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
        goto fail_compressed;
 
       if (p == NULL)
-       p = (bfd_byte *) bfd_malloc (sz);
+       p = (bfd_byte *) bfd_malloc (allocsz);
       if (p == NULL)
        goto fail_compressed;
 
@@ -743,7 +809,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       bool is_zstd = compress_status == DECOMPRESS_SECTION_ZSTD;
       if (!decompress_contents (
              is_zstd, compressed_buffer + compression_header_size,
-             sec->compressed_size - compression_header_size, p, sz))
+             sec->compressed_size - compression_header_size, p, readsz))
        {
          bfd_set_error (bfd_error_bad_value);
          if (p != *ptr)
@@ -762,14 +828,14 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
        return false;
       if (p == NULL)
        {
-         p = (bfd_byte *) bfd_malloc (sz);
+         p = (bfd_byte *) bfd_malloc (allocsz);
          if (p == NULL)
            return false;
          *ptr = p;
        }
       /* PR 17512; file: 5bc29788.  */
       if (p != sec->contents)
-       memcpy (p, sec->contents, sz);
+       memcpy (p, sec->contents, readsz);
       return true;
 
     default:
@@ -999,7 +1065,8 @@ bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
       || sec->size == 0
       || sec->rawsize != 0
       || sec->contents != NULL
-      || sec->compress_status != COMPRESS_SECTION_NONE)
+      || sec->compress_status != COMPRESS_SECTION_NONE
+      || _bfd_section_size_insane (abfd, sec))
     {
       bfd_set_error (bfd_error_invalid_operation);
       return false;
@@ -1014,7 +1081,10 @@ bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
 
   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
                                 0, uncompressed_size))
-    return false;
+    {
+      free (uncompressed_buffer);
+      return false;
+    }
 
   sec->contents = uncompressed_buffer;
   if (bfd_compress_section_contents (abfd, sec) == 0)