aboutsummaryrefslogtreecommitdiff
path: root/gold/layout.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-06-24 00:38:00 +0000
committerIan Lance Taylor <ian@airs.com>2009-06-24 00:38:00 +0000
commit1518dc8f89bfcd443f8853368fd44cbd526f2a7f (patch)
tree137c3587d4a25e9d527e5e8e7eeac06fe2553ed2 /gold/layout.cc
parenta71d5864861507609376014210d365250704b225 (diff)
downloadgdb-1518dc8f89bfcd443f8853368fd44cbd526f2a7f.zip
gdb-1518dc8f89bfcd443f8853368fd44cbd526f2a7f.tar.gz
gdb-1518dc8f89bfcd443f8853368fd44cbd526f2a7f.tar.bz2
PR 10219
* layout.cc (Layout::Layout): Initialize have_stabstr_section_. (Layout::make_output_section): Set have_stabstr_section_ if we see a .stab*str section. (Layout::finalize): Call link_stabs_sections. (Layout::link_stabs_sections): New file. * layout.h (class Layout): Add have_stabstr_section_ field. Declare link_stabs_sections.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r--gold/layout.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index 4efb9c1..8dba501 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -124,6 +124,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
has_static_tls_(false),
any_postprocessing_sections_(false),
resized_signatures_(false),
+ have_stabstr_section_(false),
incremental_inputs_(NULL)
{
// Make space for more than enough segments for a typical file.
@@ -823,6 +824,14 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
}
}
+ // Check for .stab*str sections, as .stab* sections need to link to
+ // them.
+ if (type == elfcpp::SHT_STRTAB
+ && !this->have_stabstr_section_
+ && strncmp(name, ".stab", 5) == 0
+ && strcmp(name + strlen(name) - 3, "str") == 0)
+ this->have_stabstr_section_ = true;
+
// If we have already attached the sections to segments, then we
// need to attach this one now. This happens for sections created
// directly by the linker.
@@ -1192,6 +1201,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
this->create_gold_note();
this->create_executable_stack_info(target);
this->create_build_id();
+ this->link_stabs_sections();
Output_segment* phdr_seg = NULL;
if (!parameters->options().relocatable() && !parameters->doing_static_link())
@@ -1616,6 +1626,40 @@ Layout::create_build_id()
}
}
+// If we have both .stabXX and .stabXXstr sections, then the sh_link
+// field of the former should point to the latter. I'm not sure who
+// started this, but the GNU linker does it, and some tools depend
+// upon it.
+
+void
+Layout::link_stabs_sections()
+{
+ if (!this->have_stabstr_section_)
+ return;
+
+ for (Section_list::iterator p = this->section_list_.begin();
+ p != this->section_list_.end();
+ ++p)
+ {
+ if ((*p)->type() != elfcpp::SHT_STRTAB)
+ continue;
+
+ const char* name = (*p)->name();
+ if (strncmp(name, ".stab", 5) != 0)
+ continue;
+
+ size_t len = strlen(name);
+ if (strcmp(name + len - 3, "str") != 0)
+ continue;
+
+ std::string stab_name(name, len - 3);
+ Output_section* stab_sec;
+ stab_sec = this->find_output_section(stab_name.c_str());
+ if (stab_sec != NULL)
+ stab_sec->set_link_section(*p);
+ }
+}
+
// Create .gnu_incremental_inputs and .gnu_incremental_strtab sections needed
// for the next run of incremental linking to check what has changed.