Extract get_uncompressed_size
[deliverable/binutils-gdb.git] / bfd / compress.c
1 /* Compressed section support (intended for debug sections).
2 Copyright (C) 2008-2015 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program 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 of the License, or
9 (at your option) any later version.
10
11 This program 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 this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21 #include "sysdep.h"
22 #include <zlib.h>
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "safe-ctype.h"
26
27 static bfd_boolean
28 decompress_contents (bfd_byte *compressed_buffer,
29 bfd_size_type compressed_size,
30 bfd_byte *uncompressed_buffer,
31 bfd_size_type uncompressed_size)
32 {
33 z_stream strm;
34 int rc;
35
36 /* It is possible the section consists of several compressed
37 buffers concatenated together, so we uncompress in a loop. */
38 strm.zalloc = NULL;
39 strm.zfree = NULL;
40 strm.opaque = NULL;
41 strm.avail_in = compressed_size - 12;
42 strm.next_in = (Bytef*) compressed_buffer + 12;
43 strm.avail_out = uncompressed_size;
44
45 BFD_ASSERT (Z_OK == 0);
46 rc = inflateInit (&strm);
47 while (strm.avail_in > 0 && strm.avail_out > 0)
48 {
49 if (rc != Z_OK)
50 break;
51 strm.next_out = ((Bytef*) uncompressed_buffer
52 + (uncompressed_size - strm.avail_out));
53 rc = inflate (&strm, Z_FINISH);
54 if (rc != Z_STREAM_END)
55 break;
56 rc = inflateReset (&strm);
57 }
58 rc |= inflateEnd (&strm);
59 return rc == Z_OK && strm.avail_out == 0;
60 }
61
62 static bfd_size_type
63 get_uncompressed_size (bfd_byte *uncompressed_size_buffer)
64 {
65 bfd_size_type uncompressed_size = uncompressed_size_buffer[0];
66 uncompressed_size <<= 8;
67 uncompressed_size += uncompressed_size_buffer[1];
68 uncompressed_size <<= 8;
69 uncompressed_size += uncompressed_size_buffer[2];
70 uncompressed_size <<= 8;
71 uncompressed_size += uncompressed_size_buffer[3];
72 uncompressed_size <<= 8;
73 uncompressed_size += uncompressed_size_buffer[4];
74 uncompressed_size <<= 8;
75 uncompressed_size += uncompressed_size_buffer[5];
76 uncompressed_size <<= 8;
77 uncompressed_size += uncompressed_size_buffer[6];
78 uncompressed_size <<= 8;
79 uncompressed_size += uncompressed_size_buffer[7];
80 return uncompressed_size;;
81 }
82
83 /* Compress data of the size specified in @var{uncompressed_size}
84 and pointed to by @var{uncompressed_buffer} using zlib and store
85 as the contents field. This function assumes the contents
86 field was allocated using bfd_malloc() or equivalent. If zlib
87 is not installed on this machine, the input is unmodified.
88
89 Return @code{TRUE} if the full section contents is compressed
90 successfully. */
91
92 static bfd_boolean
93 bfd_compress_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
94 bfd_byte *uncompressed_buffer,
95 bfd_size_type uncompressed_size)
96 {
97 uLong compressed_size;
98 bfd_byte *compressed_buffer;
99
100 compressed_size = compressBound (uncompressed_size) + 12;
101 compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);
102
103 if (compressed_buffer == NULL)
104 return FALSE;
105
106 if (compress ((Bytef*) compressed_buffer + 12,
107 &compressed_size,
108 (const Bytef*) uncompressed_buffer,
109 uncompressed_size) != Z_OK)
110 {
111 free (compressed_buffer);
112 bfd_set_error (bfd_error_bad_value);
113 return FALSE;
114 }
115
116 compressed_size += 12;
117
118 /* PR binutils/18087: If compression didn't make the section smaller,
119 just keep it uncompressed. */
120 if (compressed_size < uncompressed_size)
121 {
122 /* Write the zlib header. In this case, it should be "ZLIB" followed
123 by the uncompressed section size, 8 bytes in big-endian order. */
124 memcpy (compressed_buffer, "ZLIB", 4);
125 compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8;
126 compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8;
127 compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8;
128 compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8;
129 compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8;
130 compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8;
131 compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8;
132 compressed_buffer[4] = uncompressed_size;
133
134 free (uncompressed_buffer);
135 sec->contents = compressed_buffer;
136 sec->size = compressed_size;
137 sec->compress_status = COMPRESS_SECTION_DONE;
138 }
139 else
140 {
141 sec->contents = uncompressed_buffer;
142 sec->compress_status = COMPRESS_SECTION_NONE;
143 }
144
145 return TRUE;
146 }
147
148 /*
149 FUNCTION
150 bfd_get_full_section_contents
151
152 SYNOPSIS
153 bfd_boolean bfd_get_full_section_contents
154 (bfd *abfd, asection *section, bfd_byte **ptr);
155
156 DESCRIPTION
157 Read all data from @var{section} in BFD @var{abfd}, decompress
158 if needed, and store in @var{*ptr}. If @var{*ptr} is NULL,
159 return @var{*ptr} with memory malloc'd by this function.
160
161 Return @code{TRUE} if the full section contents is retrieved
162 successfully. If the section has no contents then this function
163 returns @code{TRUE} but @var{*ptr} is set to NULL.
164 */
165
166 bfd_boolean
167 bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
168 {
169 bfd_size_type sz;
170 bfd_byte *p = *ptr;
171 bfd_boolean ret;
172 bfd_size_type save_size;
173 bfd_size_type save_rawsize;
174 bfd_byte *compressed_buffer;
175
176 if (abfd->direction != write_direction && sec->rawsize != 0)
177 sz = sec->rawsize;
178 else
179 sz = sec->size;
180 if (sz == 0)
181 {
182 *ptr = NULL;
183 return TRUE;
184 }
185
186 switch (sec->compress_status)
187 {
188 case COMPRESS_SECTION_NONE:
189 if (p == NULL)
190 {
191 p = (bfd_byte *) bfd_malloc (sz);
192 if (p == NULL)
193 return FALSE;
194 }
195
196 if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
197 {
198 if (*ptr != p)
199 free (p);
200 return FALSE;
201 }
202 *ptr = p;
203 return TRUE;
204
205 case DECOMPRESS_SECTION_SIZED:
206 /* Read in the full compressed section contents. */
207 compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
208 if (compressed_buffer == NULL)
209 return FALSE;
210 save_rawsize = sec->rawsize;
211 save_size = sec->size;
212 /* Clear rawsize, set size to compressed size and set compress_status
213 to COMPRESS_SECTION_NONE. If the compressed size is bigger than
214 the uncompressed size, bfd_get_section_contents will fail. */
215 sec->rawsize = 0;
216 sec->size = sec->compressed_size;
217 sec->compress_status = COMPRESS_SECTION_NONE;
218 ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
219 0, sec->compressed_size);
220 /* Restore rawsize and size. */
221 sec->rawsize = save_rawsize;
222 sec->size = save_size;
223 sec->compress_status = DECOMPRESS_SECTION_SIZED;
224 if (!ret)
225 goto fail_compressed;
226
227 if (p == NULL)
228 p = (bfd_byte *) bfd_malloc (sz);
229 if (p == NULL)
230 goto fail_compressed;
231
232 if (!decompress_contents (compressed_buffer, sec->compressed_size, p, sz))
233 {
234 bfd_set_error (bfd_error_bad_value);
235 if (p != *ptr)
236 free (p);
237 fail_compressed:
238 free (compressed_buffer);
239 return FALSE;
240 }
241
242 free (compressed_buffer);
243 *ptr = p;
244 return TRUE;
245
246 case COMPRESS_SECTION_DONE:
247 if (sec->contents == NULL)
248 return FALSE;
249 if (p == NULL)
250 {
251 p = (bfd_byte *) bfd_malloc (sz);
252 if (p == NULL)
253 return FALSE;
254 *ptr = p;
255 }
256 /* PR 17512; file: 5bc29788. */
257 if (p != sec->contents)
258 memcpy (p, sec->contents, sz);
259 return TRUE;
260
261 default:
262 abort ();
263 }
264 }
265
266 /*
267 FUNCTION
268 bfd_cache_section_contents
269
270 SYNOPSIS
271 void bfd_cache_section_contents
272 (asection *sec, void *contents);
273
274 DESCRIPTION
275 Stash @var(contents) so any following reads of @var(sec) do
276 not need to decompress again.
277 */
278
279 void
280 bfd_cache_section_contents (asection *sec, void *contents)
281 {
282 if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
283 sec->compress_status = COMPRESS_SECTION_DONE;
284 sec->contents = contents;
285 sec->flags |= SEC_IN_MEMORY;
286 }
287
288
289 /*
290 FUNCTION
291 bfd_is_section_compressed
292
293 SYNOPSIS
294 bfd_boolean bfd_is_section_compressed
295 (bfd *abfd, asection *section);
296
297 DESCRIPTION
298 Return @code{TRUE} if @var{section} is compressed.
299 */
300
301 bfd_boolean
302 bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
303 {
304 bfd_byte compressed_buffer [12];
305 unsigned int saved = sec->compress_status;
306 bfd_boolean compressed;
307
308 /* Don't decompress the section. */
309 sec->compress_status = COMPRESS_SECTION_NONE;
310
311 /* Read the zlib header. In this case, it should be "ZLIB" followed
312 by the uncompressed section size, 8 bytes in big-endian order. */
313 compressed = (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)
314 && CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"));
315
316 /* Check for the pathalogical case of a debug string section that
317 contains the string ZLIB.... as the first entry. We assume that
318 no uncompressed .debug_str section would ever be big enough to
319 have the first byte of its (big-endian) size be non-zero. */
320 if (compressed
321 && strcmp (sec->name, ".debug_str") == 0
322 && ISPRINT (compressed_buffer[4]))
323 compressed = FALSE;
324
325 /* Restore compress_status. */
326 sec->compress_status = saved;
327 return compressed;
328 }
329
330 /*
331 FUNCTION
332 bfd_init_section_decompress_status
333
334 SYNOPSIS
335 bfd_boolean bfd_init_section_decompress_status
336 (bfd *abfd, asection *section);
337
338 DESCRIPTION
339 Record compressed section size, update section size with
340 decompressed size and set compress_status to
341 DECOMPRESS_SECTION_SIZED.
342
343 Return @code{FALSE} if the section is not a valid compressed
344 section or zlib is not installed on this machine. Otherwise,
345 return @code{TRUE}.
346 */
347
348 bfd_boolean
349 bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
350 {
351 bfd_byte compressed_buffer [12];
352 bfd_size_type uncompressed_size;
353
354 if (sec->rawsize != 0
355 || sec->contents != NULL
356 || sec->compress_status != COMPRESS_SECTION_NONE
357 || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12))
358 {
359 bfd_set_error (bfd_error_invalid_operation);
360 return FALSE;
361 }
362
363 /* Read the zlib header. In this case, it should be "ZLIB" followed
364 by the uncompressed section size, 8 bytes in big-endian order. */
365 if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
366 {
367 bfd_set_error (bfd_error_wrong_format);
368 return FALSE;
369 }
370
371 uncompressed_size = get_uncompressed_size (compressed_buffer + 4);
372 sec->compressed_size = sec->size;
373 sec->size = uncompressed_size;
374 sec->compress_status = DECOMPRESS_SECTION_SIZED;
375
376 return TRUE;
377 }
378
379 /*
380 FUNCTION
381 bfd_init_section_compress_status
382
383 SYNOPSIS
384 bfd_boolean bfd_init_section_compress_status
385 (bfd *abfd, asection *section);
386
387 DESCRIPTION
388 If open for read, compress section, update section size with
389 compressed size and set compress_status to COMPRESS_SECTION_DONE.
390
391 Return @code{FALSE} if the section is not a valid compressed
392 section or zlib is not installed on this machine. Otherwise,
393 return @code{TRUE}.
394 */
395
396 bfd_boolean
397 bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
398 {
399 bfd_size_type uncompressed_size;
400 bfd_byte *uncompressed_buffer;
401 bfd_boolean ret;
402
403 /* Error if not opened for read. */
404 if (abfd->direction != read_direction
405 || sec->size == 0
406 || sec->rawsize != 0
407 || sec->contents != NULL
408 || sec->compress_status != COMPRESS_SECTION_NONE)
409 {
410 bfd_set_error (bfd_error_invalid_operation);
411 return FALSE;
412 }
413
414 /* Read in the full section contents and compress it. */
415 uncompressed_size = sec->size;
416 uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
417 if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
418 0, uncompressed_size))
419 ret = FALSE;
420 else
421 ret = bfd_compress_section_contents (abfd, sec,
422 uncompressed_buffer,
423 uncompressed_size);
424
425 return ret;
426 }
This page took 0.038959 seconds and 5 git commands to generate.