Commit 4a114e3e authored by H.J. Lu's avatar H.J. Lu

Add compressed debug section support to binutils and ld.

bfd/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>
	    Cary Coutant  <ccoutant@google.com>

	* archive.c (bfd_openr_next_archived_file): Copy BFD_COMPRESS
	and BFD_DECOMPRESS.

	* bfd.c (BFD_COMPRESS): New.
	(BFD_DECOMPRESS): Likewise.
	(BFD_FLAGS_SAVED): Likewise.
	(bfd_preserve_save): Replace BFD_IN_MEMORY with BFD_FLAGS_SAVED.

	* compress.c (bfd_uncompress_section_contents): Removed.
	(get_uncompressed_size): New.
	(decompress_contents): Likewise.
	(bfd_compress_section_contents): Likewise.
	(bfd_get_full_section_contents): Likewise.
	(bfd_is_section_compressed): Likewise.
	(bfd_init_section_decompress_status): Likewise.
	(bfd_init_section_compress_status): Likewise.

	* dwarf2.c (dwarf_debug_sections): New.
	(dwarf_debug_section_enum): Likewise.
	(read_section): Remove section_name and compressed_section_name.
	Add dwarf_debug_section_enum.  Try compressed debug section.
	(read_indirect_string): Updated.
	(read_abbrevs): Likewise.
	(decode_line_info): Likewise.
	(read_debug_ranges): Likewise.
	(find_line): Updated.

	* ecoff.c (bfd_debug_section): Add compress_status and
	compressed_size.

	* elf.c (_bfd_elf_make_section_from_shdr): Call
	bfd_is_section_compressed to check if a DWARF debug section is
	compressed.  Call bfd_init_section_compress_status or
	bfd_init_section_decompress_status if needed.

	* elflink.c (elf_link_input_bfd): Replace bfd_get_section_contents
	with bfd_get_full_section_contents.
	* merge.c (_bfd_add_merge_section): Likewise.
	* reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
	* simple.c (bfd_simple_get_relocated_section_contents): Likewise.

	* elfxx-target.h (TARGET_BIG_SYM): Allow BFD_COMPRESS and
	BFD_DECOMPRESS.
	(TARGET_LITTLE_SYM): Likewise.

	* libbfd-in.h (dwarf_debug_section): New.
	(dwarf_debug_sections): Likewise.

	* libbfd.c (_bfd_generic_get_section_contents): Issue an error
	when getting contents on compressed/decompressed section.

	* section.c (COMPRESS_SECTION_NONE): New.
	(COMPRESS_SECTION_DONE): Likewise.
	(DECOMPRESS_SECTION_SIZED): Likewise.
	(BFD_FAKE_SECTION): Add compress_status and compressed_size.
	(bfd_malloc_and_get_section): Replace bfd_get_section_contents
	with bfd_get_full_section_contents.

	* bfd-in2.h: Regenerated.
	* libbfd.h: Likewise.

binutils/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>

	* addr2line.c (process_file): Set BFD_DECOMPRESS.

	* objcopy.c (do_debug_sections): New.
	(OPTION_COMPRESS_DEBUG_SECTIONS): New.
	(OPTION_DECOMPRESS_DEBUG_SECTIONS): Likewise.
	(copy_options): Add OPTION_COMPRESS_DEBUG_SECTIONS and
	OPTION_DECOMPRESS_DEBUG_SECTIONS.
	(copy_usage): Add --compress-debug-sections and
	--decompress-debug-sections.
	(copy_file): Set BFD_COMPRESS or BFD_DECOMPRESS.
	(copy_section): Replace bfd_get_section_contents with
	bfd_get_full_section_contents.
	(copy_main): Handle OPTION_COMPRESS_DEBUG_SECTIONS and
	OPTION_DECOMPRESS_DEBUG_SECTIONS.  Check do_debug_sections to
	rename DWARF debug sections.

	* objdump.c (load_specific_debug_section): Replace
	bfd_get_section_contents with bfd_get_full_section_contents.
	Remove bfd_uncompress_section_contents.
	(dump_section): Replace bfd_get_section_contents with
	bfd_get_full_section_contents.
	(display_file): Set BFD_DECOMPRESS if needed.

	* readelf.c (uncompress_section_contents): Set buffer to NULL
	to indiate decompression failure.
	(load_specific_debug_section): Always call
	uncompress_section_contents.

	* doc/binutils.texi: Document --compress-debug-sections and
	--decompress-debug-sections.

