// script-sections.cc -- linker script SECTIONS for gold
-// Copyright 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2008-2015 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
// Set the section name.
void
set_section_name(const std::string name)
- { this->section_name_ = name; }
+ {
+ if (is_compressed_debug_section(name.c_str()))
+ this->section_name_ = corresponding_uncompressed_section_name(name);
+ else
+ this->section_name_ = name;
+ }
// Return the section size.
uint64_t
// We build a list of sections which match each
// Input_section_pattern.
+ // If none of the patterns specify a sort option, we throw all
+ // matching input sections into a single bin, in the order we
+ // find them. Otherwise, we put matching input sections into
+ // a separate bin for each pattern, and sort each one as
+ // specified. Thus, an input section spec like this:
+ // *(.foo .bar)
+ // will group all .foo and .bar sections in the order seen,
+ // whereas this:
+ // *(.foo) *(.bar)
+ // will group all .foo sections followed by all .bar sections.
+ // This matches Gnu ld behavior.
+
+ // Things get really weird, though, when you add a sort spec
+ // on some, but not all, of the patterns, like this:
+ // *(SORT_BY_NAME(.foo) .bar)
+ // We do not attempt to match Gnu ld behavior in this case.
+
typedef std::vector<std::vector<Input_section_info> > Matching_sections;
size_t input_pattern_count = this->input_section_patterns_.size();
- if (input_pattern_count == 0)
+ bool any_patterns_with_sort = false;
+ for (size_t i = 0; i < input_pattern_count; ++i)
+ {
+ const Input_section_pattern& isp(this->input_section_patterns_[i]);
+ if (isp.sort != SORT_WILDCARD_NONE)
+ any_patterns_with_sort = true;
+ }
+ if (input_pattern_count == 0 || !any_patterns_with_sort)
input_pattern_count = 1;
Matching_sections matching_sections(input_pattern_count);
++p;
else
{
+ if (!any_patterns_with_sort)
+ i = 0;
matching_sections[i].push_back(isi);
p = input_sections->erase(p);
}
address += size;
}
- // An SHF_TLS/SHT_NOBITS section does not take up any address space.
- if (this->os_ == NULL
- || (this->os_->flags() & elfcpp::SHF_TLS) == 0
- || this->os_->type() != elfcpp::SHT_NOBITS)
+ if (parameters->options().relocatable())
+ {
+ // For a relocatable link, reset DOT_VALUE to 0.
+ *dot_value = 0;
+ *load_address = 0;
+ }
+ else if (this->os_ == NULL
+ || (this->os_->flags() & elfcpp::SHF_TLS) == 0
+ || this->os_->type() != elfcpp::SHT_NOBITS)
{
+ // An SHF_TLS/SHT_NOBITS section does not take up any address space.
if (!have_load_address)
*load_address = address;
else
data_segment_align_start_(),
saw_data_segment_align_(false),
saw_relro_end_(false),
- saw_segment_start_expression_(false)
+ saw_segment_start_expression_(false),
+ segments_created_(false)
{
}
saw_tls = true;
}
- // If we are making a shared library, and we see a section named
- // .interp then put the .interp section in a PT_INTERP segment.
+ // If we see a section named .interp then put the .interp section
+ // in a PT_INTERP segment.
// This is for GNU ld compatibility.
if (strcmp((*p)->name(), ".interp") == 0)
{
oseg->add_output_section_to_nonload(*p, seg_flags);
}
}
+
+ this->segments_created_ = true;
}
// Add a program header. The PHDRS clause is syntactically distinct
size_t
Script_sections::expected_segment_count(const Layout* layout) const
{
+ // If we've already created the segments, we won't be adding any more.
+ if (this->segments_created_)
+ return 0;
+
if (this->saw_phdrs_clause())
return this->phdrs_elements_->size();
bool saw_note = false;
bool saw_tls = false;
+ bool saw_interp = false;
for (Layout::Section_list::const_iterator p = sections.begin();
p != sections.end();
++p)
saw_tls = true;
}
}
+ else if (strcmp((*p)->name(), ".interp") == 0)
+ {
+ // There can only be one PT_INTERP segment.
+ if (!saw_interp)
+ {
+ ++ret;
+ saw_interp = true;
+ }
+ }
}
return ret;
p != this->phdrs_elements_->end();
++p)
name_to_segment[(*p)->name()] = (*p)->create_segment(layout);
+ this->segments_created_ = true;
// Walk through the output sections and attach them to segments.
// Output sections in the script which do not list segments are