summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/gold/layout.cc
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.25/gold/layout.cc')
-rw-r--r--binutils-2.25/gold/layout.cc75
1 files changed, 46 insertions, 29 deletions
diff --git a/binutils-2.25/gold/layout.cc b/binutils-2.25/gold/layout.cc
index 38fd272b..7cbbe39b 100644
--- a/binutils-2.25/gold/layout.cc
+++ b/binutils-2.25/gold/layout.cc
@@ -1,7 +1,6 @@
// layout.cc -- lay out output file sections for gold
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2014 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@@ -564,7 +563,9 @@ static const char* gdb_fast_lookup_sections[] =
{
"aranges",
"pubnames",
+ "gnu_pubnames",
"pubtypes",
+ "gnu_pubtypes",
};
// Returns whether the given debug section is in the list of
@@ -645,7 +646,13 @@ Layout::include_section(Sized_relobj_file<size, big_endian>*, const char* name,
&& (shdr.get_sh_flags() & elfcpp::SHF_EXCLUDE))
return false;
- switch (shdr.get_sh_type())
+ elfcpp::Elf_Word sh_type = shdr.get_sh_type();
+
+ if ((sh_type >= elfcpp::SHT_LOOS && sh_type <= elfcpp::SHT_HIOS)
+ || (sh_type >= elfcpp::SHT_LOPROC && sh_type <= elfcpp::SHT_HIPROC))
+ return parameters->target().should_include_section(sh_type);
+
+ switch (sh_type)
{
case elfcpp::SHT_NULL:
case elfcpp::SHT_SYMTAB:
@@ -2744,12 +2751,14 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
// If there is a load segment that contains the file and program headers,
// provide a symbol __ehdr_start pointing there.
// A program can use this to examine itself robustly.
- if (load_seg != NULL)
- symtab->define_in_output_segment("__ehdr_start", NULL,
- Symbol_table::PREDEFINED, load_seg, 0, 0,
- elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
- elfcpp::STV_HIDDEN, 0,
- Symbol::SEGMENT_START, true);
+ Symbol *ehdr_start = symtab->lookup("__ehdr_start");
+ if (ehdr_start != NULL && ehdr_start->is_predefined())
+ {
+ if (load_seg != NULL)
+ ehdr_start->set_output_segment(load_seg, Symbol::SEGMENT_START);
+ else
+ ehdr_start->set_undefined();
+ }
// Set the file offsets of all the non-data sections we've seen so
// far which don't have to wait for the input sections. We need
@@ -4299,18 +4308,20 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
}
}
- // Create the hash tables.
+ // Create the hash tables. The Gnu-style hash table must be
+ // built first, because it changes the order of the symbols
+ // in the dynamic symbol table.
- if (strcmp(parameters->options().hash_style(), "sysv") == 0
+ if (strcmp(parameters->options().hash_style(), "gnu") == 0
|| strcmp(parameters->options().hash_style(), "both") == 0)
{
unsigned char* phash;
unsigned int hashlen;
- Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
+ Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen);
Output_section* hashsec =
- this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
+ this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
elfcpp::SHF_ALLOC, false,
ORDER_DYNAMIC_LINKER, false);
@@ -4325,23 +4336,28 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
{
if (dynsym != NULL)
hashsec->set_link_section(dynsym);
- hashsec->set_entsize(4);
- }
- if (odyn != NULL)
- odyn->add_section_address(elfcpp::DT_HASH, hashsec);
+ // For a 64-bit target, the entries in .gnu.hash do not have
+ // a uniform size, so we only set the entry size for a
+ // 32-bit target.
+ if (parameters->target().get_size() == 32)
+ hashsec->set_entsize(4);
+
+ if (odyn != NULL)
+ odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+ }
}
- if (strcmp(parameters->options().hash_style(), "gnu") == 0
+ if (strcmp(parameters->options().hash_style(), "sysv") == 0
|| strcmp(parameters->options().hash_style(), "both") == 0)
{
unsigned char* phash;
unsigned int hashlen;
- Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
+ Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen);
Output_section* hashsec =
- this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
+ this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
elfcpp::SHF_ALLOC, false,
ORDER_DYNAMIC_LINKER, false);
@@ -4356,16 +4372,11 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
{
if (dynsym != NULL)
hashsec->set_link_section(dynsym);
-
- // For a 64-bit target, the entries in .gnu.hash do not have
- // a uniform size, so we only set the entry size for a
- // 32-bit target.
- if (parameters->target().get_size() == 32)
- hashsec->set_entsize(4);
-
- if (odyn != NULL)
- odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+ hashsec->set_entsize(4);
}
+
+ if (odyn != NULL)
+ odyn->add_section_address(elfcpp::DT_HASH, hashsec);
}
}
@@ -5485,6 +5496,10 @@ Layout::print_to_mapfile(Mapfile* mapfile) const
p != this->segment_list_.end();
++p)
(*p)->print_sections_to_mapfile(mapfile);
+ for (Section_list::const_iterator p = this->unattached_section_list_.begin();
+ p != this->unattached_section_list_.end();
+ ++p)
+ (*p)->print_to_mapfile(mapfile);
}
// Print statistical information to stderr. This is used for --stats.
@@ -5519,6 +5534,8 @@ void
Write_sections_task::locks(Task_locker* tl)
{
tl->add(this, this->output_sections_blocker_);
+ if (this->input_sections_blocker_ != NULL)
+ tl->add(this, this->input_sections_blocker_);
tl->add(this, this->final_blocker_);
}