aboutsummaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-06-22 06:51:53 +0000
committerIan Lance Taylor <ian@airs.com>2009-06-22 06:51:53 +0000
commit8a5e3e08a6faa0fdba3daa1fa4295b02c7ebe1eb (patch)
tree01736b6b47e8048239544872455cc12eb3d5bcc6 /gold/symtab.cc
parent1998a8e0333f8ebc40a5387532d74f90f510591d (diff)
downloadgdb-8a5e3e08a6faa0fdba3daa1fa4295b02c7ebe1eb.zip
gdb-8a5e3e08a6faa0fdba3daa1fa4295b02c7ebe1eb.tar.gz
gdb-8a5e3e08a6faa0fdba3daa1fa4295b02c7ebe1eb.tar.bz2
* layout.cc (Layout::make_output_section): Call
Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc36
1 files changed, 26 insertions, 10 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 3d179ef..daf9daf 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -280,6 +280,16 @@ Sized_symbol<size>::init_undefined(const char* name, const char* version,
this->symsize_ = 0;
}
+// Return true if SHNDX represents a common symbol.
+
+bool
+Symbol::is_common_shndx(unsigned int shndx)
+{
+ return (shndx == elfcpp::SHN_COMMON
+ || shndx == parameters->target().small_common_shndx()
+ || shndx == parameters->target().large_common_shndx());
+}
+
// Allocate a common symbol.
template<int size>
@@ -477,7 +487,8 @@ Symbol::set_output_section(Output_section* os)
Symbol_table::Symbol_table(unsigned int count,
const Version_script_info& version_script)
: saw_undefined_(0), offset_(0), table_(count), namepool_(),
- forwarders_(), commons_(), tls_commons_(), forced_locals_(), warnings_(),
+ forwarders_(), commons_(), tls_commons_(), small_commons_(),
+ large_commons_(), forced_locals_(), warnings_(),
version_script_(version_script), gc_(NULL)
{
namepool_.reserve(count);
@@ -975,10 +986,16 @@ Symbol_table::add_from_object(Object* object,
// allocation.
if (!was_common && ret->is_common())
{
- if (ret->type() != elfcpp::STT_TLS)
- this->commons_.push_back(ret);
- else
+ if (ret->type() == elfcpp::STT_TLS)
this->tls_commons_.push_back(ret);
+ else if (!is_ordinary
+ && st_shndx == parameters->target().small_common_shndx())
+ this->small_commons_.push_back(ret);
+ else if (!is_ordinary
+ && st_shndx == parameters->target().large_common_shndx())
+ this->large_commons_.push_back(ret);
+ else
+ this->commons_.push_back(ret);
}
// If we're not doing a relocatable link, then any symbol with
@@ -2370,10 +2387,9 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
bool is_ordinary;
unsigned int shndx = sym->shndx(&is_ordinary);
- // FIXME: We need some target specific support here.
if (!is_ordinary
&& shndx != elfcpp::SHN_ABS
- && shndx != elfcpp::SHN_COMMON)
+ && !Symbol::is_common_shndx(shndx))
{
gold_error(_("%s: unsupported symbol section 0x%x"),
sym->demangled_name().c_str(), shndx);
@@ -2394,7 +2410,8 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
else if (shndx == elfcpp::SHN_UNDEF)
value = 0;
else if (!is_ordinary
- && (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON))
+ && (shndx == elfcpp::SHN_ABS
+ || Symbol::is_common_shndx(shndx)))
value = sym->value();
else
{
@@ -2597,10 +2614,9 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
bool is_ordinary;
unsigned int in_shndx = sym->shndx(&is_ordinary);
- // FIXME: We need some target specific support here.
if (!is_ordinary
&& in_shndx != elfcpp::SHN_ABS
- && in_shndx != elfcpp::SHN_COMMON)
+ && !Symbol::is_common_shndx(in_shndx))
{
gold_error(_("%s: unsupported symbol section 0x%x"),
sym->demangled_name().c_str(), in_shndx);
@@ -2620,7 +2636,7 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
else if (in_shndx == elfcpp::SHN_UNDEF
|| (!is_ordinary
&& (in_shndx == elfcpp::SHN_ABS
- || in_shndx == elfcpp::SHN_COMMON)))
+ || Symbol::is_common_shndx(in_shndx))))
shndx = in_shndx;
else
{