mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 06:17:47 +08:00
Add SHF_COMPRESSED support to readelf
This patch updates readelf to dump compression header with readelf -S -W: [ 4] .debug_info PROGBITS 00000000 000038 00007d 00 C 0 0 1 readelf -t -W: [ 4] .debug_info PROGBITS 00000000 000038 00007d 00 0 0 1 [00000800]: COMPRESSED ZLIB, 0000009d, 1 It also checks the compression header when decompressing the compressed section. * readelf.c (get_elf_section_flags): Support SHF_COMPRESSED. (get_compression_header): New. (process_section_headers): Dump compression header if needed. (uncompress_section_contents): Don't free compressed_buffer here. (load_specific_debug_section): Free the compressed buffer, update the section buffer and the section size if uncompress is successful.
This commit is contained in:
@ -1,3 +1,13 @@
|
|||||||
|
2015-04-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* readelf.c (get_elf_section_flags): Support SHF_COMPRESSED.
|
||||||
|
(get_compression_header): New.
|
||||||
|
(process_section_headers): Dump compression header if needed.
|
||||||
|
(uncompress_section_contents): Don't free compressed_buffer here.
|
||||||
|
(load_specific_debug_section): Free the compressed buffer, update
|
||||||
|
the section buffer and the section size if uncompress is
|
||||||
|
successful.
|
||||||
|
|
||||||
2015-04-02 H.J. Lu <hongjiu.lu@intel.com>
|
2015-04-02 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* configure: Regenerated.
|
* configure: Regenerated.
|
||||||
|
@ -5155,7 +5155,8 @@ get_elf_section_flags (bfd_vma sh_flags)
|
|||||||
/* Generic. */
|
/* Generic. */
|
||||||
/* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
|
/* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
|
||||||
/* SPARC specific. */
|
/* SPARC specific. */
|
||||||
/* 19 */ { STRING_COMMA_LEN ("ORDERED") }
|
/* 19 */ { STRING_COMMA_LEN ("ORDERED") },
|
||||||
|
/* 20 */ { STRING_COMMA_LEN ("COMPRESSED") }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (do_section_details)
|
if (do_section_details)
|
||||||
@ -5187,6 +5188,7 @@ get_elf_section_flags (bfd_vma sh_flags)
|
|||||||
case SHF_GROUP: sindex = 8; break;
|
case SHF_GROUP: sindex = 8; break;
|
||||||
case SHF_TLS: sindex = 9; break;
|
case SHF_TLS: sindex = 9; break;
|
||||||
case SHF_EXCLUDE: sindex = 18; break;
|
case SHF_EXCLUDE: sindex = 18; break;
|
||||||
|
case SHF_COMPRESSED: sindex = 20; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sindex = -1;
|
sindex = -1;
|
||||||
@ -5268,6 +5270,7 @@ get_elf_section_flags (bfd_vma sh_flags)
|
|||||||
case SHF_GROUP: *p = 'G'; break;
|
case SHF_GROUP: *p = 'G'; break;
|
||||||
case SHF_TLS: *p = 'T'; break;
|
case SHF_TLS: *p = 'T'; break;
|
||||||
case SHF_EXCLUDE: *p = 'E'; break;
|
case SHF_EXCLUDE: *p = 'E'; break;
|
||||||
|
case SHF_COMPRESSED: *p = 'C'; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((elf_header.e_machine == EM_X86_64
|
if ((elf_header.e_machine == EM_X86_64
|
||||||
@ -5355,6 +5358,27 @@ get_elf_section_flags (bfd_vma sh_flags)
|
|||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
|
||||||
|
{
|
||||||
|
if (is_32bit_elf)
|
||||||
|
{
|
||||||
|
Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
|
||||||
|
chdr->ch_type = BYTE_GET (echdr->ch_type);
|
||||||
|
chdr->ch_size = BYTE_GET (echdr->ch_size);
|
||||||
|
chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
|
||||||
|
return sizeof (*echdr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
|
||||||
|
chdr->ch_type = BYTE_GET (echdr->ch_type);
|
||||||
|
chdr->ch_size = BYTE_GET (echdr->ch_size);
|
||||||
|
chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
|
||||||
|
return sizeof (*echdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_section_headers (FILE * file)
|
process_section_headers (FILE * file)
|
||||||
{
|
{
|
||||||
@ -5799,7 +5823,29 @@ process_section_headers (FILE * file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (do_section_details)
|
if (do_section_details)
|
||||||
|
{
|
||||||
printf (" %s\n", get_elf_section_flags (section->sh_flags));
|
printf (" %s\n", get_elf_section_flags (section->sh_flags));
|
||||||
|
if ((section->sh_flags & SHF_COMPRESSED) != 0)
|
||||||
|
{
|
||||||
|
/* Minimum section size is 12 bytes for 32-bit compression
|
||||||
|
header + 12 bytes for compressed data header. */
|
||||||
|
unsigned char buf[24];
|
||||||
|
assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
|
||||||
|
if (get_data (&buf, (FILE *) file, section->sh_offset, 1,
|
||||||
|
sizeof (buf), _("compression header")))
|
||||||
|
{
|
||||||
|
Elf_Internal_Chdr chdr;
|
||||||
|
get_compression_header (&chdr, buf);
|
||||||
|
if (chdr.ch_type == ELFCOMPRESS_ZLIB)
|
||||||
|
printf (" ZLIB, ");
|
||||||
|
else
|
||||||
|
printf (_(" [<unknown>: 0x%x], "),
|
||||||
|
chdr.ch_type);
|
||||||
|
print_vma (chdr.ch_size, LONG_HEX);
|
||||||
|
printf (", %lu\n", (unsigned long) chdr.ch_addralign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!do_section_details)
|
if (!do_section_details)
|
||||||
@ -12007,7 +12053,6 @@ uncompress_section_contents (unsigned char **buffer,
|
|||||||
|| strm.avail_out != 0)
|
|| strm.avail_out != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
free (compressed_buffer);
|
|
||||||
*buffer = uncompressed_buffer;
|
*buffer = uncompressed_buffer;
|
||||||
*size = uncompressed_size;
|
*size = uncompressed_size;
|
||||||
return 1;
|
return 1;
|
||||||
@ -12040,9 +12085,30 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
|
|||||||
section->size = 0;
|
section->size = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
section->size = sec->sh_size;
|
unsigned char *start = section->start;
|
||||||
if (uncompress_section_contents (§ion->start, §ion->size))
|
dwarf_size_type size = sec->sh_size;
|
||||||
sec->sh_size = section->size;
|
|
||||||
|
if ((sec->sh_flags & SHF_COMPRESSED) != 0)
|
||||||
|
{
|
||||||
|
Elf_Internal_Chdr chdr;
|
||||||
|
unsigned int compression_header_size
|
||||||
|
= get_compression_header (&chdr, start);
|
||||||
|
if (chdr.ch_type != ELFCOMPRESS_ZLIB
|
||||||
|
|| chdr.ch_addralign != sec->sh_addralign)
|
||||||
|
return 0;
|
||||||
|
start += compression_header_size;
|
||||||
|
size -= compression_header_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uncompress_section_contents (&start, &size))
|
||||||
|
{
|
||||||
|
/* Free the compressed buffer, update the section buffer
|
||||||
|
and the section size if uncompress is successful. */
|
||||||
|
free (section->start);
|
||||||
|
section->start = start;
|
||||||
|
sec->sh_size = size;
|
||||||
|
}
|
||||||
|
section->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section->start == NULL)
|
if (section->start == NULL)
|
||||||
|
Reference in New Issue
Block a user