(root)/
binutils-2.41/
gas/
compress-debug.c
       1  /* compress-debug.c - compress debug sections
       2     Copyright (C) 2010-2023 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  }