PATCH: readelf: Print sh_flags in hex

H. J. Lu hjl@lucon.org
Wed Aug 10 21:21:00 GMT 2005


On Wed, Aug 10, 2005 at 09:03:00AM +0100, Nick Clifton wrote:
> Hi H. J.
> 
> >I like the idea of using --full-section-name. --wide output line may be
> >too long.
> 
> OK - so how about we rename --full-section-name to 
> --full-section-details to reflect its new role.  We could also silently 
> accept --full-section-name for backwards compatibility, although I am 
> not sure that this is such a good idea.
> 

Here is the patch to add "-f/--section-details".


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

	* NEWS: Mention "-f/--section-details" and
	"-N/--full-section-name".

	* doc/binutils.texi: Document "-f/--section-details". Remove
	"-N/--full-section-name".

	* readelf.c (do_full_section_name): Renamed to ...
	(do_section_details): This.
	(option): Rename "-N/--full-section-name" to
	"-f/--section-details".
	(usage): Likewise.
	(parse_args): Likewise.
	(get_elf_section_flags): Support do_section_details.
	(process_section_headers): Updated for do_section_details.

--- binutils/NEWS.dt	2005-06-06 08:54:12.000000000 -0700
+++ binutils/NEWS	2005-08-10 13:44:19.149081927 -0700
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add "-f/--section-details" to readelf to display section details.
+"-N/--full-section-name" is deprecated.
+
 * powerpc-linux ld now supports a variant form of PLT and GOT for the security
   conscious.  This form will automatically be chosen when ld detects that all
   code in regular object files was generated by gcc -msecure-plt.  The old PLT
--- binutils/doc/binutils.texi.dt	2005-05-25 06:51:21.000000000 -0700
+++ binutils/doc/binutils.texi	2005-08-10 11:16:28.668569162 -0700
@@ -3254,7 +3254,7 @@ readelf [@option{-a}|@option{--all}] 
         [@option{-l}|@option{--program-headers}|@option{--segments}]
         [@option{-S}|@option{--section-headers}|@option{--sections}]
         [@option{-g}|@option{--section-groups}]
-        [@option{-N}|@option{--full-section-name}]
+        [@option{-t}|@option{--section-details}]
         [@option{-e}|@option{--headers}]
         [@option{-s}|@option{--syms}|@option{--symbols}]
         [@option{-n}|@option{--notes}]
@@ -3331,10 +3331,10 @@ has any.
 Displays the information contained in the file's section groups, if it
 has any.
 
-@item -N
-@itemx --full-section-name
-@cindex ELF section name information
-Displays the full section name for @option{-S}.
+@item -t
+@itemx --section-details
+@cindex ELF section information
+Displays the detailed section information. Implies @option{-S}.
 
 @item -s
 @itemx --symbols
--- binutils/readelf.c.dt	2005-08-05 10:44:01.000000000 -0700
+++ binutils/readelf.c	2005-08-10 14:17:18.434595408 -0700
@@ -147,7 +147,7 @@ static int do_syms;
 static int do_reloc;
 static int do_sections;
 static int do_section_groups;
-static int do_full_section_name;
+static int do_section_details;
 static int do_segments;
 static int do_unwind;
 static int do_using_dynamic;
@@ -2716,6 +2716,7 @@ static struct option options[] =
   {"sections",	       no_argument, 0, 'S'},
   {"section-headers",  no_argument, 0, 'S'},
   {"section-groups",   no_argument, 0, 'g'},
+  {"section-details",  no_argument, 0, 't'},
   {"full-section-name",no_argument, 0, 'N'},
   {"symbols",	       no_argument, 0, 's'},
   {"syms",	       no_argument, 0, 's'},
