aboutsummaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2006-09-26 21:00:34 +0000
committerIan Lance Taylor <iant@google.com>2006-09-26 21:00:34 +0000
commit54dc6425456514cdc00cdfef5a21a7bdacfcad2d (patch)
treea0cf4cee57e8ed1f2cd9c938febf6966cfa69920 /gold/output.cc
parent41f8ce693c4a04811bf47a8df83c1a376a9f34f4 (diff)
downloadgdb-54dc6425456514cdc00cdfef5a21a7bdacfcad2d.zip
gdb-54dc6425456514cdc00cdfef5a21a7bdacfcad2d.tar.gz
gdb-54dc6425456514cdc00cdfef5a21a7bdacfcad2d.tar.bz2
More section layout code.
Diffstat (limited to 'gold/output.cc')
-rw-r--r--gold/output.cc60
1 files changed, 49 insertions, 11 deletions
diff --git a/gold/output.cc b/gold/output.cc
index fcba113..9092301 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -24,6 +24,15 @@ Output_data_const::write(Output_file* output, off_t off)
output->write(off, data_.data(), data_.size());
}
+// Output_segment_header methods.
+
+void
+Output_segment_headers::write(Output_file*, off_t)
+{
+ // FIXME: Unimplemented.
+ abort();
+}
+
// Output_section methods.
// Construct an Output_section. NAME will point into a Stringpool.
@@ -35,7 +44,6 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
addralign_(0),
entsize_(0),
offset_(0),
- size_(0),
link_(0),
info_(0),
type_(type),
@@ -43,6 +51,10 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
{
}
+Output_section::~Output_section()
+{
+}
+
// Add an input section to an Output_section. We don't keep track of
// input sections for an Output_section. Instead, each Object keeps
// track of the Output_section for each of its input sections.
@@ -60,21 +72,22 @@ Output_section::add_input_section(Object* object, const char* secname,
static_cast<unsigned long>(addralign), secname);
gold_exit(false);
}
- this->size_ = (this->size_ + addralign - 1) &~ (addralign - 1);
if (addralign > this->addralign_)
this->addralign_ = addralign;
- off_t ret = this->size_;
- this->size_ += shdr.get_sh_size();
+ off_t ssize = this->get_size();
+ ssize = (ssize + addralign - 1) &~ (addralign - 1);
- return ret;
+ this->set_size(ssize + shdr.get_sh_size());
+
+ return size;
}
// Output segment methods.
Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
- : output_sections_(),
+ : output_data_(),
vaddr_(0),
paddr_(0),
memsz_(0),
@@ -91,6 +104,9 @@ Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
void
Output_segment::add_output_section(Output_section* os)
{
+ // Update the segment flags.
+ this->flags_ |= os->flags() & (elfcpp::PF_R | elfcpp::PF_W | elfcpp::PF_X);
+
// So that PT_NOTE segments will work correctly, we need to ensure
// that all SHT_NOTE sections are adjacent. This will normally
// happen automatically, because all the SHT_NOTE input sections
@@ -99,22 +115,44 @@ Output_segment::add_output_section(Output_section* os)
// flags, and thus be in different output sections, but for the
// different section flags to map into the same segment flags and
// thus the same output segment.
+
+ // Note that while there may be many input sections in an output
+ // section, there are normally only a few output sections in an
+ // output segment. This loop is expected to be fast.
+
if (os->type() == elfcpp::SHT_NOTE)
{
- for (Section_list::iterator p = this->output_sections_.begin();
- p != this->output_sections_.end();
+ for (Layout::Data_list::iterator p = this->output_data_.begin();
+ p != this->output_data_.end();
+ ++p)
+ {
+ if ((*p)->is_section_type(elfcpp::SHT_NOTE))
+ {
+ ++p;
+ this->output_data_.insert(p, os);
+ return;
+ }
+ }
+ }
+
+ // Similarly, so that PT_TLS segments will work, we need to group
+ // SHF_TLS sections.
+ if ((os->flags() & elfcpp::SHF_TLS) != 0)
+ {
+ for (Layout::Data_list::iterator p = this->output_data_.begin();
+ p != this->output_data_.end();
++p)
{
- if ((*p)->type() == elfcpp::SHT_NOTE)
+ if ((*p)->is_section_flag_set(elfcpp::SHF_TLS))
{
++p;
- this->output_sections_.insert(p, os);
+ this->output_data_.insert(p, os);
return;
}
}
}
- this->output_sections_.push_back(os);
+ this->output_data_.push_back(os);
}
// Output_file methods.