xref: /netbsd-src/external/gpl3/binutils/dist/gas/compress-debug.c (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1 /* compress-debug.c - compress debug sections
2    Copyright (C) 2010-2024 Free Software Foundation, Inc.
3 
4    This file is part of GAS, the GNU Assembler.
5 
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 #include "config.h"
22 #include <stdio.h>
23 #include <string.h>
24 #include <zlib.h>
25 #if HAVE_ZSTD
26 #include <zstd.h>
27 #endif
28 #include "ansidecl.h"
29 #include "compress-debug.h"
30 
31 /* Initialize the compression engine.  */
32 
33 void *
34 compress_init (bool use_zstd)
35 {
36   if (use_zstd) {
37 #if HAVE_ZSTD
38     return ZSTD_createCCtx ();
39 #endif
40   }
41 
42   static struct z_stream_s strm;
43   memset (&strm, 0, sizeof (strm));
44   deflateInit (&strm, Z_DEFAULT_COMPRESSION);
45   return &strm;
46 }
47 
48 /* Stream the contents of a frag to the compression engine.  Output
49    from the engine goes into the current frag on the obstack.  */
50 
51 int
52 compress_data (bool use_zstd, void *ctx, const char **next_in, int *avail_in,
53 	       char **next_out, int *avail_out)
54 {
55   if (use_zstd)
56     {
57 #if HAVE_ZSTD
58       ZSTD_outBuffer ob = { *next_out, *avail_out, 0 };
59       ZSTD_inBuffer ib = { *next_in, *avail_in, 0 };
60       size_t ret = ZSTD_compressStream2 (ctx, &ob, &ib, ZSTD_e_continue);
61       *next_in += ib.pos;
62       *avail_in -= ib.pos;
63       *next_out += ob.pos;
64       *avail_out -= ob.pos;
65       if (ZSTD_isError (ret))
66 	return -1;
67       return (int)ob.pos;
68 #endif
69     }
70 
71   struct z_stream_s *strm = ctx;
72 
73   strm->next_in = (Bytef *) (*next_in);
74   strm->avail_in = *avail_in;
75   strm->next_out = (Bytef *) (*next_out);
76   strm->avail_out = *avail_out;
77 
78   int x = deflate (strm, Z_NO_FLUSH);
79   if (x != Z_OK)
80     return -1;
81 
82   int out_size = *avail_out - strm->avail_out;
83   *next_in = (char *) (strm->next_in);
84   *avail_in = strm->avail_in;
85   *next_out = (char *) (strm->next_out);
86   *avail_out = strm->avail_out;
87 
88   return out_size;
89 }
90 
91 /* Finish the compression and consume the remaining compressed output.
92    Returns -1 for error, 0 when done, 1 when more output buffer is
93    needed.  */
94 
95 int
96 compress_finish (bool use_zstd, void *ctx, char **next_out,
97 		 int *avail_out, int *out_size)
98 {
99   if (use_zstd)
100     {
101 #if HAVE_ZSTD
102       ZSTD_outBuffer ob = { *next_out, *avail_out, 0 };
103       ZSTD_inBuffer ib = { 0, 0, 0 };
104       size_t ret = ZSTD_compressStream2 (ctx, &ob, &ib, ZSTD_e_end);
105       *out_size = ob.pos;
106       *next_out += ob.pos;
107       *avail_out -= ob.pos;
108       if (ZSTD_isError (ret))
109 	return -1;
110       if (ret == 0)
111 	ZSTD_freeCCtx (ctx);
112       return ret ? 1 : 0;
113 #endif
114     }
115 
116   int x;
117   struct z_stream_s *strm = ctx;
118 
119   strm->avail_in = 0;
120   strm->next_out = (Bytef *) (*next_out);
121   strm->avail_out = *avail_out;
122 
123   x = deflate (strm, Z_FINISH);
124 
125   *out_size = *avail_out - strm->avail_out;
126   *next_out = (char *) (strm->next_out);
127   *avail_out = strm->avail_out;
128 
129   if (x == Z_STREAM_END)
130     {
131       deflateEnd (strm);
132       return 0;
133     }
134   if (strm->avail_out != 0)
135     return -1;
136   return 1;
137 }
138