This is the mail archive of the binutils@sources.redhat.com 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]

PATCH: Fix readelf for section group


There are several problems with section group dump:

1. group_count isn't reset when we have more in one input file.
2. process_section_groups is called even if section group info isn't
used.
3. SHT_SYMTAB/SHT_STRTAB sections are read in for every section group.
It can be very slow if there are thousand groups in a file.
4. Intel C/C++ compiler puts section 0 in a section group. It doesn't
cause any linker problem, but generate many warnings. One should be
enough.

This patch fixes those.


H.J.
---
2005-02-10  H.J. Lu  <hongjiu.lu@intel.com>

	* readelf.c (group_count): Don't initialize it.
	(process_section_groups): Reurn 1 if we won't do unwind nor
	section groups. Set group_count to 0 before counting group
	sections and return 1 if there are no group sections. Reread
	SHT_SYMTAB/SHT_STRTAB sections only when needed. Don't skip
	section 0.
	(process_object): Only set do_unwind to 0 if
	process_section_groups return 0.

--- binutils/readelf.c.group	2005-01-31 14:17:54.000000000 -0800
+++ binutils/readelf.c	2005-02-10 15:22:50.285532542 -0800
@@ -185,7 +185,7 @@ struct group
 };
 
 struct group *section_groups;
-size_t group_count = 0;
+size_t group_count;
 
 struct group **section_headers_groups;
 
@@ -3956,11 +3956,18 @@ process_section_groups (FILE *file)
   Elf_Internal_Shdr *section;
   unsigned int i;
   struct group *group;
+  Elf_Internal_Shdr *symtab_sec, *strtab_sec;
+  Elf_Internal_Sym *symtab;
+  char *strtab;
+
+  /* Don't process section groups unless needed.  */
+  if (!do_unwind && !do_section_groups)
+    return 1;
 
   if (elf_header.e_shnum == 0)
     {
       if (do_section_groups)
-	printf (_("\nThere are no section groups in this file.\n"));
+	printf (_("\nThere are no sections in this file.\n"));
 
       return 1;
     }
@@ -3981,6 +3988,7 @@ process_section_groups (FILE *file)
     }
 
   /* Scan the sections for the group section.  */
+  group_count = 0;
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum;
        i++, section++)
@@ -3989,12 +3997,24 @@ process_section_groups (FILE *file)
 
   section_groups = calloc (group_count, sizeof (struct group));
 
+  if (group_count == 0)
+    {
+      if (do_section_groups)
+	printf (_("\nThere are no section groups in this file.\n"));
+
+      return 1;
+    }
+
   if (section_groups == NULL)
     {
       error (_("Out of memory\n"));
       return 0;
     }
 
+  symtab_sec = NULL;
+  strtab_sec = NULL;
+  symtab = NULL;
+  strtab = NULL;
   for (i = 0, section = section_headers, group = section_groups;
        i < elf_header.e_shnum;
        i++, section++)
@@ -4002,20 +4022,26 @@ process_section_groups (FILE *file)
       if (section->sh_type == SHT_GROUP)
 	{
 	  char *name = SECTION_NAME (section);
-	  char *group_name, *strtab, *start, *indices;
+	  char *group_name, *start, *indices;
 	  unsigned int entry, j, size;
+	  Elf_Internal_Shdr *sec;
 	  Elf_Internal_Sym *sym;
-	  Elf_Internal_Shdr *symtab_sec, *strtab_sec, *sec;
-	  Elf_Internal_Sym *symtab;
 
 	  /* Get the symbol table.  */
-	  symtab_sec = SECTION_HEADER (section->sh_link);
-	  if (symtab_sec->sh_type != SHT_SYMTAB)
+	  sec = SECTION_HEADER (section->sh_link);
+	  if (sec->sh_type != SHT_SYMTAB)
 	    {
 	      error (_("Bad sh_link in group section `%s'\n"), name);
 	      continue;
 	    }
-	  symtab = GET_ELF_SYMBOLS (file, symtab_sec);
+
+	  if (symtab_sec != sec)
+	    {
+	      symtab_sec = sec;
+	      if (symtab)
+		free (symtab);
+	      symtab = GET_ELF_SYMBOLS (file, symtab_sec);
+	    }
 
 	  sym = symtab + section->sh_info;
 
@@ -4034,11 +4060,16 @@ process_section_groups (FILE *file)
 	  else
 	    {
 	      /* Get the string table.  */
-	      strtab_sec = SECTION_HEADER (symtab_sec->sh_link);
-	      strtab = get_data (NULL, file, strtab_sec->sh_offset,
-				 strtab_sec->sh_size,
-				 _("string table"));
-
+	      sec = SECTION_HEADER (symtab_sec->sh_link);
+	      if (strtab_sec != sec)
+		{
+		  strtab_sec = sec;
+		  if (strtab)
+		    free (strtab);
+		  strtab = get_data (NULL, file, strtab_sec->sh_offset,
+				     strtab_sec->sh_size,
+				     _("string table"));
+		}
 	      group_name = strtab + sym->st_name;
 	    }
 
@@ -4070,9 +4101,26 @@ process_section_groups (FILE *file)
 	      if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
 		  != NULL)
 		{
-		  error (_("section [%5u] already in group section [%5u]\n"),
-			 entry, section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
-		  continue;
+		  if (entry)
+		    {
+		      error (_("section [%5u] already in group section [%5u]\n"),
+			     entry,
+			     section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
+		      continue;
+		    }
+		  else
+		    {
+		      /* Intel C/C++ compiler may put section 0 in a
+			 section group. We just warn it the first time
+			 and ignore it afterwards.  */
+		      static int warned = 0;
+		      if (!warned)
+			{
+			  error (_("section 0 in group section [%5u]\n"),
+				 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
+			  warned++;
+			}
+		    }
 		}
 
 	      section_headers_groups [SECTION_HEADER_INDEX (entry)]
@@ -4091,10 +4139,6 @@ process_section_groups (FILE *file)
 	      group->root = g;
 	    }
 
-	  if (symtab)
-	    free (symtab);
-	  if (strtab)
-	    free (strtab);
 	  if (start)
 	    free (start);
 
@@ -4102,6 +4146,10 @@ process_section_groups (FILE *file)
 	}
     }
 
+  if (symtab)
+    free (symtab);
+  if (strtab)
+    free (strtab);
   return 1;
 }
 
@@ -11660,17 +11708,22 @@ process_object (char *file_name, FILE *f
   if (! process_file_header ())
     return 1;
 
-  if (! process_section_headers (file)
-      || ! process_section_groups (file))
+  if (! process_section_headers (file))
     {
-      /* Without loaded section headers and section groups we
-	 cannot process lots of things.  */
+      /* Without loaded section headers we cannot process lots of
+	 things.  */
       do_unwind = do_version = do_dump = do_arch = 0;
 
       if (! do_using_dynamic)
 	do_syms = do_reloc = 0;
     }
 
+  if (! process_section_groups (file))
+    {
+      /* Without loaded section groups we cannot process unwind.  */
+      do_unwind = 0;
+    }
+
   if (process_program_headers (file))
     process_dynamic_section (file);
 


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