This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Segfault in objdump?


When writing https://sourceware.org/ml/binutils/2013-06/msg00005.html
I noticed that the initial loop sizing the entry table didn't exactly
match the loop filling the table.  This patch corrects that problem,
and makes sure we terminate the table in an odd corner case.

	* syms.c (_bfd_stab_section_find_nearest_line): Ignore partial
	stabs at end of .stab.  Tidy variable usage.  Don't drop the need
	for a NULL function name stab if If N_FUN stab is ignored.
	Ensure index entry count loop matches write loop.

Index: bfd/syms.c
===================================================================
RCS file: /cvs/src/src/bfd/syms.c,v
retrieving revision 1.59
diff -u -p -r1.59 syms.c
--- bfd/syms.c	3 Jun 2013 04:11:09 -0000	1.59
+++ bfd/syms.c	3 Jun 2013 11:27:46 -0000
@@ -934,12 +934,11 @@ _bfd_stab_section_find_nearest_line (bfd
   struct stab_find_info *info;
   bfd_size_type stabsize, strsize;
   bfd_byte *stab, *str;
-  bfd_byte *last_stab, *last_str;
+  bfd_byte *nul_fun, *nul_str;
   bfd_size_type stroff;
   struct indexentry *indexentry;
   char *file_name;
   char *directory_name;
-  int saw_fun;
   bfd_boolean saw_line, saw_func;
 
   *pfound = FALSE;
@@ -988,7 +987,6 @@ _bfd_stab_section_find_nearest_line (bfd
       long reloc_size, reloc_count;
       arelent **reloc_vector;
       int i;
-      char *name;
       char *function_name;
       bfd_size_type amt = sizeof *info;
 
@@ -1021,6 +1019,7 @@ _bfd_stab_section_find_nearest_line (bfd
       stabsize = (info->stabsec->rawsize
 		  ? info->stabsec->rawsize
 		  : info->stabsec->size);
+      stabsize = (stabsize / STABSIZE) * STABSIZE;
       strsize = (info->strsec->rawsize
 		 ? info->strsec->rawsize
 		 : info->strsec->size);
@@ -1102,36 +1101,37 @@ _bfd_stab_section_find_nearest_line (bfd
 	 table.  */
 
       info->indextablesize = 0;
-      saw_fun = 1;
+      nul_fun = NULL;
       for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
 	{
 	  if (stab[TYPEOFF] == (bfd_byte) N_SO)
 	    {
-	      /* N_SO with null name indicates EOF */
-	      if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
-		continue;
-
 	      /* if we did not see a function def, leave space for one.  */
-	      if (saw_fun == 0)
+	      if (nul_fun != NULL)
 		++info->indextablesize;
 
-	      saw_fun = 0;
-
-	      /* two N_SO's in a row is a filename and directory. Skip */
-	      if (stab + STABSIZE < info->stabs + stabsize
-		  && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
+	      /* N_SO with null name indicates EOF */
+	      if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
+		nul_fun = NULL;
+	      else
 		{
-		  stab += STABSIZE;
+		  nul_fun = stab;
+
+		  /* two N_SO's in a row is a filename and directory. Skip */
+		  if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
+		      && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
+		    stab += STABSIZE;
 		}
 	    }
-	  else if (stab[TYPEOFF] == (bfd_byte) N_FUN)
+	  else if (stab[TYPEOFF] == (bfd_byte) N_FUN
+		   && bfd_get_32 (abfd, stab + STRDXOFF) != 0)
 	    {
-	      saw_fun = 1;
+	      nul_fun = NULL;
 	      ++info->indextablesize;
 	    }
 	}
 
-      if (saw_fun == 0)
+      if (nul_fun != NULL)
 	++info->indextablesize;
 
       if (info->indextablesize == 0)
@@ -1146,10 +1146,10 @@ _bfd_stab_section_find_nearest_line (bfd
 
       file_name = NULL;
       directory_name = NULL;
-      saw_fun = 1;
+      nul_fun = NULL;
       stroff = 0;
 
-      for (i = 0, last_stab = stab = info->stabs, last_str = str = info->strs;
+      for (i = 0, stab = info->stabs, nul_str = str = info->strs;
 	   i < info->indextablesize && stab < info->stabs + stabsize;
 	   stab += STABSIZE)
 	{
@@ -1171,35 +1171,30 @@ _bfd_stab_section_find_nearest_line (bfd
 	         Note that a N_SO without a file name is an EOF and
 	         there could be 2 N_SO following it with the new filename
 	         and directory.  */
-	      if (saw_fun == 0)
+	      if (nul_fun != NULL)
 		{
-		  info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
-		  info->indextable[i].stab = last_stab;
-		  info->indextable[i].str = last_str;
+		  info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
+		  info->indextable[i].stab = nul_fun;
+		  info->indextable[i].str = nul_str;
 		  info->indextable[i].directory_name = directory_name;
 		  info->indextable[i].file_name = file_name;
 		  info->indextable[i].function_name = NULL;
 		  ++i;
 		}
-	      saw_fun = 0;
 
+	      directory_name = NULL;
 	      file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
-	      if (*file_name == '\0')
+	      if (file_name == (char *) str)
 		{
-		  directory_name = NULL;
 		  file_name = NULL;
-		  saw_fun = 1;
+		  nul_fun = NULL;
 		}
 	      else
 		{
-		  last_stab = stab;
-		  last_str = str;
-		  if (stab + STABSIZE >= info->stabs + stabsize
-		      || *(stab + STABSIZE + TYPEOFF) != (bfd_byte) N_SO)
-		    {
-		      directory_name = NULL;
-		    }
-		  else
+		  nul_fun = stab;
+		  nul_str = str;
+		  if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
+		      && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
 		    {
 		      /* Two consecutive N_SOs are a directory and a
 			 file name.  */
@@ -1218,17 +1213,11 @@ _bfd_stab_section_find_nearest_line (bfd
 
 	    case N_FUN:
 	      /* A function name.  */
-	      saw_fun = 1;
-	      name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
-
-	      if (*name == '\0')
-		name = NULL;
-
-	      function_name = name;
-
-	      if (name == NULL)
+	      function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+	      if (function_name == (char *) str)
 		continue;
 
+	      nul_fun = NULL;
 	      info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
 	      info->indextable[i].stab = stab;
 	      info->indextable[i].str = str;
@@ -1240,11 +1229,11 @@ _bfd_stab_section_find_nearest_line (bfd
 	    }
 	}
 
-      if (saw_fun == 0)
+      if (nul_fun != NULL)
 	{
-	  info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
-	  info->indextable[i].stab = last_stab;
-	  info->indextable[i].str = last_str;
+	  info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
+	  info->indextable[i].stab = nul_fun;
+	  info->indextable[i].str = nul_str;
 	  info->indextable[i].directory_name = directory_name;
 	  info->indextable[i].file_name = file_name;
 	  info->indextable[i].function_name = NULL;

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]