binutils/testsuite/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>

	* binutils-all/compress.exp: New.
	* binutils-all/dw2-1.S: Likewise.
	* binutils-all/dw2-2.S: Likewise.
	* binutils-all/libdw2-compressed.out: Likewise.
	* binutils-all/libdw2.out: Likewise.

gas/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>

	* write.c (compress_debug): Optimize section flags check.

gas/testsuite/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>

	* elf/dwarf2-1.s: Replace .zdebug_abbrev section with
	.debug_abbrev section.
	* elf/dwarf2-2.3: Likewise.

	* elf/dwarf2-1.d: Pass --compress-debug-sections to assembler.
	Updated.
	* elf/dwarf2-2.d: Likewise.

	* gas/i386/i386.exp: Remove xfail on dw2-compress-2 and
	x86-64-dw2-compress-2.

ld/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>

	* ldfile.c (ldfile_try_open_bfd): Set BFD_DECOMPRESS after
	bfd_openr returns.
	* emultempl/elf32.em (gld${EMULATION_NAME}_try_needed): Likewise.

	* scripttempl/elf.sc: Include compressed DWARF debug sections.

ld/testsuite/

2010-10-29  H.J. Lu  <hongjiu.lu@intel.com>

	* ld-elf/compress.exp: New.
	* ld-elf/compress1.s: Likewise.
	* ld-elf/compress1a.d: Likewise.
	* ld-elf/compress1b.d: Likewise.
	* ld-elf/compress1c.d: Likewise.
