diff options
author | Ian Lance Taylor <iant@google.com> | 2006-09-26 21:00:34 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-09-26 21:00:34 +0000 |
commit | 54dc6425456514cdc00cdfef5a21a7bdacfcad2d (patch) | |
tree | a0cf4cee57e8ed1f2cd9c938febf6966cfa69920 /gold/output.cc | |
parent | 41f8ce693c4a04811bf47a8df83c1a376a9f34f4 (diff) | |
download | gdb-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.cc | 60 |
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. |