mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
PR 10931
* options.h (class General_options): Add --sort-common option. * symtab.h (class Symbol_table): Define Sort_commons_order enum. * common.cc (Sort_common): Add sort_order parameter to constructor. Add sort_order_ field. (Sort_commons::operator): Check sort_order_. (Symbol_table::allocate_commons): Determine the sort order. (Symbol_table::do_allocate_commons): Add sort_order parameter. Change all callers. (Symbol_table::do_allocate_commons_list): Likewise.
This commit is contained in:
@ -1,3 +1,16 @@
|
|||||||
|
2009-12-30 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
PR 10931
|
||||||
|
* options.h (class General_options): Add --sort-common option.
|
||||||
|
* symtab.h (class Symbol_table): Define Sort_commons_order enum.
|
||||||
|
* common.cc (Sort_common): Add sort_order parameter to
|
||||||
|
constructor. Add sort_order_ field.
|
||||||
|
(Sort_commons::operator): Check sort_order_.
|
||||||
|
(Symbol_table::allocate_commons): Determine the sort order.
|
||||||
|
(Symbol_table::do_allocate_commons): Add sort_order parameter.
|
||||||
|
Change all callers.
|
||||||
|
(Symbol_table::do_allocate_commons_list): Likewise.
|
||||||
|
|
||||||
2009-12-30 Ian Lance Taylor <iant@google.com>
|
2009-12-30 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
PR 10916
|
PR 10916
|
||||||
|
@ -64,21 +64,26 @@ Allocate_commons_task::run(Workqueue*)
|
|||||||
this->symtab_->allocate_commons(this->layout_, this->mapfile_);
|
this->symtab_->allocate_commons(this->layout_, this->mapfile_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class is used to sort the common symbol by size. We put the
|
// This class is used to sort the common symbol. We normally put the
|
||||||
// larger common symbols first.
|
// larger common symbols first. This can be changed by using
|
||||||
|
// --sort-commons, which tells the linker to sort by alignment.
|
||||||
|
|
||||||
template<int size>
|
template<int size>
|
||||||
class Sort_commons
|
class Sort_commons
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sort_commons(const Symbol_table* symtab)
|
Sort_commons(const Symbol_table* symtab,
|
||||||
: symtab_(symtab)
|
Symbol_table::Sort_commons_order sort_order)
|
||||||
|
: symtab_(symtab), sort_order_(sort_order)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool operator()(const Symbol* a, const Symbol* b) const;
|
bool operator()(const Symbol* a, const Symbol* b) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// The symbol table.
|
||||||
const Symbol_table* symtab_;
|
const Symbol_table* symtab_;
|
||||||
|
// How to sort.
|
||||||
|
Symbol_table::Sort_commons_order sort_order_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int size>
|
template<int size>
|
||||||
@ -94,22 +99,48 @@ Sort_commons<size>::operator()(const Symbol* pa, const Symbol* pb) const
|
|||||||
const Sized_symbol<size>* psa = symtab->get_sized_symbol<size>(pa);
|
const Sized_symbol<size>* psa = symtab->get_sized_symbol<size>(pa);
|
||||||
const Sized_symbol<size>* psb = symtab->get_sized_symbol<size>(pb);
|
const Sized_symbol<size>* psb = symtab->get_sized_symbol<size>(pb);
|
||||||
|
|
||||||
// Sort by largest size first.
|
// The size.
|
||||||
typename Sized_symbol<size>::Size_type sa = psa->symsize();
|
typename Sized_symbol<size>::Size_type sa = psa->symsize();
|
||||||
typename Sized_symbol<size>::Size_type sb = psb->symsize();
|
typename Sized_symbol<size>::Size_type sb = psb->symsize();
|
||||||
|
|
||||||
|
// The alignment.
|
||||||
|
typename Sized_symbol<size>::Value_type aa = psa->value();
|
||||||
|
typename Sized_symbol<size>::Value_type ab = psb->value();
|
||||||
|
|
||||||
|
if (this->sort_order_ == Symbol_table::SORT_COMMONS_BY_ALIGNMENT_DESCENDING)
|
||||||
|
{
|
||||||
|
if (aa < ab)
|
||||||
|
return false;
|
||||||
|
else if (ab < aa)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (this->sort_order_
|
||||||
|
== Symbol_table::SORT_COMMONS_BY_ALIGNMENT_ASCENDING)
|
||||||
|
{
|
||||||
|
if (aa < ab)
|
||||||
|
return true;
|
||||||
|
else if (ab < aa)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gold_assert(this->sort_order_
|
||||||
|
== Symbol_table::SORT_COMMONS_BY_SIZE_DESCENDING);
|
||||||
|
|
||||||
|
// Sort by descending size.
|
||||||
if (sa < sb)
|
if (sa < sb)
|
||||||
return false;
|
return false;
|
||||||
else if (sb < sa)
|
else if (sb < sa)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// When the symbols are the same size, we sort them by alignment,
|
if (this->sort_order_ == Symbol_table::SORT_COMMONS_BY_SIZE_DESCENDING)
|
||||||
// largest alignment first.
|
{
|
||||||
typename Sized_symbol<size>::Value_type va = psa->value();
|
// When the symbols are the same size, we sort them by
|
||||||
typename Sized_symbol<size>::Value_type vb = psb->value();
|
// alignment, largest alignment first.
|
||||||
if (va < vb)
|
if (aa < ab)
|
||||||
return false;
|
return false;
|
||||||
else if (vb < va)
|
else if (ab < aa)
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise we stabilize the sort by sorting by name.
|
// Otherwise we stabilize the sort by sorting by name.
|
||||||
return strcmp(psa->name(), psb->name()) < 0;
|
return strcmp(psa->name(), psb->name()) < 0;
|
||||||
@ -120,10 +151,27 @@ Sort_commons<size>::operator()(const Symbol* pa, const Symbol* pb) const
|
|||||||
void
|
void
|
||||||
Symbol_table::allocate_commons(Layout* layout, Mapfile* mapfile)
|
Symbol_table::allocate_commons(Layout* layout, Mapfile* mapfile)
|
||||||
{
|
{
|
||||||
|
Sort_commons_order sort_order;
|
||||||
|
if (!parameters->options().user_set_sort_common())
|
||||||
|
sort_order = SORT_COMMONS_BY_SIZE_DESCENDING;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char* order = parameters->options().sort_common();
|
||||||
|
if (*order == '\0' || strcmp(order, "descending") == 0)
|
||||||
|
sort_order = SORT_COMMONS_BY_ALIGNMENT_DESCENDING;
|
||||||
|
else if (strcmp(order, "ascending") == 0)
|
||||||
|
sort_order = SORT_COMMONS_BY_ALIGNMENT_ASCENDING;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gold_error("invalid --sort-common argument: %s", order);
|
||||||
|
sort_order = SORT_COMMONS_BY_SIZE_DESCENDING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (parameters->target().get_size() == 32)
|
if (parameters->target().get_size() == 32)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
|
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
|
||||||
this->do_allocate_commons<32>(layout, mapfile);
|
this->do_allocate_commons<32>(layout, mapfile, sort_order);
|
||||||
#else
|
#else
|
||||||
gold_unreachable();
|
gold_unreachable();
|
||||||
#endif
|
#endif
|
||||||
@ -131,7 +179,7 @@ Symbol_table::allocate_commons(Layout* layout, Mapfile* mapfile)
|
|||||||
else if (parameters->target().get_size() == 64)
|
else if (parameters->target().get_size() == 64)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
|
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
|
||||||
this->do_allocate_commons<64>(layout, mapfile);
|
this->do_allocate_commons<64>(layout, mapfile, sort_order);
|
||||||
#else
|
#else
|
||||||
gold_unreachable();
|
gold_unreachable();
|
||||||
#endif
|
#endif
|
||||||
@ -144,20 +192,25 @@ Symbol_table::allocate_commons(Layout* layout, Mapfile* mapfile)
|
|||||||
|
|
||||||
template<int size>
|
template<int size>
|
||||||
void
|
void
|
||||||
Symbol_table::do_allocate_commons(Layout* layout, Mapfile* mapfile)
|
Symbol_table::do_allocate_commons(Layout* layout, Mapfile* mapfile,
|
||||||
|
Sort_commons_order sort_order)
|
||||||
{
|
{
|
||||||
if (!this->commons_.empty())
|
if (!this->commons_.empty())
|
||||||
this->do_allocate_commons_list<size>(layout, COMMONS_NORMAL,
|
this->do_allocate_commons_list<size>(layout, COMMONS_NORMAL,
|
||||||
&this->commons_, mapfile);
|
&this->commons_, mapfile,
|
||||||
|
sort_order);
|
||||||
if (!this->tls_commons_.empty())
|
if (!this->tls_commons_.empty())
|
||||||
this->do_allocate_commons_list<size>(layout, COMMONS_TLS,
|
this->do_allocate_commons_list<size>(layout, COMMONS_TLS,
|
||||||
&this->tls_commons_, mapfile);
|
&this->tls_commons_, mapfile,
|
||||||
|
sort_order);
|
||||||
if (!this->small_commons_.empty())
|
if (!this->small_commons_.empty())
|
||||||
this->do_allocate_commons_list<size>(layout, COMMONS_SMALL,
|
this->do_allocate_commons_list<size>(layout, COMMONS_SMALL,
|
||||||
&this->small_commons_, mapfile);
|
&this->small_commons_, mapfile,
|
||||||
|
sort_order);
|
||||||
if (!this->large_commons_.empty())
|
if (!this->large_commons_.empty())
|
||||||
this->do_allocate_commons_list<size>(layout, COMMONS_LARGE,
|
this->do_allocate_commons_list<size>(layout, COMMONS_LARGE,
|
||||||
&this->large_commons_, mapfile);
|
&this->large_commons_, mapfile,
|
||||||
|
sort_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the common symbols in a list. IS_TLS indicates whether
|
// Allocate the common symbols in a list. IS_TLS indicates whether
|
||||||
@ -169,7 +222,8 @@ Symbol_table::do_allocate_commons_list(
|
|||||||
Layout* layout,
|
Layout* layout,
|
||||||
Commons_section_type commons_section_type,
|
Commons_section_type commons_section_type,
|
||||||
Commons_type* commons,
|
Commons_type* commons,
|
||||||
Mapfile* mapfile)
|
Mapfile* mapfile,
|
||||||
|
Sort_commons_order sort_order)
|
||||||
{
|
{
|
||||||
typedef typename Sized_symbol<size>::Value_type Value_type;
|
typedef typename Sized_symbol<size>::Value_type Value_type;
|
||||||
typedef typename Sized_symbol<size>::Size_type Size_type;
|
typedef typename Sized_symbol<size>::Size_type Size_type;
|
||||||
@ -202,10 +256,9 @@ Symbol_table::do_allocate_commons_list(
|
|||||||
if (!any)
|
if (!any)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Sort the common symbols by size, so that they pack better into
|
// Sort the common symbols.
|
||||||
// memory.
|
|
||||||
std::sort(commons->begin(), commons->end(),
|
std::sort(commons->begin(), commons->end(),
|
||||||
Sort_commons<size>(this));
|
Sort_commons<size>(this, sort_order));
|
||||||
|
|
||||||
// Place them in a newly allocated BSS section.
|
// Place them in a newly allocated BSS section.
|
||||||
elfcpp::Elf_Xword flags = elfcpp::SHF_WRITE | elfcpp::SHF_ALLOC;
|
elfcpp::Elf_Xword flags = elfcpp::SHF_WRITE | elfcpp::SHF_ALLOC;
|
||||||
|
@ -819,6 +819,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_optional_string(sort_common, options::TWO_DASHES, '\0', NULL,
|
||||||
|
N_("Sort common symbols by alignment"),
|
||||||
|
N_("[={ascending,descending}]"));
|
||||||
|
|
||||||
DEFINE_bool(strip_all, options::TWO_DASHES, 's', false,
|
DEFINE_bool(strip_all, options::TWO_DASHES, 's', false,
|
||||||
N_("Strip all symbols"), NULL);
|
N_("Strip all symbols"), NULL);
|
||||||
DEFINE_bool(strip_debug, options::TWO_DASHES, 'S', false,
|
DEFINE_bool(strip_debug, options::TWO_DASHES, 'S', false,
|
||||||
|
@ -1195,6 +1195,14 @@ class Symbol_table
|
|||||||
PREDEFINED,
|
PREDEFINED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The order in which we sort common symbols.
|
||||||
|
enum Sort_commons_order
|
||||||
|
{
|
||||||
|
SORT_COMMONS_BY_SIZE_DESCENDING,
|
||||||
|
SORT_COMMONS_BY_ALIGNMENT_DESCENDING,
|
||||||
|
SORT_COMMONS_BY_ALIGNMENT_ASCENDING
|
||||||
|
};
|
||||||
|
|
||||||
// COUNT is an estimate of how many symbosl will be inserted in the
|
// COUNT is an estimate of how many symbosl will be inserted in the
|
||||||
// symbol table. It's ok to put 0 if you don't know; a correct
|
// symbol table. It's ok to put 0 if you don't know; a correct
|
||||||
// guess will just save some CPU by reducing hashtable resizes.
|
// guess will just save some CPU by reducing hashtable resizes.
|
||||||
@ -1603,13 +1611,13 @@ class Symbol_table
|
|||||||
// Allocate the common symbols, sized version.
|
// Allocate the common symbols, sized version.
|
||||||
template<int size>
|
template<int size>
|
||||||
void
|
void
|
||||||
do_allocate_commons(Layout*, Mapfile*);
|
do_allocate_commons(Layout*, Mapfile*, Sort_commons_order);
|
||||||
|
|
||||||
// Allocate the common symbols from one list.
|
// Allocate the common symbols from one list.
|
||||||
template<int size>
|
template<int size>
|
||||||
void
|
void
|
||||||
do_allocate_commons_list(Layout*, Commons_section_type, Commons_type*,
|
do_allocate_commons_list(Layout*, Commons_section_type, Commons_type*,
|
||||||
Mapfile*);
|
Mapfile*, Sort_commons_order);
|
||||||
|
|
||||||
// Implement detect_odr_violations.
|
// Implement detect_odr_violations.
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
Reference in New Issue
Block a user