OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [compress.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* Compressed section support (intended for debug sections).
2
   Copyright 2008, 2010, 2011
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;
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
  uLong 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 (compressed_buffer == NULL)
104
    return FALSE;
105
 
106
  if (compress ((Bytef*) compressed_buffer + 12,
107
                &compressed_size,
108
                (const Bytef*) uncompressed_buffer,
109
                uncompressed_size) != Z_OK)
110
    {
111
      free (compressed_buffer);
112
      bfd_set_error (bfd_error_bad_value);
113
      return FALSE;
114
    }
115
 
116
  /* Write the zlib header.  In this case, it should be "ZLIB" followed
117
     by the uncompressed section size, 8 bytes in big-endian order.  */
118
  memcpy (compressed_buffer, "ZLIB", 4);
119
  compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8;
120
  compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8;
121
  compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8;
122
  compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8;
123
  compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8;
124
  compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8;
125
  compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8;
126
  compressed_buffer[4] = uncompressed_size;
127
  compressed_size += 12;
128
 
129
  /* Free the uncompressed contents if we compress in place.  */
130
  if (uncompressed_buffer == sec->contents)
131
    free (uncompressed_buffer);
132
 
133
  sec->contents = compressed_buffer;
134
  sec->size = compressed_size;
135
  sec->compress_status = COMPRESS_SECTION_DONE;
136
 
137
  return TRUE;
138
#endif  /* HAVE_ZLIB_H */
139
}
140
 
141
/*
142
FUNCTION
143
        bfd_get_full_section_contents
144
 
145
SYNOPSIS
146
        bfd_boolean bfd_get_full_section_contents
147
          (bfd *abfd, asection *section, bfd_byte **ptr);
148
 
149
DESCRIPTION
150
        Read all data from @var{section} in BFD @var{abfd}, decompress
151
        if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
152
        return @var{*ptr} with memory malloc'd by this function.
153
 
154
        Return @code{TRUE} if the full section contents is retrieved
155
        successfully.
156
*/
157
 
158
bfd_boolean
159
bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
160
{
161
  bfd_size_type sz;
162
  bfd_byte *p = *ptr;
163
#ifdef HAVE_ZLIB_H
164
  bfd_boolean ret;
165
  bfd_size_type compressed_size;
166
  bfd_size_type uncompressed_size;
167
  bfd_size_type rawsize;
168
  bfd_byte *compressed_buffer;
169
  bfd_byte *uncompressed_buffer;
170
#endif
171
 
172
  if (abfd->direction != write_direction && sec->rawsize != 0)
173
    sz = sec->rawsize;
174
  else
175
    sz = sec->size;
176
  if (sz == 0)
177
    return TRUE;
178
 
179
  switch (sec->compress_status)
180
    {
181
    case COMPRESS_SECTION_NONE:
182
      if (p == NULL)
183
        {
184
          p = (bfd_byte *) bfd_malloc (sz);
185
          if (p == NULL)
186
            return FALSE;
187
        }
188
      if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
189
        {
190
          if (*ptr != p)
191
            free (p);
192
          return FALSE;
193
        }
194
      *ptr = p;
195
      return TRUE;
196
 
197
    case DECOMPRESS_SECTION_SIZED:
198
#ifndef HAVE_ZLIB_H
199
      bfd_set_error (bfd_error_invalid_operation);
200
      return FALSE;
201
#else
202
      /* Read in the full compressed section contents.  */
203
      uncompressed_size = sec->size;
204
      compressed_size = sec->compressed_size;
205
      compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);
206
      if (compressed_buffer == NULL)
207
        return FALSE;
208
      rawsize = sec->rawsize;
209
      /* Clear rawsize, set size to compressed size and set compress_status
210
         to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
211
         the uncompressed size, bfd_get_section_contents will fail.  */
212
      sec->rawsize = 0;
213
      sec->size = compressed_size;
214
      sec->compress_status = COMPRESS_SECTION_NONE;
215
      ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
216
                                      0, compressed_size);
217
      /* Restore rawsize and size.  */
218
      sec->rawsize = rawsize;
219
      sec->size = uncompressed_size;
220
      sec->compress_status = DECOMPRESS_SECTION_SIZED;
221
      if (!ret)
222
        goto fail_compressed;
223
 
224
      uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
225
      if (uncompressed_buffer == NULL)
226
        goto fail_compressed;
227
 
228
      if (!decompress_contents (compressed_buffer, compressed_size,
229
                                uncompressed_buffer, uncompressed_size))
230
        {
231
          bfd_set_error (bfd_error_bad_value);
232
          free (uncompressed_buffer);
233
        fail_compressed:
234
          free (compressed_buffer);
235
          return FALSE;
236
        }
237
 
238
      free (compressed_buffer);
239
      sec->contents = uncompressed_buffer;
240
      sec->compress_status = COMPRESS_SECTION_DONE;
241
      /* Fall thru */
