aboutsummaryrefslogtreecommitdiff
path: root/gold/object.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2008-04-19 18:30:58 +0000
committerIan Lance Taylor <ian@airs.com>2008-04-19 18:30:58 +0000
commitd491d34e930046f820def9d3d67a2491df8a2198 (patch)
tree7e955be0ab4ec83f4711c309a6dcf130f341da99 /gold/object.cc
parent8e91f0232ca9c286299092c896288b8657c9311b (diff)
downloadgdb-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.cc236
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)";