aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-09-22 04:42:09 +0000
committerIan Lance Taylor <iant@google.com>2007-09-22 04:42:09 +0000
commitbfd58944a64b0997a310b95fbe0423338961e71c (patch)
treeba78dccb512106e5eef43093c326272a679f08c3
parent306d9ef0484f1928594ce309c1239252fd4915c8 (diff)
downloadgdb-bfd58944a64b0997a310b95fbe0423338961e71c.zip
gdb-bfd58944a64b0997a310b95fbe0423338961e71c.tar.gz
gdb-bfd58944a64b0997a310b95fbe0423338961e71c.tar.bz2
Define __start and __stop symbols.
-rw-r--r--gold/gold.cc4
-rw-r--r--gold/layout.cc52
-rw-r--r--gold/layout.h4
3 files changed, 60 insertions, 0 deletions
diff --git a/gold/gold.cc b/gold/gold.cc
index e7b7ae2..2d33462 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 9d4b644..d72b7e7 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 8b349cc..ecb0490 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