@@ -2751,8 +2752,7 @@ usage (void)
   -S --section-headers   Display the sections' header\n\
      --sections          An alias for --section-headers\n\
   -g --section-groups    Display the section groups\n\
-  -N --full-section-name\n\
-                         Display the full section name\n\
+  -t --section-details   Display the section details\n\
   -e --headers           Equivalent to: -h -l -S\n\
   -s --syms              Display the symbol table\n\
       --symbols          An alias for --syms\n\
@@ -2825,7 +2825,7 @@ parse_args (int argc, char **argv)
     usage ();
 
   while ((c = getopt_long
-	  (argc, argv, "ersuahnldSDAINgw::x:i:vVWH", options, NULL)) != EOF)
+	  (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF)
     {
       char *cp;
       int section;
@@ -2856,8 +2856,10 @@ parse_args (int argc, char **argv)
 	case 'g':
 	  do_section_groups++;
 	  break;
+	case 't':
 	case 'N':
-	  do_full_section_name++;
+	  do_sections++;
+	  do_section_details++;
 	  break;
 	case 'e':
 	  do_header++;
@@ -3788,8 +3790,33 @@ get_64bit_elf_symbols (FILE *file, Elf_I
 static const char *
 get_elf_section_flags (bfd_vma sh_flags)
 {
-  static char buff[33];
+  static char buff[1024];
   char *p = buff;
+  int index, size = sizeof (buff) - (8 + 4 + 1);
+  const struct
+    {
+      const char *str;
+      int len;
+    }
+  flags [] =
+    {
+	{ "WRITE", 5 },
+	{ "ALLOC", 5 },
+	{ "EXEC", 4 },
+	{ "MERGE", 5 },
+	{ "STRINGS", 7 },
+	{ "INFO LINK", 9 },
+	{ "LINK ORDER", 10 },
+	{ "OS NONCONF", 10 },
+	{ "GROUP", 5 },
+	{ "TLS", 3 }
+    };
+
+  if (do_section_details)
+    {
+      sprintf (buff, "[%8.8lx]: ", (unsigned long) sh_flags);
+      p += 8 + 4;
+    }
 
   while (sh_flags)
     {
@@ -3798,38 +3825,94 @@ get_elf_section_flags (bfd_vma sh_flags)
       flag = sh_flags & - sh_flags;
       sh_flags &= ~ flag;
 
-      switch (flag)
+      if (do_section_details)
 	{
-	case SHF_WRITE:		   *p = 'W'; break;
-	case SHF_ALLOC:		   *p = 'A'; break;
-	case SHF_EXECINSTR:	   *p = 'X'; break;
-	case SHF_MERGE:		   *p = 'M'; break;
-	case SHF_STRINGS:	   *p = 'S'; break;
-	case SHF_INFO_LINK:	   *p = 'I'; break;
-	case SHF_LINK_ORDER:	   *p = 'L'; break;
-	case SHF_OS_NONCONFORMING: *p = 'O'; break;
-	case SHF_GROUP:		   *p = 'G'; break;
-	case SHF_TLS:		   *p = 'T'; break;
+	  switch (flag)
+	    {
+	    case SHF_WRITE:		index = 0; break;
+	    case SHF_ALLOC:		index = 1; break;
+	    case SHF_EXECINSTR:		index = 2; break;
+	    case SHF_MERGE:		index = 3; break;
+	    case SHF_STRINGS:		index = 4; break;
+	    case SHF_INFO_LINK:		index = 5; break;
+	    case SHF_LINK_ORDER:	index = 6; break;
+	    case SHF_OS_NONCONFORMING:	index = 7; break;
+	    case SHF_GROUP:		index = 8; break;
+	    case SHF_TLS:		index = 9; break;
 
-	default:
-	  if (elf_header.e_machine == EM_X86_64
-	      && flag == SHF_X86_64_LARGE)
-	    *p = 'l';
+	    default:
+	      index = -1;
+	      break;
+	    }
+
+	  if (p != buff + 8 + 4)
+	    {
+	      if (size < 10 + 2)
+		abort ();
+	      size -= 2;
+	      *p++ = ',';
+	      *p++ = ' ';
+	    }
+
+	  if (index != -1)
+	    {
+	      size -= flags [index].len;
+	      p = stpcpy (p, flags [index].str);
+	    }
 	  else if (flag & SHF_MASKOS)
 	    {
-	      *p = 'o';
-	      sh_flags &= ~ SHF_MASKOS;
+	      size -= 5 + 8;
+	      sprintf (p, "OS (%8.8lx)", (unsigned long) flag);
+	      p += 5 + 8;
 	    }
 	  else if (flag & SHF_MASKPROC)
 	    {
-	      *p = 'p';
-	      sh_flags &= ~ SHF_MASKPROC;
+	      size -= 7 + 8;
+	      sprintf (p, "PROC (%8.8lx)", (unsigned long) flag);
+	      p += 7 + 8;
 	    }
 	  else
-	    *p = 'x';
-	  break;
+	    {
+	      size -= 10 + 8;
+	      sprintf (p, "UNKNOWN (%8.8lx)", (unsigned long) flag);
+	      p += 10 + 8;
+	    }
+	}
+      else
+	{
+	  switch (flag)
+	    {
+	    case SHF_WRITE:		*p = 'W'; break;
+	    case SHF_ALLOC:		*p = 'A'; break;
+	    case SHF_EXECINSTR:		*p = 'X'; break;
+	    case SHF_MERGE:		*p = 'M'; break;
+	    case SHF_STRINGS:		*p = 'S'; break;
+	    case SHF_INFO_LINK:		*p = 'I'; break;
+	    case SHF_LINK_ORDER:	*p = 'L'; break;
+	    case SHF_OS_NONCONFORMING:	*p = 'O'; break;
+	    case SHF_GROUP:		*p = 'G'; break;
+	    case SHF_TLS:		*p = 'T'; break;
+
+	    default:
+	      if (elf_header.e_machine == EM_X86_64
+		  && flag == SHF_X86_64_LARGE)
+		*p = 'l';
+	      else if (flag & SHF_MASKOS)
+		{
+		  *p = 'o';
+		  sh_flags &= ~ SHF_MASKOS;
+		}
+	      else if (flag & SHF_MASKPROC)
+		{
+		  *p = 'p';
+		  sh_flags &= ~ SHF_MASKPROC;
+		}
+	      else
+		*p = 'x';
+	      break;
+	    }
+	  p++;
 	}
-      p++;
     }
 
   *p = '\0';
@@ -4009,10 +4092,10 @@ process_section_headers (FILE *file)
 
   if (is_32bit_elf)
     {
-      if (do_full_section_name)
+      if (do_section_details)
 	{
 	  printf (_("  [Nr] Name\n"));
-	  printf (_("       Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
+	  printf (_("       Type            Addr     Off    Size   ES   Lk Inf Al\n"));
 	}
       else
 	printf
@@ -4020,10 +4103,10 @@ process_section_headers (FILE *file)
     }
   else if (do_wide)
     {
-      if (do_full_section_name)
+      if (do_section_details)
 	{
 	  printf (_("  [Nr] Name\n"));
-	  printf (_("       Type            Address          Off    Size   ES Flg Lk Inf Al\n"));
+	  printf (_("       Type            Address          Off    Size   ES   Lk Inf Al\n"));
 	}
       else
 	printf
@@ -4031,11 +4114,11 @@ process_section_headers (FILE *file)
     }
   else
     {
-      if (do_full_section_name)
+      if (do_section_details)
 	{
 	  printf (_("  [Nr] Name\n"));
-	  printf (_("       Flags             Type             Address           Offset\n"));
-	  printf (_("       Size              EntSize          Link     Info     Align\n"));
+	  printf (_("       Type              Address          Offset            Link\n"));
+	  printf (_("       Size              EntSize          Info              Align\n"));
 	}
       else
 	{
@@ -4044,11 +4127,14 @@ process_section_headers (FILE *file)
 	}
     }
 
+  if (do_section_details)
+    printf (_("       Flags\n"));
+
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum;
        i++, section++)
     {
-      if (do_full_section_name)
+      if (do_section_details)
 	{
 	  printf ("  [%2u] %s\n",
 		  SECTION_HEADER_NUM (i),
@@ -4072,7 +4158,10 @@ process_section_headers (FILE *file)
 		   (unsigned long) section->sh_size,
 		   (unsigned long) section->sh_entsize);
 
-	  printf (" %3s ", get_elf_section_flags (section->sh_flags));
+	  if (do_section_details)
+	    fputs ("  ", stdout);
+	  else
+	    printf (" %3s ", get_elf_section_flags (section->sh_flags));
 
 	  printf ("%2ld %3lu %2ld\n",
 		  (unsigned long) section->sh_link,
@@ -4107,7 +4196,10 @@ process_section_headers (FILE *file)
 	      print_vma (section->sh_entsize, LONG_HEX);
 	    }
 
-	  printf (" %3s ", get_elf_section_flags (section->sh_flags));
+	  if (do_section_details)
+	    fputs ("  ", stdout);
+	  else
+	    printf (" %3s ", get_elf_section_flags (section->sh_flags));
 
 	  printf ("%2ld %3lu ",
 		  (unsigned long) section->sh_link,
@@ -4121,27 +4213,24 @@ process_section_headers (FILE *file)
 	      putchar ('\n');
 	    }
 	}
-      else if (do_full_section_name)
+      else if (do_section_details)
 	{
-	  printf ("       %-15.15s   %-15.15s ",
-		  get_elf_section_flags (section->sh_flags),
+	  printf ("       %-15.15s  ",
 		  get_section_type_name (section->sh_type));
-	  putchar (' ');
 	  print_vma (section->sh_addr, LONG_HEX);
 	  if ((long) section->sh_offset == section->sh_offset)
-	    printf ("  %8.8lx", (unsigned long) section->sh_offset);
+	    printf ("  %16.16lx", (unsigned long) section->sh_offset);
 	  else
 	    {
 	      printf ("  ");
 	      print_vma (section->sh_offset, LONG_HEX);
 	    }
-	  printf ("\n       ");
+	  printf ("  %ld\n       ", (unsigned long) section->sh_link);
 	  print_vma (section->sh_size, LONG_HEX);
-	  printf ("  ");
+	  putchar (' ');
 	  print_vma (section->sh_entsize, LONG_HEX);
 
-	  printf ("   %2ld      %3lu        %ld\n",
-		  (unsigned long) section->sh_link,
+	  printf ("  %-16lu  %ld\n",
 		  (unsigned long) section->sh_info,
 		  (unsigned long) section->sh_addralign);
 	}
@@ -4168,9 +4257,13 @@ process_section_headers (FILE *file)
 		  (unsigned long) section->sh_info,
 		  (unsigned long) section->sh_addralign);
 	}
+
+      if (do_section_details)
+	printf ("       %s\n", get_elf_section_flags (section->sh_flags));
     }
 
-  printf (_("Key to Flags:\n\
+  if (!do_section_details)
+    printf (_("Key to Flags:\n\
   W (write), A (alloc), X (execute), M (merge), S (strings)\n\
   I (info), L (link order), G (group), x (unknown)\n\
   O (extra OS processing required) o (OS specific), p (processor specific)\n"));



More information about the Binutils mailing list