forked from Imagelibrary/binutils-gdb
* 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.
This commit is contained in:
153
gold/layout.cc
153
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.
|
||||
|
||||
Reference in New Issue
Block a user