242
#endif
243
 
244
    case COMPRESS_SECTION_DONE:
245
      if (p == NULL)
246
        {
247
          p = (bfd_byte *) bfd_malloc (sz);
248
          if (p == NULL)
249
            return FALSE;
250
          *ptr = p;
251
        }
252
      memcpy (p, sec->contents, sz);
253
      return TRUE;
254
 
255
    default:
256
      abort ();
257
    }
258
}
259
 
260
/*
261
FUNCTION
262
        bfd_is_section_compressed
263
 
264
SYNOPSIS
265
        bfd_boolean bfd_is_section_compressed
266
          (bfd *abfd, asection *section);
267
 
268
DESCRIPTION
269
        Return @code{TRUE} if @var{section} is compressed.
270
*/
271
 
272
bfd_boolean
273
bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
274
{
275
  bfd_byte compressed_buffer [12];
276
 
277
  /* Read the zlib header.  In this case, it should be "ZLIB" followed
278
     by the uncompressed section size, 8 bytes in big-endian order.  */
279
  return (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)
280
          && CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"));
281
}
282
 
283
/*
284
FUNCTION
285
        bfd_init_section_decompress_status
286
 
287
SYNOPSIS
288
        bfd_boolean bfd_init_section_decompress_status
289
          (bfd *abfd, asection *section);
290
 
291
DESCRIPTION
292
        Record compressed section size, update section size with
293
        decompressed size and set compress_status to
294
        DECOMPRESS_SECTION_SIZED.
295
 
296
        Return @code{FALSE} if the section is not a valid compressed
297
        section or zlib is not installed on this machine.  Otherwise,
298
        return @code{TRUE}.
299
*/
300
 
301
bfd_boolean
302
bfd_init_section_decompress_status (bfd *abfd ATTRIBUTE_UNUSED,
303
                                    sec_ptr sec ATTRIBUTE_UNUSED)
304
{
305
#ifndef HAVE_ZLIB_H
306
  bfd_set_error (bfd_error_invalid_operation);
307
  return FALSE;
308
#else
309
  bfd_byte compressed_buffer [12];
310
  bfd_size_type uncompressed_size;
311
 
312
  if (sec->rawsize != 0
313
      || sec->contents != NULL
314
      || sec->compress_status != COMPRESS_SECTION_NONE
315
      || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12))
316
    {
317
      bfd_set_error (bfd_error_invalid_operation);
318
      return FALSE;
319
    }
320
 
321
  /* Read the zlib header.  In this case, it should be "ZLIB" followed
322
     by the uncompressed section size, 8 bytes in big-endian order.  */
323
  if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
324
    {
325
      bfd_set_error (bfd_error_wrong_format);
326
      return FALSE;
327
    }
328
 
329
  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
330
  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
331
  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
332
  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
333
  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
334
  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
335
  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
336
  uncompressed_size += compressed_buffer[11];
337
 
338
  sec->compressed_size = sec->size;
339
  sec->size = uncompressed_size;
340
  sec->compress_status = DECOMPRESS_SECTION_SIZED;
341
 
342
  return TRUE;
343
#endif
344
}
345
 
346
/*
347
FUNCTION
348
        bfd_init_section_compress_status
349
 
350
SYNOPSIS
351
        bfd_boolean bfd_init_section_compress_status
352
          (bfd *abfd, asection *section);
353
 
354
DESCRIPTION
355
        If open for read, compress section, update section size with
356
        compressed size and set compress_status to COMPRESS_SECTION_DONE.
357
 
358
        Return @code{FALSE} if the section is not a valid compressed
359
        section or zlib is not installed on this machine.  Otherwise,
360
        return @code{TRUE}.
361
*/
362
 
363
bfd_boolean
364
bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED,
365
                                  sec_ptr sec ATTRIBUTE_UNUSED)
366
{
367
#ifndef HAVE_ZLIB_H
368
  bfd_set_error (bfd_error_invalid_operation);
369
  return FALSE;
370
#else
371
  bfd_size_type uncompressed_size;
372
  bfd_byte *uncompressed_buffer;
373
  bfd_boolean ret;
374
 
375
  /* Error if not opened for read.  */
376
  if (abfd->direction != read_direction
377
      || sec->size == 0
378
      || sec->rawsize != 0
379
      || sec->contents != NULL
380
      || sec->compress_status != COMPRESS_SECTION_NONE)
381
    {
382
      bfd_set_error (bfd_error_invalid_operation);
383
      return FALSE;
384
    }
385
 
386
  /* Read in the full section contents and compress it.  */
387
  uncompressed_size = sec->size;
388
  uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
389
  if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
390
                                 0, uncompressed_size))
391
    ret = FALSE;
392
  else
393
    ret = bfd_compress_section_contents (abfd, sec,
394
                                         uncompressed_buffer,
395
                                         uncompressed_size);
396
 
397
  free (uncompressed_buffer);
398
  return ret;
399
#endif
400
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.