From bfd58944a64b0997a310b95fbe0423338961e71c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 22 Sep 2007 04:42:09 +0000 Subject: [PATCH] Define __start and __stop symbols. --- gold/gold.cc | 4 ++++ gold/layout.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ gold/layout.h | 4 ++++ 3 files changed, 60 insertions(+) diff --git a/gold/gold.cc b/gold/gold.cc index e7b7ae2939d..2d334625e83 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -148,6 +148,10 @@ queue_middle_tasks(const General_options& options, // bother to create a task for it. define_standard_symbols(symtab, layout, input_objects->target()); + // Define __start and __stop symbols for output sections where + // appropriate. + layout->define_section_symbols(symtab, input_objects->target()); + // Read the relocations of the input files. We do this to find // which symbols are used by relocations which require a GOT and/or // a PLT entry, or a COPY reloc. When we implement garbage diff --git a/gold/layout.cc b/gold/layout.cc index 9d4b644d112..d72b7e70c0d 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -337,6 +337,58 @@ Layout::create_initial_dynamic_sections(const Input_objects* input_objects, this->dynamic_section_->add_output_section_data(this->dynamic_data_); } +// For each output section whose name can be represented as C symbol, +// define __start and __stop symbols for the section. This is a GNU +// extension. + +void +Layout::define_section_symbols(Symbol_table* symtab, const Target* target) +{ + for (Section_list::const_iterator p = this->section_list_.begin(); + p != this->section_list_.end(); + ++p) + { + const char* const name = (*p)->name(); + if (name[strspn(name, + ("0123456789" + "ABCDEFGHIJKLMNOPWRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "_"))] + == '\0') + { + const std::string name_string(name); + const std::string start_name("__start_" + name_string); + const std::string stop_name("__stop_" + name_string); + + symtab->define_in_output_data(target, + start_name.c_str(), + NULL, // version + *p, + 0, // value + 0, // symsize + elfcpp::STT_NOTYPE, + elfcpp::STB_GLOBAL, + elfcpp::STV_DEFAULT, + 0, // nonvis + false, // offset_is_from_end + false); // only_if_ref + + symtab->define_in_output_data(target, + stop_name.c_str(), + NULL, // version + *p, + 0, // value + 0, // symsize + elfcpp::STT_NOTYPE, + elfcpp::STB_GLOBAL, + elfcpp::STV_DEFAULT, + 0, // nonvis + true, // offset_is_from_end + false); // only_if_ref + } + } +} + // Find the first read-only PT_LOAD segment, creating one if // necessary. diff --git a/gold/layout.h b/gold/layout.h index 8b349cc0a4b..ecb0490a589 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -85,6 +85,10 @@ class Layout void create_initial_dynamic_sections(const Input_objects*, Symbol_table*); + // Define __start and __stop symbols for output sections. + void + define_section_symbols(Symbol_table*, const Target*); + // Return the Stringpool used for symbol names. const Stringpool* sympool() const -- 2.30.2