Subversion Repositories Kolibri OS

Rev

Rev 5197 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5197 serge 1
/* Compressed section support (intended for debug sections).
6324 serge 2
   Copyright (C) 2008-2015 Free Software Foundation, Inc.
5197 serge 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"
6324 serge 22
#include 
5197 serge 23
#include "bfd.h"
24
#include "libbfd.h"
6324 serge 25
#include "safe-ctype.h"
5197 serge 26
 
6324 serge 27
#define MAX_COMPRESSION_HEADER_SIZE 24
28
 
5197 serge 29
static bfd_boolean
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.  */
6324 serge 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;
5197 serge 48
  strm.avail_out = uncompressed_size;
49
 
50
  BFD_ASSERT (Z_OK == 0);
51
  rc = inflateInit (&strm);
52
  while (strm.avail_in > 0 && strm.avail_out > 0)
53
    {
54
      if (rc != Z_OK)
55
	break;
56
      strm.next_out = ((Bytef*) uncompressed_buffer
57
                       + (uncompressed_size - strm.avail_out));
58
      rc = inflate (&strm, Z_FINISH);
59
      if (rc != Z_STREAM_END)
60
	break;
61
      rc = inflateReset (&strm);
62
    }
63
  rc |= inflateEnd (&strm);
64
  return rc == Z_OK && strm.avail_out == 0;
65
}
66
 
6324 serge 67
/* Compress data of the size specified in @var{uncompressed_size}
5197 serge 68
	and pointed to by @var{uncompressed_buffer} using zlib and store
69
	as the contents field.  This function assumes the contents
6324 serge 70
   field was allocated using bfd_malloc() or equivalent.
5197 serge 71
 
6324 serge 72
   Return the uncompressed size if the full section contents is
73
   compressed successfully.  Otherwise return 0.  */
5197 serge 74
 
6324 serge 75
static bfd_size_type
76
bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
77
			       bfd_byte *uncompressed_buffer,
78
			       bfd_size_type uncompressed_size)
