PATCH: Support '*' in pattern and fix a typo

H. J. Lu hjl@lucon.org
Fri Oct 24 07:07:00 GMT 2003
On Thu, Oct 23, 2003 at 07:50:43PM -0700, H. J. Lu wrote:
> On Thu, Oct 23, 2003 at 11:29:20AM -0700, H. J. Lu wrote:
> > On Tue, Oct 21, 2003 at 10:57:36PM -0700, H. J. Lu wrote:
> > 
> > > > I think we need something different from wildcardp, which can handle
> > > > "foo\*bar", for setting the new wildcard bit. We can modify it after
> > > > your patch is checked in.
> > > > 
> > > 
> > > I am thinking about instead of adding
> > > 
> > > unsigned int wildcard : 1;
> > > 
> > > we add
> > > 
> > > const char *symbol;
> > > 
> > > If
> > > 
> > > const char *pattern;
> > > 
> > > is a wildcard, symbol will be NULL. Otherwise, symbol will point to
> > > pattern if pattern has no backslash or point to a copy of pattern
> > > with backslashes removed. size_dynamic_sections will lookup symbol
> > > like
> > > 
> > > 	if (!d->symver && d->symbol != NULL)
> > > 	  {
> > > 	    ...
> > > 	    elf_link_hash_lookup
> > > 	    ...
> > > 	 }
> > > 
> > 
> > Here is the patch to implement it.
> > 
> 
> The patch is incorrect. Here is an update.
> 
> 

Here is another update to fix a typo:

+-      if (fnmatch (expr->pattern, sym, 0) == 0)
++      if (fnmatch (expr->pattern, s, 0) == 0)

Otherwise, extern "C++" won't work.


H.J.
-------------- next part --------------
bfd/

2003-10-23  H.J. Lu  <hongjiu.lu@intel.com>

	* elflink.h (NAME(bfd_elf,size_dynamic_sections)): Look up
	hash table for real symbols.

include/

2003-10-23  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_elf_version_expr): Add "symbol" and remove
	"wildcard".

ld/

2003-10-23  H.J. Lu  <hongjiu.lu@intel.com>

	* ldlang.c (lang_vers_match): Check "symbol" instead of
	"wildcard" and "pattern". Fix a typo.
	(lang_finalize_version_expr_head): Likewise.
	(lang_register_vers_node): Likewise.
	(realsymbol): New function.
	(lang_new_vers_pattern): Set "symbol" and remove "wildcard".

	* ldlex.l (V_IDENTIFIER): Allow '\\'.

