diff --git a/gold/ChangeLog b/gold/ChangeLog index 7a19f89ddad..56a4da6426f 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2009-06-23 Ian Lance Taylor + + 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. + 2009-06-23 Doug Kwan * Makefile.am (libgold_a_LIBADD): New. diff --git a/gold/layout.cc b/gold/layout.cc index 4efb9c195f9..8dba501813f 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. diff --git a/gold/layout.h b/gold/layout.h index 93ecd8544de..f538b643cc5 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -480,6 +480,10 @@ class Layout void create_build_id(); + // Link .stab and .stabstr sections. + void + link_stabs_sections(); + // Create .gnu_incremental_inputs and .gnu_incremental_strtab sections needed // for the next run of incremental linking to check what has changed. void @@ -724,6 +728,8 @@ class Layout bool any_postprocessing_sections_; // Whether we have resized the signatures_ hash table. bool resized_signatures_; + // Whether we have created a .stab*str output section. + bool have_stabstr_section_; // In incremental build, holds information check the inputs and build the // .gnu_incremental_inputs section. Incremental_inputs* incremental_inputs_;