xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/compress.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* Compressed section support (intended for debug sections).
2    Copyright (C) 2008-2022 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 #define MAX_COMPRESSION_HEADER_SIZE 24
28 
29 static bool
decompress_contents(bfd_byte * compressed_buffer,bfd_size_type compressed_size,bfd_byte * uncompressed_buffer,bfd_size_type uncompressed_size)30 decompress_contents (bfd_byte *compressed_buffer,
31 		     bfd_size_type compressed_size,
32 		     bfd_byte *uncompressed_buffer,
33 		     bfd_size_type uncompressed_size)
34 {
35   z_stream strm;
36   int rc;
37 
38   /* It is possible the section consists of several compressed
39      buffers concatenated together, so we uncompress in a loop.  */
40   /* PR 18313: The state field in the z_stream structure is supposed
41      to be invisible to the user (ie us), but some compilers will
42      still complain about it being used without initialisation.  So
43      we first zero the entire z_stream structure and then set the fields
44      that we need.  */
45   memset (& strm, 0, sizeof strm);
46   strm.avail_in = compressed_size;
47   strm.next_in = (Bytef*) compressed_buffer;
48   strm.avail_out = uncompressed_size;
49   /* FIXME: strm.avail_in and strm.avail_out are typically unsigned
50      int.  Supporting sizes that don't fit in an unsigned int is
51      possible but will require some rewriting of this function.  */
52   if (strm.avail_in != compressed_size || strm.avail_out != uncompressed_size)
53     return false;
54 
55   BFD_ASSERT (Z_OK == 0);
56   rc = inflateInit (&strm);
57   while (strm.avail_in > 0 && strm.avail_out > 0)
58     {
59       if (rc != Z_OK)
60 	break;
61       strm.next_out = ((Bytef*) uncompressed_buffer
62 		       + (uncompressed_size - strm.avail_out));
63       rc = inflate (&strm, Z_FINISH);
64       if (rc != Z_STREAM_END)
65 	break;
66       rc = inflateReset (&strm);
67     }
68   return inflateEnd (&strm) == Z_OK && rc == Z_OK && strm.avail_out == 0;
69 }
70 
71 /* Compress data of the size specified in @var{uncompressed_size}
72    and pointed to by @var{uncompressed_buffer} using zlib and store
73    as the contents field.  This function assumes the contents
74    field was allocated using bfd_malloc() or equivalent.
75 
76    Return the uncompressed size if the full section contents is
77    compressed successfully.  Otherwise return 0.  */
78 
79 static bfd_size_type
bfd_compress_section_contents(bfd * abfd,sec_ptr sec,bfd_byte * uncompressed_buffer,bfd_size_type uncompressed_size)80 bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
81 			       bfd_byte *uncompressed_buffer,
82 			       bfd_size_type uncompressed_size)
83 {
84   uLong compressed_size;
85   bfd_byte *buffer;
86   bfd_size_type buffer_size;
87   bool decompress;
88   int zlib_size = 0;
89   int orig_compression_header_size;
90   bfd_size_type orig_uncompressed_size;
91   unsigned int orig_uncompressed_alignment_pow;
92   int header_size = bfd_get_compression_header_size (abfd, NULL);
93   bool compressed
94     = bfd_is_section_compressed_with_header (abfd, sec,
95 					     &orig_compression_header_size,
96 					     &orig_uncompressed_size,
97 					     &orig_uncompressed_alignment_pow);
98 
99   /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
100      overhead in .zdebug* section.  */
101   if (!header_size)
102      header_size = 12;
103 
104   if (compressed)
105     {
106       /* We shouldn't decompress unsupported compressed section.  */
107       if (orig_compression_header_size < 0)
108 	abort ();
109 
110       /* Different compression schemes.  Just move the compressed section
111 	 contents to the right position. */
112       if (orig_compression_header_size == 0)
113 	{
114 	  /* Convert it from .zdebug* section.  Get the uncompressed
115 	     size first.  We need to subtract the 12-byte overhead in
116 	     .zdebug* section.  Set orig_compression_header_size to
117 	     the 12-bye overhead.  */
118 	  orig_compression_header_size = 12;
119 	  zlib_size = uncompressed_size - 12;
120 	}
121       else
122 	{
123 	  /* Convert it to .zdebug* section.  */
124 	  zlib_size = uncompressed_size - orig_compression_header_size;
125 	}
126 
127       /* Add the header size.  */
128       compressed_size = zlib_size + header_size;
129     }
130   else
131     compressed_size = compressBound (uncompressed_size) + header_size;
132 
133   /* Uncompress if it leads to smaller size.  */
134   if (compressed && compressed_size > orig_uncompressed_size)
135     {
136       decompress = true;
137       buffer_size = orig_uncompressed_size;
138     }
139   else
140     {
141       decompress = false;
142       buffer_size = compressed_size;
143     }
144   buffer = (bfd_byte *) bfd_alloc (abfd, buffer_size);
145   if (buffer == NULL)
146     return 0;
147 
148   if (compressed)
149     {
150       sec->size = orig_uncompressed_size;
151       if (decompress)
152 	{
153 	  if (!decompress_contents (uncompressed_buffer
154 				    + orig_compression_header_size,
155 				    zlib_size, buffer, buffer_size))
156 	    {
157 	      bfd_set_error (bfd_error_bad_value);
158 	      bfd_release (abfd, buffer);
159 	      return 0;
160 	    }
161 	  free (uncompressed_buffer);
162 	  bfd_set_section_alignment (sec, orig_uncompressed_alignment_pow);
163 
164 	  sec->contents = buffer;
165 	  sec->compress_status = COMPRESS_SECTION_DONE;
166 	  return orig_uncompressed_size;
167 	}
168       else
169 	{
170 	  bfd_update_compression_header (abfd, buffer, sec);
171 	  memmove (buffer + header_size,
172 		   uncompressed_buffer + orig_compression_header_size,
173 		   zlib_size);
174 	}
175     }
176   else
177     {
178       if (compress ((Bytef*) buffer + header_size,
179 		    &compressed_size,
180 		    (const Bytef*) uncompressed_buffer,
181 		    uncompressed_size) != Z_OK)
182 	{
183 	  bfd_release (abfd, buffer);
184 	  bfd_set_error (bfd_error_bad_value);
185 	  return 0;
186 	}
187 
188       compressed_size += header_size;
189       /* PR binutils/18087: If compression didn't make the section smaller,
190 	 just keep it uncompressed.  */
191       if (compressed_size < uncompressed_size)
192 	bfd_update_compression_header (abfd, buffer, sec);
193       else
194 	{
195 	  /* NOTE: There is a small memory leak here since
196 	     uncompressed_buffer is malloced and won't be freed.  */
197 	  bfd_release (abfd, buffer);
198 	  sec->contents = uncompressed_buffer;
199 	  sec->compress_status = COMPRESS_SECTION_NONE;
200 	  return uncompressed_size;
201 	}
202     }
203 
204   free (uncompressed_buffer);
205   sec->contents = buffer;
206   sec->size = compressed_size;
207   sec->compress_status = COMPRESS_SECTION_DONE;
208 
209   return uncompressed_size;
210 }
211 
212 /*
213 FUNCTION
214 	bfd_get_full_section_contents
215 
216 SYNOPSIS
217 	bool bfd_get_full_section_contents
218 	  (bfd *abfd, asection *section, bfd_byte **ptr);
219 
220 DESCRIPTION
221 	Read all data from @var{section} in BFD @var{abfd}, decompress
222 	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
223 	return @var{*ptr} with memory malloc'd by this function.
224 
225 	Return @code{TRUE} if the full section contents is retrieved
226 	successfully.  If the section has no contents then this function
227 	returns @code{TRUE} but @var{*ptr} is set to NULL.
228 */
229 
230 bool
bfd_get_full_section_contents(bfd * abfd,sec_ptr sec,bfd_byte ** ptr)231 bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
232 {
233   bfd_size_type sz;
234   bfd_byte *p = *ptr;
235   bool ret;
236   bfd_size_type save_size;
237   bfd_size_type save_rawsize;
238   bfd_byte *compressed_buffer;
239   unsigned int compression_header_size;
240 
241   if (abfd->direction != write_direction && sec->rawsize != 0)
242     sz = sec->rawsize;
243   else
244     sz = sec->size;
245   if (sz == 0)
246     {
247       *ptr = NULL;
248       return true;
249     }
250 
251   switch (sec->compress_status)
252     {
253     case COMPRESS_SECTION_NONE:
254       if (p == NULL)
255 	{
256 	  ufile_ptr filesize = bfd_get_file_size (abfd);
257 	  if (filesize > 0
258 	      && filesize < sz
259 	      /* PR 24753: Linker created sections can be larger than
260 		 the file size, eg if they are being used to hold stubs.  */
261 	      && (bfd_section_flags (sec) & SEC_LINKER_CREATED) == 0
262 	      /* PR 24753: Sections which have no content should also be
263 		 excluded as they contain no size on disk.  */
264 	      && (bfd_section_flags (sec) & SEC_HAS_CONTENTS) != 0
265 	      /* The MMO file format supports its own special compression
266 		 technique, but it uses COMPRESS_SECTION_NONE when loading
267 		 a section's contents.  */
268 	      && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
269 	    {
270 	      /* PR 24708: Avoid attempts to allocate a ridiculous amount
271 		 of memory.  */
272 	      bfd_set_error (bfd_error_file_truncated);
273 	      _bfd_error_handler
274 		/* xgettext:c-format */
275 		(_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"),
276 		 abfd, sec, (uint64_t) sz, (uint64_t) filesize);
277 	      return false;
278 	    }
279 	  p = (bfd_byte *) bfd_malloc (sz);
280 	  if (p == NULL)
281 	    {
282 	      /* PR 20801: Provide a more helpful error message.  */
283 	      if (bfd_get_error () == bfd_error_no_memory)
284 		_bfd_error_handler
285 		  /* xgettext:c-format */
286 		  (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
287 		  abfd, sec, (uint64_t) sz);
288 	      return false;
289 	    }
290 	}
291 
292       if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
293 	{
294 	  if (*ptr != p)
295 	    free (p);
296 	  return false;
297 	}
298       *ptr = p;
299       return true;
300 
301     case DECOMPRESS_SECTION_SIZED:
302       /* Read in the full compressed section contents.  */
303       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
304       if (compressed_buffer == NULL)
305 	return false;
306       save_rawsize = sec->rawsize;
307       save_size = sec->size;
308       /* Clear rawsize, set size to compressed size and set compress_status
309 	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
310 	 the uncompressed size, bfd_get_section_contents will fail.  */
311       sec->rawsize = 0;
312       sec->size = sec->compressed_size;
313       sec->compress_status = COMPRESS_SECTION_NONE;
314       ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
315 				      0, sec->compressed_size);
316       /* Restore rawsize and size.  */
317       sec->rawsize = save_rawsize;
318       sec->size = save_size;
319       sec->compress_status = DECOMPRESS_SECTION_SIZED;
320       if (!ret)
321 	goto fail_compressed;
322 
323       if (p == NULL)
324 	p = (bfd_byte *) bfd_malloc (sz);
325       if (p == NULL)
326 	goto fail_compressed;
327 
328       compression_header_size = bfd_get_compression_header_size (abfd, sec);
329       if (compression_header_size == 0)
330 	/* Set header size to the zlib header size if it is a
331 	   SHF_COMPRESSED section.  */
332 	compression_header_size = 12;
333       if (!decompress_contents (compressed_buffer + compression_header_size,
334 				sec->compressed_size - compression_header_size, p, sz))
335 	{
336 	  bfd_set_error (bfd_error_bad_value);
337 	  if (p != *ptr)
338 	    free (p);
339 	fail_compressed:
340 	  free (compressed_buffer);
341 	  return false;
342 	}
343 
344       free (compressed_buffer);
345       *ptr = p;
346       return true;
347 
348     case COMPRESS_SECTION_DONE:
349       if (sec->contents == NULL)
350 	return false;
351       if (p == NULL)
352 	{
353 	  p = (bfd_byte *) bfd_malloc (sz);
354 	  if (p == NULL)
355 	    return false;
356 	  *ptr = p;
357 	}
358       /* PR 17512; file: 5bc29788.  */
359       if (p != sec->contents)
360 	memcpy (p, sec->contents, sz);
361       return true;
362 
363     default:
364       abort ();
365     }
366 }
367 
368 /*
369 FUNCTION
370 	bfd_cache_section_contents
371 
372 SYNOPSIS
373 	void bfd_cache_section_contents
374 	  (asection *sec, void *contents);
375 
376 DESCRIPTION
377 	Stash @var(contents) so any following reads of @var(sec) do
378 	not need to decompress again.
379 */
380 
381 void
bfd_cache_section_contents(asection * sec,void * contents)382 bfd_cache_section_contents (asection *sec, void *contents)
383 {
384   if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
385     sec->compress_status = COMPRESS_SECTION_DONE;
386   sec->contents = contents;
387   sec->flags |= SEC_IN_MEMORY;
388 }
389 
390 /*
391 FUNCTION
392 	bfd_is_section_compressed_with_header
393 
394 SYNOPSIS
395 	bool bfd_is_section_compressed_with_header
396 	  (bfd *abfd, asection *section,
397 	  int *compression_header_size_p,
398 	  bfd_size_type *uncompressed_size_p,
399 	  unsigned int *uncompressed_alignment_power_p);
400 
401 DESCRIPTION
402 	Return @code{TRUE} if @var{section} is compressed.  Compression
403 	header size is returned in @var{compression_header_size_p},
404 	uncompressed size is returned in @var{uncompressed_size_p}
405 	and the uncompressed data alignement power is returned in
406 	@var{uncompressed_align_pow_p}.  If compression is
407 	unsupported, compression header size is returned with -1
408 	and uncompressed size is returned with 0.
409 */
410 
411 bool
bfd_is_section_compressed_with_header(bfd * abfd,sec_ptr sec,int * compression_header_size_p,bfd_size_type * uncompressed_size_p,unsigned int * uncompressed_align_pow_p)412 bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
413 				       int *compression_header_size_p,
414 				       bfd_size_type *uncompressed_size_p,
415 				       unsigned int *uncompressed_align_pow_p)
416 {
417   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
418   int compression_header_size;
419   int header_size;
420   unsigned int saved = sec->compress_status;
421   bool compressed;
422 
423   *uncompressed_align_pow_p = 0;
424 
425   compression_header_size = bfd_get_compression_header_size (abfd, sec);
426   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
427     abort ();
428   header_size = compression_header_size ? compression_header_size : 12;
429 
430   /* Don't decompress the section.  */
431   sec->compress_status = COMPRESS_SECTION_NONE;
432 
433   /* Read the header.  */
434   if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
435     {
436       if (compression_header_size == 0)
437 	/* In this case, it should be "ZLIB" followed by the uncompressed
438 	   section size, 8 bytes in big-endian order.  */
439 	compressed = startswith ((char*) header , "ZLIB");
440       else
441 	compressed = true;
442     }
443   else
444     compressed = false;
445 
446   *uncompressed_size_p = sec->size;
447   if (compressed)
448     {
449       if (compression_header_size != 0)
450 	{
451 	  if (!bfd_check_compression_header (abfd, header, sec,
452 					     uncompressed_size_p,
453 					     uncompressed_align_pow_p))
454 	    compression_header_size = -1;
455 	}
456       /* Check for the pathalogical case of a debug string section that
457 	 contains the string ZLIB.... as the first entry.  We assume that
458 	 no uncompressed .debug_str section would ever be big enough to
459 	 have the first byte of its (big-endian) size be non-zero.  */
460       else if (strcmp (sec->name, ".debug_str") == 0
461 	       && ISPRINT (header[4]))
462 	compressed = false;
463       else
464 	*uncompressed_size_p = bfd_getb64 (header + 4);
465     }
466 
467   /* Restore compress_status.  */
468   sec->compress_status = saved;
469   *compression_header_size_p = compression_header_size;
470   return compressed;
471 }
472 
473 /*
474 FUNCTION
475 	bfd_is_section_compressed
476 
477 SYNOPSIS
478 	bool bfd_is_section_compressed
479 	  (bfd *abfd, asection *section);
480 
481 DESCRIPTION
482 	Return @code{TRUE} if @var{section} is compressed.
483 */
484 
485 bool
bfd_is_section_compressed(bfd * abfd,sec_ptr sec)486 bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
487 {
488   int compression_header_size;
489   bfd_size_type uncompressed_size;
490   unsigned int uncompressed_align_power;
491   return (bfd_is_section_compressed_with_header (abfd, sec,
492 						 &compression_header_size,
493 						 &uncompressed_size,
494 						 &uncompressed_align_power)
495 	  && compression_header_size >= 0
496 	  && uncompressed_size > 0);
497 }
498 
499 /*
500 FUNCTION
501 	bfd_init_section_decompress_status
502 
503 SYNOPSIS
504 	bool bfd_init_section_decompress_status
505 	  (bfd *abfd, asection *section);
506 
507 DESCRIPTION
508 	Record compressed section size, update section size with
509 	decompressed size and set compress_status to
510 	DECOMPRESS_SECTION_SIZED.
511 
512 	Return @code{FALSE} if the section is not a valid compressed
513 	section.  Otherwise, return @code{TRUE}.
514 */
515 
516 bool
bfd_init_section_decompress_status(bfd * abfd,sec_ptr sec)517 bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
518 {
519   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
520   int compression_header_size;
521   int header_size;
522   bfd_size_type uncompressed_size;
523   unsigned int uncompressed_alignment_power = 0;
524   z_stream strm;
525 
526   compression_header_size = bfd_get_compression_header_size (abfd, sec);
527   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
528     abort ();
529   header_size = compression_header_size ? compression_header_size : 12;
530 
531   /* Read the header.  */
532   if (sec->rawsize != 0
533       || sec->contents != NULL
534       || sec->compress_status != COMPRESS_SECTION_NONE
535       || !bfd_get_section_contents (abfd, sec, header, 0, header_size))
536     {
537       bfd_set_error (bfd_error_invalid_operation);
538       return false;
539     }
540 
541   if (compression_header_size == 0)
542     {
543       /* In this case, it should be "ZLIB" followed by the uncompressed
544 	 section size, 8 bytes in big-endian order.  */
545       if (! startswith ((char*) header, "ZLIB"))
546 	{
547 	  bfd_set_error (bfd_error_wrong_format);
548 	  return false;
549 	}
550       uncompressed_size = bfd_getb64 (header + 4);
551     }
552   else if (!bfd_check_compression_header (abfd, header, sec,
553 					  &uncompressed_size,
554 					  &uncompressed_alignment_power))
555     {
556       bfd_set_error (bfd_error_wrong_format);
557       return false;
558     }
559 
560   /* PR28530, reject sizes unsupported by decompress_contents.  */
561   strm.avail_in = sec->size;
562   strm.avail_out = uncompressed_size;
563   if (strm.avail_in != sec->size || strm.avail_out != uncompressed_size)
564     {
565       bfd_set_error (bfd_error_nonrepresentable_section);
566       return false;
567     }
568 
569   sec->compressed_size = sec->size;
570   sec->size = uncompressed_size;
571   bfd_set_section_alignment (sec, uncompressed_alignment_power);
572   sec->compress_status = DECOMPRESS_SECTION_SIZED;
573 
574   return true;
575 }
576 
577 /*
578 FUNCTION
579 	bfd_init_section_compress_status
580 
581 SYNOPSIS
582 	bool bfd_init_section_compress_status
583 	  (bfd *abfd, asection *section);
584 
585 DESCRIPTION
586 	If open for read, compress section, update section size with
587 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
588 
589 	Return @code{FALSE} if the section is not a valid compressed
590 	section.  Otherwise, return @code{TRUE}.
591 */
592 
593 bool
bfd_init_section_compress_status(bfd * abfd,sec_ptr sec)594 bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
595 {
596   bfd_size_type uncompressed_size;
597   bfd_byte *uncompressed_buffer;
598 
599   /* Error if not opened for read.  */
600   if (abfd->direction != read_direction
601       || sec->size == 0
602       || sec->rawsize != 0
603       || sec->contents != NULL
604       || sec->compress_status != COMPRESS_SECTION_NONE)
605     {
606       bfd_set_error (bfd_error_invalid_operation);
607       return false;
608     }
609 
610   /* Read in the full section contents and compress it.  */
611   uncompressed_size = sec->size;
612   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
613   /* PR 21431 */
614   if (uncompressed_buffer == NULL)
615     return false;
616 
617   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
618 				 0, uncompressed_size))
619     return false;
620 
621   uncompressed_size = bfd_compress_section_contents (abfd, sec,
622 						     uncompressed_buffer,
623 						     uncompressed_size);
624   return uncompressed_size != 0;
625 }
626 
627 /*
628 FUNCTION
629 	bfd_compress_section
630 
631 SYNOPSIS
632 	bool bfd_compress_section
633 	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
634 
635 DESCRIPTION
636 	If open for write, compress section, update section size with
637 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
638 
639 	Return @code{FALSE} if compression fail.  Otherwise, return
640 	@code{TRUE}.
641 */
642 
643 bool
bfd_compress_section(bfd * abfd,sec_ptr sec,bfd_byte * uncompressed_buffer)644 bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
645 {
646   bfd_size_type uncompressed_size = sec->size;
647 
648   /* Error if not opened for write.  */
649   if (abfd->direction != write_direction
650       || uncompressed_size == 0
651       || uncompressed_buffer == NULL
652       || sec->contents != NULL
653       || sec->compressed_size != 0
654       || sec->compress_status != COMPRESS_SECTION_NONE)
655     {
656       bfd_set_error (bfd_error_invalid_operation);
657       return false;
658     }
659 
660   /* Compress it.  */
661   return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
662 					uncompressed_size) != 0;
663 }
664