[GOLD] reporting local symbol names
authorAlan Modra <amodra@gmail.com>
Fri, 21 Jul 2023 07:27:18 +0000 (16:57 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 26 Jul 2023 00:53:27 +0000 (10:23 +0930)
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
gold/object.h
gold/powerpc.cc
gold/target-reloc.h

index 77b2690c38144973fe203a68138ea30bdebd3237..acd7c945937cd84085703d926e789f5cefcbf251 100644 (file)
@@ -3054,7 +3054,7 @@ Sized_relobj_file<size, big_endian>::find_kept_section_object(
 // Return the name of symbol SYMNDX.
 
 template<int size, bool big_endian>
-const char*
+std::string
 Sized_relobj_file<size, big_endian>::get_symbol_name(unsigned int symndx)
 {
   if (this->symtab_shndx_ == 0)
@@ -3065,6 +3065,24 @@ Sized_relobj_file<size, big_endian>::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<size, big_endian> 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<size, big_endian>::get_symbol_name(unsigned int symndx)
     this->section_contents(symbol_names_shndx, &names_size, false);
   const char* symbol_names = reinterpret_cast<const char*>(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<size, big_endian> 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<const char*>(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.
index e7472893ca614daa5f4cd0e509ee060293874a57..d6c53eb105ef237ce2d2fb3dc2305204e6ef5d74 100644 (file)
@@ -2347,7 +2347,7 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
   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.
index d62bdea7ecbabc4c0d420cc1cb4460008142534b..e66d9cbb9005fddc11210a8581ab33fd1d95c39e 100644 (file)
@@ -12420,17 +12420,24 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
               && gsym->is_undefined()
               && is_branch_reloc<size>(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"));
        }
     }
index 5f4c5c5a101b0ca0f59229d260b3cd3a228ccb31..1df25ae452ef042fa0b27d7ce6fb4532eab28d5c 100644 (file)
@@ -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());