parent e58bcb8f
2010-10-29 H.J. Lu <hongjiu.lu@intel.com>
Cary Coutant <ccoutant@google.com>
* archive.c (bfd_openr_next_archived_file): Copy BFD_COMPRESS
and BFD_DECOMPRESS.
* bfd.c (BFD_COMPRESS): New.
(BFD_DECOMPRESS): Likewise.
(BFD_FLAGS_SAVED): Likewise.
(bfd_preserve_save): Replace BFD_IN_MEMORY with BFD_FLAGS_SAVED.
* compress.c (bfd_uncompress_section_contents): Removed.
(get_uncompressed_size): New.
(decompress_contents): Likewise.
(bfd_compress_section_contents): Likewise.
(bfd_get_full_section_contents): Likewise.
(bfd_is_section_compressed): Likewise.
(bfd_init_section_decompress_status): Likewise.
(bfd_init_section_compress_status): Likewise.
* dwarf2.c (dwarf_debug_sections): New.
(dwarf_debug_section_enum): Likewise.
(read_section): Remove section_name and compressed_section_name.
Add dwarf_debug_section_enum. Try compressed debug section.
(read_indirect_string): Updated.
(read_abbrevs): Likewise.
(decode_line_info): Likewise.
(read_debug_ranges): Likewise.
(find_line): Updated.
* ecoff.c (bfd_debug_section): Add compress_status and
compressed_size.
* elf.c (_bfd_elf_make_section_from_shdr): Call
bfd_is_section_compressed to check if a DWARF debug section is
compressed. Call bfd_init_section_compress_status or
bfd_init_section_decompress_status if needed.
* elflink.c (elf_link_input_bfd): Replace bfd_get_section_contents
with bfd_get_full_section_contents.
* merge.c (_bfd_add_merge_section): Likewise.
* reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
* simple.c (bfd_simple_get_relocated_section_contents): Likewise.
* elfxx-target.h (TARGET_BIG_SYM): Allow BFD_COMPRESS and
BFD_DECOMPRESS.
(TARGET_LITTLE_SYM): Likewise.
* libbfd-in.h (dwarf_debug_section): New.
(dwarf_debug_sections): Likewise.
* libbfd.c (_bfd_generic_get_section_contents): Issue an error
when getting contents on compressed/decompressed section.
* section.c (COMPRESS_SECTION_NONE): New.
(COMPRESS_SECTION_DONE): Likewise.
(DECOMPRESS_SECTION_SIZED): Likewise.
(BFD_FAKE_SECTION): Add compress_status and compressed_size.
(bfd_malloc_and_get_section): Replace bfd_get_section_contents
with bfd_get_full_section_contents.
* bfd-in2.h: Regenerated.
* libbfd.h: Likewise.
2010-10-29 Bernd Schmidt <bernds@codesourcery.com>
Joseph Myers <joseph@codesourcery.com>
......
......@@ -697,6 +697,8 @@ DESCRIPTION
bfd *
bfd_openr_next_archived_file (bfd *archive, bfd *last_file)
{
bfd *abfd;
if ((bfd_get_format (archive) != bfd_archive)
|| (archive->direction == write_direction))
{
......@@ -704,8 +706,14 @@ bfd_openr_next_archived_file (bfd *archive, bfd *last_file)
return NULL;
}
return BFD_SEND (archive,
abfd = BFD_SEND (archive,
openr_next_archived_file, (archive, last_file));
/* Copy BFD_COMPRESS and BFD_DECOMPRESS flags. */
if (abfd)
abfd->flags |= archive->flags & (BFD_COMPRESS | BFD_DECOMPRESS);
return abfd;
}
bfd *
......
......@@ -1353,6 +1353,12 @@ typedef struct bfd_section
/* Mark flag used by some linker backends for garbage collection. */
unsigned int gc_mark : 1;
/* Section compression status. */
unsigned int compress_status : 2;
#define COMPRESS_SECTION_NONE 0
#define COMPRESS_SECTION_DONE 1
#define DECOMPRESS_SECTION_SIZED 2
/* The following flags are used by the ELF linker. */
/* Mark sections which have been allocated to segments. */
......@@ -1409,6 +1415,9 @@ typedef struct bfd_section
section size calculated on a previous linker relaxation pass. */
bfd_size_type rawsize;
/* The compressed size of the section in octets. */
bfd_size_type compressed_size;
/* Relaxation table. */
struct relax_table *relax;
......@@ -1642,17 +1651,17 @@ extern asection bfd_ind_section;
/* name, id, index, next, prev, flags, user_set_vma, */ \
{ NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
\
/* linker_mark, linker_has_input, gc_mark, segment_mark, */ \
/* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
0, 0, 1, 0, \
\
/* sec_info_type, use_rela_p, */ \
0, 0, \
/* segment_mark, sec_info_type, use_rela_p, */ \
0, 0, 0, \
\
/* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \
0, 0, 0, 0, 0, 0, \
\
/* vma, lma, size, rawsize, relax, relax_count, */ \
0, 0, 0, 0, 0, 0, \
/* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \
0, 0, 0, 0, 0, 0, 0, \
\
/* output_offset, output_section, alignment_power, */ \
0, (struct bfd_section *) &SEC, 0, \
......@@ -5062,6 +5071,16 @@ struct bfd
will be consistent from run to run. */
#define BFD_DETERMINISTIC_OUTPUT 0x4000
/* Compress sections in this BFD. */
#define BFD_COMPRESS 0x8000
/* Decompress sections in this BFD. */
#define BFD_DECOMPRESS 0x10000
/* Flags bits to be saved in bfd_preserve_save. */
#define BFD_FLAGS_SAVED \
(BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS)
/* Currently my_archive is tested before adding origin to
anything. I believe that this can become always an add of
origin, with origin set to 0 for non archive files. */
......@@ -5893,8 +5912,21 @@ bfd_byte *bfd_simple_get_relocated_section_contents
(bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
/* Extracted from compress.c. */
bfd_boolean bfd_uncompress_section_contents
(bfd_byte **buffer, bfd_size_type *size);
bfd_boolean bfd_compress_section_contents
(bfd *abfd, asection *section, bfd_byte *uncompressed_buffer,
bfd_size_type uncompressed_size);
bfd_boolean bfd_get_full_section_contents
(bfd *abfd, asection *section, bfd_byte **ptr);
bfd_boolean bfd_is_section_compressed
(bfd *abfd, asection *section);
bfd_boolean bfd_init_section_decompress_status
(bfd *abfd, asection *section);
bfd_boolean bfd_init_section_compress_status
(bfd *abfd, asection *section);
#ifdef __cplusplus
}
......
......@@ -151,6 +151,16 @@ CODE_FRAGMENT
. will be consistent from run to run. *}
.#define BFD_DETERMINISTIC_OUTPUT 0x4000
.
. {* Compress sections in this BFD. *}
.#define BFD_COMPRESS 0x8000
.
. {* Decompress sections in this BFD. *}
.#define BFD_DECOMPRESS 0x10000
.
. {* Flags bits to be saved in bfd_preserve_save. *}
.#define BFD_FLAGS_SAVED \
. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS)
.
. {* Currently my_archive is tested before adding origin to
. anything. I believe that this can become always an add of
. origin, with origin set to 0 for non archive files. *}
......@@ -1628,7 +1638,7 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
abfd->tdata.any = NULL;
abfd->arch_info = &bfd_default_arch_struct;
abfd->flags &= BFD_IN_MEMORY;
abfd->flags &= BFD_FLAGS_SAVED;
abfd->sections = NULL;
abfd->section_last = NULL;
abfd->section_count = 0;
......
This diff is collapsed.
......@@ -275,6 +275,60 @@ struct attr_abbrev
enum dwarf_form form;
};
/* Map of uncompressed DWARF debug section name to compressed one. It
is terminated by NULL uncompressed_name. */
struct dwarf_debug_section dwarf_debug_sections[] =
{
{ ".debug_abbrev", ".zdebug_abbrev" },
{ ".debug_aranges", ".zdebug_aranges" },
{ ".debug_frame", ".zdebug_frame" },
{ ".debug_info", ".zdebug_info" },
{ ".debug_line", ".zdebug_line" },
{ ".debug_loc", ".zdebug_loc" },
{ ".debug_macinfo", ".zdebug_macinfo" },
{ ".debug_pubnames", ".zdebug_pubnames" },
{ ".debug_pubtypes", ".zdebug_pubtypes" },
{ ".debug_ranges", ".zdebug_ranges" },
{ ".debug_static_func", ".zdebug_static_func" },
{ ".debug_static_vars", ".zdebug_static_vars" },
{ ".debug_str", ".zdebug_str", },
{ ".debug_types", ".zdebug_types" },
/* GNU DWARF 1 extensions */
{ ".debug_sfnames", ".zdebug_sfnames" },
{ ".debug_srcinfo", ".zebug_srcinfo" },
/* SGI/MIPS DWARF 2 extensions */
{ ".debug_funcnames", ".zdebug_funcnames" },
{ ".debug_typenames", ".zdebug_typenames" },
{ ".debug_varnames", ".zdebug_varnames" },
{ ".debug_weaknames", ".zdebug_weaknames" },
{ NULL, NULL },
};
enum dwarf_debug_section_enum
{
debug_abbrev = 0,
debug_aranges,
debug_frame,
debug_info,
debug_line,
debug_loc,
debug_macinfo,
debug_pubnames,
debug_pubtypes,
debug_ranges,
debug_static_func,
debug_static_vars,
debug_str,
debug_types,
debug_sfnames,
debug_srcinfo,
debug_funcnames,
debug_typenames,
debug_varnames,
debug_weaknames
};
#ifndef ABBREV_HASH_SIZE
#define ABBREV_HASH_SIZE 121
#endif
......@@ -413,24 +467,23 @@ lookup_info_hash_table (struct info_hash_table *hash_table, const char *key)
static bfd_boolean
read_section (bfd * abfd,
const char * section_name,
const char * compressed_section_name,
enum dwarf_debug_section_enum sec,
asymbol ** syms,
bfd_uint64_t offset,
bfd_byte ** section_buffer,
bfd_size_type * section_size)
{
asection *msec;
bfd_boolean section_is_compressed = FALSE;
const char *section_name = dwarf_debug_sections[sec].uncompressed_name;
/* read_section is a noop if the section has already been read. */
if (!*section_buffer)
{
msec = bfd_get_section_by_name (abfd, section_name);
if (! msec && compressed_section_name)
if (! msec)
{
msec = bfd_get_section_by_name (abfd, compressed_section_name);
section_is_compressed = TRUE;
section_name = dwarf_debug_sections[sec].compressed_name;
msec = bfd_get_section_by_name (abfd, section_name);
}
if (! msec)
{
......@@ -456,16 +509,6 @@ read_section (bfd * abfd,
0, *section_size))
return FALSE;
}
if (section_is_compressed)
{
if (! bfd_uncompress_section_contents (section_buffer, section_size))
{
(*_bfd_error_handler) (_("Dwarf Error: unable to decompress %s section."), compressed_section_name);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
}
}
/* It is possible to get a bad value for the offset into the section
......@@ -561,8 +604,7 @@ read_indirect_string (struct comp_unit * unit,
*bytes_read_ptr = unit->offset_size;
if (! read_section (unit->abfd, ".debug_str", ".zdebug_str",
stash->syms, offset,
if (! read_section (unit->abfd, debug_str, stash->syms, offset,
&stash->dwarf_str_buffer, &stash->dwarf_str_size))
return NULL;
......@@ -644,8 +686,7 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
unsigned int abbrev_form, hash_number;
bfd_size_type amt;
if (! read_section (abfd, ".debug_abbrev", ".zdebug_abbrev",
stash->syms, offset,
if (! read_section (abfd, debug_abbrev, stash->syms, offset,
&stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size))
return NULL;
......@@ -1353,8 +1394,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
unsigned char op_code, extended_op, adj_opcode;
bfd_size_type amt;
if (! read_section (abfd, ".debug_line", ".zdebug_line",
stash->syms, unit->line_offset,
if (! read_section (abfd, debug_line, stash->syms, unit->line_offset,
&stash->dwarf_line_buffer, &stash->dwarf_line_size))
return NULL;
......@@ -1769,8 +1809,7 @@ static bfd_boolean
read_debug_ranges (struct comp_unit *unit)
{
struct dwarf2_debug *stash = unit->stash;
return read_section (unit->abfd, ".debug_ranges", ".zdebug_ranges",
stash->syms, 0,
return read_section (unit->abfd, debug_ranges, stash->syms, 0,
&stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size);
}
......@@ -3192,86 +3231,37 @@ find_line (bfd *abfd,
{
/* Case 1: only one info section. */
total_size = msec->size;
if (! read_section (debug_bfd, ".debug_info", ".zdebug_info",
symbols, 0,
if (! read_section (debug_bfd, debug_info, symbols, 0,
&stash->info_ptr_memory, &total_size))
goto done;
}
else
{
int all_uncompressed = 1;
/* Case 2: multiple sections. */
for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec))
{
total_size += msec->size;
if (strcmp (msec->name, DWARF2_COMPRESSED_DEBUG_INFO) == 0)
all_uncompressed = 0;
}
if (all_uncompressed)
{
/* Case 2: multiple sections, but none is compressed. */
stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
if (stash->info_ptr_memory == NULL)
goto done;
total_size = 0;
for (msec = find_debug_info (debug_bfd, NULL);
msec;
msec = find_debug_info (debug_bfd, msec))
{
bfd_size_type size;
size = msec->size;
if (size == 0)
continue;
total_size += msec->size;
if (!(bfd_simple_get_relocated_section_contents
(debug_bfd, msec, stash->info_ptr_memory + total_size,
symbols)))
goto done;
stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
if (stash->info_ptr_memory == NULL)
goto done;
total_size += size;
}
}
else
total_size = 0;
for (msec = find_debug_info (debug_bfd, NULL);
msec;
msec = find_debug_info (debug_bfd, msec))
{
/* Case 3: multiple sections, some or all compressed. */
stash->info_ptr_memory = NULL;
total_size = 0;
for (msec = find_debug_info (debug_bfd, NULL);
msec;
msec = find_debug_info (debug_bfd, msec))
{
bfd_size_type size = msec->size;
bfd_byte *buffer, *tmp;
bfd_size_type size;
if (size == 0)
continue;
size = msec->size;
if (size == 0)
continue;
buffer = (bfd_simple_get_relocated_section_contents
(debug_bfd, msec, NULL, symbols));
if (! buffer)
goto done;
if (!(bfd_simple_get_relocated_section_contents
(debug_bfd, msec, stash->info_ptr_memory + total_size,
symbols)))
goto done;
if (strcmp (msec->name, DWARF2_COMPRESSED_DEBUG_INFO) == 0)
{
if (! bfd_uncompress_section_contents (&buffer, &size))
{
free (buffer);
goto done;
}
}
tmp = (bfd_byte *) bfd_realloc (stash->info_ptr_memory,
total_size + size);
if (tmp == NULL)
{
free (buffer);
goto done;
}
stash->info_ptr_memory = tmp;
memcpy (stash->info_ptr_memory + total_size, buffer, size);
free (buffer);
total_size += size;
}
total_size += size;
}
}
......
......@@ -55,14 +55,14 @@ static asection bfd_debug_section =
{
/* name, id, index, next, prev, flags, user_set_vma, */
"*DEBUG*", 0, 0, NULL, NULL, 0, 0,
/* linker_mark, linker_has_input, gc_mark, segment_mark, */
/* linker_mark, linker_has_input, gc_mark, compress_status, */
0, 0, 1, 0,
/* sec_info_type, use_rela_p, */
0, 0,
/* segment_mark, sec_info_type, use_rela_p, */
0, 0, 0,
/* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */
0, 0, 0, 0, 0, 0,
/* vma, lma, size, rawsize, relax, relax_count, */
0, 0, 0, 0, 0, 0,
/* vma, lma, size, rawsize, compressed_size, relax, relax_count, */
0, 0, 0, 0, 0, 0, 0,
/* output_offset, output_section, alignment_power, */
0, NULL, 0,
/* relocation, orelocation, reloc_count, filepos, rel_filepos, */
......
......@@ -1009,6 +1009,52 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
}
}
/* Compress/decompress DWARF debug sections with names: .debug_* and
.zdebug_*, after the section flags is set. */
if ((flags & SEC_DEBUGGING)
&& ((name[1] == 'd' && name[6] == '_')
|| (name[1] == 'z' && name[7] == '_')))
{
enum { nothing, compress, decompress } action = nothing;
if (bfd_is_section_compressed (abfd, newsect))
{
/* Compressed section. Check if we should decompress. */
if ((abfd->flags & BFD_DECOMPRESS))
action = decompress;
}
else
{
/* Normal section. Check if we should compress. */
if ((abfd->flags & BFD_COMPRESS))
action = compress;
}
switch (action)
{
case nothing:
break;
case compress:
if (!bfd_init_section_compress_status (abfd, newsect))
{
(*_bfd_error_handler)
(_("%B: unable to initialize commpress status for section %s"),
abfd, name);
return FALSE;
}
break;
case decompress:
if (!bfd_init_section_decompress_status (abfd, newsect))
{
(*_bfd_error_handler)
(_("%B: unable to initialize decommpress status for section %s"),
abfd, name);
return FALSE;
}
break;
}
}
return TRUE;
}
......
......@@ -9354,10 +9354,8 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
contents = elf_section_data (o)->this_hdr.contents;
else
{
bfd_size_type amt = o->rawsize ? o->rawsize : o->size;
contents = finfo->contents;
if (! bfd_get_section_contents (input_bfd, o, contents, 0, amt))
if (! bfd_get_full_section_contents (input_bfd, o, &contents))
return FALSE;
}
......
......@@ -785,7 +785,7 @@ const bfd_target TARGET_BIG_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
| DYNAMIC | WP_TEXT | D_PAGED),
| DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
......@@ -881,7 +881,7 @@ const bfd_target TARGET_LITTLE_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
| DYNAMIC | WP_TEXT | D_PAGED),
| DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
......
......@@ -808,3 +808,13 @@ extern void bfd_section_already_linked_table_traverse
extern bfd_vma read_unsigned_leb128 (bfd *, bfd_byte *, unsigned int *);
extern bfd_signed_vma read_signed_leb128 (bfd *, bfd_byte *, unsigned int *);
struct dwarf_debug_section
{
const char *uncompressed_name;
const char *compressed_name;
};
/* Map of uncompressed DWARF debug section name to compressed one. It
is terminated by NULL uncompressed_name. */
extern struct dwarf_debug_section dwarf_debug_sections[];
......@@ -857,6 +857,15 @@ _bfd_generic_get_section_contents (bfd *abfd,
if (count == 0)
return TRUE;
if (section->compress_status != COMPRESS_SECTION_NONE)
{
(*_bfd_error_handler)
(_("%B: unable to get decompressed section %A"),
abfd, section);
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
}
sz = section->rawsize ? section->rawsize : section->size;
if (offset + count < count
|| offset + count > sz)
......
......@@ -813,6 +813,16 @@ extern void bfd_section_already_linked_table_traverse
extern bfd_vma read_unsigned_leb128 (bfd *, bfd_byte *, unsigned int *);
extern bfd_signed_vma read_signed_leb128 (bfd *, bfd_byte *, unsigned int *);
struct dwarf_debug_section
{
const char *uncompressed_name;
const char *compressed_name;
};
/* Map of uncompressed DWARF debug section name to compressed one. It
is terminated by NULL uncompressed_name. */
extern struct dwarf_debug_section dwarf_debug_sections[];
/* Extracted from init.c. */
/* Extracted from libbfd.c. */
bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
......
......@@ -348,6 +348,7 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
struct sec_merge_sec_info *secinfo;
unsigned int align;
bfd_size_type amt;
bfd_byte *contents;
if ((abfd->flags & DYNAMIC) != 0
|| (sec->flags & SEC_MERGE) == 0)
......@@ -432,8 +433,8 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
sec->rawsize = sec->size;
if (sec->flags & SEC_STRINGS)
memset (secinfo->contents + sec->size, 0, sec->entsize);
if (! bfd_get_section_contents (sec->owner, sec, secinfo->contents,
0, sec->size))
contents = secinfo->contents;
if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
goto error_return;
return TRUE;
......
......@@ -5721,15 +5721,13 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
long reloc_size;
arelent **reloc_vector;
long reloc_count;
bfd_size_type sz;
reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
if (reloc_size < 0)
return NULL;
/* Read in the section. */
sz = input_section->rawsize ? input_section->rawsize : input_section->size;
if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
return NULL;
if (reloc_size == 0)
......
......@@ -364,6 +364,12 @@ CODE_FRAGMENT
. {* Mark flag used by some linker backends for garbage collection. *}
. unsigned int gc_mark : 1;
.
. {* Section compression status. *}
. unsigned int compress_status : 2;
.#define COMPRESS_SECTION_NONE 0
.#define COMPRESS_SECTION_DONE 1
.#define DECOMPRESS_SECTION_SIZED 2
.
. {* The following flags are used by the ELF linker. *}
.
. {* Mark sections which have been allocated to segments. *}
......@@ -420,6 +426,9 @@ CODE_FRAGMENT
. section size calculated on a previous linker relaxation pass. *}
. bfd_size_type rawsize;
.
. {* The compressed size of the section in octets. *}
. bfd_size_type compressed_size;
.
. {* Relaxation table. *}
. struct relax_table *relax;
.
......@@ -653,17 +662,17 @@ CODE_FRAGMENT
. {* name, id, index, next, prev, flags, user_set_vma, *} \
. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
. \
. {* linker_mark, linker_has_input, gc_mark, segment_mark, *} \
. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \
. 0, 0, 1, 0, \
. \
. {* sec_info_type, use_rela_p, *} \
. 0, 0, \
. {* segment_mark, sec_info_type, use_rela_p, *} \
. 0, 0, 0, \
. \
. {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \
. 0, 0, 0, 0, 0, 0, \
. \
. {* vma, lma, size, rawsize, relax, relax_count, *} \
. 0, 0, 0, 0, 0, 0, \
. {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \
. 0, 0, 0, 0, 0, 0, 0, \
. \
. {* output_offset, output_section, alignment_power, *} \
. 0, (struct bfd_section *) &SEC, 0, \
......@@ -1480,20 +1489,8 @@ DESCRIPTION
bfd_boolean
bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf)
{
bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
bfd_byte *p = NULL;
*buf = p;
if (sz == 0)
return TRUE;
p = (bfd_byte *)
bfd_malloc (sec->rawsize > sec->size ? sec->rawsize : sec->size);
if (p == NULL)
return FALSE;
*buf = p;
return bfd_get_section_contents (abfd, sec, p, 0, sz);
*buf = NULL;
return bfd_get_full_section_contents (abfd, sec, buf);
}
/*
FUNCTION
......