]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libbacktrace: support compressed block with no sequences
authorIan Lance Taylor <iant@golang.org>
Tue, 2 Jun 2026 04:34:27 +0000 (21:34 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 2 Jun 2026 04:36:18 +0000 (21:36 -0700)
* elf.c (elf_zstd_decompress_frame): Support a compressed block
with no sequences, only literals.

libbacktrace/elf.c

index 5aee4afd0d1b5d1baac5bc80d9995eba32e9c14c..f3033580e037a5e478f9b7bdb72823296aca2db6 100644 (file)
@@ -4620,6 +4620,11 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
                pin += 2;
              }
 
+           pback = NULL;
+           bits = 0;
+           literal_state = 0;
+           offset_state = 0;
+           match_state = 0;
            if (seq_count > 0)
              {
                int (*pfn)(const struct elf_zstd_fse_entry *,
@@ -4659,27 +4664,27 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
                                                 match_fse_table, 9, pfn,
                                                 &match_decode))
                  return 0;
-             }
 
-           pback = pblockend - 1;
-           if (!elf_fetch_backward_init (&pback, pin, &val, &bits))
-             return 0;
+               pback = pblockend - 1;
+               if (!elf_fetch_backward_init (&pback, pin, &val, &bits))
+                 return 0;
 
-           bits -= literal_decode.table_bits;
-           literal_state = ((val >> bits)
-                            & ((1U << literal_decode.table_bits) - 1));
+               bits -= literal_decode.table_bits;
+               literal_state = ((val >> bits)
+                                & ((1U << literal_decode.table_bits) - 1));
 
-           if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
-             return 0;
-           bits -= offset_decode.table_bits;
-           offset_state = ((val >> bits)
-                           & ((1U << offset_decode.table_bits) - 1));
+               if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+                 return 0;
+               bits -= offset_decode.table_bits;
+               offset_state = ((val >> bits)
+                               & ((1U << offset_decode.table_bits) - 1));
 
-           if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
-             return 0;
-           bits -= match_decode.table_bits;
-           match_state = ((val >> bits)
-                          & ((1U << match_decode.table_bits) - 1));
+               if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+                 return 0;
+               bits -= match_decode.table_bits;
+               match_state = ((val >> bits)
+                              & ((1U << match_decode.table_bits) - 1));
+             }
 
            seq = 0;
            while (1)
@@ -4701,6 +4706,40 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
                uint32_t need;
                uint32_t add;
 
+               if (unlikely (seq >= seq_count))
+                 {
+                   /* Copy remaining literals.  */
+                   if (literal_count > 0 && plit != pout)
+                     {
+                       if (unlikely ((size_t)(poutend - pout)
+                                     < literal_count))
+                         {
+                           elf_uncompress_failed ();
+                           return 0;
+                         }
+
+                       if ((size_t)(plit - pout) < literal_count)
+                         {
+                           uint32_t move;
+
+                           move = plit - pout;
+                           while (literal_count > move)
+                             {
+                               memcpy (pout, plit, move);
+                               pout += move;
+                               plit += move;
+                               literal_count -= move;
+                             }
+                         }
+
+                       memcpy (pout, plit, literal_count);
+                     }
+
+                   pout += literal_count;
+
+                   break;
+                 }
+
                pt = &offset_decode.table[offset_state];
                offset_basebits = pt->basebits;
                offset_baseline = pt->baseline;
@@ -4938,40 +4977,6 @@ elf_zstd_decompress_frame (const unsigned char **ppin,
                          }
                      }
                  }
-
-               if (unlikely (seq >= seq_count))
-                 {
-                   /* Copy remaining literals.  */
-                   if (literal_count > 0 && plit != pout)
-                     {
-                       if (unlikely ((size_t)(poutend - pout)
-                                     < literal_count))
-                         {
-                           elf_uncompress_failed ();
-                           return 0;
-                         }
-
-                       if ((size_t)(plit - pout) < literal_count)
-                         {
-                           uint32_t move;
-
-                           move = plit - pout;
-                           while (literal_count > move)
-                             {
-                               memcpy (pout, plit, move);
-                               pout += move;
-                               plit += move;
-                               literal_count -= move;
-                             }
-                         }
-
-                       memcpy (pout, plit, literal_count);
-                     }
-
-                   pout += literal_count;
-
-                   break;
-                 }
              }
 
            pin = pblockend;