aboutsummaryrefslogtreecommitdiff
path: root/gold/reloc.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2010-07-12 17:59:58 +0000
committerCary Coutant <ccoutant@google.com>2010-07-12 17:59:58 +0000
commita2e4736229d6ce6f804ed26ea8d763c538de9d2c (patch)
tree25de3c95f1bf545500aa9adf3278422f477ace18 /gold/reloc.cc
parentadd265ae415ecd40208537d1f84155f868668ef5 (diff)
downloadgdb-a2e4736229d6ce6f804ed26ea8d763c538de9d2c.zip
gdb-a2e4736229d6ce6f804ed26ea8d763c538de9d2c.tar.gz
gdb-a2e4736229d6ce6f804ed26ea8d763c538de9d2c.tar.bz2
* compressed_output.cc (zlib_decompress): New function.
(get_uncompressed_size): New function. (decompress_input_section): New function. * compressed_output.h (get_uncompressed_size): New function. (decompress_input_section): New function. * dwarf_reader.cc (Sized_dwarf_line_info::Sized_dwarf_line_info) Handle compressed debug sections. * layout.cc (is_compressed_debug_section): New function. (Layout::output_section_name): Map compressed section names to canonical names. * layout.h (is_compressed_debug_section): New function. (is_debug_info_section): Recognize compressed debug sections. * merge.cc: Include compressed_output.h. (Output_merge_data::do_add_input_section): Handle compressed debug sections. (Output_merge_string::do_add_input_section): Handle compressed debug sections. * object.cc: Include compressed_output.h. (Sized_relobj::Sized_relobj): Initialize new data members. (build_compressed_section_map): New function. (Sized_relobj::do_read_symbols): Handle compressed debug sections. * object.h (Object::section_is_compressed): New method. (Object::do_section_is_compressed): New method. (Sized_relobj::Compressed_section_map): New type. (Sized_relobj::do_section_is_compressed): New method. (Sized_relobj::compressed_sections_): New data member. * output.cc (Output_section::add_input_section): Handle compressed debug sections. * reloc.cc: Include compressed_output.h. (Sized_relobj::write_sections): Handle compressed debug sections.
Diffstat (limited to 'gold/reloc.cc')
-rw-r--r--gold/reloc.cc33
1 files changed, 27 insertions, 6 deletions
diff --git a/gold/reloc.cc b/gold/reloc.cc
index 8879f0a..9f7355e 100644
--- a/gold/reloc.cc
+++ b/gold/reloc.cc
@@ -32,6 +32,7 @@
#include "target-reloc.h"
#include "reloc.h"
#include "icf.h"
+#include "compressed_output.h"
namespace gold
{
@@ -732,10 +733,17 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
off_t view_start;
section_size_type view_size;
+ bool must_decompress = false;
if (output_offset != invalid_address)
{
view_start = output_section_offset + output_offset;
view_size = convert_to_section_size_type(shdr.get_sh_size());
+ section_size_type uncompressed_size;
+ if (this->section_is_compressed(i, &uncompressed_size))
+ {
+ view_size = uncompressed_size;
+ must_decompress = true;
+ }
}
else
{
@@ -754,7 +762,7 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
{
unsigned char* buffer = os->postprocessing_buffer();
view = buffer + view_start;
- if (output_offset != invalid_address)
+ if (output_offset != invalid_address && !must_decompress)
{
off_t sh_offset = shdr.get_sh_offset();
if (!rm.empty() && rm.back().file_offset > sh_offset)
@@ -770,14 +778,27 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
else
{
view = of->get_output_view(view_start, view_size);
- off_t sh_offset = shdr.get_sh_offset();
- if (!rm.empty() && rm.back().file_offset > sh_offset)
- is_sorted = false;
- rm.push_back(File_read::Read_multiple_entry(sh_offset,
- view_size, view));
+ if (!must_decompress)
+ {
+ off_t sh_offset = shdr.get_sh_offset();
+ if (!rm.empty() && rm.back().file_offset > sh_offset)
+ is_sorted = false;
+ rm.push_back(File_read::Read_multiple_entry(sh_offset,
+ view_size, view));
+ }
}
}
+ if (must_decompress)
+ {
+ // Read and decompress the section.
+ section_size_type len;
+ const unsigned char* p = this->section_contents(i, &len, false);
+ if (!decompress_input_section(p, len, view, view_size))
+ this->error(_("could not decompress section %s"),
+ this->section_name(i).c_str());
+ }
+
pvs->view = view;
pvs->address = os->address();
if (output_offset != invalid_address)