xref: /netbsd/external/gpl3/gdb/dist/bfd/compress.c (revision 1424dfb3)
1377e23a2Schristos /* Compressed section support (intended for debug sections).
2*1424dfb3Schristos    Copyright (C) 2008-2020 Free Software Foundation, Inc.
3377e23a2Schristos 
4377e23a2Schristos    This file is part of BFD, the Binary File Descriptor library.
5377e23a2Schristos 
6377e23a2Schristos    This program is free software; you can redistribute it and/or modify
7377e23a2Schristos    it under the terms of the GNU General Public License as published by
8377e23a2Schristos    the Free Software Foundation; either version 3 of the License, or
9377e23a2Schristos    (at your option) any later version.
10377e23a2Schristos 
11377e23a2Schristos    This program is distributed in the hope that it will be useful,
12377e23a2Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13377e23a2Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14377e23a2Schristos    GNU General Public License for more details.
15377e23a2Schristos 
16377e23a2Schristos    You should have received a copy of the GNU General Public License
17377e23a2Schristos    along with this program; if not, write to the Free Software
18377e23a2Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19377e23a2Schristos    MA 02110-1301, USA.  */
20377e23a2Schristos 
21377e23a2Schristos #include "sysdep.h"
22ed6a76a9Schristos #include <zlib.h>
23377e23a2Schristos #include "bfd.h"
24377e23a2Schristos #include "libbfd.h"
255e098073Schristos #include "safe-ctype.h"
26377e23a2Schristos 
27ed6a76a9Schristos #define MAX_COMPRESSION_HEADER_SIZE 24
28ed6a76a9Schristos 
29377e23a2Schristos static bfd_boolean
decompress_contents(bfd_byte * compressed_buffer,bfd_size_type compressed_size,bfd_byte * uncompressed_buffer,bfd_size_type uncompressed_size)30377e23a2Schristos decompress_contents (bfd_byte *compressed_buffer,
31377e23a2Schristos 		     bfd_size_type compressed_size,
32377e23a2Schristos 		     bfd_byte *uncompressed_buffer,
33377e23a2Schristos 		     bfd_size_type uncompressed_size)
34377e23a2Schristos {
35377e23a2Schristos   z_stream strm;
36377e23a2Schristos   int rc;
37377e23a2Schristos 
38377e23a2Schristos   /* It is possible the section consists of several compressed
39377e23a2Schristos      buffers concatenated together, so we uncompress in a loop.  */
40ed6a76a9Schristos   /* PR 18313: The state field in the z_stream structure is supposed
41ed6a76a9Schristos      to be invisible to the user (ie us), but some compilers will
42ed6a76a9Schristos      still complain about it being used without initialisation.  So
43ed6a76a9Schristos      we first zero the entire z_stream structure and then set the fields
44ed6a76a9Schristos      that we need.  */
45ed6a76a9Schristos   memset (& strm, 0, sizeof strm);
46ed6a76a9Schristos   strm.avail_in = compressed_size;
47ed6a76a9Schristos   strm.next_in = (Bytef*) compressed_buffer;
48377e23a2Schristos   strm.avail_out = uncompressed_size;
49377e23a2Schristos 
507af5a897Schristos   BFD_ASSERT (Z_OK == 0);
51377e23a2Schristos   rc = inflateInit (&strm);
5248596154Schristos   while (strm.avail_in > 0 && strm.avail_out > 0)
53377e23a2Schristos     {
54377e23a2Schristos       if (rc != Z_OK)
557af5a897Schristos 	break;
56377e23a2Schristos       strm.next_out = ((Bytef*) uncompressed_buffer
57377e23a2Schristos 		       + (uncompressed_size - strm.avail_out));
58377e23a2Schristos       rc = inflate (&strm, Z_FINISH);
59377e23a2Schristos       if (rc != Z_STREAM_END)
607af5a897Schristos 	break;
61377e23a2Schristos       rc = inflateReset (&strm);
62377e23a2Schristos     }
637af5a897Schristos   rc |= inflateEnd (&strm);
64377e23a2Schristos   return rc == Z_OK && strm.avail_out == 0;
65377e23a2Schristos }
66377e23a2Schristos 
67ed6a76a9Schristos /* Compress data of the size specified in @var{uncompressed_size}
68377e23a2Schristos    and pointed to by @var{uncompressed_buffer} using zlib and store
69377e23a2Schristos    as the contents field.  This function assumes the contents
70ed6a76a9Schristos    field was allocated using bfd_malloc() or equivalent.
71377e23a2Schristos 
72ed6a76a9Schristos    Return the uncompressed size if the full section contents is
73ed6a76a9Schristos    compressed successfully.  Otherwise return 0.  */
74377e23a2Schristos 
75ed6a76a9Schristos static bfd_size_type
bfd_compress_section_contents(bfd * abfd,sec_ptr sec,bfd_byte * uncompressed_buffer,bfd_size_type uncompressed_size)76ed6a76a9Schristos bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
77ed6a76a9Schristos 			       bfd_byte *uncompressed_buffer,
78ed6a76a9Schristos 			       bfd_size_type uncompressed_size)
79377e23a2Schristos {
80377e23a2Schristos   uLong compressed_size;
81ed6a76a9Schristos   bfd_byte *buffer;
82ed6a76a9Schristos   bfd_size_type buffer_size;
83ed6a76a9Schristos   bfd_boolean decompress;
84ed6a76a9Schristos   int zlib_size = 0;
85ed6a76a9Schristos   int orig_compression_header_size;
86ed6a76a9Schristos   bfd_size_type orig_uncompressed_size;
8707163879Schristos   unsigned int orig_uncompressed_alignment_pow;
88ed6a76a9Schristos   int header_size = bfd_get_compression_header_size (abfd, NULL);
89ed6a76a9Schristos   bfd_boolean compressed
90ed6a76a9Schristos     = bfd_is_section_compressed_with_header (abfd, sec,
91ed6a76a9Schristos 					     &orig_compression_header_size,
9207163879Schristos 					     &orig_uncompressed_size,
9307163879Schristos 					     &orig_uncompressed_alignment_pow);
94377e23a2Schristos 
95ed6a76a9Schristos   /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
96ed6a76a9Schristos      overhead in .zdebug* section.  */
97ed6a76a9Schristos   if (!header_size)
98ed6a76a9Schristos      header_size = 12;
99377e23a2Schristos 
100ed6a76a9Schristos   if (compressed)
101ed6a76a9Schristos     {
102ed6a76a9Schristos       /* We shouldn't decompress unsupported compressed section.  */
103ed6a76a9Schristos       if (orig_compression_header_size < 0)
104ed6a76a9Schristos 	abort ();
105377e23a2Schristos 
106ed6a76a9Schristos       /* Different compression schemes.  Just move the compressed section
107ed6a76a9Schristos 	 contents to the right position. */
108ed6a76a9Schristos       if (orig_compression_header_size == 0)
109ed6a76a9Schristos 	{
110ed6a76a9Schristos 	  /* Convert it from .zdebug* section.  Get the uncompressed
11107163879Schristos 	     size first.  We need to subtract the 12-byte overhead in
112ed6a76a9Schristos 	     .zdebug* section.  Set orig_compression_header_size to
113ed6a76a9Schristos 	     the 12-bye overhead.  */
114ed6a76a9Schristos 	  orig_compression_header_size = 12;
115ed6a76a9Schristos 	  zlib_size = uncompressed_size - 12;
116ed6a76a9Schristos 	}
117ed6a76a9Schristos       else
118ed6a76a9Schristos 	{
119ed6a76a9Schristos 	  /* Convert it to .zdebug* section.  */
120ed6a76a9Schristos 	  zlib_size = uncompressed_size - orig_compression_header_size;
121ed6a76a9Schristos 	}
122ed6a76a9Schristos 
123ed6a76a9Schristos       /* Add the header size.  */
124ed6a76a9Schristos       compressed_size = zlib_size + header_size;
125ed6a76a9Schristos     }
126ed6a76a9Schristos   else
127ed6a76a9Schristos     compressed_size = compressBound (uncompressed_size) + header_size;
128ed6a76a9Schristos 
129ed6a76a9Schristos   /* Uncompress if it leads to smaller size.  */
130ed6a76a9Schristos   if (compressed && compressed_size > orig_uncompressed_size)
131ed6a76a9Schristos     {
132ed6a76a9Schristos       decompress = TRUE;
133ed6a76a9Schristos       buffer_size = orig_uncompressed_size;
134ed6a76a9Schristos     }
135ed6a76a9Schristos   else
136ed6a76a9Schristos     {
137ed6a76a9Schristos       decompress = FALSE;
138ed6a76a9Schristos       buffer_size = compressed_size;
139ed6a76a9Schristos     }
140ed6a76a9Schristos   buffer = (bfd_byte *) bfd_alloc (abfd, buffer_size);
141ed6a76a9Schristos   if (buffer == NULL)
142ed6a76a9Schristos     return 0;
143ed6a76a9Schristos 
144ed6a76a9Schristos   if (compressed)
145ed6a76a9Schristos     {
146ed6a76a9Schristos       sec->size = orig_uncompressed_size;
147ed6a76a9Schristos       if (decompress)
148ed6a76a9Schristos 	{
149ed6a76a9Schristos 	  if (!decompress_contents (uncompressed_buffer
150ed6a76a9Schristos 				    + orig_compression_header_size,
151ed6a76a9Schristos 				    zlib_size, buffer, buffer_size))
152ed6a76a9Schristos 	    {
153ed6a76a9Schristos 	      bfd_set_error (bfd_error_bad_value);
154ed6a76a9Schristos 	      bfd_release (abfd, buffer);
155ed6a76a9Schristos 	      return 0;
156ed6a76a9Schristos 	    }
157ed6a76a9Schristos 	  free (uncompressed_buffer);
158*1424dfb3Schristos 	  bfd_set_section_alignment (sec, orig_uncompressed_alignment_pow);
15907163879Schristos 
160ed6a76a9Schristos 	  sec->contents = buffer;
161ed6a76a9Schristos 	  sec->compress_status = COMPRESS_SECTION_DONE;
162ed6a76a9Schristos 	  return orig_uncompressed_size;
163ed6a76a9Schristos 	}
164ed6a76a9Schristos       else
165ed6a76a9Schristos 	{
166ed6a76a9Schristos 	  bfd_update_compression_header (abfd, buffer, sec);
167ed6a76a9Schristos 	  memmove (buffer + header_size,
168ed6a76a9Schristos 		   uncompressed_buffer + orig_compression_header_size,
169ed6a76a9Schristos 		   zlib_size);
170ed6a76a9Schristos 	}
171ed6a76a9Schristos     }
172ed6a76a9Schristos   else
173ed6a76a9Schristos     {
174ed6a76a9Schristos       if (compress ((Bytef*) buffer + header_size,
175377e23a2Schristos 		    &compressed_size,
176377e23a2Schristos 		    (const Bytef*) uncompressed_buffer,
177377e23a2Schristos 		    uncompressed_size) != Z_OK)
178377e23a2Schristos 	{
179ed6a76a9Schristos 	  bfd_release (abfd, buffer);
180377e23a2Schristos 	  bfd_set_error (bfd_error_bad_value);
181ed6a76a9Schristos 	  return 0;
182377e23a2Schristos 	}
183377e23a2Schristos 
184ed6a76a9Schristos       compressed_size += header_size;
185ed6a76a9Schristos       /* PR binutils/18087: If compression didn't make the section smaller,
186ed6a76a9Schristos 	 just keep it uncompressed.  */
187ed6a76a9Schristos       if (compressed_size < uncompressed_size)
188ed6a76a9Schristos 	bfd_update_compression_header (abfd, buffer, sec);
189ed6a76a9Schristos       else
190ed6a76a9Schristos 	{
191ed6a76a9Schristos 	  /* NOTE: There is a small memory leak here since
192ed6a76a9Schristos 	     uncompressed_buffer is malloced and won't be freed.  */
193ed6a76a9Schristos 	  bfd_release (abfd, buffer);
194ed6a76a9Schristos 	  sec->contents = uncompressed_buffer;
195ed6a76a9Schristos 	  sec->compress_status = COMPRESS_SECTION_NONE;
196ed6a76a9Schristos 	  return uncompressed_size;
197ed6a76a9Schristos 	}
198ed6a76a9Schristos     }
199377e23a2Schristos 
200377e23a2Schristos   free (uncompressed_buffer);
201ed6a76a9Schristos   sec->contents = buffer;
202377e23a2Schristos   sec->size = compressed_size;
203377e23a2Schristos   sec->compress_status = COMPRESS_SECTION_DONE;
204377e23a2Schristos 
205ed6a76a9Schristos   return uncompressed_size;
206377e23a2Schristos }
207377e23a2Schristos 
208377e23a2Schristos /*
209377e23a2Schristos FUNCTION
210377e23a2Schristos 	bfd_get_full_section_contents
211377e23a2Schristos 
212377e23a2Schristos SYNOPSIS
213377e23a2Schristos 	bfd_boolean bfd_get_full_section_contents
214377e23a2Schristos 	  (bfd *abfd, asection *section, bfd_byte **ptr);
215377e23a2Schristos 
216377e23a2Schristos DESCRIPTION
217377e23a2Schristos 	Read all data from @var{section} in BFD @var{abfd}, decompress
218377e23a2Schristos 	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
219377e23a2Schristos 	return @var{*ptr} with memory malloc'd by this function.
220377e23a2Schristos 
221377e23a2Schristos 	Return @code{TRUE} if the full section contents is retrieved
2225e098073Schristos 	successfully.  If the section has no contents then this function
2235e098073Schristos 	returns @code{TRUE} but @var{*ptr} is set to NULL.
224377e23a2Schristos */
225377e23a2Schristos 
226377e23a2Schristos bfd_boolean
bfd_get_full_section_contents(bfd * abfd,sec_ptr sec,bfd_byte ** ptr)227377e23a2Schristos bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
228377e23a2Schristos {
22948596154Schristos   bfd_size_type sz;
230377e23a2Schristos   bfd_byte *p = *ptr;
231377e23a2Schristos   bfd_boolean ret;
23248596154Schristos   bfd_size_type save_size;
23348596154Schristos   bfd_size_type save_rawsize;
234377e23a2Schristos   bfd_byte *compressed_buffer;
235ed6a76a9Schristos   unsigned int compression_header_size;
236377e23a2Schristos 
23748596154Schristos   if (abfd->direction != write_direction && sec->rawsize != 0)
23848596154Schristos     sz = sec->rawsize;
23948596154Schristos   else
24048596154Schristos     sz = sec->size;
241377e23a2Schristos   if (sz == 0)
2425e098073Schristos     {
2435e098073Schristos       *ptr = NULL;
244377e23a2Schristos       return TRUE;
2455e098073Schristos     }
246377e23a2Schristos 
247377e23a2Schristos   switch (sec->compress_status)
248377e23a2Schristos     {
249377e23a2Schristos     case COMPRESS_SECTION_NONE:
250377e23a2Schristos       if (p == NULL)
251377e23a2Schristos 	{
252*1424dfb3Schristos 	  ufile_ptr filesize = bfd_get_file_size (abfd);
253*1424dfb3Schristos 	  if (filesize > 0
254*1424dfb3Schristos 	      && filesize < sz
255*1424dfb3Schristos 	      /* PR 24753: Linker created sections can be larger than
256*1424dfb3Schristos 		 the file size, eg if they are being used to hold stubs.  */
257*1424dfb3Schristos 	      && (bfd_section_flags (sec) & SEC_LINKER_CREATED) == 0
258*1424dfb3Schristos 	      /* PR 24753: Sections which have no content should also be
259*1424dfb3Schristos 		 excluded as they contain no size on disk.  */
260*1424dfb3Schristos 	      && (bfd_section_flags (sec) & SEC_HAS_CONTENTS) != 0
261*1424dfb3Schristos 	      /* The MMO file format supports its own special compression
262*1424dfb3Schristos 		 technique, but it uses COMPRESS_SECTION_NONE when loading
263*1424dfb3Schristos 		 a section's contents.  */
264*1424dfb3Schristos 	      && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
265*1424dfb3Schristos 	    {
266*1424dfb3Schristos 	      /* PR 24708: Avoid attempts to allocate a ridiculous amount
267*1424dfb3Schristos 		 of memory.  */
268*1424dfb3Schristos 	      bfd_set_error (bfd_error_no_memory);
269*1424dfb3Schristos 	      _bfd_error_handler
270*1424dfb3Schristos 		/* xgettext:c-format */
271*1424dfb3Schristos 		(_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"),
272*1424dfb3Schristos 		 abfd, sec, (uint64_t) sz, (uint64_t) filesize);
273*1424dfb3Schristos 	      return FALSE;
274*1424dfb3Schristos 	    }
275377e23a2Schristos 	  p = (bfd_byte *) bfd_malloc (sz);
276377e23a2Schristos 	  if (p == NULL)
2771c468f90Schristos 	    {
2781c468f90Schristos 	      /* PR 20801: Provide a more helpful error message.  */
2791c468f90Schristos 	      if (bfd_get_error () == bfd_error_no_memory)
2801c468f90Schristos 		_bfd_error_handler
2811c468f90Schristos 		  /* xgettext:c-format */
28207163879Schristos 		  (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
28307163879Schristos 		  abfd, sec, (uint64_t) sz);
284377e23a2Schristos 	      return FALSE;
285377e23a2Schristos 	    }
2861c468f90Schristos 	}
2875e098073Schristos 
288377e23a2Schristos       if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
289377e23a2Schristos 	{
290377e23a2Schristos 	  if (*ptr != p)
291377e23a2Schristos 	    free (p);
292377e23a2Schristos 	  return FALSE;
293377e23a2Schristos 	}
294377e23a2Schristos       *ptr = p;
295377e23a2Schristos       return TRUE;
296377e23a2Schristos 
297377e23a2Schristos     case DECOMPRESS_SECTION_SIZED:
298377e23a2Schristos       /* Read in the full compressed section contents.  */
29948596154Schristos       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
300377e23a2Schristos       if (compressed_buffer == NULL)
301377e23a2Schristos 	return FALSE;
30248596154Schristos       save_rawsize = sec->rawsize;
30348596154Schristos       save_size = sec->size;
304377e23a2Schristos       /* Clear rawsize, set size to compressed size and set compress_status
305377e23a2Schristos 	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
306377e23a2Schristos 	 the uncompressed size, bfd_get_section_contents will fail.  */
307377e23a2Schristos       sec->rawsize = 0;
30848596154Schristos       sec->size = sec->compressed_size;
309377e23a2Schristos       sec->compress_status = COMPRESS_SECTION_NONE;
310377e23a2Schristos       ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
31148596154Schristos 				      0, sec->compressed_size);
312377e23a2Schristos       /* Restore rawsize and size.  */
31348596154Schristos       sec->rawsize = save_rawsize;
31448596154Schristos       sec->size = save_size;
315377e23a2Schristos       sec->compress_status = DECOMPRESS_SECTION_SIZED;
316377e23a2Schristos       if (!ret)
317377e23a2Schristos 	goto fail_compressed;
318377e23a2Schristos 
31948596154Schristos       if (p == NULL)
32048596154Schristos 	p = (bfd_byte *) bfd_malloc (sz);
32148596154Schristos       if (p == NULL)
322377e23a2Schristos 	goto fail_compressed;
323377e23a2Schristos 
324ed6a76a9Schristos       compression_header_size = bfd_get_compression_header_size (abfd, sec);
325ed6a76a9Schristos       if (compression_header_size == 0)
326ed6a76a9Schristos 	/* Set header size to the zlib header size if it is a
327ed6a76a9Schristos 	   SHF_COMPRESSED section.  */
328ed6a76a9Schristos 	compression_header_size = 12;
329ed6a76a9Schristos       if (!decompress_contents (compressed_buffer + compression_header_size,
3301c468f90Schristos 				sec->compressed_size - compression_header_size, p, sz))
331377e23a2Schristos 	{
332377e23a2Schristos 	  bfd_set_error (bfd_error_bad_value);
33348596154Schristos 	  if (p != *ptr)
33448596154Schristos 	    free (p);
335377e23a2Schristos 	fail_compressed:
336377e23a2Schristos 	  free (compressed_buffer);
337377e23a2Schristos 	  return FALSE;
338377e23a2Schristos 	}
339377e23a2Schristos 
340377e23a2Schristos       free (compressed_buffer);
34148596154Schristos       *ptr = p;
34248596154Schristos       return TRUE;
343377e23a2Schristos 
344377e23a2Schristos     case COMPRESS_SECTION_DONE:
3455e098073Schristos       if (sec->contents == NULL)
3465e098073Schristos 	return FALSE;
347377e23a2Schristos       if (p == NULL)
348377e23a2Schristos 	{
349377e23a2Schristos 	  p = (bfd_byte *) bfd_malloc (sz);
350377e23a2Schristos 	  if (p == NULL)
351377e23a2Schristos 	    return FALSE;
352377e23a2Schristos 	  *ptr = p;
353377e23a2Schristos 	}
3545e098073Schristos       /* PR 17512; file: 5bc29788.  */
3555e098073Schristos       if (p != sec->contents)
356377e23a2Schristos 	memcpy (p, sec->contents, sz);
357377e23a2Schristos       return TRUE;
358377e23a2Schristos 
359377e23a2Schristos     default:
360377e23a2Schristos       abort ();
361377e23a2Schristos     }
362377e23a2Schristos }
363377e23a2Schristos 
364377e23a2Schristos /*
365377e23a2Schristos FUNCTION
36648596154Schristos 	bfd_cache_section_contents
36748596154Schristos 
36848596154Schristos SYNOPSIS
36948596154Schristos 	void bfd_cache_section_contents
37048596154Schristos 	  (asection *sec, void *contents);
37148596154Schristos 
37248596154Schristos DESCRIPTION
37348596154Schristos 	Stash @var(contents) so any following reads of @var(sec) do
37448596154Schristos 	not need to decompress again.
37548596154Schristos */
37648596154Schristos 
37748596154Schristos void
bfd_cache_section_contents(asection * sec,void * contents)37848596154Schristos bfd_cache_section_contents (asection *sec, void *contents)
37948596154Schristos {
38048596154Schristos   if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
38148596154Schristos     sec->compress_status = COMPRESS_SECTION_DONE;
38248596154Schristos   sec->contents = contents;
38348596154Schristos   sec->flags |= SEC_IN_MEMORY;
38448596154Schristos }
38548596154Schristos 
386ed6a76a9Schristos /*
387ed6a76a9Schristos FUNCTION
388ed6a76a9Schristos 	bfd_is_section_compressed_with_header
389ed6a76a9Schristos 
390ed6a76a9Schristos SYNOPSIS
391ed6a76a9Schristos 	bfd_boolean bfd_is_section_compressed_with_header
392ed6a76a9Schristos 	  (bfd *abfd, asection *section,
393ed6a76a9Schristos 	  int *compression_header_size_p,
39407163879Schristos 	  bfd_size_type *uncompressed_size_p,
39507163879Schristos 	  unsigned int *uncompressed_alignment_power_p);
396ed6a76a9Schristos 
397ed6a76a9Schristos DESCRIPTION
398ed6a76a9Schristos 	Return @code{TRUE} if @var{section} is compressed.  Compression
39907163879Schristos 	header size is returned in @var{compression_header_size_p},
40007163879Schristos 	uncompressed size is returned in @var{uncompressed_size_p}
40107163879Schristos 	and the uncompressed data alignement power is returned in
40207163879Schristos 	@var{uncompressed_align_pow_p}.  If compression is
40307163879Schristos 	unsupported, compression header size is returned with -1
40407163879Schristos 	and uncompressed size is returned with 0.
405ed6a76a9Schristos */
406ed6a76a9Schristos 
407ed6a76a9Schristos bfd_boolean
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)408ed6a76a9Schristos bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
409ed6a76a9Schristos 				       int *compression_header_size_p,
41007163879Schristos 				       bfd_size_type *uncompressed_size_p,
41107163879Schristos 				       unsigned int *uncompressed_align_pow_p)
412ed6a76a9Schristos {
413ed6a76a9Schristos   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
414ed6a76a9Schristos   int compression_header_size;
415ed6a76a9Schristos   int header_size;
416ed6a76a9Schristos   unsigned int saved = sec->compress_status;
417ed6a76a9Schristos   bfd_boolean compressed;
418ed6a76a9Schristos 
41907163879Schristos   *uncompressed_align_pow_p = 0;
42007163879Schristos 
421ed6a76a9Schristos   compression_header_size = bfd_get_compression_header_size (abfd, sec);
422ed6a76a9Schristos   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
423ed6a76a9Schristos     abort ();
424ed6a76a9Schristos   header_size = compression_header_size ? compression_header_size : 12;
425ed6a76a9Schristos 
426ed6a76a9Schristos   /* Don't decompress the section.  */
427ed6a76a9Schristos   sec->compress_status = COMPRESS_SECTION_NONE;
428ed6a76a9Schristos 
429ed6a76a9Schristos   /* Read the header.  */
430ed6a76a9Schristos   if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
431ed6a76a9Schristos     {
432ed6a76a9Schristos       if (compression_header_size == 0)
433ed6a76a9Schristos 	/* In this case, it should be "ZLIB" followed by the uncompressed
434ed6a76a9Schristos 	   section size, 8 bytes in big-endian order.  */
435ed6a76a9Schristos 	compressed = CONST_STRNEQ ((char*) header , "ZLIB");
436ed6a76a9Schristos       else
437ed6a76a9Schristos 	compressed = TRUE;
438ed6a76a9Schristos     }
439ed6a76a9Schristos   else
440ed6a76a9Schristos     compressed = FALSE;
441ed6a76a9Schristos 
442ed6a76a9Schristos   *uncompressed_size_p = sec->size;
443ed6a76a9Schristos   if (compressed)
444ed6a76a9Schristos     {
445ed6a76a9Schristos       if (compression_header_size != 0)
446ed6a76a9Schristos 	{
447ed6a76a9Schristos 	  if (!bfd_check_compression_header (abfd, header, sec,
44807163879Schristos 					     uncompressed_size_p,
44907163879Schristos 					     uncompressed_align_pow_p))
450ed6a76a9Schristos 	    compression_header_size = -1;
451ed6a76a9Schristos 	}
452ed6a76a9Schristos       /* Check for the pathalogical case of a debug string section that
453ed6a76a9Schristos 	 contains the string ZLIB.... as the first entry.  We assume that
454ed6a76a9Schristos 	 no uncompressed .debug_str section would ever be big enough to
455ed6a76a9Schristos 	 have the first byte of its (big-endian) size be non-zero.  */
456ed6a76a9Schristos       else if (strcmp (sec->name, ".debug_str") == 0
457ed6a76a9Schristos 	       && ISPRINT (header[4]))
458ed6a76a9Schristos 	compressed = FALSE;
459ed6a76a9Schristos       else
460ed6a76a9Schristos 	*uncompressed_size_p = bfd_getb64 (header + 4);
461ed6a76a9Schristos     }
462ed6a76a9Schristos 
463ed6a76a9Schristos   /* Restore compress_status.  */
464ed6a76a9Schristos   sec->compress_status = saved;
465ed6a76a9Schristos   *compression_header_size_p = compression_header_size;
466ed6a76a9Schristos   return compressed;
467ed6a76a9Schristos }
46848596154Schristos 
46948596154Schristos /*
47048596154Schristos FUNCTION
471377e23a2Schristos 	bfd_is_section_compressed
472377e23a2Schristos 
473377e23a2Schristos SYNOPSIS
474377e23a2Schristos 	bfd_boolean bfd_is_section_compressed
475377e23a2Schristos 	  (bfd *abfd, asection *section);
476377e23a2Schristos 
477377e23a2Schristos DESCRIPTION
478377e23a2Schristos 	Return @code{TRUE} if @var{section} is compressed.
479377e23a2Schristos */
480377e23a2Schristos 
481377e23a2Schristos bfd_boolean
bfd_is_section_compressed(bfd * abfd,sec_ptr sec)482377e23a2Schristos bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
483377e23a2Schristos {
484ed6a76a9Schristos   int compression_header_size;
485ed6a76a9Schristos   bfd_size_type uncompressed_size;
48607163879Schristos   unsigned int uncompressed_align_power;
487ed6a76a9Schristos   return (bfd_is_section_compressed_with_header (abfd, sec,
488ed6a76a9Schristos 						 &compression_header_size,
48907163879Schristos 						 &uncompressed_size,
49007163879Schristos 						 &uncompressed_align_power)
491ed6a76a9Schristos 	  && compression_header_size >= 0
492ed6a76a9Schristos 	  && uncompressed_size > 0);
493377e23a2Schristos }
494377e23a2Schristos 
495377e23a2Schristos /*
496377e23a2Schristos FUNCTION
497377e23a2Schristos 	bfd_init_section_decompress_status
498377e23a2Schristos 
499377e23a2Schristos SYNOPSIS
500377e23a2Schristos 	bfd_boolean bfd_init_section_decompress_status
501377e23a2Schristos 	  (bfd *abfd, asection *section);
502377e23a2Schristos 
503377e23a2Schristos DESCRIPTION
504377e23a2Schristos 	Record compressed section size, update section size with
505377e23a2Schristos 	decompressed size and set compress_status to
506377e23a2Schristos 	DECOMPRESS_SECTION_SIZED.
507377e23a2Schristos 
508377e23a2Schristos 	Return @code{FALSE} if the section is not a valid compressed
509ed6a76a9Schristos 	section.  Otherwise, return @code{TRUE}.
510377e23a2Schristos */
511377e23a2Schristos 
512377e23a2Schristos bfd_boolean
bfd_init_section_decompress_status(bfd * abfd,sec_ptr sec)513ed6a76a9Schristos bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
514377e23a2Schristos {
515ed6a76a9Schristos   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
516ed6a76a9Schristos   int compression_header_size;
517ed6a76a9Schristos   int header_size;
518377e23a2Schristos   bfd_size_type uncompressed_size;
51907163879Schristos   unsigned int uncompressed_alignment_power = 0;
520377e23a2Schristos 
521ed6a76a9Schristos   compression_header_size = bfd_get_compression_header_size (abfd, sec);
522ed6a76a9Schristos   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
523ed6a76a9Schristos     abort ();
524ed6a76a9Schristos   header_size = compression_header_size ? compression_header_size : 12;
525ed6a76a9Schristos 
526ed6a76a9Schristos   /* Read the header.  */
527377e23a2Schristos   if (sec->rawsize != 0
528377e23a2Schristos       || sec->contents != NULL
529377e23a2Schristos       || sec->compress_status != COMPRESS_SECTION_NONE
530ed6a76a9Schristos       || !bfd_get_section_contents (abfd, sec, header, 0, header_size))
531377e23a2Schristos     {
532377e23a2Schristos       bfd_set_error (bfd_error_invalid_operation);
533377e23a2Schristos       return FALSE;
534377e23a2Schristos     }
535377e23a2Schristos 
536ed6a76a9Schristos   if (compression_header_size == 0)
537ed6a76a9Schristos     {
538ed6a76a9Schristos       /* In this case, it should be "ZLIB" followed by the uncompressed
539ed6a76a9Schristos 	 section size, 8 bytes in big-endian order.  */
540ed6a76a9Schristos       if (! CONST_STRNEQ ((char*) header, "ZLIB"))
541377e23a2Schristos 	{
542377e23a2Schristos 	  bfd_set_error (bfd_error_wrong_format);
543377e23a2Schristos 	  return FALSE;
544377e23a2Schristos 	}
545ed6a76a9Schristos       uncompressed_size = bfd_getb64 (header + 4);
546ed6a76a9Schristos     }
547ed6a76a9Schristos   else if (!bfd_check_compression_header (abfd, header, sec,
54807163879Schristos 					  &uncompressed_size,
54907163879Schristos 					  &uncompressed_alignment_power))
550ed6a76a9Schristos     {
551ed6a76a9Schristos       bfd_set_error (bfd_error_wrong_format);
552ed6a76a9Schristos       return FALSE;
553ed6a76a9Schristos     }
554377e23a2Schristos 
555377e23a2Schristos   sec->compressed_size = sec->size;
556377e23a2Schristos   sec->size = uncompressed_size;
557*1424dfb3Schristos   bfd_set_section_alignment (sec, uncompressed_alignment_power);
558377e23a2Schristos   sec->compress_status = DECOMPRESS_SECTION_SIZED;
559377e23a2Schristos 
560377e23a2Schristos   return TRUE;
561377e23a2Schristos }
562377e23a2Schristos 
563377e23a2Schristos /*
564377e23a2Schristos FUNCTION
565377e23a2Schristos 	bfd_init_section_compress_status
566377e23a2Schristos 
567377e23a2Schristos SYNOPSIS
568377e23a2Schristos 	bfd_boolean bfd_init_section_compress_status
569377e23a2Schristos 	  (bfd *abfd, asection *section);
570377e23a2Schristos 
571377e23a2Schristos DESCRIPTION
572377e23a2Schristos 	If open for read, compress section, update section size with
573377e23a2Schristos 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
574377e23a2Schristos 
575377e23a2Schristos 	Return @code{FALSE} if the section is not a valid compressed
576ed6a76a9Schristos 	section.  Otherwise, return @code{TRUE}.
577377e23a2Schristos */
578377e23a2Schristos 
579377e23a2Schristos bfd_boolean
bfd_init_section_compress_status(bfd * abfd,sec_ptr sec)580ed6a76a9Schristos bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
581377e23a2Schristos {
582377e23a2Schristos   bfd_size_type uncompressed_size;
583377e23a2Schristos   bfd_byte *uncompressed_buffer;
584377e23a2Schristos 
585377e23a2Schristos   /* Error if not opened for read.  */
586377e23a2Schristos   if (abfd->direction != read_direction
587377e23a2Schristos       || sec->size == 0
588377e23a2Schristos       || sec->rawsize != 0
589377e23a2Schristos       || sec->contents != NULL
590377e23a2Schristos       || sec->compress_status != COMPRESS_SECTION_NONE)
591377e23a2Schristos     {
592377e23a2Schristos       bfd_set_error (bfd_error_invalid_operation);
593377e23a2Schristos       return FALSE;
594377e23a2Schristos     }
595377e23a2Schristos 
596377e23a2Schristos   /* Read in the full section contents and compress it.  */
597377e23a2Schristos   uncompressed_size = sec->size;
598377e23a2Schristos   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
59907163879Schristos   /* PR 21431 */
60007163879Schristos   if (uncompressed_buffer == NULL)
60107163879Schristos     return FALSE;
60207163879Schristos 
603377e23a2Schristos   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
604377e23a2Schristos 				 0, uncompressed_size))
60507163879Schristos     return FALSE;
60607163879Schristos 
607ed6a76a9Schristos   uncompressed_size = bfd_compress_section_contents (abfd, sec,
608377e23a2Schristos 						     uncompressed_buffer,
609377e23a2Schristos 						     uncompressed_size);
61007163879Schristos   return uncompressed_size != 0;
611ed6a76a9Schristos }
612ed6a76a9Schristos 
613ed6a76a9Schristos /*
614ed6a76a9Schristos FUNCTION
615ed6a76a9Schristos 	bfd_compress_section
616ed6a76a9Schristos 
617ed6a76a9Schristos SYNOPSIS
618ed6a76a9Schristos 	bfd_boolean bfd_compress_section
619ed6a76a9Schristos 	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
620ed6a76a9Schristos 
621ed6a76a9Schristos DESCRIPTION
622ed6a76a9Schristos 	If open for write, compress section, update section size with
623ed6a76a9Schristos 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
624ed6a76a9Schristos 
625ed6a76a9Schristos 	Return @code{FALSE} if compression fail.  Otherwise, return
626ed6a76a9Schristos 	@code{TRUE}.
627ed6a76a9Schristos */
628ed6a76a9Schristos 
629ed6a76a9Schristos bfd_boolean
bfd_compress_section(bfd * abfd,sec_ptr sec,bfd_byte * uncompressed_buffer)630ed6a76a9Schristos bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
631ed6a76a9Schristos {
632ed6a76a9Schristos   bfd_size_type uncompressed_size = sec->size;
633ed6a76a9Schristos 
634ed6a76a9Schristos   /* Error if not opened for write.  */
635ed6a76a9Schristos   if (abfd->direction != write_direction
636ed6a76a9Schristos       || uncompressed_size == 0
637ed6a76a9Schristos       || uncompressed_buffer == NULL
638ed6a76a9Schristos       || sec->contents != NULL
639ed6a76a9Schristos       || sec->compressed_size != 0
640ed6a76a9Schristos       || sec->compress_status != COMPRESS_SECTION_NONE)
641ed6a76a9Schristos     {
642ed6a76a9Schristos       bfd_set_error (bfd_error_invalid_operation);
643ed6a76a9Schristos       return FALSE;
644ed6a76a9Schristos     }
645ed6a76a9Schristos 
646ed6a76a9Schristos   /* Compress it.  */
647ed6a76a9Schristos   return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
648ed6a76a9Schristos 					uncompressed_size) != 0;
649377e23a2Schristos }
650