diff options
author | Ian Lance Taylor <iant@google.com> | 2006-10-20 20:40:49 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-10-20 20:40:49 +0000 |
commit | 92e059d8dc78c3f65e29e48e368f6e47ea0ab671 (patch) | |
tree | f448eb3317d9cbb0f5946422cc28ef157a5f65cb /gold/layout.cc | |
parent | af4658dc3db33004d6166b161588221ecb463a5f (diff) | |
download | gdb-92e059d8dc78c3f65e29e48e368f6e47ea0ab671.zip gdb-92e059d8dc78c3f65e29e48e368f6e47ea0ab671.tar.gz gdb-92e059d8dc78c3f65e29e48e368f6e47ea0ab671.tar.bz2 |
Framework for relocation scanning. Implement simple static TLS
relocations.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r-- | gold/layout.cc | 85 |
1 files changed, 19 insertions, 66 deletions
diff --git a/gold/layout.cc b/gold/layout.cc index 61b6895..a81fd43 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -14,36 +14,13 @@ namespace gold { -// Layout_task methods. - -Layout_task::~Layout_task() -{ -} - -// This task can be run when it is unblocked. - -Task::Is_runnable_type -Layout_task::is_runnable(Workqueue*) -{ - if (this->this_blocker_->is_blocked()) - return IS_BLOCKED; - return IS_RUNNABLE; -} - -// We don't need to hold any locks for the duration of this task. In -// fact this task will be the only one running. - -Task_locker* -Layout_task::locks(Workqueue*) -{ - return NULL; -} +// Layout_task_runner methods. // Lay out the sections. This is called after all the input objects // have been read. void -Layout_task::run(Workqueue* workqueue) +Layout_task_runner::run(Workqueue* workqueue) { off_t file_size = this->layout_->finalize(this->input_objects_, this->symtab_); @@ -63,7 +40,7 @@ Layout_task::run(Workqueue* workqueue) Layout::Layout(const General_options& options) : options_(options), last_shndx_(0), namepool_(), sympool_(), signatures_(), section_name_map_(), segment_list_(), section_list_(), - special_output_list_() + special_output_list_(), tls_segment_(NULL) { // Make space for more than enough segments for a typical file. // This is just for efficiency--it's OK if we wind up needing more. @@ -256,30 +233,16 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type, } // If we see a loadable SHF_TLS section, we create a PT_TLS - // segment. + // segment. There can only be one such segment. if ((flags & elfcpp::SHF_TLS) != 0) { - // See if we already have an equivalent PT_TLS segment. - for (p = this->segment_list_.begin(); - p != segment_list_.end(); - ++p) + if (this->tls_segment_ == NULL) { - if ((*p)->type() == elfcpp::PT_TLS - && (((*p)->flags() & elfcpp::PF_W) - == (seg_flags & elfcpp::PF_W))) - { - (*p)->add_output_section(os, seg_flags); - break; - } - } - - if (p == this->segment_list_.end()) - { - Output_segment* oseg = new Output_segment(elfcpp::PT_TLS, - seg_flags); - this->segment_list_.push_back(oseg); - oseg->add_output_section(os, seg_flags); + this->tls_segment_ = new Output_segment(elfcpp::PT_TLS, + seg_flags); + this->segment_list_.push_back(this->tls_segment_); } + this->tls_segment_->add_output_section(os, seg_flags); } } @@ -440,6 +403,14 @@ Layout::segment_precedes(const Output_segment* seg1, if (type2 == elfcpp::PT_LOAD && type1 != elfcpp::PT_LOAD) return false; + // We put the PT_TLS segment last, because that is where the dynamic + // linker expects to find it (this is just for efficiency; other + // positions would also work correctly). + if (type1 == elfcpp::PT_TLS && type2 != elfcpp::PT_TLS) + return false; + if (type2 == elfcpp::PT_TLS && type1 != elfcpp::PT_TLS) + return true; + const elfcpp::Elf_Word flags1 = seg1->flags(); const elfcpp::Elf_Word flags2 = seg2->flags(); @@ -865,30 +836,12 @@ Write_symbols_task::run(Workqueue*) this->symtab_->write_globals(this->target_, this->sympool_, this->of_); } -// Close_task methods. - -// We can't run until FINAL_BLOCKER is unblocked. - -Task::Is_runnable_type -Close_task::is_runnable(Workqueue*) -{ - if (this->final_blocker_->is_blocked()) - return IS_BLOCKED; - return IS_RUNNABLE; -} - -// We don't lock anything. - -Task_locker* -Close_task::locks(Workqueue*) -{ - return NULL; -} +// Close_task_runner methods. // Run the task--close the file. void -Close_task::run(Workqueue*) +Close_task_runner::run(Workqueue*) { this->of_->close(); } |