gprofng: fix SIGSEGV when processing unusual dwarf

Message ID 20230207015340.2021329-1-vladimir.mezentsev@oracle.com
State Accepted
Headers
Series gprofng: fix SIGSEGV when processing unusual dwarf |

Checks

Context Check Description
snail/binutils-gdb-check success Github commit url

Commit Message

Vladimir Mezentsev Feb. 7, 2023, 1:53 a.m. UTC
  From: Vladimir Mezentsev <vladimir.mezentsev@oracle.com>

gprofng/ChangeLog
2023-02-06  Vladimir Mezentsev  <vladimir.mezentsev@oracle.com>

	* src/Dwarf.cc: add nullptr check.
	* src/DwarfLib.cc: Likewise.
---
 gprofng/src/Dwarf.cc    | 16 ++++++++--------
 gprofng/src/DwarfLib.cc | 18 ++++++++++++------
 2 files changed, 20 insertions(+), 14 deletions(-)
  

Patch

diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc
index 1b33ae8f243..5485be7f796 100644
--- a/gprofng/src/Dwarf.cc
+++ b/gprofng/src/Dwarf.cc
@@ -606,12 +606,15 @@  Dwarf::archive_Dwarf (LoadObject *lo)
 	{
 	  mod->hdrOffset = dwrCUs->size ();
 	  DwrLineRegs *lineReg = dwrCU->get_dwrLineReg ();
-	  dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
-	  for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
+	  if (lineReg != NULL)
 	    {
-	      char *fname = lineReg->getPath (i + 1);
-	      SourceFile *sf = mod->findSource (fname, true);
-	      dwrCU->srcFiles->append (sf);
+	      dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names));
+	      for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++)
+		{
+		  char *fname = lineReg->getPath (i + 1);
+		  SourceFile *sf = mod->findSource (fname, true);
+		  dwrCU->srcFiles->append (sf);
+		}
 	    }
 
 	  Dwarf_cnt ctx;
@@ -986,9 +989,6 @@  DwrCU::append_Function (Dwarf_cnt *ctx)
       if (lineno > 0)
 	{
 	  func->setLineFirst (lineno);
-	  if (dwrLineReg == NULL)
-	    dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
-						   stmt_list_offset), comp_dir);
 	  int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1;
 	  SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno)
 		  : module->getMainSrc ();
diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc
index 4f86a78d1c8..9dd96fa2cb1 100644
--- a/gprofng/src/DwarfLib.cc
+++ b/gprofng/src/DwarfLib.cc
@@ -31,6 +31,7 @@ 
 #include "DbeArray.h"
 #include "DbeSession.h"
 
+#define NO_STMT_LIST 0xffffffffffffffffULL
 #define CASE_S(x)   case x: s = (char *) #x; break
 
 static char *
@@ -1557,8 +1558,11 @@  DwrLineRegs::getPath (int fn)
   if (*dir != '/')
     { // not absolute
       char *s = include_directories->fetch (0);
-      sb.append (s);
-      sb.append ('/');
+      if (s != NULL && *s != 0)
+	{
+	  sb.append (s);
+	  sb.append ('/');
+	}
     }
   sb.append (dir);
   sb.append ('/');
@@ -1590,7 +1594,7 @@  DwrCU::DwrCU (Dwarf *_dwarf)
   abbrevTable = NULL;
   dwrInlinedSubrs = NULL;
   srcFiles = NULL;
-  stmt_list_offset = 0;
+  stmt_list_offset = NO_STMT_LIST;
   dwrLineReg = NULL;
   isMemop = false;
   isGNU = false;
@@ -1857,7 +1861,7 @@  DwrCU::parse_cu_header (LoadObject *lo)
   char *name = Dwarf_string (DW_AT_name);
   if (name == NULL)
     name = NTXT ("UnnamedUnit");
-  stmt_list_offset = Dwarf_data (DW_AT_stmt_list);
+  stmt_list_offset = Dwarf_ref (DW_AT_stmt_list);
   comp_dir = dbe_strdup (Dwarf_string (DW_AT_comp_dir));
   char *dir_name = comp_dir ? StrChr (comp_dir, ':') : NULL;
   char *orig_name = Dwarf_string (DW_AT_SUN_original_name);
@@ -2073,6 +2077,8 @@  DwrCU::map_dwarf_lines (Module *mod)
 					Stabs::is_fortran (mod->lang_code));
 	}
     }
+  if (lineReg == NULL)
+    return;
   Vector<DwrLine *> *lines = lineReg->get_lines ();
 
   Include *includes = new Include;
@@ -2083,7 +2089,7 @@  DwrCU::map_dwarf_lines (Module *mod)
   for (long i = 0, sz = VecSize (lines); i < sz; i++)
     {
       DwrLine *dwrLine = lines->get (i);
-      char *filename = dwrLineReg->getPath (dwrLine->file);
+      char *filename = lineReg->getPath (dwrLine->file);
       if (filename == NULL)
 	continue;
       uint64_t pc = dwrLine->address;
@@ -2123,7 +2129,7 @@  DwrCU::map_dwarf_lines (Module *mod)
 DwrLineRegs *
 DwrCU::get_dwrLineReg ()
 {
-  if (dwrLineReg == NULL)
+  if (dwrLineReg == NULL && stmt_list_offset != NO_STMT_LIST)
     dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec,
 					      stmt_list_offset), comp_dir);
   return dwrLineReg;