Line 657... |
Line 657... |
|
|
// Make two passes over the sections. The first one copies the
|
// Make two passes over the sections. The first one copies the
|
// section data to the output file. The second one applies
|
// section data to the output file. The second one applies
|
// relocations.
|
// relocations.
|
|
|
this->write_sections(pshdrs, of, &views);
|
this->write_sections(layout, pshdrs, of, &views);
|
|
|
// To speed up relocations, we set up hash tables for fast lookup of
|
// To speed up relocations, we set up hash tables for fast lookup of
|
// input offsets to output addresses.
|
// input offsets to output addresses.
|
this->initialize_input_to_output_maps();
|
this->initialize_input_to_output_maps();
|
|
|
Line 676... |
Line 676... |
// Write out the accumulated views.
|
// Write out the accumulated views.
|
for (unsigned int i = 1; i < shnum; ++i)
|
for (unsigned int i = 1; i < shnum; ++i)
|
{
|
{
|
if (views[i].view != NULL)
|
if (views[i].view != NULL)
|
{
|
{
|
|
if (views[i].is_ctors_reverse_view)
|
|
this->reverse_words(views[i].view, views[i].view_size);
|
if (!views[i].is_postprocessing_view)
|
if (!views[i].is_postprocessing_view)
|
{
|
{
|
if (views[i].is_input_output_view)
|
if (views[i].is_input_output_view)
|
of->write_input_output_view(views[i].offset,
|
of->write_input_output_view(views[i].offset,
|
views[i].view_size,
|
views[i].view_size,
|
Line 710... |
Line 712... |
// section headers. Record the views in *PVIEWS for use when
|
// section headers. Record the views in *PVIEWS for use when
|
// relocating.
|
// relocating.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
Sized_relobj_file<size, big_endian>::write_sections(const Layout* layout,
|
|
const unsigned char* pshdrs,
|
Output_file* of,
|
Output_file* of,
|
Views* pviews)
|
Views* pviews)
|
{
|
{
|
unsigned int shnum = this->shnum();
|
unsigned int shnum = this->shnum();
|
const Output_sections& out_sections(this->output_sections());
|
const Output_sections& out_sections(this->output_sections());
|
Line 759... |
Line 762... |
pvs->view_size = posd->data_size();
|
pvs->view_size = posd->data_size();
|
pvs->view = of->get_output_view(pvs->offset, pvs->view_size);
|
pvs->view = of->get_output_view(pvs->offset, pvs->view_size);
|
pvs->address = posd->address();
|
pvs->address = posd->address();
|
pvs->is_input_output_view = false;
|
pvs->is_input_output_view = false;
|
pvs->is_postprocessing_view = false;
|
pvs->is_postprocessing_view = false;
|
|
pvs->is_ctors_reverse_view = false;
|
|
|
continue;
|
continue;
|
}
|
}
|
|
|
// In the normal case, this input section is simply mapped to
|
// In the normal case, this input section is simply mapped to
|
Line 873... |
Line 877... |
pvs->address += output_offset;
|
pvs->address += output_offset;
|
pvs->offset = view_start;
|
pvs->offset = view_start;
|
pvs->view_size = view_size;
|
pvs->view_size = view_size;
|
pvs->is_input_output_view = output_offset == invalid_address;
|
pvs->is_input_output_view = output_offset == invalid_address;
|
pvs->is_postprocessing_view = os->requires_postprocessing();
|
pvs->is_postprocessing_view = os->requires_postprocessing();
|
|
pvs->is_ctors_reverse_view =
|
|
(!parameters->options().relocatable()
|
|
&& view_size > size / 8
|
|
&& (strcmp(os->name(), ".init_array") == 0
|
|
|| strcmp(os->name(), ".fini_array") == 0)
|
|
&& layout->is_ctors_in_init_array(this, i));
|
}
|
}
|
|
|
// Actually read the data.
|
// Actually read the data.
|
if (!rm.empty())
|
if (!rm.empty())
|
{
|
{
|
Line 1481... |
Line 1491... |
|
|
(*function_offsets)[value] = fnsize;
|
(*function_offsets)[value] = fnsize;
|
}
|
}
|
}
|
}
|
|
|
|
// Reverse the words in a section. Used for .ctors sections mapped to
|
|
// .init_array sections. See ctors_sections_in_init_array in
|
|
// layout.cc.
|
|
|
|
template<int size, bool big_endian>
|
|
void
|
|
Sized_relobj_file<size, big_endian>::reverse_words(unsigned char* view,
|
|
section_size_type view_size)
|
|
{
|
|
typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
|
|
Valtype* vview = reinterpret_cast<Valtype*>(view);
|
|
section_size_type vview_size = view_size / (size / 8);
|
|
for (section_size_type i = 0; i < vview_size / 2; ++i)
|
|
{
|
|
Valtype tmp = vview[i];
|
|
vview[i] = vview[vview_size - 1 - i];
|
|
vview[vview_size - 1 - i] = tmp;
|
|
}
|
|
}
|
|
|
// Class Merged_symbol_value.
|
// Class Merged_symbol_value.
|
|
|
template<int size>
|
template<int size>
|
void
|
void
|
Merged_symbol_value<size>::initialize_input_to_output_map(
|
Merged_symbol_value<size>::initialize_input_to_output_map(
|