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: [RFA] Fix binutils/14662


On Fri, Oct 05, 2012 at 01:18:40PM -0700, Cary Coutant wrote:
> > @@ -920,6 +920,9 @@ _bfd_elf_make_section_from_shdr (bfd *ab
> >               && strncmp (&name [1], debug_sections [i].name,
> >                           debug_sections [i].len) == 0)
> >             flags |= SEC_DEBUGGING;
> > +         /* Treat .gdb_index as a debugging section.  */
> > +         if (strcmp (name, ".gdb_index") == 0)
> > +           flags |= SEC_DEBUGGING;
> 
> You're going to be doing this strcmp for every section that begins
> with '\.[d-z]'. Unfortunately, the simple hash table used here has a
> collision between ".gdb_index" and ".gnu_linkonce.wi". Since no pair
> of entries are adjacent, you could extend the lookup to check the next
> slot if the first slot is non-zero and doesn't match, and just put
> .gdb_index in the 'h' slot. Something like this (untested):

I don't think is is worth obfuscating the code.  In fact the following
performs as well as Cary's idea according to my testing on AMD and
PowerPC.  Note that I deliberately do not trim off the chars already
tested from strings passed to strncmp.  It probably doesn't matter too
much with small strings like these (and "name" isn't aligned anyway),
but in general it's better to compare from the start of the string.
On targets that align strings and use optimised strcmp library
functions you get word at a time comparisons on aligned words.

	PR binutils/14662
	* elf.c (_bfd_elf_make_section_from_shdr): Treat .gdb_index as
	SEC_DEBUGGING.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.570
diff -u -p -r1.570 elf.c
--- bfd/elf.c	4 Sep 2012 12:35:34 -0000	1.570
+++ bfd/elf.c	7 Oct 2012 23:05:57 -0000
@@ -880,45 +880,25 @@ _bfd_elf_make_section_from_shdr (bfd *ab
     {
       /* The debugging sections appear to be recognized only by name,
 	 not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
-      static const struct
-	{
-	  const char *name;
-	  int len;
-	} debug_sections [] =
-	{
-	  { STRING_COMMA_LEN ("debug") },	/* 'd' */
-	  { NULL,		 0  },	/* 'e' */
-	  { NULL,		 0  },	/* 'f' */
-	  { STRING_COMMA_LEN ("gnu.linkonce.wi.") },	/* 'g' */
-	  { NULL,		 0  },	/* 'h' */
-	  { NULL,		 0  },	/* 'i' */
-	  { NULL,		 0  },	/* 'j' */
-	  { NULL,		 0  },	/* 'k' */
-	  { STRING_COMMA_LEN ("line") },	/* 'l' */
-	  { NULL,		 0  },	/* 'm' */
-	  { NULL,		 0  },	/* 'n' */
-	  { NULL,		 0  },	/* 'o' */
-	  { NULL,		 0  },	/* 'p' */
-	  { NULL,		 0  },	/* 'q' */
-	  { NULL,		 0  },	/* 'r' */
-	  { STRING_COMMA_LEN ("stab") },	/* 's' */
-	  { NULL,		 0  },	/* 't' */
-	  { NULL,		 0  },	/* 'u' */
-	  { NULL,		 0  },	/* 'v' */
-	  { NULL,		 0  },	/* 'w' */
-	  { NULL,		 0  },	/* 'x' */
-	  { NULL,		 0  },	/* 'y' */
-	  { STRING_COMMA_LEN ("zdebug") }	/* 'z' */
-	};
-
       if (name [0] == '.')
 	{
-	  int i = name [1] - 'd';
-	  if (i >= 0
-	      && i < (int) ARRAY_SIZE (debug_sections)
-	      && debug_sections [i].name != NULL
-	      && strncmp (&name [1], debug_sections [i].name,
-			  debug_sections [i].len) == 0)
+	  const char *p;
+	  int n;
+	  if (name[1] == 'd')
+	    p = ".debug", n = 6;
+	  else if (name[1] == 'g' && name[2] == 'n')
+	    p = ".gnu.linkonce.wi.", n = 17;
+	  else if (name[1] == 'g' && name[2] == 'd')
+	    p = ".gdb_index", n = 11; /* yes we really do mean 11.  */
+	  else if (name[1] == 'l')
+	    p = ".line", n = 5;
+	  else if (name[1] == 's')
+	    p = ".stab", n = 5;
+	  else if (name[1] == 'z')
+	    p = ".zdebug", n = 7;
+	  else
+	    p = NULL, n = 0;
+	  if (p != NULL && strncmp (name, p, n) == 0)
 	    flags |= SEC_DEBUGGING;
 	}
     }

-- 
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]