aboutsummaryrefslogtreecommitdiff
path: root/gold/merge.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/merge.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/merge.cc')
-rw-r--r--gold/merge.cc43
1 files changed, 41 insertions, 2 deletions
diff --git a/gold/merge.cc b/gold/merge.cc
index 6e44ddd..ec11c90 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -1,6 +1,6 @@
// merge.cc -- handle section merging for gold
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -26,6 +26,7 @@
#include <algorithm>
#include "merge.h"
+#include "compressed_output.h"
namespace gold
{
@@ -404,12 +405,29 @@ bool
Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx)
{
section_size_type len;
+ section_size_type uncompressed_size = 0;
+ unsigned char* uncompressed_data = NULL;
const unsigned char* p = object->section_contents(shndx, &len, false);
+ if (object->section_is_compressed(shndx, &uncompressed_size))
+ {
+ uncompressed_data = new unsigned char[uncompressed_size];
+ if (!decompress_input_section(p, len, uncompressed_data,
+ uncompressed_size))
+ object->error(_("could not decompress section %s"),
+ object->section_name(shndx).c_str());
+ p = uncompressed_data;
+ len = uncompressed_size;
+ }
+
section_size_type entsize = convert_to_section_size_type(this->entsize());
if (len % entsize != 0)
- return false;
+ {
+ if (uncompressed_data != NULL)
+ delete[] uncompressed_data;
+ return false;
+ }
this->input_count_ += len / entsize;
@@ -438,6 +456,9 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx)
if (this->keeps_input_sections())
record_input_section(object, shndx);
+ if (uncompressed_data != NULL)
+ delete[] uncompressed_data;
+
return true;
}
@@ -495,8 +516,21 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
unsigned int shndx)
{
section_size_type len;
+ section_size_type uncompressed_size = 0;
+ unsigned char* uncompressed_data = NULL;
const unsigned char* pdata = object->section_contents(shndx, &len, false);
+ if (object->section_is_compressed(shndx, &uncompressed_size))
+ {
+ uncompressed_data = new unsigned char[uncompressed_size];
+ if (!decompress_input_section(pdata, len, uncompressed_data,
+ uncompressed_size))
+ object->error(_("could not decompress section %s"),
+ object->section_name(shndx).c_str());
+ pdata = uncompressed_data;
+ len = uncompressed_size;
+ }
+
const Char_type* p = reinterpret_cast<const Char_type*>(pdata);
const Char_type* pend = p + len / sizeof(Char_type);
@@ -504,6 +538,8 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
{
object->error(_("mergeable string section length not multiple of "
"character size"));
+ if (uncompressed_data != NULL)
+ delete[] uncompressed_data;
return false;
}
@@ -545,6 +581,9 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
if (this->keeps_input_sections())
record_input_section(object, shndx);
+ if (uncompressed_data != NULL)
+ delete[] uncompressed_data;
+
return true;
}