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