+/*
+FUNCTION
+ bfd_cache_section_contents
+
+SYNOPSIS
+ void bfd_cache_section_contents
+ (asection *sec, void *contents);
+
+DESCRIPTION
+ Stash @var(contents) so any following reads of @var(sec) do
+ not need to decompress again.
+*/
+
+void
+bfd_cache_section_contents (asection *sec, void *contents)
+{
+ if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
+ sec->compress_status = COMPRESS_SECTION_DONE;
+ sec->contents = contents;
+ sec->flags |= SEC_IN_MEMORY;
+}
+
+/*
+FUNCTION
+ bfd_is_section_compressed_with_header
+
+SYNOPSIS
+ bfd_boolean bfd_is_section_compressed_with_header
+ (bfd *abfd, asection *section,
+ int *compression_header_size_p,
+ bfd_size_type *uncompressed_size_p,
+ unsigned int *uncompressed_alignment_power_p);
+
+DESCRIPTION
+ Return @code{TRUE} if @var{section} is compressed. Compression
+ header size is returned in @var{compression_header_size_p},
+ uncompressed size is returned in @var{uncompressed_size_p}
+ and the uncompressed data alignement power is returned in
+ @var{uncompressed_align_pow_p}. If compression is
+ unsupported, compression header size is returned with -1
+ and uncompressed size is returned with 0.
+*/
+
+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)
+{
+ bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
+ int compression_header_size;
+ int header_size;
+ unsigned int saved = sec->compress_status;
+ bfd_boolean compressed;
+
+ *uncompressed_align_pow_p = 0;
+
+ compression_header_size = bfd_get_compression_header_size (abfd, sec);
+ if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
+ abort ();
+ header_size = compression_header_size ? compression_header_size : 12;
+
+ /* Don't decompress the section. */
+ sec->compress_status = COMPRESS_SECTION_NONE;
+
+ /* Read the header. */
+ if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
+ {
+ if (compression_header_size == 0)
+ /* In this case, it should be "ZLIB" followed by the uncompressed
+ section size, 8 bytes in big-endian order. */
+ compressed = CONST_STRNEQ ((char*) header , "ZLIB");
+ else
+ compressed = TRUE;
+ }
+ else
+ compressed = FALSE;
+
+ *uncompressed_size_p = sec->size;
+ if (compressed)
+ {
+ if (compression_header_size != 0)
+ {
+ if (!bfd_check_compression_header (abfd, header, sec,
+ uncompressed_size_p,
+ uncompressed_align_pow_p))
+ compression_header_size = -1;
+ }
+ /* Check for the pathalogical case of a debug string section that
+ contains the string ZLIB.... as the first entry. We assume that
+ no uncompressed .debug_str section would ever be big enough to
+ have the first byte of its (big-endian) size be non-zero. */
+ else if (strcmp (sec->name, ".debug_str") == 0
+ && ISPRINT (header[4]))
+ compressed = FALSE;
+ else
+ *uncompressed_size_p = bfd_getb64 (header + 4);
+ }
+
+ /* Restore compress_status. */
+ sec->compress_status = saved;
+ *compression_header_size_p = compression_header_size;
+ return compressed;
+}
+