5197 serge 79
{
80
  uLong compressed_size;
6324 serge 81
  bfd_byte *buffer;
82
  bfd_size_type buffer_size;
83
  bfd_boolean decompress;
84
  int zlib_size = 0;
85
  int orig_compression_header_size;
86
  bfd_size_type orig_uncompressed_size;
87
  int header_size = bfd_get_compression_header_size (abfd, NULL);
88
  bfd_boolean compressed
89
    = bfd_is_section_compressed_with_header (abfd, sec,
90
					     &orig_compression_header_size,
91
					     &orig_uncompressed_size);
5197 serge 92
 
6324 serge 93
  /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
94
     overhead in .zdebug* section.  */
95
  if (!header_size)
96
     header_size = 12;
5197 serge 97
 
6324 serge 98
  if (compressed)
99
    {
100
      /* We shouldn't decompress unsupported compressed section.  */
101
      if (orig_compression_header_size < 0)
102
	abort ();
5197 serge 103
 
6324 serge 104
      /* Different compression schemes.  Just move the compressed section
105
	 contents to the right position. */
106
      if (orig_compression_header_size == 0)
107
	{
108
	  /* Convert it from .zdebug* section.  Get the uncompressed
109
	     size first.  We need to substract the 12-byte overhead in
110
	     .zdebug* section.  Set orig_compression_header_size to
111
	     the 12-bye overhead.  */
112
	  orig_compression_header_size = 12;
113
	  zlib_size = uncompressed_size - 12;
114
	}
115
      else
116
	{
117
	  /* Convert it to .zdebug* section.  */
118
	  zlib_size = uncompressed_size - orig_compression_header_size;
119
	}
120
 
121
      /* Add the header size.  */
122
      compressed_size = zlib_size + header_size;
123
    }
124
  else
125
    compressed_size = compressBound (uncompressed_size) + header_size;
126
 
127
  /* Uncompress if it leads to smaller size.  */
128
  if (compressed && compressed_size > orig_uncompressed_size)
129
    {
130
      decompress = TRUE;
131
      buffer_size = orig_uncompressed_size;
132
    }
133
  else
134
    {
135
      decompress = FALSE;
136
      buffer_size = compressed_size;
137
    }
138
  buffer = (bfd_byte *) bfd_alloc (abfd, buffer_size);
139
  if (buffer == NULL)
140
    return 0;
141
 
142
  if (compressed)
143
    {
144
      sec->size = orig_uncompressed_size;
145
      if (decompress)
146
	{
147
	  if (!decompress_contents (uncompressed_buffer
148
				    + orig_compression_header_size,
149
				    zlib_size, buffer, buffer_size))
150
	    {
151
	      bfd_set_error (bfd_error_bad_value);
152
	      bfd_release (abfd, buffer);
153
	      return 0;
154
	    }
155
	  free (uncompressed_buffer);
156
	  sec->contents = buffer;
157
	  sec->compress_status = COMPRESS_SECTION_DONE;
158
	  return orig_uncompressed_size;
159
	}
160
      else
161
	{
162
	  bfd_update_compression_header (abfd, buffer, sec);
163
	  memmove (buffer + header_size,
164
		   uncompressed_buffer + orig_compression_header_size,
165
		   zlib_size);
166
	}
167
    }
168
  else
169
    {
170
      if (compress ((Bytef*) buffer + header_size,
5197 serge 171
		&compressed_size,
172
		(const Bytef*) uncompressed_buffer,
173
		uncompressed_size) != Z_OK)
174
    {
6324 serge 175
	  bfd_release (abfd, buffer);
5197 serge 176
      bfd_set_error (bfd_error_bad_value);
6324 serge 177
	  return 0;
5197 serge 178
    }
179
 
6324 serge 180
      compressed_size += header_size;
181
      /* PR binutils/18087: If compression didn't make the section smaller,
182
	 just keep it uncompressed.  */
183
      if (compressed_size < uncompressed_size)
184
	bfd_update_compression_header (abfd, buffer, sec);
185
      else
186
	{
187
	  /* NOTE: There is a small memory leak here since
188
	     uncompressed_buffer is malloced and won't be freed.  */
189
	  bfd_release (abfd, buffer);
190
	  sec->contents = uncompressed_buffer;
191
	  sec->compress_status = COMPRESS_SECTION_NONE;
192
	  return uncompressed_size;
193
	}
194
    }
5197 serge 195
 
196
    free (uncompressed_buffer);
6324 serge 197
  sec->contents = buffer;
5197 serge 198
  sec->size = compressed_size;
199
  sec->compress_status = COMPRESS_SECTION_DONE;
200
 
6324 serge 201
  return uncompressed_size;
5197 serge 202
}
203
 
204
/*
205
FUNCTION
206
	bfd_get_full_section_contents
207
 
208
SYNOPSIS
209
	bfd_boolean bfd_get_full_section_contents
210
	  (bfd *abfd, asection *section, bfd_byte **ptr);
211
 
212
DESCRIPTION
213
	Read all data from @var{section} in BFD @var{abfd}, decompress
214
	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
215
	return @var{*ptr} with memory malloc'd by this function.
216
 
217
	Return @code{TRUE} if the full section contents is retrieved
6324 serge 218
	successfully.  If the section has no contents then this function
219
	returns @code{TRUE} but @var{*ptr} is set to NULL.
5197 serge 220
*/
221
 