--- binutils/bfd/elflink.h.pat	2003-10-22 23:27:01.000000000 -0700
+++ binutils/bfd/elflink.h	2003-10-23 09:04:06.000000000 -0700
@@ -2059,16 +2059,14 @@ NAME(bfd_elf,size_dynamic_sections) (bfd
       /* Make all global versions with definiton.  */
       for (t = verdefs; t != NULL; t = t->next)
 	for (d = t->globals.list; d != NULL; d = d->next)
-	  /* FIXME: Shouldn't this be !d->symver && d->wildcard == 0
-	     instead?  */
-	  if (!d->symver && strchr (d->pattern, '*') == NULL)
+	  if (!d->symver && d->symbol)
 	    {
 	      const char *verstr, *name;
 	      size_t namelen, verlen, newlen;
 	      char *newname, *p;
 	      struct elf_link_hash_entry *newh;
 
-	      name = d->pattern;
+	      name = d->symbol;
 	      namelen = strlen (name);
 	      verstr = t->name;
 	      verlen = strlen (verstr);
--- binutils/include/bfdlink.h.pat	2003-10-22 23:27:02.000000000 -0700
+++ binutils/include/bfdlink.h	2003-10-23 08:36:29.000000000 -0700
@@ -625,12 +625,12 @@ struct bfd_elf_version_expr
   struct bfd_elf_version_expr *next;
   /* Glob pattern.  */
   const char *pattern;
+  /* NULL for a glob pattern, otherwise a straight symbol.  */
+  const char *symbol;
   /* Defined by ".symver".  */
   unsigned int symver : 1;
   /* Defined by version script.  */
   unsigned int script : 1;
-  /* Is this a wildcard?.  */
-  unsigned int wildcard : 1;
   /* Pattern type.  */
 #define BFD_ELF_VERSION_C_TYPE		1
 #define BFD_ELF_VERSION_CXX_TYPE	2
--- binutils/ld/ldlang.c.pat	2003-10-22 23:27:02.000000000 -0700
+++ binutils/ld/ldlang.c	2003-10-24 00:01:57.000000000 -0700
@@ -5000,7 +5000,7 @@ lang_vers_match (struct bfd_elf_version_
 	java_sym = sym;
     }
 
-  if (head->htab && (prev == NULL || prev->wildcard == 0))
+  if (head->htab && (prev == NULL || prev->symbol))
     {
       struct bfd_elf_version_expr e;
 
@@ -5009,9 +5009,9 @@ lang_vers_match (struct bfd_elf_version_
 	  case 0:
 	    if (head->mask & BFD_ELF_VERSION_C_TYPE)
 	      {
-		e.pattern = sym;
+		e.symbol = sym;
 		expr = htab_find (head->htab, &e);
-		while (expr && strcmp (expr->pattern, sym) == 0)
+		while (expr && strcmp (expr->symbol, sym) == 0)
 		  if (expr->mask == BFD_ELF_VERSION_C_TYPE)
 		    goto out_ret;
 		else
@@ -5021,9 +5021,9 @@ lang_vers_match (struct bfd_elf_version_
 	  case BFD_ELF_VERSION_C_TYPE:
 	    if (head->mask & BFD_ELF_VERSION_CXX_TYPE)
 	      {
-		e.pattern = cxx_sym;
+		e.symbol = cxx_sym;
 		expr = htab_find (head->htab, &e);
-		while (expr && strcmp (expr->pattern, sym) == 0)
+		while (expr && strcmp (expr->symbol, sym) == 0)
 		  if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
 		    goto out_ret;
 		else
@@ -5033,9 +5033,9 @@ lang_vers_match (struct bfd_elf_version_
 	  case BFD_ELF_VERSION_CXX_TYPE:
 	    if (head->mask & BFD_ELF_VERSION_JAVA_TYPE)
 	      {
-		e.pattern = java_sym;
+		e.symbol = java_sym;
 		expr = htab_find (head->htab, &e);
-		while (expr && strcmp (expr->pattern, sym) == 0)
+		while (expr && strcmp (expr->symbol, sym) == 0)
 		  if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
 		    goto out_ret;
 		else
@@ -5048,7 +5048,7 @@ lang_vers_match (struct bfd_elf_version_
     }
 
   /* Finally, try the wildcards.  */
-  if (prev == NULL || prev->wildcard == 0)
+  if (prev == NULL || prev->symbol)
     expr = head->remaining;
   else
     expr = prev->next;
@@ -5065,7 +5065,7 @@ lang_vers_match (struct bfd_elf_version_
 	s = cxx_sym;
       else
 	s = sym;
-      if (fnmatch (expr->pattern, sym, 0) == 0)
+      if (fnmatch (expr->pattern, s, 0) == 0)
 	break;
       expr = expr->next;
     }
@@ -5078,6 +5078,50 @@ out_ret:
   return expr;
 }
 
+/* Return NULL if the PATTERN argument is a glob pattern, otherwise,
+   return a string pointing to the symbol name.  */
+
+static const char *
+realsymbol (const char *pattern)
+{
+  const char *p;
+  bfd_boolean changed = FALSE, backslash = FALSE;
+  char *s, *symbol = xmalloc (strlen (pattern) + 1);
+
+  for (p = pattern, s = symbol; *p != '\0'; ++p)
+    {
+      /* It is a glob pattern only if there is no preceding
+	 backslash.  */
+      if (! backslash && (*p == '?' || *p == '*' || *p == '['))
+	{
+	  free (symbol);
+	  return NULL;
+	}
+
+      if (backslash)
+	{
+	  /* Remove the preceding backslash.  */
+	  *(s - 1) = *p;
+	  changed = TRUE;
+	}
+      else
+	*s++ = *p;
+
+      backslash = *p == '\\';
+    }
+
+  if (changed)
+    {
+      *s = '\0';
+      return symbol;
+    }
+  else
+    {
+      free (symbol);
+      return pattern;
+    }
+}
+
 /* This is called for each variable name or match expression.  */
 
 struct bfd_elf_version_expr *
@@ -5092,7 +5136,7 @@ lang_new_vers_pattern (struct bfd_elf_ve
   ret->pattern = new;
   ret->symver = 0;
   ret->script = 0;
-  ret->wildcard = wildcardp (new);
+  ret->symbol = realsymbol (new);
 
   if (lang == NULL || strcasecmp (lang, "C") == 0)
     ret->mask = BFD_ELF_VERSION_C_TYPE;
@@ -5136,7 +5180,7 @@ version_expr_head_hash (const void *p)
 {
   const struct bfd_elf_version_expr *e = p;
 
-  return htab_hash_string (e->pattern);
+  return htab_hash_string (e->symbol);
 }
 
 static int
@@ -5145,7 +5189,7 @@ version_expr_head_eq (const void *p1, co
   const struct bfd_elf_version_expr *e1 = p1;
   const struct bfd_elf_version_expr *e2 = p2;
 
-  return strcmp (e1->pattern, e2->pattern) == 0;
+  return strcmp (e1->symbol, e2->symbol) == 0;
 }
 
 static void
@@ -5157,7 +5201,7 @@ lang_finalize_version_expr_head (struct 
 
   for (e = head->list; e; e = e->next)
     {
-      if (!e->wildcard)
+      if (e->symbol)
 	count++;
       head->mask |= e->mask;
     }
@@ -5171,7 +5215,7 @@ lang_finalize_version_expr_head (struct 
       for (e = head->list; e; e = next)
 	{
 	  next = e->next;
-	  if (e->wildcard)
+	  if (!e->symbol)
 	    {
 	      *remaining_loc = e;
 	      remaining_loc = &e->next;
@@ -5196,14 +5240,14 @@ lang_finalize_version_expr_head (struct 
 		      last = e1;
 		      e1 = e1->next;
 		    }
-		  while (e1 && strcmp (e1->pattern, e->pattern) == 0);
+		  while (e1 && strcmp (e1->symbol, e->symbol) == 0);
 
 		  if (last == NULL)
 		    {
 		      /* This is a duplicate.  */
 		      /* FIXME: Memory leak.  Sometimes pattern is not
 			 xmalloced alone, but in larger chunk of memory.  */
-		      /* free (e->pattern); */
+		      /* free (e->symbol); */
 		      free (e);
 		    }
 		  else
@@ -5266,18 +5310,18 @@ lang_register_vers_node (const char *nam
 	{
 	  struct bfd_elf_version_expr *e2;
 
-	  if (t->locals.htab && e1->wildcard == 0)
+	  if (t->locals.htab && e1->symbol)
 	    {
 	      e2 = htab_find (t->locals.htab, e1);
-	      while (e2 && strcmp (e1->pattern, e2->pattern) == 0)
+	      while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
 		{
 		  if (e1->mask == e2->mask)
 		    einfo (_("%X%P: duplicate expression `%s' in version information\n"),
-			   e1->pattern);
+			   e1->symbol);
 		  e2 = e2->next;
 		}
 	    }
-	  else if (e1->wildcard)
+	  else if (!e1->symbol)
 	    for (e2 = t->locals.remaining; e2 != NULL; e2 = e2->next)
 	      if (strcmp (e1->pattern, e2->pattern) == 0 && e1->mask == e2->mask)
 		einfo (_("%X%P: duplicate expression `%s' in version information\n"),
@@ -5291,18 +5335,18 @@ lang_register_vers_node (const char *nam
 	{
 	  struct bfd_elf_version_expr *e2;
 
-	  if (t->globals.htab && e1->wildcard == 0)
+	  if (t->globals.htab && e1->symbol)
 	    {
 	      e2 = htab_find (t->globals.htab, e1);
-	      while (e2 && strcmp (e1->pattern, e2->pattern) == 0)
+	      while (e2 && strcmp (e1->symbol, e2->symbol) == 0)
 		{
 		  if (e1->mask == e2->mask)
 		    einfo (_("%X%P: duplicate expression `%s' in version information\n"),
-			   e1->pattern);
+			   e1->symbol);
 		  e2 = e2->next;
 		}
 	    }
-	  else if (e1->wildcard)
+	  else if (!e1->symbol)
 	    for (e2 = t->globals.remaining; e2 != NULL; e2 = e2->next)
 	      if (strcmp (e1->pattern, e2->pattern) == 0 && e1->mask == e2->mask)
 		einfo (_("%X%P: duplicate expression `%s' in version information\n"),
--- binutils/ld/ldlex.l.pat	2003-07-28 07:41:43.000000000 -0700
+++ binutils/ld/ldlex.l	2003-10-23 10:22:39.000000000 -0700
@@ -113,7 +113,7 @@ WHITE		[ \t\n\r]+
 NOCFILENAMECHAR	[_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
 
 V_TAG [.$_a-zA-Z][._a-zA-Z0-9]*
-V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^]([*?.$_a-zA-Z0-9\[\]\-\!\^]|::)*
+V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 
 %s SCRIPT
 %s EXPRESSION


More information about the Binutils mailing list