[3/3] gprofng: Remove duplicate symbols

Message ID 20250402091530.10597-3-claudiu.zissulescu-ianculescu@oracle.com
State New
Headers
Series [1/3] gprofng: Remove check_Relocs() function |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Claudiu Zissulescu-Ianculescu April 2, 2025, 9:15 a.m. UTC
  From: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>

Remove all duplicate symbols which can be in SymLst.  The duplication
is due to processing of both static and dynamic symbols.  The
Stabs::removeDupSyms function is called before computing symbol
aliases.

Introduce a new vector function (i.e., truncate()), that truncates a
vector lenght to the given new count.  This functionis used by
removeDupSyms function.

Signed-off-by: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
---
 gprofng/src/Stabs.cc | 35 +++++++++++++++++++++++++++++++++++
 gprofng/src/Stabs.h  |  1 +
 gprofng/src/vec.h    |  7 +++++++
 3 files changed, 43 insertions(+)
  

Patch

diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc
index 2f64810b25f..b98ac283887 100644
--- a/gprofng/src/Stabs.cc
+++ b/gprofng/src/Stabs.cc
@@ -241,6 +241,40 @@  RelValueCmp (const void *a, const void *b)
 	  (item1->value == item2->value) ? 0 : -1;
 }
 
+/* Remove all duplicate symbols which can be in SymLst.  The
+   duplication is due to processing of both static and dynamic
+   symbols.  This function is called before computing symbol
+   aliases.  */
+
+void
+Stabs::removeDupSyms ()
+{
+  long ind, i, last;
+  Symbol *symA, *symB;
+  SymLst->sort (SymImgOffsetCmp);
+  dump ();
+
+  last = 0;
+  ind = SymLst->size ();
+  for (i = 0; i < ind; i++)
+    {
+      symA = SymLst->fetch (i);
+      if (symA->img_offset == 0) // Ignore this bad symbol
+	continue;
+
+      SymLst->put (last++, symA);
+      for (long k = i + 1; k < ind; k++, i++)
+	{
+	  symB = SymLst->fetch (k);
+	  if (symA->img_offset != symB->img_offset)
+	    break;
+	  if (strcmp (symA->name, symB->name) != 0)
+	    break;
+	}
+    }
+  SymLst->truncate (last);
+}
+
 Stabs *
 Stabs::NewStabs (char *_path, char *lo_name)
 {
@@ -1801,6 +1835,7 @@  Stabs::readSymSec (Elf *elf, bool is_dynamic)
 	  }
 	}
     }
+  removeDupSyms ();
   fixSymtabAlias ();
   SymLst->sort (SymValueCmp);
   get_save_addr (elf->need_swap_endian);
diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h
index a6a572d938c..d34741f8f91 100644
--- a/gprofng/src/Stabs.h
+++ b/gprofng/src/Stabs.h
@@ -148,6 +148,7 @@  class Stabs {
     bool	st_check_symtab;
     Function	*createFunction(LoadObject *lo, Module *module, Symbol *sym);
     void        fixSymtabAlias();
+    void	removeDupSyms ();
 
     // Interface with dwarf
     Dwarf       *openDwarf();
diff --git a/gprofng/src/vec.h b/gprofng/src/vec.h
index 04cce4eba7f..a768a02b9e8 100644
--- a/gprofng/src/vec.h
+++ b/gprofng/src/vec.h
@@ -112,6 +112,13 @@  public:
     return data[index];
   }
 
+  void
+  truncate (long ncount)
+  {
+    if (count > ncount && ncount >= 0)
+      count = ncount;
+  }
+
   // Return the first index in "this" that equals "item".
   // Return -1 if "item" is not found.
   long find (const ITEM item);