222
bfd_boolean
223
bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
224
{
225
  bfd_size_type sz;
226
  bfd_byte *p = *ptr;
227
  bfd_boolean ret;
228
  bfd_size_type save_size;
229
  bfd_size_type save_rawsize;
230
  bfd_byte *compressed_buffer;
6324 serge 231
  unsigned int compression_header_size;
5197 serge 232
 
233
  if (abfd->direction != write_direction && sec->rawsize != 0)
234
    sz = sec->rawsize;
235
  else
236
    sz = sec->size;
237
  if (sz == 0)
6324 serge 238
    {
239
      *ptr = NULL;
5197 serge 240
    return TRUE;
6324 serge 241
    }
5197 serge 242
 
243
  switch (sec->compress_status)
244
    {
245
    case COMPRESS_SECTION_NONE:
246
      if (p == NULL)
247
	{
248
	  p = (bfd_byte *) bfd_malloc (sz);
249
	  if (p == NULL)
250
	    return FALSE;
251
	}
6324 serge 252
 
5197 serge 253
      if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
254
	{
255
	  if (*ptr != p)
256
	    free (p);
257
	  return FALSE;
258
	}
259
      *ptr = p;
260
      return TRUE;
261
 
262
    case DECOMPRESS_SECTION_SIZED:
263
      /* Read in the full compressed section contents.  */
264
      compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
265
      if (compressed_buffer == NULL)
266
	return FALSE;
267
      save_rawsize = sec->rawsize;
268
      save_size = sec->size;
269
      /* Clear rawsize, set size to compressed size and set compress_status
270
	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
271
	 the uncompressed size, bfd_get_section_contents will fail.  */
272
      sec->rawsize = 0;
273
      sec->size = sec->compressed_size;
274
      sec->compress_status = COMPRESS_SECTION_NONE;
275
      ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
276
				      0, sec->compressed_size);
277
      /* Restore rawsize and size.  */
278
      sec->rawsize = save_rawsize;
279
      sec->size = save_size;
280
      sec->compress_status = DECOMPRESS_SECTION_SIZED;
281
      if (!ret)
282
	goto fail_compressed;
283
 
284
      if (p == NULL)
285
	p = (bfd_byte *) bfd_malloc (sz);
286
      if (p == NULL)
287
	goto fail_compressed;
288
 
6324 serge 289
      compression_header_size = bfd_get_compression_header_size (abfd, sec);
290
      if (compression_header_size == 0)
291
	/* Set header size to the zlib header size if it is a
292
	   SHF_COMPRESSED section.  */
293
	compression_header_size = 12;
294
      if (!decompress_contents (compressed_buffer + compression_header_size,
295
				sec->compressed_size, p, sz))
5197 serge 296
	{
297
	  bfd_set_error (bfd_error_bad_value);
298
	  if (p != *ptr)
299
	    free (p);
300
	fail_compressed:
301
	  free (compressed_buffer);
302
	  return FALSE;
303
	}
304
 
305
      free (compressed_buffer);
306
      *ptr = p;
307
      return TRUE;
308
 
309
    case COMPRESS_SECTION_DONE:
6324 serge 310
      if (sec->contents == NULL)
311
	return FALSE;
5197 serge 312
      if (p == NULL)
313
	{
314
	  p = (bfd_byte *) bfd_malloc (sz);
315
	  if (p == NULL)
316
	    return FALSE;
317
	  *ptr = p;
318
	}
6324 serge 319
      /* PR 17512; file: 5bc29788.  */
320
      if (p != sec->contents)
5197 serge 321
      memcpy (p, sec->contents, sz);
322
      return TRUE;
323
 
324
    default:
325
      abort ();
326
    }
327
}
328
 
329
/*
330
FUNCTION
331
	bfd_cache_section_contents
332
 
333
SYNOPSIS
334
	void bfd_cache_section_contents
335
	  (asection *sec, void *contents);
336
 
337
DESCRIPTION
338
	Stash @var(contents) so any following reads of @var(sec) do
339
	not need to decompress again.
340
*/
341
 
342
void
343
bfd_cache_section_contents (asection *sec, void *contents)
344
{
345
  if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
346
    sec->compress_status = COMPRESS_SECTION_DONE;
347
  sec->contents = contents;
348
  sec->flags |= SEC_IN_MEMORY;
349
}
350
 
351
/*
352
FUNCTION
6324 serge 353
	bfd_is_section_compressed_with_header
5197 serge 354
 
355
SYNOPSIS
6324 serge 356
	bfd_boolean bfd_is_section_compressed_with_header
357
	  (bfd *abfd, asection *section,
358
	  int *compression_header_size_p,
359
	  bfd_size_type *uncompressed_size_p);
5197 serge 360
 
361
DESCRIPTION
6324 serge 362
	Return @code{TRUE} if @var{section} is compressed.  Compression
363
	header size is returned in @var{compression_header_size_p} and
364
	uncompressed size is returned in @var{uncompressed_size_p}.  If
365
	compression is unsupported, compression header size is returned
366
	with -1 and uncompressed size is returned with 0.
5197 serge 367
*/
368
 
