From eb14a8b4bfb767beebfb54d7911da4132b5c0f94 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 21 Jul 2023 16:57:18 +0930 Subject: [PATCH] [GOLD] reporting local symbol names get_symbol_name currently returns "" for the usual STT_SECTION symbols generated by gas. That's not very helpful, return the section name. Demangle local symbols too, fixing an inconsistency in issue_discarded_error where global symbols are demangled. * object.cc (Sized_relobj_file::get_symbol_name): Return a std::string. Return section name for STT_SECTION symbols with zero st_name. Sanity check st_name, and don't run off the end of an improperly terminated .strtab. Demangle sym names. * object.h (Sized_relobj_file::get_symbol_name): Update decl. * target-reloc.h (issue_discarded_error): Adjust. * powerpc.cc (Target_powerpc::Relocate::relocate): Report reloc type and symbol for relocation overflows. --- gold/object.cc | 45 +++++++++++++++++++++++++++++++++++++-------- gold/object.h | 2 +- gold/powerpc.cc | 11 +++++++++-- gold/target-reloc.h | 4 ++-- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/gold/object.cc b/gold/object.cc index 77b2690c381..acd7c945937 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -3054,7 +3054,7 @@ Sized_relobj_file::find_kept_section_object( // Return the name of symbol SYMNDX. template -const char* +std::string Sized_relobj_file::get_symbol_name(unsigned int symndx) { if (this->symtab_shndx_ == 0) @@ -3065,6 +3065,24 @@ Sized_relobj_file::get_symbol_name(unsigned int symndx) &symbols_size, false); + const unsigned char* p = symbols + symndx * This::sym_size; + if (p >= symbols + symbols_size) + return NULL; + + elfcpp::Sym sym(p); + + if (sym.get_st_name() == 0 && sym.get_st_type() == elfcpp::STT_SECTION) + { + 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()) + return NULL; + + return this->section_name(sym_shndx); + } + unsigned int symbol_names_shndx = this->adjust_shndx(this->section_link(this->symtab_shndx_)); section_size_type names_size; @@ -3072,14 +3090,25 @@ Sized_relobj_file::get_symbol_name(unsigned int symndx) this->section_contents(symbol_names_shndx, &names_size, false); const char* symbol_names = reinterpret_cast(symbol_names_u); - const unsigned char* p = symbols + symndx * This::sym_size; - - if (p >= symbols + symbols_size) + unsigned int sym_name = sym.get_st_name(); + if (sym_name >= names_size) return NULL; - - elfcpp::Sym sym(p); - - return symbol_names + sym.get_st_name(); + const char* namep = symbol_names + sym_name; + const void* endp = memchr(namep, 0, names_size - sym_name); + if (!endp) + endp = symbol_names + names_size; + std::string name = std::string(namep, static_cast(endp) - namep); + + if (!parameters->options().do_demangle()) + return name; + + char* demangled_name = cplus_demangle(name.c_str(), DMGL_ANSI | DMGL_PARAMS); + if (!demangled_name) + return name; + + name = demangled_name; + free(demangled_name); + return name; } // Get symbol counts. diff --git a/gold/object.h b/gold/object.h index e7472893ca6..d6c53eb105e 100644 --- a/gold/object.h +++ b/gold/object.h @@ -2347,7 +2347,7 @@ class Sized_relobj_file : public Sized_relobj find_kept_section_object(unsigned int shndx, unsigned int* symndx_p) const; // Return the name of symbol SYMNDX. - const char* + std::string get_symbol_name(unsigned int symndx); // Compute final local symbol value. R_SYM is the local symbol index. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index d62bdea7ecb..e66d9cbb900 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -12420,17 +12420,24 @@ Target_powerpc::Relocate::relocate( && gsym->is_undefined() && is_branch_reloc(r_type)))) { + std::string name; + if (gsym) + name = gsym->demangled_name(); + else + name = relinfo->object->get_symbol_name(r_sym); if (os->flags() & elfcpp::SHF_ALLOC) { gold_error_at_location(relinfo, relnum, rela.get_r_offset(), - _("relocation overflow")); + _("reloc type %u overflow against '%s'"), + r_type, name.c_str()); if (has_stub_value) gold_info(_("try relinking with a smaller --stub-group-size")); } else { gold_warning_at_location(relinfo, relnum, rela.get_r_offset(), - _("relocation overflow")); + _("reloc type %u overflow against '%s'"), + r_type, name.c_str()); gold_info(_("debug info may be unreliable, compile with -gdwarf64")); } } diff --git a/gold/target-reloc.h b/gold/target-reloc.h index 5f4c5c5a101..1df25ae452e 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -242,7 +242,7 @@ issue_discarded_error( relinfo, shndx, offset, _("relocation refers to local symbol \"%s\" [%u], " "which is defined in a discarded section"), - object->get_symbol_name(r_sym), r_sym); + object->get_symbol_name(r_sym).c_str(), r_sym); } else { @@ -264,7 +264,7 @@ issue_discarded_error( &key_symndx); if (key_symndx != 0) gold_info(_(" section group signature: \"%s\""), - object->get_symbol_name(key_symndx)); + object->get_symbol_name(key_symndx).c_str()); if (kept_obj != NULL) gold_info(_(" prevailing definition is from %s"), kept_obj->name().c_str()); -- 2.30.2