1 // compressed_output.cc -- manage compressed output sections for gold
3 // Copyright 2007 Free Software Foundation, Inc.
4 // Written by Ian Lance Taylor <iant@google.com>.
6 // This file is part of gold.
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 // MA 02110-1301, USA.
29 #include "compressed_output.h"
30 #include "parameters.h"
35 // Compress UNCOMPRESSED_DATA of size UNCOMPRESSED_SIZE. Returns true
36 // if it successfully compressed, false if it failed for any reason
37 // (including not having zlib support in the library). If it returns
38 // true, it allocates memory for the compressed data using new, and
39 // sets *COMPRESSED_DATA and *COMPRESSED_SIZE to appropriate values.
42 zlib_compress(const char* uncompressed_data
, unsigned long uncompressed_size
,
43 char** compressed_data
, unsigned long* compressed_size
)
48 *compressed_size
= uncompressed_size
+ uncompressed_size
/ 1000 + 128;
49 *compressed_data
= new char[*compressed_size
];
52 if (parameters
->optimization_level() >= 1)
57 int rc
= compress2(reinterpret_cast<Bytef
*>(*compressed_data
),
59 reinterpret_cast<const Bytef
*>(uncompressed_data
),
66 delete[] *compressed_data
;
67 *compressed_data
= NULL
;
70 #endif // #ifdef HAVE_ZLIB_H
73 // After compressing an output section, we rename it from foo to
74 // foo.zlib.nnnn, where nnnn is the uncompressed size of the section.
77 zlib_compressed_suffix(unsigned long uncompressed_size
)
80 snprintf(size_string
, sizeof(size_string
), "%lu", uncompressed_size
);
81 return std::string(".zlib.") + size_string
;
84 // Class Output_compressed_section_data.
86 // Add an input section. In this case, we just keep track of the sections.
89 Output_compressed_section_data::do_add_input_section(Relobj
* obj
,
92 this->objects_
.push_back(Object_entry(obj
, shndx
));
96 // Set the final data size of a compressed section. This is where
97 // we actually compress the section data.
100 Output_compressed_section_data::set_final_data_size()
102 // FIXME: assert that relocations have already been applied.
104 off_t uncompressed_size
= 0;
105 for (std::vector
<Object_entry
>::iterator it
= this->objects_
.begin();
106 it
!= this->objects_
.end();
110 = it
->object
->section_contents(it
->shndx
, &it
->length
, false);
111 uncompressed_size
+= it
->length
;
114 // (Try to) compress the data.
115 unsigned long compressed_size
;
116 char* uncompressed_data
= new char[uncompressed_size
];
118 for (std::vector
<Object_entry
>::const_iterator it
= this->objects_
.begin();
119 it
!= this->objects_
.end();
122 memcpy(uncompressed_data
+ pos
,
123 reinterpret_cast<const char*>(it
->contents
),
128 bool success
= false;
129 if (options_
.zlib_compress_debug_sections())
130 success
= zlib_compress(uncompressed_data
, uncompressed_size
,
131 &this->data_
, &compressed_size
);
134 delete[] uncompressed_data
;
135 this->set_data_size(compressed_size
);
136 this->new_section_name_
= zlib_compressed_suffix(uncompressed_size
);
140 gold_warning(_("Not compressing section data: zlib error"));
141 gold_assert(this->data_
== NULL
);
142 this->data_
= uncompressed_data
;
143 this->set_data_size(uncompressed_size
);
147 // Change the name of the output section to reflect it's compressed.
148 // The layout routines call into this right before finalizing the
152 Output_compressed_section_data::do_modified_output_section_name(
155 // This mean we never compressed the data.
156 if (this->new_section_name_
.empty())
158 this->new_section_name_
= std::string(name
) + this->new_section_name_
;
159 return this->new_section_name_
.c_str();
162 // Write out a compressed section. If we couldn't compress, we just
163 // write it out as normal, uncompressed data.
166 Output_compressed_section_data::do_write(Output_file
* of
)
168 unsigned char* uview
= of
->get_output_view(this->offset(),
170 char* view
= reinterpret_cast<char*>(uview
);
171 memcpy(view
, this->data_
, this->data_size());
172 of
->write_output_view(this->offset(), this->data_size(), uview
);
175 // Class Output_compressed_string.
177 // Add an input section. We don't do anything special here.
179 template<typename Char_type
>
181 Output_compressed_string
<Char_type
>::do_add_input_section(Relobj
* object
,
184 return Output_merge_string
<Char_type
>::do_add_input_section(object
, shndx
);
187 // Set the final data size of a compressed section. This is where
188 // we actually compress the section data.
190 template<typename Char_type
>
192 Output_compressed_string
<Char_type
>::set_final_data_size()
194 // First let the superclass finalize all its data, then write it to
196 unsigned long uncompressed_size
= this->finalize_merged_data();
197 char* uncompressed_data
= new char[uncompressed_size
];
198 this->stringpool_to_buffer(uncompressed_data
, uncompressed_size
);
200 // (Try to) compress the data.
201 unsigned long compressed_size
;
202 if (options_
.zlib_compress_debug_sections()
203 && zlib_compress(uncompressed_data
, uncompressed_size
,
204 &this->compressed_data_
, &compressed_size
))
206 this->set_data_size(compressed_size
);
208 this->clear_stringpool();
209 // We will be renaming the section to name.zlib.uncompressed_size.
210 this->new_section_name_
= zlib_compressed_suffix(uncompressed_size
);
214 this->compressed_data_
= NULL
;
215 this->set_data_size(uncompressed_size
);
218 delete[] uncompressed_data
;
221 // Change the name of the output section to reflect it's compressed.
222 // The layout routines call into this right before finalizing the
225 template<typename Char_type
>
227 Output_compressed_string
<Char_type
>::do_modified_output_section_name(
230 // This mean we never compressed the data
231 if (this->new_section_name_
.empty())
233 this->new_section_name_
= std::string(name
) + this->new_section_name_
;
234 return this->new_section_name_
.c_str();
237 // Write out a compressed string section. If we couldn't compress,
238 // we just write out the normal string section.
240 template<typename Char_type
>
242 Output_compressed_string
<Char_type
>::do_write(Output_file
* of
)
244 if (this->compressed_data_
== NULL
)
245 Output_merge_string
<Char_type
>::do_write(of
);
248 unsigned char* uview
= of
->get_output_view(this->offset(),
250 char* view
= reinterpret_cast<char*>(uview
);
251 memcpy(view
, this->compressed_data_
, this->data_size());
252 of
->write_output_view(this->offset(), this->data_size(), uview
);
256 // Instantiate the templates we need.
259 class Output_compressed_string
<char>;
262 class Output_compressed_string
<uint16_t>;
265 class Output_compressed_string
<uint32_t>;
267 } // End namespace gold.
This page took 0.037191 seconds and 5 git commands to generate.