369
bfd_boolean
6324 serge 370
bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
371
				       int *compression_header_size_p,
372
				       bfd_size_type *uncompressed_size_p)
5197 serge 373
{
6324 serge 374
  bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
375
  int compression_header_size;
376
  int header_size;
5197 serge 377
  unsigned int saved = sec->compress_status;
378
  bfd_boolean compressed;
379
 
6324 serge 380
  compression_header_size = bfd_get_compression_header_size (abfd, sec);
381
  if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
382
    abort ();
383
  header_size = compression_header_size ? compression_header_size : 12;
384
 
5197 serge 385
  /* Don't decompress the section.  */
386
  sec->compress_status = COMPRESS_SECTION_NONE;
387
 
6324 serge 388
  /* Read the header.  */
389
  if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
390
    {
391
      if (compression_header_size == 0)
392
        /* In this case, it should be "ZLIB" followed by the uncompressed
393
	   section size, 8 bytes in big-endian order.  */
394
	compressed = CONST_STRNEQ ((char*) header , "ZLIB");
395
      else
396
	compressed = TRUE;
397
    }
398
  else
399
    compressed = FALSE;
5197 serge 400
 
6324 serge 401
  *uncompressed_size_p = sec->size;
402
  if (compressed)
403
    {
404
      if (compression_header_size != 0)
405
	{
406
	  if (!bfd_check_compression_header (abfd, header, sec,
407
					     uncompressed_size_p))
408
	    compression_header_size = -1;
409
	}
410
      /* Check for the pathalogical case of a debug string section that
411
	 contains the string ZLIB.... as the first entry.  We assume that
412
	 no uncompressed .debug_str section would ever be big enough to
413
	 have the first byte of its (big-endian) size be non-zero.  */
414
      else if (strcmp (sec->name, ".debug_str") == 0
415
	       && ISPRINT (header[4]))
416
	compressed = FALSE;
417
      else
418
	*uncompressed_size_p = bfd_getb64 (header + 4);
419
    }
420
 
5197 serge 421
  /* Restore compress_status.  */
422
  sec->compress_status = saved;
6324 serge 423
  *compression_header_size_p = compression_header_size;
5197 serge 424
  return compressed;
425
}
426
 
427
/*
428
FUNCTION
6324 serge 429
	bfd_is_section_compressed
430
 
431
SYNOPSIS
432
	bfd_boolean bfd_is_section_compressed
433
	  (bfd *abfd, asection *section);
434
 
435
DESCRIPTION
436
	Return @code{TRUE} if @var{section} is compressed.
437
*/
438
 
439
bfd_boolean
440
bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
441
{
442
  int compression_header_size;
443
  bfd_size_type uncompressed_size;
444
  return (bfd_is_section_compressed_with_header (abfd, sec,
445
						 &compression_header_size,
446
						 &uncompressed_size)
447
	  && compression_header_size >= 0
448
	  && uncompressed_size > 0);
449
}
450
 
451
/*
452
FUNCTION
5197 serge 453
	bfd_init_section_decompress_status
454
 
455
SYNOPSIS
456
	bfd_boolean bfd_init_section_decompress_status
457
	  (bfd *abfd, asection *section);
458
 
459
DESCRIPTION
460
	Record compressed section size, update section size with
461
	decompressed size and set compress_status to
462
	DECOMPRESS_SECTION_SIZED.
463
 
464
	Return @code{FALSE} if the section is not a valid compressed
6324 serge 465
	section.  Otherwise, return @code{TRUE}.
5197 serge 466
*/
467
 
