xref: /dflybsd-src/contrib/gdb-7/bfd/compress.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1cf7f2e2dSJohn Marino /* Compressed section support (intended for debug sections).
2*ef5ccd6cSJohn Marino    Copyright 2008, 2010, 2011, 2012
35796c8dcSSimon Schubert    Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of BFD, the Binary File Descriptor library.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program; if not, write to the Free Software
195796c8dcSSimon Schubert    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
205796c8dcSSimon Schubert    MA 02110-1301, USA.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "sysdep.h"
235796c8dcSSimon Schubert #include "bfd.h"
245796c8dcSSimon Schubert #include "libbfd.h"
255796c8dcSSimon Schubert #ifdef HAVE_ZLIB_H
265796c8dcSSimon Schubert #include <zlib.h>
275796c8dcSSimon Schubert #endif
285796c8dcSSimon Schubert 
29c50c785cSJohn Marino #ifdef HAVE_ZLIB_H
30c50c785cSJohn Marino static bfd_boolean
decompress_contents(bfd_byte * compressed_buffer,bfd_size_type compressed_size,bfd_byte * uncompressed_buffer,bfd_size_type uncompressed_size)31c50c785cSJohn Marino decompress_contents (bfd_byte *compressed_buffer,
32c50c785cSJohn Marino 		     bfd_size_type compressed_size,
33c50c785cSJohn Marino 		     bfd_byte *uncompressed_buffer,
34c50c785cSJohn Marino 		     bfd_size_type uncompressed_size)
35c50c785cSJohn Marino {
36c50c785cSJohn Marino   z_stream strm;
37c50c785cSJohn Marino   int rc;
38c50c785cSJohn Marino 
39c50c785cSJohn Marino   /* It is possible the section consists of several compressed
40c50c785cSJohn Marino      buffers concatenated together, so we uncompress in a loop.  */
41c50c785cSJohn Marino   strm.zalloc = NULL;
42c50c785cSJohn Marino   strm.zfree = NULL;
43c50c785cSJohn Marino   strm.opaque = NULL;
44c50c785cSJohn Marino   strm.avail_in = compressed_size - 12;
45c50c785cSJohn Marino   strm.next_in = (Bytef*) compressed_buffer + 12;
46c50c785cSJohn Marino   strm.avail_out = uncompressed_size;
47c50c785cSJohn Marino 
48c50c785cSJohn Marino   rc = inflateInit (&strm);
49*ef5ccd6cSJohn Marino   while (strm.avail_in > 0 && strm.avail_out > 0)
50c50c785cSJohn Marino     {
51c50c785cSJohn Marino       if (rc != Z_OK)
52c50c785cSJohn Marino 	return FALSE;
53c50c785cSJohn Marino       strm.next_out = ((Bytef*) uncompressed_buffer
54c50c785cSJohn Marino                        + (uncompressed_size - strm.avail_out));
55c50c785cSJohn Marino       rc = inflate (&strm, Z_FINISH);
56c50c785cSJohn Marino       if (rc != Z_STREAM_END)
57c50c785cSJohn Marino 	return FALSE;
58c50c785cSJohn Marino       rc = inflateReset (&strm);
59c50c785cSJohn Marino     }
60c50c785cSJohn Marino   rc = inflateEnd (&strm);
61c50c785cSJohn Marino   return rc == Z_OK && strm.avail_out == 0;
62c50c785cSJohn Marino }
63c50c785cSJohn Marino #endif
64c50c785cSJohn Marino 
655796c8dcSSimon Schubert /*
665796c8dcSSimon Schubert FUNCTION
67c50c785cSJohn Marino 	bfd_compress_section_contents
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert SYNOPSIS
70c50c785cSJohn Marino 	bfd_boolean bfd_compress_section_contents
71c50c785cSJohn Marino 	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer,
72c50c785cSJohn Marino 	   bfd_size_type uncompressed_size);
735796c8dcSSimon Schubert 
745796c8dcSSimon Schubert DESCRIPTION
755796c8dcSSimon Schubert 
76c50c785cSJohn Marino 	Compress data of the size specified in @var{uncompressed_size}
77c50c785cSJohn Marino 	and pointed to by @var{uncompressed_buffer} using zlib and store
78c50c785cSJohn Marino 	as the contents field.  This function assumes the contents
79c50c785cSJohn Marino 	field was allocated using bfd_malloc() or equivalent.  If zlib
80c50c785cSJohn Marino 	is not installed on this machine, the input is unmodified.
815796c8dcSSimon Schubert 
82c50c785cSJohn Marino 	Return @code{TRUE} if the full section contents is compressed
83c50c785cSJohn Marino 	successfully.
845796c8dcSSimon Schubert */
855796c8dcSSimon Schubert 
865796c8dcSSimon Schubert bfd_boolean
bfd_compress_section_contents(bfd * abfd ATTRIBUTE_UNUSED,sec_ptr sec ATTRIBUTE_UNUSED,bfd_byte * uncompressed_buffer ATTRIBUTE_UNUSED,bfd_size_type uncompressed_size ATTRIBUTE_UNUSED)87c50c785cSJohn Marino bfd_compress_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
88c50c785cSJohn Marino 			       sec_ptr sec ATTRIBUTE_UNUSED,
89c50c785cSJohn Marino 			       bfd_byte *uncompressed_buffer ATTRIBUTE_UNUSED,
90c50c785cSJohn Marino 			       bfd_size_type uncompressed_size ATTRIBUTE_UNUSED)
915796c8dcSSimon Schubert {
925796c8dcSSimon Schubert #ifndef HAVE_ZLIB_H
93c50c785cSJohn Marino   bfd_set_error (bfd_error_invalid_operation);
945796c8dcSSimon Schubert   return FALSE;
955796c8dcSSimon Schubert #else
96c50c785cSJohn Marino   uLong compressed_size;
97c50c785cSJohn Marino   bfd_byte *compressed_buffer;
98c50c785cSJohn Marino 
99c50c785cSJohn Marino   compressed_size = compressBound (uncompressed_size) + 12;
100c50c785cSJohn Marino   compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);
101c50c785cSJohn Marino 
102c50c785cSJohn Marino   if (compressed_buffer == NULL)
103c50c785cSJohn Marino     return FALSE;
104c50c785cSJohn Marino 
105c50c785cSJohn Marino   if (compress ((Bytef*) compressed_buffer + 12,
106c50c785cSJohn Marino 		&compressed_size,
107c50c785cSJohn Marino 		(const Bytef*) uncompressed_buffer,
108c50c785cSJohn Marino 		uncompressed_size) != Z_OK)
109c50c785cSJohn Marino     {
110c50c785cSJohn Marino       free (compressed_buffer);
111c50c785cSJohn Marino       bfd_set_error (bfd_error_bad_value);
112c50c785cSJohn Marino       return FALSE;
113c50c785cSJohn Marino     }
114c50c785cSJohn Marino 
115c50c785cSJohn Marino   /* Write the zlib header.  In this case, it should be "ZLIB" followed
116c50c785cSJohn Marino      by the uncompressed section size, 8 bytes in big-endian order.  */
117c50c785cSJohn Marino   memcpy (compressed_buffer, "ZLIB", 4);
118c50c785cSJohn Marino   compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8;
119c50c785cSJohn Marino   compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8;
120c50c785cSJohn Marino   compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8;
121c50c785cSJohn Marino   compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8;
122c50c785cSJohn Marino   compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8;
123c50c785cSJohn Marino   compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8;
124c50c785cSJohn Marino   compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8;
125c50c785cSJohn Marino   compressed_buffer[4] = uncompressed_size;
126c50c785cSJohn Marino   compressed_size += 12;
127c50c785cSJohn Marino 
128c50c785cSJohn Marino   /* Free the uncompressed contents if we compress in place.  */
129c50c785cSJohn Marino   if (uncompressed_buffer == sec->contents)
130c50c785cSJohn Marino     free (uncompressed_buffer);
131c50c785cSJohn Marino 
132c50c785cSJohn Marino   sec->contents = compressed_buffer;
133c50c785cSJohn Marino   sec->size = compressed_size;
134c50c785cSJohn Marino   sec->compress_status = COMPRESS_SECTION_DONE;
135c50c785cSJohn Marino 
136c50c785cSJohn Marino   return TRUE;
137c50c785cSJohn Marino #endif  /* HAVE_ZLIB_H */
138c50c785cSJohn Marino }
139c50c785cSJohn Marino 
140c50c785cSJohn Marino /*
141c50c785cSJohn Marino FUNCTION
142c50c785cSJohn Marino 	bfd_get_full_section_contents
143c50c785cSJohn Marino 
144c50c785cSJohn Marino SYNOPSIS
145c50c785cSJohn Marino 	bfd_boolean bfd_get_full_section_contents
146c50c785cSJohn Marino 	  (bfd *abfd, asection *section, bfd_byte **ptr);
147c50c785cSJohn Marino 
148c50c785cSJohn Marino DESCRIPTION
149c50c785cSJohn Marino 	Read all data from @var{section} in BFD @var{abfd}, decompress
150c50c785cSJohn Marino 	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
151c50c785cSJohn Marino 	return @var{*ptr} with memory malloc'd by this function.
152c50c785cSJohn Marino 
153c50c785cSJohn Marino 	Return @code{TRUE} if the full section contents is retrieved
154c50c785cSJohn Marino 	successfully.
155c50c785cSJohn Marino */
156c50c785cSJohn Marino 
157c50c785cSJohn Marino bfd_boolean
bfd_get_full_section_contents(bfd * abfd,sec_ptr sec,bfd_byte ** ptr)158c50c785cSJohn Marino bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
159c50c785cSJohn Marino {
160a45ae5f8SJohn Marino   bfd_size_type sz;
161c50c785cSJohn Marino   bfd_byte *p = *ptr;
162c50c785cSJohn Marino #ifdef HAVE_ZLIB_H
163c50c785cSJohn Marino   bfd_boolean ret;
164*ef5ccd6cSJohn Marino   bfd_size_type save_size;
165*ef5ccd6cSJohn Marino   bfd_size_type save_rawsize;
166c50c785cSJohn Marino   bfd_byte *compressed_buffer;
167c50c785cSJohn Marino #endif
168c50c785cSJohn Marino 
169a45ae5f8SJohn Marino   if (abfd->direction != write_direction && sec->rawsize != 0)
170a45ae5f8SJohn Marino     sz = sec->rawsize;
171a45ae5f8SJohn Marino   else
172a45ae5f8SJohn Marino     sz = sec->size;
173c50c785cSJohn Marino   if (sz == 0)
174c50c785cSJohn Marino     return TRUE;
175c50c785cSJohn Marino 
176c50c785cSJohn Marino   switch (sec->compress_status)
177c50c785cSJohn Marino     {
178c50c785cSJohn Marino     case COMPRESS_SECTION_NONE:
179c50c785cSJohn Marino       if (p == NULL)
180c50c785cSJohn Marino 	{
181c50c785cSJohn Marino 	  p = (bfd_byte *) bfd_malloc (sz);
182c50c785cSJohn Marino 	  if (p == NULL)
183c50c785cSJohn Marino 	    return FALSE;
184c50c785cSJohn Marino 	}
185c50c785cSJohn Marino       if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
186c50c785cSJohn Marino 	{
187c50c785cSJohn Marino 	  if (*ptr != p)
188c50c785cSJohn Marino 	    free (p);
189c50c785cSJohn Marino 	  return FALSE;
190c50c785cSJohn Marino 	}
191c50c785cSJohn Marino       *ptr = p;
192c50c785cSJohn Marino       return TRUE;
193c50c785cSJohn Marino 
194c50c785cSJohn Marino     case DECOMPRESS_SECTION_SIZED:
195c50c785cSJohn Marino #ifndef HAVE_ZLIB_H
196c50c785cSJohn Marino       bfd_set_error (bfd_error_invalid_operation);
197c50c785cSJohn Marino       return FALSE;
198c50c785cSJohn Marino #else
199c50c785cSJohn Marino       /* Read in the full compressed section contents.  */
200*ef5ccd6cSJohn Marino       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
201c50c785cSJohn Marino       if (compressed_buffer == NULL)
202c50c785cSJohn Marino 	return FALSE;
203*ef5ccd6cSJohn Marino       save_rawsize = sec->rawsize;
204*ef5ccd6cSJohn Marino       save_size = sec->size;
205c50c785cSJohn Marino       /* Clear rawsize, set size to compressed size and set compress_status
206c50c785cSJohn Marino 	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
207c50c785cSJohn Marino 	 the uncompressed size, bfd_get_section_contents will fail.  */
208c50c785cSJohn Marino       sec->rawsize = 0;
209*ef5ccd6cSJohn Marino       sec->size = sec->compressed_size;
210c50c785cSJohn Marino       sec->compress_status = COMPRESS_SECTION_NONE;
211c50c785cSJohn Marino       ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
212*ef5ccd6cSJohn Marino 				      0, sec->compressed_size);
213c50c785cSJohn Marino       /* Restore rawsize and size.  */
214*ef5ccd6cSJohn Marino       sec->rawsize = save_rawsize;
215*ef5ccd6cSJohn Marino       sec->size = save_size;
216c50c785cSJohn Marino       sec->compress_status = DECOMPRESS_SECTION_SIZED;
217c50c785cSJohn Marino       if (!ret)
218c50c785cSJohn Marino 	goto fail_compressed;
219c50c785cSJohn Marino 
220*ef5ccd6cSJohn Marino       if (p == NULL)
221*ef5ccd6cSJohn Marino 	p = (bfd_byte *) bfd_malloc (sz);
222*ef5ccd6cSJohn Marino       if (p == NULL)
223c50c785cSJohn Marino 	goto fail_compressed;
224c50c785cSJohn Marino 
225*ef5ccd6cSJohn Marino       if (!decompress_contents (compressed_buffer, sec->compressed_size, p, sz))
226c50c785cSJohn Marino 	{
227c50c785cSJohn Marino 	  bfd_set_error (bfd_error_bad_value);
228*ef5ccd6cSJohn Marino 	  if (p != *ptr)
229*ef5ccd6cSJohn Marino 	    free (p);
230c50c785cSJohn Marino 	fail_compressed:
231c50c785cSJohn Marino 	  free (compressed_buffer);
232c50c785cSJohn Marino 	  return FALSE;
233c50c785cSJohn Marino 	}
234c50c785cSJohn Marino 
235c50c785cSJohn Marino       free (compressed_buffer);
236*ef5ccd6cSJohn Marino       *ptr = p;
237*ef5ccd6cSJohn Marino       return TRUE;
238c50c785cSJohn Marino #endif
239c50c785cSJohn Marino 
240c50c785cSJohn Marino     case COMPRESS_SECTION_DONE:
241c50c785cSJohn Marino       if (p == NULL)
242c50c785cSJohn Marino 	{
243c50c785cSJohn Marino 	  p = (bfd_byte *) bfd_malloc (sz);
244c50c785cSJohn Marino 	  if (p == NULL)
245c50c785cSJohn Marino 	    return FALSE;
246c50c785cSJohn Marino 	  *ptr = p;
247c50c785cSJohn Marino 	}
248c50c785cSJohn Marino       memcpy (p, sec->contents, sz);
249c50c785cSJohn Marino       return TRUE;
250c50c785cSJohn Marino 
251c50c785cSJohn Marino     default:
252c50c785cSJohn Marino       abort ();
253c50c785cSJohn Marino     }
254c50c785cSJohn Marino }
255c50c785cSJohn Marino 
256c50c785cSJohn Marino /*
257c50c785cSJohn Marino FUNCTION
258*ef5ccd6cSJohn Marino 	bfd_cache_section_contents
259*ef5ccd6cSJohn Marino 
260*ef5ccd6cSJohn Marino SYNOPSIS
261*ef5ccd6cSJohn Marino 	void bfd_cache_section_contents
262*ef5ccd6cSJohn Marino 	  (asection *sec, void *contents);
263*ef5ccd6cSJohn Marino 
264*ef5ccd6cSJohn Marino DESCRIPTION
265*ef5ccd6cSJohn Marino 	Stash @var(contents) so any following reads of @var(sec) do
266*ef5ccd6cSJohn Marino 	not need to decompress again.
267*ef5ccd6cSJohn Marino */
268*ef5ccd6cSJohn Marino 
269*ef5ccd6cSJohn Marino void
bfd_cache_section_contents(asection * sec,void * contents)270*ef5ccd6cSJohn Marino bfd_cache_section_contents (asection *sec, void *contents)
271*ef5ccd6cSJohn Marino {
272*ef5ccd6cSJohn Marino   if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
273*ef5ccd6cSJohn Marino     sec->compress_status = COMPRESS_SECTION_DONE;
274*ef5ccd6cSJohn Marino   sec->contents = contents;
275*ef5ccd6cSJohn Marino   sec->flags |= SEC_IN_MEMORY;
276*ef5ccd6cSJohn Marino }
277*ef5ccd6cSJohn Marino 
278*ef5ccd6cSJohn Marino 
279*ef5ccd6cSJohn Marino /*
280*ef5ccd6cSJohn Marino FUNCTION
281c50c785cSJohn Marino 	bfd_is_section_compressed
282c50c785cSJohn Marino 
283c50c785cSJohn Marino SYNOPSIS
284c50c785cSJohn Marino 	bfd_boolean bfd_is_section_compressed
285c50c785cSJohn Marino 	  (bfd *abfd, asection *section);
286c50c785cSJohn Marino 
287c50c785cSJohn Marino DESCRIPTION
288c50c785cSJohn Marino 	Return @code{TRUE} if @var{section} is compressed.
289c50c785cSJohn Marino */
290c50c785cSJohn Marino 
291c50c785cSJohn Marino bfd_boolean
bfd_is_section_compressed(bfd * abfd,sec_ptr sec)292c50c785cSJohn Marino bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
293c50c785cSJohn Marino {
294c50c785cSJohn Marino   bfd_byte compressed_buffer [12];
295*ef5ccd6cSJohn Marino   unsigned int saved = sec->compress_status;
296*ef5ccd6cSJohn Marino   bfd_boolean compressed;
297*ef5ccd6cSJohn Marino 
298*ef5ccd6cSJohn Marino   /* Don't decompress the section.  */
299*ef5ccd6cSJohn Marino   sec->compress_status = COMPRESS_SECTION_NONE;
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert   /* Read the zlib header.  In this case, it should be "ZLIB" followed
3025796c8dcSSimon Schubert      by the uncompressed section size, 8 bytes in big-endian order.  */
303*ef5ccd6cSJohn Marino   compressed = (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)
304c50c785cSJohn Marino 		&& CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"));
305*ef5ccd6cSJohn Marino 
306*ef5ccd6cSJohn Marino   /* Restore compress_status.  */
307*ef5ccd6cSJohn Marino   sec->compress_status = saved;
308*ef5ccd6cSJohn Marino   return compressed;
309c50c785cSJohn Marino }
310c50c785cSJohn Marino 
311c50c785cSJohn Marino /*
312c50c785cSJohn Marino FUNCTION
313c50c785cSJohn Marino 	bfd_init_section_decompress_status
314c50c785cSJohn Marino 
315c50c785cSJohn Marino SYNOPSIS
316c50c785cSJohn Marino 	bfd_boolean bfd_init_section_decompress_status
317c50c785cSJohn Marino 	  (bfd *abfd, asection *section);
318c50c785cSJohn Marino 
319c50c785cSJohn Marino DESCRIPTION
320c50c785cSJohn Marino 	Record compressed section size, update section size with
321c50c785cSJohn Marino 	decompressed size and set compress_status to
322c50c785cSJohn Marino 	DECOMPRESS_SECTION_SIZED.
323c50c785cSJohn Marino 
324c50c785cSJohn Marino 	Return @code{FALSE} if the section is not a valid compressed
325c50c785cSJohn Marino 	section or zlib is not installed on this machine.  Otherwise,
326c50c785cSJohn Marino 	return @code{TRUE}.
327c50c785cSJohn Marino */
328c50c785cSJohn Marino 
329c50c785cSJohn Marino bfd_boolean
bfd_init_section_decompress_status(bfd * abfd ATTRIBUTE_UNUSED,sec_ptr sec ATTRIBUTE_UNUSED)330c50c785cSJohn Marino bfd_init_section_decompress_status (bfd *abfd ATTRIBUTE_UNUSED,
331c50c785cSJohn Marino 				    sec_ptr sec ATTRIBUTE_UNUSED)
332c50c785cSJohn Marino {
333c50c785cSJohn Marino #ifndef HAVE_ZLIB_H
334c50c785cSJohn Marino   bfd_set_error (bfd_error_invalid_operation);
3355796c8dcSSimon Schubert   return FALSE;
336c50c785cSJohn Marino #else
337c50c785cSJohn Marino   bfd_byte compressed_buffer [12];
338c50c785cSJohn Marino   bfd_size_type uncompressed_size;
339c50c785cSJohn Marino 
340c50c785cSJohn Marino   if (sec->rawsize != 0
341c50c785cSJohn Marino       || sec->contents != NULL
342c50c785cSJohn Marino       || sec->compress_status != COMPRESS_SECTION_NONE
343c50c785cSJohn Marino       || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12))
344c50c785cSJohn Marino     {
345c50c785cSJohn Marino       bfd_set_error (bfd_error_invalid_operation);
346c50c785cSJohn Marino       return FALSE;
347c50c785cSJohn Marino     }
348c50c785cSJohn Marino 
349c50c785cSJohn Marino   /* Read the zlib header.  In this case, it should be "ZLIB" followed
350c50c785cSJohn Marino      by the uncompressed section size, 8 bytes in big-endian order.  */
351c50c785cSJohn Marino   if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
352c50c785cSJohn Marino     {
353c50c785cSJohn Marino       bfd_set_error (bfd_error_wrong_format);
354c50c785cSJohn Marino       return FALSE;
355c50c785cSJohn Marino     }
356c50c785cSJohn Marino 
3575796c8dcSSimon Schubert   uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
3585796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
3595796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
3605796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
3615796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
3625796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
3635796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
3645796c8dcSSimon Schubert   uncompressed_size += compressed_buffer[11];
3655796c8dcSSimon Schubert 
366c50c785cSJohn Marino   sec->compressed_size = sec->size;
367c50c785cSJohn Marino   sec->size = uncompressed_size;
368c50c785cSJohn Marino   sec->compress_status = DECOMPRESS_SECTION_SIZED;
3695796c8dcSSimon Schubert 
3705796c8dcSSimon Schubert   return TRUE;
371c50c785cSJohn Marino #endif
372c50c785cSJohn Marino }
3735796c8dcSSimon Schubert 
374c50c785cSJohn Marino /*
375c50c785cSJohn Marino FUNCTION
376c50c785cSJohn Marino 	bfd_init_section_compress_status
377c50c785cSJohn Marino 
378c50c785cSJohn Marino SYNOPSIS
379c50c785cSJohn Marino 	bfd_boolean bfd_init_section_compress_status
380c50c785cSJohn Marino 	  (bfd *abfd, asection *section);
381c50c785cSJohn Marino 
382c50c785cSJohn Marino DESCRIPTION
383c50c785cSJohn Marino 	If open for read, compress section, update section size with
384c50c785cSJohn Marino 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
385c50c785cSJohn Marino 
386c50c785cSJohn Marino 	Return @code{FALSE} if the section is not a valid compressed
387c50c785cSJohn Marino 	section or zlib is not installed on this machine.  Otherwise,
388c50c785cSJohn Marino 	return @code{TRUE}.
389c50c785cSJohn Marino */
390c50c785cSJohn Marino 
391c50c785cSJohn Marino bfd_boolean
bfd_init_section_compress_status(bfd * abfd ATTRIBUTE_UNUSED,sec_ptr sec ATTRIBUTE_UNUSED)392c50c785cSJohn Marino bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED,
393c50c785cSJohn Marino 				  sec_ptr sec ATTRIBUTE_UNUSED)
394c50c785cSJohn Marino {
395c50c785cSJohn Marino #ifndef HAVE_ZLIB_H
396c50c785cSJohn Marino   bfd_set_error (bfd_error_invalid_operation);
3975796c8dcSSimon Schubert   return FALSE;
398c50c785cSJohn Marino #else
399c50c785cSJohn Marino   bfd_size_type uncompressed_size;
400c50c785cSJohn Marino   bfd_byte *uncompressed_buffer;
401c50c785cSJohn Marino   bfd_boolean ret;
402c50c785cSJohn Marino 
403c50c785cSJohn Marino   /* Error if not opened for read.  */
404c50c785cSJohn Marino   if (abfd->direction != read_direction
405c50c785cSJohn Marino       || sec->size == 0
406c50c785cSJohn Marino       || sec->rawsize != 0
407c50c785cSJohn Marino       || sec->contents != NULL
408c50c785cSJohn Marino       || sec->compress_status != COMPRESS_SECTION_NONE)
409c50c785cSJohn Marino     {
410c50c785cSJohn Marino       bfd_set_error (bfd_error_invalid_operation);
411c50c785cSJohn Marino       return FALSE;
412c50c785cSJohn Marino     }
413c50c785cSJohn Marino 
414c50c785cSJohn Marino   /* Read in the full section contents and compress it.  */
415c50c785cSJohn Marino   uncompressed_size = sec->size;
416c50c785cSJohn Marino   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
417c50c785cSJohn Marino   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
418c50c785cSJohn Marino 				 0, uncompressed_size))
419c50c785cSJohn Marino     ret = FALSE;
420c50c785cSJohn Marino   else
421c50c785cSJohn Marino     ret = bfd_compress_section_contents (abfd, sec,
422c50c785cSJohn Marino 					 uncompressed_buffer,
423c50c785cSJohn Marino 					 uncompressed_size);
424c50c785cSJohn Marino 
425c50c785cSJohn Marino   free (uncompressed_buffer);
426c50c785cSJohn Marino   return ret;
427c50c785cSJohn Marino #endif
4285796c8dcSSimon Schubert }
429