diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-04-19 18:30:58 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-04-19 18:30:58 +0000 |
commit | d491d34e930046f820def9d3d67a2491df8a2198 (patch) | |
tree | 7e955be0ab4ec83f4711c309a6dcf130f341da99 /gold/layout.cc | |
parent | 8e91f0232ca9c286299092c896288b8657c9311b (diff) | |
download | gdb-d491d34e930046f820def9d3d67a2491df8a2198.zip gdb-d491d34e930046f820def9d3d67a2491df8a2198.tar.gz gdb-d491d34e930046f820def9d3d67a2491df8a2198.tar.bz2 |
* 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.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r-- | gold/layout.cc | 153 |
1 files changed, 125 insertions, 28 deletions
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. |