468
bfd_boolean
6324 serge 469
bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
5197 serge 470
{
6324 serge 471
  bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
472
  int compression_header_size;
473
  int header_size;
5197 serge 474
  bfd_size_type uncompressed_size;
475
 
6324 serge 476
  compression_header_size = bfd_get_compression_header_size (abfd, sec);
477
  if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
478
    abort ();
479
  header_size = compression_header_size ? compression_header_size : 12;
480
 
481
  /* Read the header.  */
5197 serge 482
  if (sec->rawsize != 0
483
      || sec->contents != NULL
484
      || sec->compress_status != COMPRESS_SECTION_NONE
6324 serge 485
      || !bfd_get_section_contents (abfd, sec, header, 0, header_size))
5197 serge 486
    {
487
      bfd_set_error (bfd_error_invalid_operation);
488
      return FALSE;
489
    }
490
 
6324 serge 491
  if (compression_header_size == 0)
5197 serge 492
    {
6324 serge 493
      /* In this case, it should be "ZLIB" followed by the uncompressed
494
	 section size, 8 bytes in big-endian order.  */
495
      if (! CONST_STRNEQ ((char*) header, "ZLIB"))
496
    {
5197 serge 497
      bfd_set_error (bfd_error_wrong_format);
498
      return FALSE;
499
    }
6324 serge 500
      uncompressed_size = bfd_getb64 (header + 4);
501
    }
502
  else if (!bfd_check_compression_header (abfd, header, sec,
503
					 &uncompressed_size))
504
    {
505
      bfd_set_error (bfd_error_wrong_format);
506
      return FALSE;
507
    }
5197 serge 508
 
509
  sec->compressed_size = sec->size;
510
  sec->size = uncompressed_size;
511
  sec->compress_status = DECOMPRESS_SECTION_SIZED;
512
 
513
  return TRUE;
514
}
515
 
516
/*
517
FUNCTION
518
	bfd_init_section_compress_status
519
 
520
SYNOPSIS
521
	bfd_boolean bfd_init_section_compress_status
522
	  (bfd *abfd, asection *section);
523
 
524
DESCRIPTION
525
	If open for read, compress section, update section size with
526
	compressed size and set compress_status to COMPRESS_SECTION_DONE.
527
 
528
	Return @code{FALSE} if the section is not a valid compressed
6324 serge 529
	section.  Otherwise, return @code{TRUE}.
5197 serge 530
*/
531
 
532
bfd_boolean
6324 serge 533
bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
5197 serge 534
{
535
  bfd_size_type uncompressed_size;
536
  bfd_byte *uncompressed_buffer;
537
  bfd_boolean ret;
538
 
539
  /* Error if not opened for read.  */
540
  if (abfd->direction != read_direction
541
      || sec->size == 0
542
      || sec->rawsize != 0
543
      || sec->contents != NULL
544
      || sec->compress_status != COMPRESS_SECTION_NONE)
545
    {
546
      bfd_set_error (bfd_error_invalid_operation);
547
      return FALSE;
548
    }
549
 
550
  /* Read in the full section contents and compress it.  */
551
  uncompressed_size = sec->size;
552
  uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
553
  if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
554
				 0, uncompressed_size))
555
    ret = FALSE;
556
  else
6324 serge 557
    {
558
      uncompressed_size = bfd_compress_section_contents (abfd, sec,
5197 serge 559
					 uncompressed_buffer,
560
					 uncompressed_size);
6324 serge 561
      ret = uncompressed_size != 0;
562
    }
5197 serge 563
 
564
  return ret;
565
}
6324 serge 566
 
567
/*
568
FUNCTION
569
	bfd_compress_section
570
 
571
SYNOPSIS
572
	bfd_boolean bfd_compress_section
573
	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
574
 
575
DESCRIPTION
576
	If open for write, compress section, update section size with
577
	compressed size and set compress_status to COMPRESS_SECTION_DONE.
578
 
579
	Return @code{FALSE} if compression fail.  Otherwise, return
580
	@code{TRUE}.
581
*/
582
 
583
bfd_boolean
584
bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
585
{
586
  bfd_size_type uncompressed_size = sec->size;
587
 
588
  /* Error if not opened for write.  */
589
  if (abfd->direction != write_direction
590
      || uncompressed_size == 0
591
      || uncompressed_buffer == NULL
592
      || sec->contents != NULL
593
      || sec->compressed_size != 0
594
      || sec->compress_status != COMPRESS_SECTION_NONE)
595
    {
596
      bfd_set_error (bfd_error_invalid_operation);
597
      return FALSE;
598
    }
599
 
600
  /* Compress it.  */
601
  return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
602
					uncompressed_size) != 0;
603
}