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/object.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/object.cc')
-rw-r--r-- | gold/object.cc | 236 |
1 files changed, 199 insertions, 37 deletions
diff --git a/gold/object.cc b/gold/object.cc index 2849093..19d9185 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -40,6 +40,93 @@ namespace gold { +// Class Xindex. + +// Initialize the symtab_xindex_ array. Find the SHT_SYMTAB_SHNDX +// section and read it in. SYMTAB_SHNDX is the index of the symbol +// table we care about. + +template<int size, bool big_endian> +void +Xindex::initialize_symtab_xindex(Object* object, unsigned int symtab_shndx) +{ + if (!this->symtab_xindex_.empty()) + return; + + gold_assert(symtab_shndx != 0); + + // Look through the sections in reverse order, on the theory that it + // is more likely to be near the end than the beginning. + unsigned int i = object->shnum(); + while (i > 0) + { + --i; + if (object->section_type(i) == elfcpp::SHT_SYMTAB_SHNDX + && this->adjust_shndx(object->section_link(i)) == symtab_shndx) + { + this->read_symtab_xindex<size, big_endian>(object, i, NULL); + return; + } + } + + object->error(_("missing SHT_SYMTAB_SHNDX section")); +} + +// Read in the symtab_xindex_ array, given the section index of the +// SHT_SYMTAB_SHNDX section. If PSHDRS is not NULL, it points at the +// section headers. + +template<int size, bool big_endian> +void +Xindex::read_symtab_xindex(Object* object, unsigned int xindex_shndx, + const unsigned char* pshdrs) +{ + section_size_type bytecount; + const unsigned char* contents; + if (pshdrs == NULL) + contents = object->section_contents(xindex_shndx, &bytecount, false); + else + { + const unsigned char* p = (pshdrs + + (xindex_shndx + * elfcpp::Elf_sizes<size>::shdr_size)); + typename elfcpp::Shdr<size, big_endian> shdr(p); + bytecount = convert_to_section_size_type(shdr.get_sh_size()); + contents = object->get_view(shdr.get_sh_offset(), bytecount, true, false); + } + + gold_assert(this->symtab_xindex_.empty()); + this->symtab_xindex_.reserve(bytecount / 4); + for (section_size_type i = 0; i < bytecount; i += 4) + { + unsigned int shndx = elfcpp::Swap<32, big_endian>::readval(contents + i); + // We preadjust the section indexes we save. + this->symtab_xindex_.push_back(this->adjust_shndx(shndx)); + } +} + +// Symbol symndx has a section of SHN_XINDEX; return the real section +// index. + +unsigned int +Xindex::sym_xindex_to_shndx(Object* object, unsigned int symndx) +{ + if (symndx >= this->symtab_xindex_.size()) + { + object->error(_("symbol %u out of range for SHT_SYMTAB_SHNDX section"), + symndx); + return elfcpp::SHN_UNDEF; + } + unsigned int shndx = this->symtab_xindex_[symndx]; + if (shndx < elfcpp::SHN_LORESERVE || shndx >= object->shnum()) + { + object->error(_("extended index for symbol %u out of range: %u"), + symndx, shndx); + return elfcpp::SHN_UNDEF; + } + return shndx; +} + // Class Object. // Set the target based on fields in the ELF file header. @@ -204,6 +291,8 @@ Sized_relobj<size, big_endian>::find_symtab(const unsigned char* pshdrs) // to put the symbol table at the end. const unsigned char* p = pshdrs + shnum * This::shdr_size; unsigned int i = shnum; + unsigned int xindex_shndx = 0; + unsigned int xindex_link = 0; while (i > 0) { --i; @@ -212,12 +301,43 @@ Sized_relobj<size, big_endian>::find_symtab(const unsigned char* pshdrs) if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB) { this->symtab_shndx_ = i; + if (xindex_shndx > 0 && xindex_link == i) + { + Xindex* xindex = + new Xindex(this->elf_file_.large_shndx_offset()); + xindex->read_symtab_xindex<size, big_endian>(this, + xindex_shndx, + pshdrs); + this->set_xindex(xindex); + } break; } + + // Try to pick up the SHT_SYMTAB_SHNDX section, if there is + // one. This will work if it follows the SHT_SYMTAB + // section. + if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB_SHNDX) + { + xindex_shndx = i; + xindex_link = this->adjust_shndx(shdr.get_sh_link()); + } } } } +// Return the Xindex structure to use for object with lots of +// sections. + +template<int size, bool big_endian> +Xindex* +Sized_relobj<size, big_endian>::do_initialize_xindex() +{ + gold_assert(this->symtab_shndx_ != -1U); + Xindex* xindex = new Xindex(this->elf_file_.large_shndx_offset()); + xindex->initialize_symtab_xindex<size, big_endian>(this, this->symtab_shndx_); + return xindex; +} + // Return whether SHDR has the right type and flags to be a GNU // .eh_frame section. @@ -323,7 +443,7 @@ Sized_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd) File_view* fvsymtab = this->get_lasting_view(readoff, readsize, true, false); // Read the section header for the symbol names. - unsigned int strtab_shndx = symtabshdr.get_sh_link(); + unsigned int strtab_shndx = this->adjust_shndx(symtabshdr.get_sh_link()); if (strtab_shndx >= this->shnum()) { this->error(_("invalid symbol table name index: %u"), strtab_shndx); @@ -351,14 +471,17 @@ Sized_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd) } // Return the section index of symbol SYM. Set *VALUE to its value in -// the object file. Note that for a symbol which is not defined in -// this object file, this will set *VALUE to 0 and return SHN_UNDEF; -// it will not return the final value of the symbol in the link. +// the object file. Set *IS_ORDINARY if this is an ordinary section +// index. not a special cod between SHN_LORESERVE and SHN_HIRESERVE. +// Note that for a symbol which is not defined in this object file, +// this will set *VALUE to 0 and return SHN_UNDEF; it will not return +// the final value of the symbol in the link. template<int size, bool big_endian> unsigned int Sized_relobj<size, big_endian>::symbol_section_and_value(unsigned int sym, - Address* value) + Address* value, + bool* is_ordinary) { section_size_type symbols_size; const unsigned char* symbols = this->section_contents(this->symtab_shndx_, @@ -370,8 +493,8 @@ Sized_relobj<size, big_endian>::symbol_section_and_value(unsigned int sym, elfcpp::Sym<size, big_endian> elfsym(symbols + sym * This::sym_size); *value = elfsym.get_st_value(); - // FIXME: Handle SHN_XINDEX. - return elfsym.get_st_shndx(); + + return this->adjust_sym_shndx(sym, elfsym.get_st_shndx(), is_ordinary); } // Return whether to include a section group in the link. LAYOUT is @@ -408,17 +531,18 @@ Sized_relobj<size, big_endian>::include_section_group( // Get the appropriate symbol table header (this will normally be // the single SHT_SYMTAB section, but in principle it need not be). - const unsigned int link = shdr.get_sh_link(); + const unsigned int link = this->adjust_shndx(shdr.get_sh_link()); typename This::Shdr symshdr(this, this->elf_file_.section_header(link)); // Read the symbol table entry. - if (shdr.get_sh_info() >= symshdr.get_sh_size() / This::sym_size) + unsigned int symndx = shdr.get_sh_info(); + if (symndx >= symshdr.get_sh_size() / This::sym_size) { this->error(_("section group %u info %u out of range"), - index, shdr.get_sh_info()); + index, symndx); return false; } - off_t symoff = symshdr.get_sh_offset() + shdr.get_sh_info() * This::sym_size; + off_t symoff = symshdr.get_sh_offset() + symndx * This::sym_size; const unsigned char* psym = this->get_view(symoff, This::sym_size, true, false); elfcpp::Sym<size, big_endian> sym(psym); @@ -426,15 +550,15 @@ Sized_relobj<size, big_endian>::include_section_group( // Read the symbol table names. section_size_type symnamelen; const unsigned char* psymnamesu; - psymnamesu = this->section_contents(symshdr.get_sh_link(), &symnamelen, - true); + psymnamesu = this->section_contents(this->adjust_shndx(symshdr.get_sh_link()), + &symnamelen, true); const char* psymnames = reinterpret_cast<const char*>(psymnamesu); // Get the section group signature. if (sym.get_st_name() >= symnamelen) { this->error(_("symbol %u name offset %u out of range"), - shdr.get_sh_info(), sym.get_st_name()); + symndx, sym.get_st_name()); return false; } @@ -443,11 +567,20 @@ Sized_relobj<size, big_endian>::include_section_group( // It seems that some versions of gas will create a section group // associated with a section symbol, and then fail to give a name to // the section symbol. In such a case, use the name of the section. - // FIXME. std::string secname; if (signature[0] == '\0' && sym.get_st_type() == elfcpp::STT_SECTION) { - secname = this->section_name(sym.get_st_shndx()); + bool is_ordinary; + unsigned int sym_shndx = this->adjust_sym_shndx(symndx, + sym.get_st_shndx(), + &is_ordinary); + if (!is_ordinary || sym_shndx >= this->shnum()) + { + this->error(_("symbol %u invalid section index %u"), + symndx, sym_shndx); + return false; + } + secname = this->section_name(sym_shndx); signature = secname.c_str(); } @@ -559,7 +692,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, unsigned int sh_type = shdr.get_sh_type(); if (sh_type == elfcpp::SHT_REL || sh_type == elfcpp::SHT_RELA) { - unsigned int target_shndx = shdr.get_sh_info(); + unsigned int target_shndx = this->adjust_shndx(shdr.get_sh_info()); if (target_shndx == 0 || target_shndx >= shnum) { this->error(_("relocation section %u has bad info %u"), @@ -723,7 +856,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, pshdr = sd->section_headers->data() + i * This::shdr_size; typename This::Shdr shdr(pshdr); - unsigned int data_shndx = shdr.get_sh_info(); + unsigned int data_shndx = this->adjust_shndx(shdr.get_sh_info()); if (data_shndx >= shnum) { // We already warned about this above. @@ -813,7 +946,11 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab, reinterpret_cast<const char*>(sd->symbol_names->data()); symtab->add_from_relobj(this, sd->symbols->data() + sd->external_symbols_offset, - symcount, sym_names, sd->symbol_names_size, + symcount, + (sd->external_symbols_offset == 0 + ? this->local_symbol_count_ + : 0), + sym_names, sd->symbol_names_size, &this->symbols_); delete sd->symbols; @@ -855,7 +992,8 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool, locsize, true, true); // Read the symbol names. - const unsigned int strtab_shndx = symtabshdr.get_sh_link(); + const unsigned int strtab_shndx = + this->adjust_shndx(symtabshdr.get_sh_link()); section_size_type strtab_size; const unsigned char* pnamesu = this->section_contents(strtab_shndx, &strtab_size, @@ -876,8 +1014,10 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool, Symbol_value<size>& lv(this->local_values_[i]); - unsigned int shndx = sym.get_st_shndx(); - lv.set_input_shndx(shndx); + bool is_ordinary; + unsigned int shndx = this->adjust_sym_shndx(i, sym.get_st_shndx(), + &is_ordinary); + lv.set_input_shndx(shndx, is_ordinary); if (sym.get_st_type() == elfcpp::STT_SECTION) lv.set_is_section_symbol(); @@ -937,7 +1077,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool, template<int size, bool big_endian> unsigned int Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, - off_t off) + off_t off) { gold_assert(off == static_cast<off_t>(align_address(off, size >> 3))); @@ -951,17 +1091,17 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, { Symbol_value<size>& lv(this->local_values_[i]); - unsigned int shndx = lv.input_shndx(); + bool is_ordinary; + unsigned int shndx = lv.input_shndx(&is_ordinary); // Set the output symbol value. - if (shndx >= elfcpp::SHN_LORESERVE) + if (!is_ordinary) { if (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON) lv.set_output_value(lv.input_value()); else { - // FIXME: Handle SHN_XINDEX. this->error(_("unknown section index %u for local symbol %u"), shndx, i); lv.set_output_value(0); @@ -1062,7 +1202,9 @@ void Sized_relobj<size, big_endian>::write_local_symbols( Output_file* of, const Stringpool* sympool, - const Stringpool* dynpool) + const Stringpool* dynpool, + Output_symtab_xindex* symtab_xindex, + Output_symtab_xindex* dynsym_xindex) { if (parameters->options().strip_all() && this->output_local_dynsym_count_ == 0) @@ -1090,7 +1232,8 @@ Sized_relobj<size, big_endian>::write_local_symbols( locsize, true, false); // Read the symbol names. - const unsigned int strtab_shndx = symtabshdr.get_sh_link(); + const unsigned int strtab_shndx = + this->adjust_shndx(symtabshdr.get_sh_link()); section_size_type strtab_size; const unsigned char* pnamesu = this->section_contents(strtab_shndx, &strtab_size, @@ -1121,18 +1264,30 @@ Sized_relobj<size, big_endian>::write_local_symbols( { elfcpp::Sym<size, big_endian> isym(psyms); - unsigned int st_shndx = isym.get_st_shndx(); - if (st_shndx < elfcpp::SHN_LORESERVE) + Symbol_value<size>& lv(this->local_values_[i]); + + bool is_ordinary; + unsigned int st_shndx = this->adjust_sym_shndx(i, isym.get_st_shndx(), + &is_ordinary); + if (is_ordinary) { gold_assert(st_shndx < mo.size()); if (mo[st_shndx].output_section == NULL) continue; st_shndx = mo[st_shndx].output_section->out_shndx(); + if (st_shndx >= elfcpp::SHN_LORESERVE) + { + if (lv.needs_output_symtab_entry()) + symtab_xindex->add(lv.output_symtab_index(), st_shndx); + if (lv.needs_output_dynsym_entry()) + dynsym_xindex->add(lv.output_dynsym_index(), st_shndx); + st_shndx = elfcpp::SHN_XINDEX; + } } // Write the symbol to the output symbol table. if (!parameters->options().strip_all() - && this->local_values_[i].needs_output_symtab_entry()) + && lv.needs_output_symtab_entry()) { elfcpp::Sym_write<size, big_endian> osym(ov); @@ -1149,7 +1304,7 @@ Sized_relobj<size, big_endian>::write_local_symbols( } // Write the symbol to the output dynamic symbol table. - if (this->local_values_[i].needs_output_dynsym_entry()) + if (lv.needs_output_dynsym_entry()) { gold_assert(dyn_ov < dyn_oview + dyn_output_size); elfcpp::Sym_write<size, big_endian> osym(dyn_ov); @@ -1201,7 +1356,8 @@ Sized_relobj<size, big_endian>::get_symbol_location_info( &symbols_size, false); - unsigned int symbol_names_shndx = this->section_link(this->symtab_shndx_); + unsigned int symbol_names_shndx = + this->adjust_shndx(this->section_link(this->symtab_shndx_)); section_size_type names_size; const unsigned char* symbol_names_u = this->section_contents(symbol_names_shndx, &names_size, false); @@ -1221,11 +1377,17 @@ Sized_relobj<size, big_endian>::get_symbol_location_info( info->source_file = "(invalid)"; else info->source_file = symbol_names + sym.get_st_name(); + continue; } - else if (sym.get_st_shndx() == shndx - && static_cast<off_t>(sym.get_st_value()) <= offset - && (static_cast<off_t>(sym.get_st_value() + sym.get_st_size()) - > offset)) + + bool is_ordinary; + unsigned int st_shndx = this->adjust_sym_shndx(i, sym.get_st_shndx(), + &is_ordinary); + if (is_ordinary + && st_shndx == shndx + && static_cast<off_t>(sym.get_st_value()) <= offset + && (static_cast<off_t>(sym.get_st_value() + sym.get_st_size()) + > offset)) { if (sym.get_st_name() > names_size) info->enclosing_symbol_name = "(invalid)"; |