mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-01 09:49:43 +08:00
* gold.h (is_wildcard_string): New function.
* layout.cc (Layout::layout): Pass this pointer to add_input_section. (Layout::layout_eh_frame): Ditto. (Layout::find_section_order_index): New method. (Layout::read_layout_from_file): New method. * layout.h (Layout::find_section_order_index): New method. (Layout::read_layout_from_file): New method. (Layout::input_section_position_): New private member. (Layout::input_section_glob_): New private member. * main.cc (main): Call read_layout_from_file here. * options.h (--section-ordering-file): New option. * output.cc (Output_section::input_section_order_specified_): New member. (Output_section::Output_section): Initialize new member. (Output_section::add_input_section): Add new parameter. Keep input sections when --section-ordering-file is used. (Output_section::set_final_data_size): Sort input sections when section ordering file is specified. (Output_section::Input_section_sort_entry): Add new parameter. Check sorting type. (Output_section::Input_section_sort_entry::compare_section_ordering): New method. (Output_section::Input_section_sort_compare::operator()): Change to consider section_order_index. (Output_section::Input_section_sort_init_fini_compare::operator()): Change to consider section_order_index. (Output_section::Input_section_sort_section_order_index_compare ::operator()): New method. (Output_section::sort_attached_input_sections): Change to sort according to section order when specified. (Output_section::add_input_section<32, true>): Add new parameter. (Output_section::add_input_section<64, true>): Add new parameter. (Output_section::add_input_section<32, false>): Add new parameter. (Output_section::add_input_section<64, false>): Add new parameter. * output.h (Output_section::add_input_section): Add new parameter. (Output_section::input_section_order_specified): New method. (Output_section::set_input_section_order_specified): New method. (Input_section::Input_section): Initialize section_order_index_. (Input_section::section_order_index): New method. (Input_section::set_section_order_index): New method. (Input_section::section_order_index_): New member. (Input_section::Input_section_sort_section_order_index_compare): New struct. (Output_section::input_section_order_specified_): New member. * script-sections.cc (is_wildcard_string): Delete and move modified method to gold.h. (Output_section_element_input::Output_section_element_input): Modify call to is_wildcard_string. (Output_section_element_input::Input_section_pattern ::Input_section_pattern): Ditto. (Output_section_element_input::Output_section_element_input): Ditto. * testsuite/Makefile.am (final_layout): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/final_layout.cc: New file. * testsuite/final_layout.sh: New file.
This commit is contained in:
@ -1,3 +1,62 @@
|
|||||||
|
2010-06-01 Sriraman Tallam <tmsriram@google.com>
|
||||||
|
|
||||||
|
* gold.h (is_wildcard_string): New function.
|
||||||
|
* layout.cc (Layout::layout): Pass this pointer to add_input_section.
|
||||||
|
(Layout::layout_eh_frame): Ditto.
|
||||||
|
(Layout::find_section_order_index): New method.
|
||||||
|
(Layout::read_layout_from_file): New method.
|
||||||
|
* layout.h (Layout::find_section_order_index): New method.
|
||||||
|
(Layout::read_layout_from_file): New method.
|
||||||
|
(Layout::input_section_position_): New private member.
|
||||||
|
(Layout::input_section_glob_): New private member.
|
||||||
|
* main.cc (main): Call read_layout_from_file here.
|
||||||
|
* options.h (--section-ordering-file): New option.
|
||||||
|
* output.cc (Output_section::input_section_order_specified_): New
|
||||||
|
member.
|
||||||
|
(Output_section::Output_section): Initialize new member.
|
||||||
|
(Output_section::add_input_section): Add new parameter.
|
||||||
|
Keep input sections when --section-ordering-file is used.
|
||||||
|
(Output_section::set_final_data_size): Sort input sections when
|
||||||
|
section ordering file is specified.
|
||||||
|
(Output_section::Input_section_sort_entry): Add new parameter.
|
||||||
|
Check sorting type.
|
||||||
|
(Output_section::Input_section_sort_entry::compare_section_ordering):
|
||||||
|
New method.
|
||||||
|
(Output_section::Input_section_sort_compare::operator()): Change to
|
||||||
|
consider section_order_index.
|
||||||
|
(Output_section::Input_section_sort_init_fini_compare::operator()):
|
||||||
|
Change to consider section_order_index.
|
||||||
|
(Output_section::Input_section_sort_section_order_index_compare
|
||||||
|
::operator()): New method.
|
||||||
|
(Output_section::sort_attached_input_sections): Change to sort
|
||||||
|
according to section order when specified.
|
||||||
|
(Output_section::add_input_section<32, true>): Add new parameter.
|
||||||
|
(Output_section::add_input_section<64, true>): Add new parameter.
|
||||||
|
(Output_section::add_input_section<32, false>): Add new parameter.
|
||||||
|
(Output_section::add_input_section<64, false>): Add new parameter.
|
||||||
|
* output.h (Output_section::add_input_section): Add new parameter.
|
||||||
|
(Output_section::input_section_order_specified): New
|
||||||
|
method.
|
||||||
|
(Output_section::set_input_section_order_specified): New method.
|
||||||
|
(Input_section::Input_section): Initialize section_order_index_.
|
||||||
|
(Input_section::section_order_index): New method.
|
||||||
|
(Input_section::set_section_order_index): New method.
|
||||||
|
(Input_section::section_order_index_): New member.
|
||||||
|
(Input_section::Input_section_sort_section_order_index_compare): New
|
||||||
|
struct.
|
||||||
|
(Output_section::input_section_order_specified_): New member.
|
||||||
|
* script-sections.cc (is_wildcard_string): Delete and move modified
|
||||||
|
method to gold.h.
|
||||||
|
(Output_section_element_input::Output_section_element_input): Modify
|
||||||
|
call to is_wildcard_string.
|
||||||
|
(Output_section_element_input::Input_section_pattern
|
||||||
|
::Input_section_pattern): Ditto.
|
||||||
|
(Output_section_element_input::Output_section_element_input): Ditto.
|
||||||
|
* testsuite/Makefile.am (final_layout): New test case.
|
||||||
|
* testsuite/Makefile.in: Regenerate.
|
||||||
|
* testsuite/final_layout.cc: New file.
|
||||||
|
* testsuite/final_layout.sh: New file.
|
||||||
|
|
||||||
2010-06-01 Rafael Espindola <espindola@google.com>
|
2010-06-01 Rafael Espindola <espindola@google.com>
|
||||||
|
|
||||||
* plugin.cc (Plugin::load): Pass the output name to the plugin.
|
* plugin.cc (Plugin::load): Pass the output name to the plugin.
|
||||||
|
@ -401,6 +401,15 @@ string_hash(const Char_type* s)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return whether STRING contains a wildcard character. This is used
|
||||||
|
// to speed up matching.
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
is_wildcard_string(const char* s)
|
||||||
|
{
|
||||||
|
return strpbrk(s, "?*[") != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
} // End namespace gold.
|
} // End namespace gold.
|
||||||
|
|
||||||
#endif // !defined(GOLD_GOLD_H)
|
#endif // !defined(GOLD_GOLD_H)
|
||||||
|
@ -26,8 +26,10 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "libiberty.h"
|
#include "libiberty.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
@ -668,7 +670,7 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
|
|||||||
|
|
||||||
// FIXME: Handle SHF_LINK_ORDER somewhere.
|
// FIXME: Handle SHF_LINK_ORDER somewhere.
|
||||||
|
|
||||||
*off = os->add_input_section(object, shndx, name, shdr, reloc_shndx,
|
*off = os->add_input_section(this, object, shndx, name, shdr, reloc_shndx,
|
||||||
this->script_options_->saw_sections_clause());
|
this->script_options_->saw_sections_clause());
|
||||||
this->have_added_input_section_ = true;
|
this->have_added_input_section_ = true;
|
||||||
|
|
||||||
@ -886,7 +888,7 @@ Layout::layout_eh_frame(Sized_relobj<size, big_endian>* object,
|
|||||||
// We couldn't handle this .eh_frame section for some reason.
|
// We couldn't handle this .eh_frame section for some reason.
|
||||||
// Add it as a normal section.
|
// Add it as a normal section.
|
||||||
bool saw_sections_clause = this->script_options_->saw_sections_clause();
|
bool saw_sections_clause = this->script_options_->saw_sections_clause();
|
||||||
*off = os->add_input_section(object, shndx, name, shdr, reloc_shndx,
|
*off = os->add_input_section(this, object, shndx, name, shdr, reloc_shndx,
|
||||||
saw_sections_clause);
|
saw_sections_clause);
|
||||||
this->have_added_input_section_ = true;
|
this->have_added_input_section_ = true;
|
||||||
}
|
}
|
||||||
@ -1642,6 +1644,72 @@ Layout::relaxation_loop_body(
|
|||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search the list of patterns and find the postion of the given section
|
||||||
|
// name in the output section. If the section name matches a glob
|
||||||
|
// pattern and a non-glob name, then the non-glob position takes
|
||||||
|
// precedence. Return 0 if no match is found.
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
Layout::find_section_order_index(const std::string& section_name)
|
||||||
|
{
|
||||||
|
Unordered_map<std::string, unsigned int>::iterator map_it;
|
||||||
|
map_it = this->input_section_position_.find(section_name);
|
||||||
|
if (map_it != this->input_section_position_.end())
|
||||||
|
return map_it->second;
|
||||||
|
|
||||||
|
// Absolute match failed. Linear search the glob patterns.
|
||||||
|
std::vector<std::string>::iterator it;
|
||||||
|
for (it = this->input_section_glob_.begin();
|
||||||
|
it != this->input_section_glob_.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
if (fnmatch((*it).c_str(), section_name.c_str(), FNM_NOESCAPE) == 0)
|
||||||
|
{
|
||||||
|
map_it = this->input_section_position_.find(*it);
|
||||||
|
gold_assert(map_it != this->input_section_position_.end());
|
||||||
|
return map_it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the sequence of input sections from the file specified with
|
||||||
|
// --section-ordering-file.
|
||||||
|
|
||||||
|
void
|
||||||
|
Layout::read_layout_from_file()
|
||||||
|
{
|
||||||
|
const char* filename = parameters->options().section_ordering_file();
|
||||||
|
std::ifstream in;
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
in.open(filename);
|
||||||
|
if (!in)
|
||||||
|
gold_fatal(_("unable to open --section-ordering-file file %s: %s"),
|
||||||
|
filename, strerror(errno));
|
||||||
|
|
||||||
|
std::getline(in, line); // this chops off the trailing \n, if any
|
||||||
|
unsigned int position = 1;
|
||||||
|
|
||||||
|
while (in)
|
||||||
|
{
|
||||||
|
if (!line.empty() && line[line.length() - 1] == '\r') // Windows
|
||||||
|
line.resize(line.length() - 1);
|
||||||
|
// Ignore comments, beginning with '#'
|
||||||
|
if (line[0] == '#')
|
||||||
|
{
|
||||||
|
std::getline(in, line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this->input_section_position_[line] = position;
|
||||||
|
// Store all glob patterns in a vector.
|
||||||
|
if (is_wildcard_string(line.c_str()))
|
||||||
|
this->input_section_glob_.push_back(line);
|
||||||
|
position++;
|
||||||
|
std::getline(in, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Finalize the layout. When this is called, we have created all the
|
// Finalize the layout. When this is called, we have created all the
|
||||||
// output sections and all the output segments which are based on
|
// output sections and all the output segments which are based on
|
||||||
// input sections. We have several things to do, and we have to do
|
// input sections. We have several things to do, and we have to do
|
||||||
|
@ -308,6 +308,12 @@ class Layout
|
|||||||
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
||||||
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
find_section_order_index(const std::string&);
|
||||||
|
|
||||||
|
void
|
||||||
|
read_layout_from_file();
|
||||||
|
|
||||||
// Layout an input reloc section when doing a relocatable link. The
|
// Layout an input reloc section when doing a relocatable link. The
|
||||||
// section is RELOC_SHNDX in OBJECT, with data in SHDR.
|
// section is RELOC_SHNDX in OBJECT, with data in SHDR.
|
||||||
// DATA_SECTION is the reloc section to which it refers. RR is the
|
// DATA_SECTION is the reloc section to which it refers. RR is the
|
||||||
@ -1037,6 +1043,10 @@ class Layout
|
|||||||
Segment_states* segment_states_;
|
Segment_states* segment_states_;
|
||||||
// A relaxation debug checker. We only create one when in debugging mode.
|
// A relaxation debug checker. We only create one when in debugging mode.
|
||||||
Relaxation_debug_check* relaxation_debug_check_;
|
Relaxation_debug_check* relaxation_debug_check_;
|
||||||
|
// Hash a pattern to its position in the section ordering file.
|
||||||
|
Unordered_map<std::string, unsigned int> input_section_position_;
|
||||||
|
// Vector of glob only patterns in the section_ordering file.
|
||||||
|
std::vector<std::string> input_section_glob_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This task handles writing out data in output sections which is not
|
// This task handles writing out data in output sections which is not
|
||||||
|
@ -234,6 +234,9 @@ main(int argc, char** argv)
|
|||||||
layout.incremental_inputs()->report_inputs(command_line.inputs());
|
layout.incremental_inputs()->report_inputs(command_line.inputs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameters->options().section_ordering_file())
|
||||||
|
layout.read_layout_from_file();
|
||||||
|
|
||||||
// Get the search path from the -L options.
|
// Get the search path from the -L options.
|
||||||
Dirsearch search_path;
|
Dirsearch search_path;
|
||||||
search_path.initialize(&workqueue, &command_line.options().library_path());
|
search_path.initialize(&workqueue, &command_line.options().library_path());
|
||||||
|
@ -892,6 +892,10 @@ class General_options
|
|||||||
N_("Add DIR to link time shared library search path"),
|
N_("Add DIR to link time shared library search path"),
|
||||||
N_("DIR"));
|
N_("DIR"));
|
||||||
|
|
||||||
|
DEFINE_string(section_ordering_file, options::TWO_DASHES, '\0', NULL,
|
||||||
|
N_("Layout sections in the order specified."),
|
||||||
|
N_("FILENAME"));
|
||||||
|
|
||||||
DEFINE_special(section_start, options::TWO_DASHES, '\0',
|
DEFINE_special(section_start, options::TWO_DASHES, '\0',
|
||||||
N_("Set address of section"), N_("SECTION=ADDRESS"));
|
N_("Set address of section"), N_("SECTION=ADDRESS"));
|
||||||
|
|
||||||
|
112
gold/output.cc
112
gold/output.cc
@ -1933,6 +1933,7 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
|
|||||||
found_in_sections_clause_(false),
|
found_in_sections_clause_(false),
|
||||||
has_load_address_(false),
|
has_load_address_(false),
|
||||||
info_uses_section_index_(false),
|
info_uses_section_index_(false),
|
||||||
|
input_section_order_specified_(false),
|
||||||
may_sort_attached_input_sections_(false),
|
may_sort_attached_input_sections_(false),
|
||||||
must_sort_attached_input_sections_(false),
|
must_sort_attached_input_sections_(false),
|
||||||
attached_input_sections_are_sorted_(false),
|
attached_input_sections_are_sorted_(false),
|
||||||
@ -1994,7 +1995,8 @@ Output_section::set_entsize(uint64_t v)
|
|||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
off_t
|
off_t
|
||||||
Output_section::add_input_section(Sized_relobj<size, big_endian>* object,
|
Output_section::add_input_section(Layout* layout,
|
||||||
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
const char* secname,
|
const char* secname,
|
||||||
const elfcpp::Shdr<size, big_endian>& shdr,
|
const elfcpp::Shdr<size, big_endian>& shdr,
|
||||||
@ -2090,16 +2092,30 @@ Output_section::add_input_section(Sized_relobj<size, big_endian>* object,
|
|||||||
// We need to keep track of this section if we are already keeping
|
// We need to keep track of this section if we are already keeping
|
||||||
// track of sections, or if we are relaxing. Also, if this is a
|
// track of sections, or if we are relaxing. Also, if this is a
|
||||||
// section which requires sorting, or which may require sorting in
|
// section which requires sorting, or which may require sorting in
|
||||||
// the future, we keep track of the sections.
|
// the future, we keep track of the sections. If the
|
||||||
|
// --section-ordering-file option is used to specify the order of
|
||||||
|
// sections, we need to keep track of sections.
|
||||||
if (have_sections_script
|
if (have_sections_script
|
||||||
|| !this->input_sections_.empty()
|
|| !this->input_sections_.empty()
|
||||||
|| this->may_sort_attached_input_sections()
|
|| this->may_sort_attached_input_sections()
|
||||||
|| this->must_sort_attached_input_sections()
|
|| this->must_sort_attached_input_sections()
|
||||||
|| parameters->options().user_set_Map()
|
|| parameters->options().user_set_Map()
|
||||||
|| parameters->target().may_relax())
|
|| parameters->target().may_relax()
|
||||||
this->input_sections_.push_back(Input_section(object, shndx,
|
|| parameters->options().section_ordering_file())
|
||||||
shdr.get_sh_size(),
|
{
|
||||||
addralign));
|
Input_section isecn(object, shndx, shdr.get_sh_size(), addralign);
|
||||||
|
if (parameters->options().section_ordering_file())
|
||||||
|
{
|
||||||
|
unsigned int section_order_index =
|
||||||
|
layout->find_section_order_index(std::string(secname));
|
||||||
|
if (section_order_index != 0)
|
||||||
|
{
|
||||||
|
isecn.set_section_order_index(section_order_index);
|
||||||
|
this->set_input_section_order_specified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->input_sections_.push_back(isecn);
|
||||||
|
}
|
||||||
|
|
||||||
return aligned_offset_in_section;
|
return aligned_offset_in_section;
|
||||||
}
|
}
|
||||||
@ -2623,7 +2639,8 @@ Output_section::set_final_data_size()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->must_sort_attached_input_sections())
|
if (this->must_sort_attached_input_sections()
|
||||||
|
|| this->input_section_order_specified())
|
||||||
this->sort_attached_input_sections();
|
this->sort_attached_input_sections();
|
||||||
|
|
||||||
uint64_t address = this->address();
|
uint64_t address = this->address();
|
||||||
@ -2700,12 +2717,14 @@ class Output_section::Input_section_sort_entry
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
Input_section_sort_entry(const Input_section& input_section,
|
Input_section_sort_entry(const Input_section& input_section,
|
||||||
unsigned int index)
|
unsigned int index,
|
||||||
|
bool must_sort_attached_input_sections)
|
||||||
: input_section_(input_section), index_(index),
|
: input_section_(input_section), index_(index),
|
||||||
section_has_name_(input_section.is_input_section()
|
section_has_name_(input_section.is_input_section()
|
||||||
|| input_section.is_relaxed_input_section())
|
|| input_section.is_relaxed_input_section())
|
||||||
{
|
{
|
||||||
if (this->section_has_name_)
|
if (this->section_has_name_
|
||||||
|
&& must_sort_attached_input_sections)
|
||||||
{
|
{
|
||||||
// This is only called single-threaded from Layout::finalize,
|
// This is only called single-threaded from Layout::finalize,
|
||||||
// so it is OK to lock. Unfortunately we have no way to pass
|
// so it is OK to lock. Unfortunately we have no way to pass
|
||||||
@ -2782,6 +2801,22 @@ class Output_section::Input_section_sort_entry
|
|||||||
return memcmp(base_name + base_len - 2, ".o", 2) == 0;
|
return memcmp(base_name + base_len - 2, ".o", 2) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns 0 if sections are not comparable. Returns 1 if THIS is the
|
||||||
|
// first section in order, returns -1 for S.
|
||||||
|
int
|
||||||
|
compare_section_ordering(const Input_section_sort_entry& s) const
|
||||||
|
{
|
||||||
|
gold_assert(this->index_ != -1U);
|
||||||
|
if (this->input_section_.section_order_index() == 0
|
||||||
|
|| s.input_section().section_order_index() == 0)
|
||||||
|
return 0;
|
||||||
|
if (this->input_section_.section_order_index()
|
||||||
|
< s.input_section().section_order_index())
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The Input_section we are sorting.
|
// The Input_section we are sorting.
|
||||||
Input_section input_section_;
|
Input_section input_section_;
|
||||||
@ -2843,6 +2878,12 @@ Output_section::Input_section_sort_compare::operator()(
|
|||||||
if (!s1_has_priority && s2_has_priority)
|
if (!s1_has_priority && s2_has_priority)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Check if a section order exists for these sections through a section
|
||||||
|
// ordering file. If sequence_num is 0, an order does not exist.
|
||||||
|
int sequence_num = s1.compare_section_ordering(s2);
|
||||||
|
if (sequence_num != 0)
|
||||||
|
return sequence_num == 1;
|
||||||
|
|
||||||
// Otherwise we sort by name.
|
// Otherwise we sort by name.
|
||||||
int compare = s1.section_name().compare(s2.section_name());
|
int compare = s1.section_name().compare(s2.section_name());
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -2879,6 +2920,12 @@ Output_section::Input_section_sort_init_fini_compare::operator()(
|
|||||||
if (!s1_has_priority && s2_has_priority)
|
if (!s1_has_priority && s2_has_priority)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Check if a section order exists for these sections through a section
|
||||||
|
// ordering file. If sequence_num is 0, an order does not exist.
|
||||||
|
int sequence_num = s1.compare_section_ordering(s2);
|
||||||
|
if (sequence_num != 0)
|
||||||
|
return sequence_num == 1;
|
||||||
|
|
||||||
// Otherwise we sort by name.
|
// Otherwise we sort by name.
|
||||||
int compare = s1.section_name().compare(s2.section_name());
|
int compare = s1.section_name().compare(s2.section_name());
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -2888,6 +2935,22 @@ Output_section::Input_section_sort_init_fini_compare::operator()(
|
|||||||
return s1.index() < s2.index();
|
return s1.index() < s2.index();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if S1 should come before S2.
|
||||||
|
bool
|
||||||
|
Output_section::Input_section_sort_section_order_index_compare::operator()(
|
||||||
|
const Output_section::Input_section_sort_entry& s1,
|
||||||
|
const Output_section::Input_section_sort_entry& s2) const
|
||||||
|
{
|
||||||
|
// Check if a section order exists for these sections through a section
|
||||||
|
// ordering file. If sequence_num is 0, an order does not exist.
|
||||||
|
int sequence_num = s1.compare_section_ordering(s2);
|
||||||
|
if (sequence_num != 0)
|
||||||
|
return sequence_num == 1;
|
||||||
|
|
||||||
|
// Otherwise we keep the input order.
|
||||||
|
return s1.index() < s2.index();
|
||||||
|
}
|
||||||
|
|
||||||
// Sort the input sections attached to an output section.
|
// Sort the input sections attached to an output section.
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2913,17 +2976,27 @@ Output_section::sort_attached_input_sections()
|
|||||||
for (Input_section_list::iterator p = this->input_sections_.begin();
|
for (Input_section_list::iterator p = this->input_sections_.begin();
|
||||||
p != this->input_sections_.end();
|
p != this->input_sections_.end();
|
||||||
++p, ++i)
|
++p, ++i)
|
||||||
sort_list.push_back(Input_section_sort_entry(*p, i));
|
sort_list.push_back(Input_section_sort_entry(*p, i,
|
||||||
|
this->must_sort_attached_input_sections()));
|
||||||
|
|
||||||
// Sort the input sections.
|
// Sort the input sections.
|
||||||
if (this->type() == elfcpp::SHT_PREINIT_ARRAY
|
if (this->must_sort_attached_input_sections())
|
||||||
|| this->type() == elfcpp::SHT_INIT_ARRAY
|
{
|
||||||
|| this->type() == elfcpp::SHT_FINI_ARRAY)
|
if (this->type() == elfcpp::SHT_PREINIT_ARRAY
|
||||||
std::sort(sort_list.begin(), sort_list.end(),
|
|| this->type() == elfcpp::SHT_INIT_ARRAY
|
||||||
Input_section_sort_init_fini_compare());
|
|| this->type() == elfcpp::SHT_FINI_ARRAY)
|
||||||
|
std::sort(sort_list.begin(), sort_list.end(),
|
||||||
|
Input_section_sort_init_fini_compare());
|
||||||
|
else
|
||||||
|
std::sort(sort_list.begin(), sort_list.end(),
|
||||||
|
Input_section_sort_compare());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
std::sort(sort_list.begin(), sort_list.end(),
|
{
|
||||||
Input_section_sort_compare());
|
gold_assert(parameters->options().section_ordering_file());
|
||||||
|
std::sort(sort_list.begin(), sort_list.end(),
|
||||||
|
Input_section_sort_section_order_index_compare());
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the sorted input sections back to our list.
|
// Copy the sorted input sections back to our list.
|
||||||
this->input_sections_.clear();
|
this->input_sections_.clear();
|
||||||
@ -2931,6 +3004,7 @@ Output_section::sort_attached_input_sections()
|
|||||||
p != sort_list.end();
|
p != sort_list.end();
|
||||||
++p)
|
++p)
|
||||||
this->input_sections_.push_back(p->input_section());
|
this->input_sections_.push_back(p->input_section());
|
||||||
|
sort_list.clear();
|
||||||
|
|
||||||
// Remember that we sorted the input sections, since we might get
|
// Remember that we sorted the input sections, since we might get
|
||||||
// called again.
|
// called again.
|
||||||
@ -4466,6 +4540,7 @@ Output_file::close()
|
|||||||
template
|
template
|
||||||
off_t
|
off_t
|
||||||
Output_section::add_input_section<32, false>(
|
Output_section::add_input_section<32, false>(
|
||||||
|
Layout* layout,
|
||||||
Sized_relobj<32, false>* object,
|
Sized_relobj<32, false>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
const char* secname,
|
const char* secname,
|
||||||
@ -4478,6 +4553,7 @@ Output_section::add_input_section<32, false>(
|
|||||||
template
|
template
|
||||||
off_t
|
off_t
|
||||||
Output_section::add_input_section<32, true>(
|
Output_section::add_input_section<32, true>(
|
||||||
|
Layout* layout,
|
||||||
Sized_relobj<32, true>* object,
|
Sized_relobj<32, true>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
const char* secname,
|
const char* secname,
|
||||||
@ -4490,6 +4566,7 @@ Output_section::add_input_section<32, true>(
|
|||||||
template
|
template
|
||||||
off_t
|
off_t
|
||||||
Output_section::add_input_section<64, false>(
|
Output_section::add_input_section<64, false>(
|
||||||
|
Layout* layout,
|
||||||
Sized_relobj<64, false>* object,
|
Sized_relobj<64, false>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
const char* secname,
|
const char* secname,
|
||||||
@ -4502,6 +4579,7 @@ Output_section::add_input_section<64, false>(
|
|||||||
template
|
template
|
||||||
off_t
|
off_t
|
||||||
Output_section::add_input_section<64, true>(
|
Output_section::add_input_section<64, true>(
|
||||||
|
Layout* layout,
|
||||||
Sized_relobj<64, true>* object,
|
Sized_relobj<64, true>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
const char* secname,
|
const char* secname,
|
||||||
|
@ -2515,8 +2515,8 @@ class Output_section : public Output_data
|
|||||||
// within the output section.
|
// within the output section.
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
off_t
|
off_t
|
||||||
add_input_section(Sized_relobj<size, big_endian>* object, unsigned int shndx,
|
add_input_section(Layout* layout, Sized_relobj<size, big_endian>* object,
|
||||||
const char *name,
|
unsigned int shndx, const char *name,
|
||||||
const elfcpp::Shdr<size, big_endian>& shdr,
|
const elfcpp::Shdr<size, big_endian>& shdr,
|
||||||
unsigned int reloc_shndx, bool have_sections_script);
|
unsigned int reloc_shndx, bool have_sections_script);
|
||||||
|
|
||||||
@ -2736,6 +2736,18 @@ class Output_section : public Output_data
|
|||||||
set_may_sort_attached_input_sections()
|
set_may_sort_attached_input_sections()
|
||||||
{ this->may_sort_attached_input_sections_ = true; }
|
{ this->may_sort_attached_input_sections_ = true; }
|
||||||
|
|
||||||
|
// Returns true if input sections must be sorted according to the
|
||||||
|
// order in which their name appear in the --section-ordering-file.
|
||||||
|
bool
|
||||||
|
input_section_order_specified()
|
||||||
|
{ return this->input_section_order_specified_; }
|
||||||
|
|
||||||
|
// Record that input sections must be sorted as some of their names
|
||||||
|
// match the patterns specified through --section-ordering-file.
|
||||||
|
void
|
||||||
|
set_input_section_order_specified()
|
||||||
|
{ this->input_section_order_specified_ = true; }
|
||||||
|
|
||||||
// Return whether the input sections attached to this output section
|
// Return whether the input sections attached to this output section
|
||||||
// require sorting. This is used to handle constructor priorities
|
// require sorting. This is used to handle constructor priorities
|
||||||
// compatibly with GNU ld.
|
// compatibly with GNU ld.
|
||||||
@ -2972,7 +2984,8 @@ class Output_section : public Output_data
|
|||||||
Input_section(Relobj* object, unsigned int shndx, off_t data_size,
|
Input_section(Relobj* object, unsigned int shndx, off_t data_size,
|
||||||
uint64_t addralign)
|
uint64_t addralign)
|
||||||
: shndx_(shndx),
|
: shndx_(shndx),
|
||||||
p2align_(ffsll(static_cast<long long>(addralign)))
|
p2align_(ffsll(static_cast<long long>(addralign))),
|
||||||
|
section_order_index_(0)
|
||||||
{
|
{
|
||||||
gold_assert(shndx != OUTPUT_SECTION_CODE
|
gold_assert(shndx != OUTPUT_SECTION_CODE
|
||||||
&& shndx != MERGE_DATA_SECTION_CODE
|
&& shndx != MERGE_DATA_SECTION_CODE
|
||||||
@ -2984,7 +2997,8 @@ class Output_section : public Output_data
|
|||||||
|
|
||||||
// For a non-merge output section.
|
// For a non-merge output section.
|
||||||
Input_section(Output_section_data* posd)
|
Input_section(Output_section_data* posd)
|
||||||
: shndx_(OUTPUT_SECTION_CODE), p2align_(0)
|
: shndx_(OUTPUT_SECTION_CODE), p2align_(0),
|
||||||
|
section_order_index_(0)
|
||||||
{
|
{
|
||||||
this->u1_.data_size = 0;
|
this->u1_.data_size = 0;
|
||||||
this->u2_.posd = posd;
|
this->u2_.posd = posd;
|
||||||
@ -2995,7 +3009,8 @@ class Output_section : public Output_data
|
|||||||
: shndx_(is_string
|
: shndx_(is_string
|
||||||
? MERGE_STRING_SECTION_CODE
|
? MERGE_STRING_SECTION_CODE
|
||||||
: MERGE_DATA_SECTION_CODE),
|
: MERGE_DATA_SECTION_CODE),
|
||||||
p2align_(0)
|
p2align_(0),
|
||||||
|
section_order_index_(0)
|
||||||
{
|
{
|
||||||
this->u1_.entsize = entsize;
|
this->u1_.entsize = entsize;
|
||||||
this->u2_.posd = posd;
|
this->u2_.posd = posd;
|
||||||
@ -3003,12 +3018,25 @@ class Output_section : public Output_data
|
|||||||
|
|
||||||
// For a relaxed input section.
|
// For a relaxed input section.
|
||||||
Input_section(Output_relaxed_input_section *psection)
|
Input_section(Output_relaxed_input_section *psection)
|
||||||
: shndx_(RELAXED_INPUT_SECTION_CODE), p2align_(0)
|
: shndx_(RELAXED_INPUT_SECTION_CODE), p2align_(0),
|
||||||
|
section_order_index_(0)
|
||||||
{
|
{
|
||||||
this->u1_.data_size = 0;
|
this->u1_.data_size = 0;
|
||||||
this->u2_.poris = psection;
|
this->u2_.poris = psection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
section_order_index() const
|
||||||
|
{
|
||||||
|
return this->section_order_index_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_section_order_index(unsigned int number)
|
||||||
|
{
|
||||||
|
this->section_order_index_ = number;
|
||||||
|
}
|
||||||
|
|
||||||
// The required alignment.
|
// The required alignment.
|
||||||
uint64_t
|
uint64_t
|
||||||
addralign() const
|
addralign() const
|
||||||
@ -3234,6 +3262,9 @@ class Output_section : public Output_data
|
|||||||
// For RELAXED_INPUT_SECTION_CODE, the data.
|
// For RELAXED_INPUT_SECTION_CODE, the data.
|
||||||
Output_relaxed_input_section* poris;
|
Output_relaxed_input_section* poris;
|
||||||
} u2_;
|
} u2_;
|
||||||
|
// The line number of the pattern it matches in the --section-ordering-file
|
||||||
|
// file. It is 0 if does not match any pattern.
|
||||||
|
unsigned int section_order_index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store the list of input sections for this Output_section into the
|
// Store the list of input sections for this Output_section into the
|
||||||
@ -3540,6 +3571,15 @@ class Output_section : public Output_data
|
|||||||
const Input_section_sort_entry&) const;
|
const Input_section_sort_entry&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is the sort comparison function when a section order is specified
|
||||||
|
// from an input file.
|
||||||
|
struct Input_section_sort_section_order_index_compare
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
operator()(const Input_section_sort_entry&,
|
||||||
|
const Input_section_sort_entry&) const;
|
||||||
|
};
|
||||||
|
|
||||||
// Fill data. This is used to fill in data between input sections.
|
// Fill data. This is used to fill in data between input sections.
|
||||||
// It is also used for data statements (BYTE, WORD, etc.) in linker
|
// It is also used for data statements (BYTE, WORD, etc.) in linker
|
||||||
// scripts. When we have to keep track of the input sections, we
|
// scripts. When we have to keep track of the input sections, we
|
||||||
@ -3707,6 +3747,9 @@ class Output_section : public Output_data
|
|||||||
// section, false if it means the symbol index of the corresponding
|
// section, false if it means the symbol index of the corresponding
|
||||||
// section symbol.
|
// section symbol.
|
||||||
bool info_uses_section_index_ : 1;
|
bool info_uses_section_index_ : 1;
|
||||||
|
// True if input sections attached to this output section have to be
|
||||||
|
// sorted according to a specified order.
|
||||||
|
bool input_section_order_specified_ : 1;
|
||||||
// True if the input sections attached to this output section may
|
// True if the input sections attached to this output section may
|
||||||
// need sorting.
|
// need sorting.
|
||||||
bool may_sort_attached_input_sections_ : 1;
|
bool may_sort_attached_input_sections_ : 1;
|
||||||
|
@ -983,15 +983,6 @@ class Output_section_element_fill : public Output_section_element
|
|||||||
Expression* val_;
|
Expression* val_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return whether STRING contains a wildcard character. This is used
|
|
||||||
// to speed up matching.
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
is_wildcard_string(const std::string& s)
|
|
||||||
{
|
|
||||||
return strpbrk(s.c_str(), "?*[") != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// An input section specification in an output section
|
// An input section specification in an output section
|
||||||
|
|
||||||
class Output_section_element_input : public Output_section_element
|
class Output_section_element_input : public Output_section_element
|
||||||
@ -1035,7 +1026,7 @@ class Output_section_element_input : public Output_section_element
|
|||||||
Input_section_pattern(const char* patterna, size_t patternlena,
|
Input_section_pattern(const char* patterna, size_t patternlena,
|
||||||
Sort_wildcard sorta)
|
Sort_wildcard sorta)
|
||||||
: pattern(patterna, patternlena),
|
: pattern(patterna, patternlena),
|
||||||
pattern_is_wildcard(is_wildcard_string(this->pattern)),
|
pattern_is_wildcard(is_wildcard_string(this->pattern.c_str())),
|
||||||
sort(sorta)
|
sort(sorta)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@ -1102,7 +1093,7 @@ Output_section_element_input::Output_section_element_input(
|
|||||||
if (spec->file.name.length != 1 || spec->file.name.value[0] != '*')
|
if (spec->file.name.length != 1 || spec->file.name.value[0] != '*')
|
||||||
this->filename_pattern_.assign(spec->file.name.value,
|
this->filename_pattern_.assign(spec->file.name.value,
|
||||||
spec->file.name.length);
|
spec->file.name.length);
|
||||||
this->filename_is_wildcard_ = is_wildcard_string(this->filename_pattern_);
|
this->filename_is_wildcard_ = is_wildcard_string(this->filename_pattern_.c_str());
|
||||||
|
|
||||||
if (spec->input_sections.exclude != NULL)
|
if (spec->input_sections.exclude != NULL)
|
||||||
{
|
{
|
||||||
@ -1111,7 +1102,7 @@ Output_section_element_input::Output_section_element_input(
|
|||||||
p != spec->input_sections.exclude->end();
|
p != spec->input_sections.exclude->end();
|
||||||
++p)
|
++p)
|
||||||
{
|
{
|
||||||
bool is_wildcard = is_wildcard_string(*p);
|
bool is_wildcard = is_wildcard_string((*p).c_str());
|
||||||
this->filename_exclusions_.push_back(std::make_pair(*p,
|
this->filename_exclusions_.push_back(std::make_pair(*p,
|
||||||
is_wildcard));
|
is_wildcard));
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,18 @@ icf_safe_so_test_1.stdout: icf_safe_so_test
|
|||||||
icf_safe_so_test_2.stdout: icf_safe_so_test
|
icf_safe_so_test_2.stdout: icf_safe_so_test
|
||||||
$(TEST_READELF) -h icf_safe_so_test > icf_safe_so_test_2.stdout
|
$(TEST_READELF) -h icf_safe_so_test > icf_safe_so_test_2.stdout
|
||||||
|
|
||||||
|
check_SCRIPTS += final_layout.sh
|
||||||
|
check_DATA += final_layout.stdout
|
||||||
|
MOSTLYCLEANFILES += final_layout
|
||||||
|
final_layout.o: final_layout.cc
|
||||||
|
$(CXXCOMPILE) -O0 -c -ffunction-sections -fdata-sections -g -o $@ $<
|
||||||
|
final_layout_sequence.txt:
|
||||||
|
(echo "*_Z3barv*" && echo ".text._Z3bazv" && echo "*_Z3foov*" && echo "*global_varb*" && echo "*global_vara*" && echo "*global_varc*") > final_layout_sequence.txt
|
||||||
|
final_layout: final_layout.o final_layout_sequence.txt gcctestdir/ld
|
||||||
|
$(CXXLINK) -Bgcctestdir/ -Wl,--section-ordering-file,final_layout_sequence.txt final_layout.o
|
||||||
|
final_layout.stdout: final_layout
|
||||||
|
$(TEST_NM) final_layout > final_layout.stdout
|
||||||
|
|
||||||
check_PROGRAMS += icf_virtual_function_folding_test
|
check_PROGRAMS += icf_virtual_function_folding_test
|
||||||
MOSTLYCLEANFILES += icf_virtual_function_folding_test
|
MOSTLYCLEANFILES += icf_virtual_function_folding_test
|
||||||
icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
|
icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
|
||||||
|
@ -62,6 +62,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test.sh \
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \
|
||||||
@ -94,6 +95,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test_2.stdout \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test_2.stdout \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test_1.stdout \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test_1.stdout \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test_2.stdout \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test_2.stdout \
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout.stdout \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.stdout \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.stdout \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.stdout \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.stdout \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
|
||||||
@ -118,6 +120,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test icf_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_orphan_section_test icf_test \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test icf_safe_so_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test icf_safe_so_test \
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test \
|
||||||
@ -2609,6 +2612,14 @@ uninstall-am:
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) icf_safe_so_test > icf_safe_so_test_1.stdout
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) icf_safe_so_test > icf_safe_so_test_1.stdout
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_so_test_2.stdout: icf_safe_so_test
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_safe_so_test_2.stdout: icf_safe_so_test
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -h icf_safe_so_test > icf_safe_so_test_2.stdout
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -h icf_safe_so_test > icf_safe_so_test_2.stdout
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@final_layout.o: final_layout.cc
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fdata-sections -g -o $@ $<
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@final_layout_sequence.txt:
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ (echo "*_Z3barv*" && echo ".text._Z3bazv" && echo "*_Z3foov*" && echo "*global_varb*" && echo "*global_vara*" && echo "*global_varc*") > final_layout_sequence.txt
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@final_layout: final_layout.o final_layout_sequence.txt gcctestdir/ld
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--section-ordering-file,final_layout_sequence.txt final_layout.o
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@final_layout.stdout: final_layout
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) final_layout > final_layout.stdout
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fPIE -g -o $@ $<
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fPIE -g -o $@ $<
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test: icf_virtual_function_folding_test.o gcctestdir/ld
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test: icf_virtual_function_folding_test.o gcctestdir/ld
|
||||||
|
48
gold/testsuite/final_layout.cc
Normal file
48
gold/testsuite/final_layout.cc
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// final_layout.cc -- a test case for gold
|
||||||
|
|
||||||
|
// Copyright 2010 Free Software Foundation, Inc.
|
||||||
|
// Written by Sriraman Tallam <tmsriram@google.com>.
|
||||||
|
|
||||||
|
// This file is part of gold.
|
||||||
|
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||||
|
// MA 02110-1301, USA.
|
||||||
|
|
||||||
|
// The goal of this program is to verify if --section-ordering-file orders
|
||||||
|
// the .text and .data sections correctly as specified.
|
||||||
|
|
||||||
|
int global_vara;
|
||||||
|
int global_varb;
|
||||||
|
int global_varc;
|
||||||
|
|
||||||
|
int foo()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bar()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int baz()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
42
gold/testsuite/final_layout.sh
Executable file
42
gold/testsuite/final_layout.sh
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# final_layout.sh -- test --final-layout
|
||||||
|
|
||||||
|
# Copyright 2010 Free Software Foundation, Inc.
|
||||||
|
# Written by Sriraman Tallam <tmsriram@google.com>.
|
||||||
|
|
||||||
|
# This file is part of gold.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||||
|
# MA 02110-1301, USA.
|
||||||
|
|
||||||
|
# The goal of this program is to verify if --section-ordering-file works as
|
||||||
|
# intended. File final_layout.cc is in this test.
|
||||||
|
|
||||||
|
check()
|
||||||
|
{
|
||||||
|
func_addr_1=$((16#`grep $2 $1 | awk '{print $1}'`))
|
||||||
|
func_addr_2=$((16#`grep $3 $1 | awk '{print $1}'`))
|
||||||
|
if [ $func_addr_1 -gt $func_addr_2 ]
|
||||||
|
then
|
||||||
|
echo "final layout of" $2 "and" $3 "is not right."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check final_layout.stdout "_Z3barv" "_Z3bazv"
|
||||||
|
check final_layout.stdout "_Z3bazv" "_Z3foov"
|
||||||
|
check final_layout.stdout "global_varb" "global_vara"
|
||||||
|
check final_layout.stdout "global_vara" "global_varc"
|
Reference in New Issue
Block a user