From d491d34e930046f820def9d3d67a2491df8a2198 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 19 Apr 2008 18:30:58 +0000 Subject: * object.cc (Xindex::initialize_symtab_xindex): New function. (Xindex::read_symtab_xindex): New function. (Xindex::sym_xindex_to_shndx): New function. (Sized_relobj::find_symtab): Pick up SHT_SYMTAB_SHNDX section if available. (Sized_relobj::do_initialize_xindex): New function. (Sized_relobj::do_read_symbols): Adjust section links. (Sized_relobj::symbol_section_and_value): Add is_ordinary parameter. Change all callers. (Sized_relobj::include_section_group): Adjust section links and symbol section indexes. (Sized_relobj::do_layout): Adjust section links. (Sized_relobj::do_count_local_symbols): Adjust section links and symbol section indexes. (Sized_relobj::do_finalize_local_symbols): Distinguish between ordinary and special symbols. (Sized_relobj::write_local_symbols): Add symtab_xindex and dynsym_xindex parameters. Change all callers. Adjust section links. Use SHN_XINDEX when needed. (Sized_relobj::get_symbol_location_info): Adjust section links. Don't get fooled by special symbols. * object.h (class Xindex): Define. (class Object): Add xindex_ parameter. Declare virtual functoin do_initialize_xindex. (Object::adjust_sym_shndx): New function. (Object::set_xindex): New protected function. (class Symbol_value): Add is_ordinary_shndx_ field. (Symbol_value::Symbol_value): Initialize is_ordinary_shndx_. (Symbol_value::value): Assert ordinary section. (Symbol_value::initialize_input_to_output_map): Likewise. (Symbol_value::set_input_shndx): Add is_ordinary parameter. Change all callers. (Symbol_value::input_shndx): Add is_ordinary parameter. Change all callers. (class Sized_relobj): Update declarations. (Sized_relobj::local_symbol_input_shndx): Add is_ordinary parameter. Change all callers. (Sized_relobj::adjust_shndx): New function. * dynobj.cc (Sized_dynobj::Sized_dynobj): Initialize dynsym_shndx_ field. (Sized_dynobj::find_dynsym_sections): Remove pdynsym_shndx parameter. Change all callers. Pick up SHT_DYNSYM_SHNDX section for SHT_DYNSYM section if available. Set dynsym_shndx_ field. (Sized_dynobj::read_dynsym_section): Adjust section links. (Sized_dynobj::read_dynamic): Likewise. (Sized_dynobj::do_read_symbols): Use dynsym_shndx_ field. Adjust section links. (Sized_dynobj::do_initialize_xindex): New function. * dynobj.h (class Sized_dynobj): Add dynsym_shndx_ field. Declare do_initialize_xindex. (Sized_dynobj::adjust_shndx): New function. * layout.cc (Layout::Layout): Initialize symtab_xindex_ and dynsym_xindex_ fields. (Layout::finalize): Add a call to set_section_indexes before creating the symtab sections. (Layout::set_section_indexes): Don't do anything if the section already has a section index. (Layout::create_symtab_sections): Add shnum parameter. Change caller. Create .symtab_shndx section if needed. (Layout::create_shdrs): Add shstrtab_section parameter. Change caller. (Layout::allocated_output_section_count): New function. (Layout::create_dynamic_symtab): Create .dynsym_shndx section if needed. * layout.h (class Layout): Add symtab_xindex_ and dynsym_xindex_ fields. Update declarations. (Layout::symtab_xindex): New function. (Layout::dynsym_xindex): New function. (class Write_symbols_task): Add layout_ field. (Write_symbols_task::Write_symbols_task): Add layout parameter. Change caller. * output.cc (Output_section_headers::Output_section_headers): Add shstrtab_section parameter. Change all callers. (Output_section_headers::do_sized_write): Store overflow values for section count and section string table section index in section header zero. (Output_file_header::do_sized_write): Check for overflow of section count and section string table section index. (Output_symtab_xindex::do_write): New function. (Output_symtab_xindex::endian_do_write): New function. * output.h (class Output_section_headers): Add shstrtab_section_. Update declarations. (class Output_symtab_xindex): Define. (Output_section::has_out_shndx): New function. * symtab.cc (Symbol::init_fields): Initialize is_ordinary_shndx_ field. (Symbol::init_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::init): Likewise. (Symbol::output_section): Check for ordinary symbol. (Symbol_table::add_from_object): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. (Symbol_table::add_from_relobj): Add symndx_offset parameter. Change all callers. Simplify handling of symbols from sections not included in the link. (Symbol_table::add_from_dynobj): Handle ordinary symbol distinction. (Weak_alias_sorter::operator()): Assert that symbols are ordinary. (Symbol_table::sized_finalize_symbol): Handle ordinary symbol distinction. (Symbol_table::write_globals): Add symtab_xindex and dynsym_xindex parameters. Change all callers. (Symbol_table::sized_write_globals): Likewise. Handle ordinary symbol distinction. Use SHN_XINDEX when needed. (Symbol_table::write_section_symbol): Add symtab_xindex parameter. Change all callers. (Symbol_table::sized_write_section_symbol): Likewise. Use SHN_XINDEX when needed. * symtab.h (class Symbol): Add is_ordinary_shndx_ field. Update declarations. (Symbol::shndx): Add is_ordinary parameter. Change all callers. (Symbol::is_defined): Check is_ordinary. (Symbol::is_undefined, Symbol::is_weak_undefined): Likewise. (Symbol::is_absolute, Symbol::is_common): Likewise. (class Sized_symbol): Update declarations. (class Symbol_table): Update declarations. * resolve.cc (Symbol::override_base): Add st_shndx and is_ordinary parameters. Change all callers. (Sized_symbol::override): Likewise. (Symbol_table::override): Likewise. (symbol_to_bits): Add is_ordinary parameter. Change all callers. (Symbol_table::resolve): Remove orig_sym parameter. Add st_shndx, is_ordinary, and orig_st_shndx parameters. Change all callers. * copy-relocs.cc (Copy_relocs::emit_copy_reloc): Require symbol to be in an ordinary section. * dwarf_reader.cc (Sized_dwarf_line_info::symbol_section): Add object and is_ordinary parameters. Change all callers. (Sized_dwarf_line_info::read_relocs): Add object parameter. Change all callers. Don't add undefined or non-ordinary symbols to reloc_map_. (Sized_dwarf_line_info::read_line_mappings): Add object parameter. Change all callers. * dwarf_reader.h (class Sized_dwarf_line_info): Update declarations. * ehframe.cc (Eh_frame::read_fde): Check for ordinary symbol. * reloc.cc (Sized_relobj::do_read_relocs): Adjust section links. (Sized_relobj::relocate_sections): Likewise. * target-reloc.h (scan_relocs): Adjust section symbol index. (scan_relocatable_relocs): Likewise. * i386.cc (Scan::local): Check for ordinary symbols. * sparc.cc (Scan::local): Likewise. * x86_64.cc (Scan::local): Likewise. * testsuite/binary_unittest.cc (Sized_binary_test): Update calls to symbol_section_and_value. * testsuite/many_sections_test.cc: New file. * testsuite/Makefile.am (BUILT_SOURCES): Define. (check_PROGRAMS): Add many_sections_test. (many_sections_test_SOURCES): Define. (many_sections_test_DEPENDENCIES): Define. (many_sections_test_LDFLAGS): Define. (BUILT_SOURCES): Add many_sections_define.h. (many_sections_define.h): New target. (BUILT_SOURCES): Add many_sections_check.h. (many_sections_check.h): New target. (check_PROGRAMS): Add many_sections_r_test. (many_sections_r_test_SOURCES): Define. (many_sections_r_test_DEPENDENCIES): Define. (many_sections_r_test_LDFLAGS): Define. (many_sections_r_test_LDADD): Define. (many_sections_r_test.o): New target. * testsuite/Makefile.in: Rebuild. --- gold/layout.cc | 153 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 125 insertions(+), 28 deletions(-) (limited to 'gold/layout.cc') diff --git a/gold/layout.cc b/gold/layout.cc index fa0d4c8..a3bcf21 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -76,15 +76,33 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task) // Layout methods. Layout::Layout(const General_options& options, Script_options* script_options) - : options_(options), script_options_(script_options), namepool_(), - sympool_(), dynpool_(), signatures_(), - section_name_map_(), segment_list_(), section_list_(), - unattached_section_list_(), sections_are_attached_(false), - special_output_list_(), section_headers_(NULL), tls_segment_(NULL), - symtab_section_(NULL), dynsym_section_(NULL), dynamic_section_(NULL), - dynamic_data_(NULL), eh_frame_section_(NULL), eh_frame_data_(NULL), - added_eh_frame_data_(false), eh_frame_hdr_section_(NULL), - build_id_note_(NULL), group_signatures_(), output_file_size_(-1), + : options_(options), + script_options_(script_options), + namepool_(), + sympool_(), + dynpool_(), + signatures_(), + section_name_map_(), + segment_list_(), + section_list_(), + unattached_section_list_(), + sections_are_attached_(false), + special_output_list_(), + section_headers_(NULL), + tls_segment_(NULL), + symtab_section_(NULL), + symtab_xindex_(NULL), + dynsym_section_(NULL), + dynsym_xindex_(NULL), + dynamic_section_(NULL), + dynamic_data_(NULL), + eh_frame_section_(NULL), + eh_frame_data_(NULL), + added_eh_frame_data_(false), + eh_frame_hdr_section_(NULL), + build_id_note_(NULL), + group_signatures_(), + output_file_size_(-1), input_requires_executable_stack_(false), input_with_gnu_stack_note_(false), input_without_gnu_stack_note_(false), @@ -1149,8 +1167,12 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // sections. off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS); + // Set the section indexes of all unallocated sections seen so far, + // in case any of them are somehow referenced by a symbol. + shndx = this->set_section_indexes(shndx); + // Create the symbol table sections. - this->create_symtab_sections(input_objects, symtab, &off); + this->create_symtab_sections(input_objects, symtab, shndx, &off); if (!parameters->doing_static_link()) this->assign_local_dynsym_offsets(input_objects); @@ -1165,11 +1187,12 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // don't have to wait for the input sections. off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS); - // Now that all sections have been created, set the section indexes. + // Now that all sections have been created, set the section indexes + // for any sections which haven't been done yet. shndx = this->set_section_indexes(shndx); // Create the section table header. - this->create_shdrs(&off); + this->create_shdrs(shstrtab_section, &off); // If there are no sections which require postprocessing, we can // handle the section names now, and avoid a resize later. @@ -1816,18 +1839,15 @@ Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass) unsigned int Layout::set_section_indexes(unsigned int shndx) { - const bool output_is_object = parameters->options().relocatable(); for (Section_list::iterator p = this->unattached_section_list_.begin(); p != this->unattached_section_list_.end(); ++p) { - // In a relocatable link, we already did group sections. - if (output_is_object - && (*p)->type() == elfcpp::SHT_GROUP) - continue; - - (*p)->set_out_shndx(shndx); - ++shndx; + if (!(*p)->has_out_shndx()) + { + (*p)->set_out_shndx(shndx); + ++shndx; + } } return shndx; } @@ -1893,11 +1913,12 @@ Layout::count_local_symbols(const Task* task, // Create the symbol table sections. Here we also set the final // values of the symbols. At this point all the loadable sections are -// fully laid out. +// fully laid out. SHNUM is the number of sections so far. void Layout::create_symtab_sections(const Input_objects* input_objects, Symbol_table* symtab, + unsigned int shnum, off_t* poff) { int symsize; @@ -1988,6 +2009,38 @@ Layout::create_symtab_sections(const Input_objects* input_objects, align); osymtab->add_output_section_data(pos); + // We generate a .symtab_shndx section if we have more than + // SHN_LORESERVE sections. Technically it is possible that we + // don't need one, because it is possible that there are no + // symbols in any of sections with indexes larger than + // SHN_LORESERVE. That is probably unusual, though, and it is + // easier to always create one than to compute section indexes + // twice (once here, once when writing out the symbols). + if (shnum >= elfcpp::SHN_LORESERVE) + { + const char* symtab_xindex_name = this->namepool_.add(".symtab_shndx", + false, NULL); + Output_section* osymtab_xindex = + this->make_output_section(symtab_xindex_name, + elfcpp::SHT_SYMTAB_SHNDX, 0); + + size_t symcount = (off - startoff) / symsize; + this->symtab_xindex_ = new Output_symtab_xindex(symcount); + + osymtab_xindex->add_output_section_data(this->symtab_xindex_); + + osymtab_xindex->set_link_section(osymtab); + osymtab_xindex->set_addralign(4); + osymtab_xindex->set_entsize(4); + + osymtab_xindex->set_after_input_sections(); + + // This tells the driver code to wait until the symbol table + // has written out before writing out the postprocessing + // sections, including the .symtab_shndx section. + this->any_postprocessing_sections_ = true; + } + const char* strtab_name = this->namepool_.add(".strtab", false, NULL); Output_section* ostrtab = this->make_output_section(strtab_name, elfcpp::SHT_STRTAB, @@ -2035,14 +2088,15 @@ Layout::create_shstrtab() // offset. void -Layout::create_shdrs(off_t* poff) +Layout::create_shdrs(const Output_section* shstrtab_section, off_t* poff) { Output_section_headers* oshdrs; oshdrs = new Output_section_headers(this, &this->segment_list_, &this->section_list_, &this->unattached_section_list_, - &this->namepool_); + &this->namepool_, + shstrtab_section); off_t off = align_address(*poff, oshdrs->addralign()); oshdrs->set_address_and_file_offset(0, off); off += oshdrs->data_size(); @@ -2050,6 +2104,19 @@ Layout::create_shdrs(off_t* poff) this->section_headers_ = oshdrs; } +// Count the allocated sections. + +size_t +Layout::allocated_output_section_count() const +{ + size_t section_count = 0; + for (Segment_list::const_iterator p = this->segment_list_.begin(); + p != this->segment_list_.end(); + ++p) + section_count += (*p)->output_section_count(); + return section_count; +} + // Create the dynamic symbol table. void @@ -2093,8 +2160,6 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, unsigned int local_symcount = index; *plocal_dynamic_count = local_symcount; - // FIXME: We have to tell set_dynsym_indexes whether the - // -E/--export-dynamic option was used. index = symtab->set_dynsym_indexes(index, pdynamic_symbols, &this->dynpool_, pversions); @@ -2135,6 +2200,37 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, odyn->add_section_address(elfcpp::DT_SYMTAB, dynsym); odyn->add_constant(elfcpp::DT_SYMENT, symsize); + // If there are more than SHN_LORESERVE allocated sections, we + // create a .dynsym_shndx section. It is possible that we don't + // need one, because it is possible that there are no dynamic + // symbols in any of the sections with indexes larger than + // SHN_LORESERVE. This is probably unusual, though, and at this + // time we don't know the actual section indexes so it is + // inconvenient to check. + if (this->allocated_output_section_count() >= elfcpp::SHN_LORESERVE) + { + Output_section* dynsym_xindex = + this->choose_output_section(NULL, ".dynsym_shndx", + elfcpp::SHT_SYMTAB_SHNDX, + elfcpp::SHF_ALLOC, + false); + + this->dynsym_xindex_ = new Output_symtab_xindex(index); + + dynsym_xindex->add_output_section_data(this->dynsym_xindex_); + + dynsym_xindex->set_link_section(dynsym); + dynsym_xindex->set_addralign(4); + dynsym_xindex->set_entsize(4); + + dynsym_xindex->set_after_input_sections(); + + // This tells the driver code to wait until the symbol table has + // written out before writing out the postprocessing sections, + // including the .dynsym_shndx section. + this->any_postprocessing_sections_ = true; + } + // Create the dynamic string table section. Output_section* dynstr = this->choose_output_section(NULL, ".dynstr", @@ -2766,7 +2862,7 @@ Layout::write_data(const Symbol_table* symtab, Output_file* of) const gold_assert(index > 0 && index != -1U); off_t off = (symtab_section->offset() + index * symtab_section->entsize()); - symtab->write_section_symbol(*p, of, off); + symtab->write_section_symbol(*p, this->symtab_xindex_, of, off); } } } @@ -2783,7 +2879,7 @@ Layout::write_data(const Symbol_table* symtab, Output_file* of) const gold_assert(index > 0 && index != -1U); off_t off = (dynsym_section->offset() + index * dynsym_section->entsize()); - symtab->write_section_symbol(*p, of, off); + symtab->write_section_symbol(*p, this->dynsym_xindex_, of, off); } } @@ -3014,7 +3110,8 @@ void Write_symbols_task::run(Workqueue*) { this->symtab_->write_globals(this->input_objects_, this->sympool_, - this->dynpool_, this->of_); + this->dynpool_, this->layout_->symtab_xindex(), + this->layout_->dynsym_xindex(), this->of_); } // Write_after_input_sections_task methods. -- cgit v1.1