xref: /dragonfly/contrib/gdb-7/bfd/compress.c (revision 92fc8b5c)
1 /* Compressed section support (intended for debug sections).
2    Copyright 2008, 2010
3    Free Software Foundation, Inc.
4 
5    This file is part of BFD, the Binary File Descriptor library.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21 
22 #include "config.h"
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #ifdef HAVE_ZLIB_H
27 #include <zlib.h>
28 #endif
29 
30 /*
31 FUNCTION
32 	bfd_uncompress_section_contents
33 
34 SYNOPSIS
35 	bfd_boolean bfd_uncompress_section_contents
36 	  (bfd_byte **buffer, bfd_size_type *size);
37 
38 DESCRIPTION
39 
40 	Uncompresses a section that was compressed using zlib, in place.  At
41 	the call to this function, *@var{buffer} and *@var{size} should point
42 	to the section contents to be uncompressed.  At the end of the
43 	function, *@var{buffer} and *@var{size} will point to the uncompressed
44 	contents.  This function assumes *BUFFER was allocated using
45 	bfd_malloc() or equivalent.  If the section is not a valid compressed
46 	section, or zlib is not installed on this machine, the input is
47 	unmodified.
48 
49         Returns @code{FALSE} if unable to uncompress successfully; in that case
50         the input is unmodified.  Otherwise, returns @code{TRUE}.
51 */
52 
53 bfd_boolean
54 bfd_uncompress_section_contents (bfd_byte **buffer ATTRIBUTE_UNUSED,
55 				 bfd_size_type *size ATTRIBUTE_UNUSED)
56 {
57 #ifndef HAVE_ZLIB_H
58   return FALSE;
59 #else
60   bfd_size_type compressed_size = *size;
61   bfd_byte *compressed_buffer = *buffer;
62   bfd_size_type uncompressed_size;
63   bfd_byte *uncompressed_buffer;
64   z_stream strm;
65   int rc;
66   bfd_size_type header_size = 12;
67 
68   /* Read the zlib header.  In this case, it should be "ZLIB" followed
69      by the uncompressed section size, 8 bytes in big-endian order.  */
70   if (compressed_size < header_size
71       || ! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
72     return FALSE;
73   uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
74   uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
75   uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
76   uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
77   uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
78   uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
79   uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
80   uncompressed_size += compressed_buffer[11];
81 
82   /* It is possible the section consists of several compressed
83      buffers concatenated together, so we uncompress in a loop.  */
84   strm.zalloc = NULL;
85   strm.zfree = NULL;
86   strm.opaque = NULL;
87   strm.avail_in = compressed_size - header_size;
88   strm.next_in = (Bytef*) compressed_buffer + header_size;
89   strm.avail_out = uncompressed_size;
90   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
91   if (! uncompressed_buffer)
92     return FALSE;
93 
94   rc = inflateInit (&strm);
95   while (strm.avail_in > 0)
96     {
97       if (rc != Z_OK)
98         goto fail;
99       strm.next_out = ((Bytef*) uncompressed_buffer
100                        + (uncompressed_size - strm.avail_out));
101       rc = inflate (&strm, Z_FINISH);
102       if (rc != Z_STREAM_END)
103         goto fail;
104       rc = inflateReset (&strm);
105     }
106   rc = inflateEnd (&strm);
107   if (rc != Z_OK
108       || strm.avail_out != 0)
109     goto fail;
110 
111   free (compressed_buffer);
112   *buffer = uncompressed_buffer;
113   *size = uncompressed_size;
114   return TRUE;
115 
116  fail:
117   free (uncompressed_buffer);
118   return FALSE;
119 #endif  /* HAVE_ZLIB_H */
120 }
121