* ld.texino: Describe double-quoted string syntax for version
authorMark Mitchell <mark@codesourcery.com>
Thu, 13 Oct 2005 17:29:57 +0000 (17:29 +0000)
committerMark Mitchell <mark@codesourcery.com>
Thu, 13 Oct 2005 17:29:57 +0000 (17:29 +0000)
nodes.
* ldlang.h (lang_new_vers_pattern): Add literal_p parameter.
* ldgram.y (vers_defns): Allow NAME as well as VERS_IDENTIFIER.
Adjust calls to lang_new_vers_pattern to pass literal_p argument.
* ldlang.c (lang_vers_match): Fix indentation.  Do not glob-match
version nodes without a pattern.
(lang_new_vers_pattern): Add literal_p parameter.
(lang_do_version_exports_section): Pass it.

* ld-elfvers/vers.exp: Add vers31.
* ld-elfvers/vers31.c: New file.
* ld-elfvers/vers31.dsym: Likewise.
* ld-elfvers/vers31.map: Likewise.
* ld-elfvers/vers31.ver: Likewise.

ld/ChangeLog
ld/ld.texinfo
ld/ldgram.y
ld/ldlang.c
ld/ldlang.h
ld/testsuite/ChangeLog
ld/testsuite/ld-elfvers/vers.exp
ld/testsuite/ld-elfvers/vers31.c [new file with mode: 0644]
ld/testsuite/ld-elfvers/vers31.dsym [new file with mode: 0644]
ld/testsuite/ld-elfvers/vers31.map [new file with mode: 0644]
ld/testsuite/ld-elfvers/vers31.ver [new file with mode: 0644]

index 4d7d34da26acd837c40eec7d31e62dcf4f387024..dfa7317dca7bc749138e8eee97fb83f67a25a563 100644 (file)
@@ -1,3 +1,15 @@
+2005-10-13  Mark Mitchell  <mark@codesourcery.com>
+
+       * ld.texino: Describe double-quoted string syntax for version
+       nodes.
+       * ldlang.h (lang_new_vers_pattern): Add literal_p parameter.
+       * ldgram.y (vers_defns): Allow NAME as well as VERS_IDENTIFIER.
+       Adjust calls to lang_new_vers_pattern to pass literal_p argument.
+       * ldlang.c (lang_vers_match): Fix indentation.  Do not glob-match
+       version nodes without a pattern.
+       (lang_new_vers_pattern): Add literal_p parameter.
+       (lang_do_version_exports_section): Pass it.
+
 2005-10-12  Mark Mitchell  <mark@codesourcery.com>
 
        * NEWS: Mention @file.
index a95a329a1f7fc42c6aab310b76df2b323c38d0dc..238fde94cc416babe9e343dd68af80e4a483617b 100644 (file)
@@ -4289,6 +4289,10 @@ VERS_1.2 @{
 
 VERS_2.0 @{
                 bar1; bar2;
+        extern "C++" @{       
+                ns::*;
+                "int f(int, double)";
+         @}         
 @} VERS_1.2;
 @end smallexample
 
@@ -4300,6 +4304,8 @@ of the shared library; this is done using wildcard patterns, so that any
 symbol whose name begins with @samp{old}, @samp{original}, or @samp{new}
 is matched.  The wildcard patterns available are the same as those used
 in the shell when matching filenames (also known as ``globbing'').
+However, if you specify the symbol name inside double quotes, then the
+name is treated as literal, rather than as a glob pattern.
 
 Next, the version script defines node @samp{VERS_1.2}.  This node
 depends upon @samp{VERS_1.1}.  The script binds the symbol @samp{foo2}
@@ -4409,6 +4415,16 @@ The linker will iterate over the list of symbols at the link time and
 demangle them according to @samp{lang} before matching them to the
 patterns specified in @samp{version-script-commands}.
 
+Demangled names may contains spaces and other special characters.  As
+described above, you can use a glob pattern to match demangled names,
+or you can use a double-quoted string to match the string exactly.  In
+the latter case, be aware that minor differences (such as differing
+whitespace) between the version script and the demangler output will
+cause a mismatch.  As the exact string generated by the demangler
+might change in the future, even if the mangled name does not, you
+should check that all of your version directives are behaving as you
+expect when you upgrade.
+
 @node Expressions
 @section Expressions in Linker Scripts
 @cindex expressions
index f6e2aa22151336763c95ddfc0dc617bad15173f6..3829e6ae00a15597ce4001619493fe6b85e9ad47 100644 (file)
@@ -1219,11 +1219,19 @@ vers_tag:
 vers_defns:
                VERS_IDENTIFIER
                {
-                 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, FALSE);
+               }
+        |       NAME
+               {
+                 $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, TRUE);
                }
        |       vers_defns ';' VERS_IDENTIFIER
                {
-                 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, FALSE);
+               }
+       |       vers_defns ';' NAME
+               {
+                 $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, TRUE);
                }
        |       vers_defns ';' EXTERN NAME '{'
                        {
@@ -1250,27 +1258,27 @@ vers_defns:
                        }
        |       GLOBAL
                {
-                 $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, FALSE);
                }
        |       vers_defns ';' GLOBAL
                {
-                 $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, FALSE);
                }
        |       LOCAL
                {
-                 $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, FALSE);
                }
        |       vers_defns ';' LOCAL
                {
-                 $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, FALSE);
                }
        |       EXTERN
                {
-                 $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, FALSE);
                }
        |       vers_defns ';' EXTERN
                {
-                 $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang);
+                 $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, FALSE);
                }
        ;
 
index fa01216dffc217c3a93c4880d4576557175ec339..3ff4d819b0a3192a79845dce46eb2e37f48bd871 100644 (file)
@@ -6222,8 +6222,8 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
                while (expr && strcmp (expr->symbol, sym) == 0)
                  if (expr->mask == BFD_ELF_VERSION_C_TYPE)
                    goto out_ret;
-               else
-                 expr = expr->next;
+                 else
+                   expr = expr->next;
              }
            /* Fallthrough */
          case BFD_ELF_VERSION_C_TYPE:
@@ -6234,8 +6234,8 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
                while (expr && strcmp (expr->symbol, cxx_sym) == 0)
                  if (expr->mask == BFD_ELF_VERSION_CXX_TYPE)
                    goto out_ret;
-               else
-                 expr = expr->next;
+                 else
+                   expr = expr->next;
              }
            /* Fallthrough */
          case BFD_ELF_VERSION_CXX_TYPE:
@@ -6246,8 +6246,8 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
                while (expr && strcmp (expr->symbol, java_sym) == 0)
                  if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE)
                    goto out_ret;
-               else
-                 expr = expr->next;
+                 else
+                   expr = expr->next;
              }
            /* Fallthrough */
          default:
@@ -6260,10 +6260,13 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
     expr = head->remaining;
   else
     expr = prev->next;
-  while (expr)
+  for (; expr; expr = expr->next)
     {
       const char *s;
 
+      if (!expr->pattern)
+       continue;
+
       if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
        break;
 
@@ -6275,7 +6278,6 @@ lang_vers_match (struct bfd_elf_version_expr_head *head,
        s = sym;
       if (fnmatch (expr->pattern, s, 0) == 0)
        break;
-      expr = expr->next;
     }
 
 out_ret:
@@ -6330,21 +6332,24 @@ realsymbol (const char *pattern)
     }
 }
 
-/* This is called for each variable name or match expression.  */
+/* This is called for each variable name or match expression.  NEW is
+   the name of the symbol to match, or, if LITERAL_P is FALSE, a glob
+   pattern to be matched against symbol names.  */
 
 struct bfd_elf_version_expr *
 lang_new_vers_pattern (struct bfd_elf_version_expr *orig,
                       const char *new,
-                      const char *lang)
+                      const char *lang,
+                      bfd_boolean literal_p)
 {
   struct bfd_elf_version_expr *ret;
 
   ret = xmalloc (sizeof *ret);
   ret->next = orig;
-  ret->pattern = new;
+  ret->pattern = literal_p ? NULL : new;
   ret->symver = 0;
   ret->script = 0;
-  ret->symbol = realsymbol (new);
+  ret->symbol = literal_p ? new : realsymbol (new);
 
   if (lang == NULL || strcasecmp (lang, "C") == 0)
     ret->mask = BFD_ELF_VERSION_C_TYPE;
@@ -6628,7 +6633,7 @@ lang_do_version_exports_section (void)
       p = contents;
       while (p < contents + len)
        {
-         greg = lang_new_vers_pattern (greg, p, NULL);
+         greg = lang_new_vers_pattern (greg, p, NULL, FALSE);
          p = strchr (p, '\0') + 1;
        }
 
@@ -6638,7 +6643,7 @@ lang_do_version_exports_section (void)
       sec->flags |= SEC_EXCLUDE;
     }
 
-  lreg = lang_new_vers_pattern (NULL, "*", NULL);
+  lreg = lang_new_vers_pattern (NULL, "*", NULL, FALSE);
   lang_register_vers_node (command_line.version_exports_section,
                           lang_new_vers_node (greg, lreg), NULL);
 }
index 8ce312db31815c6a11bd19c4c33b2cee5d61c95a..168caecf4767812fe1ba1249d76e2002423b6cae 100644 (file)
@@ -586,7 +586,7 @@ extern void lang_leave_overlay
 extern struct bfd_elf_version_tree *lang_elf_version_info;
 
 extern struct bfd_elf_version_expr *lang_new_vers_pattern
-  (struct bfd_elf_version_expr *, const char *, const char *);
+  (struct bfd_elf_version_expr *, const char *, const char *, bfd_boolean);
 extern struct bfd_elf_version_tree *lang_new_vers_node
   (struct bfd_elf_version_expr *, struct bfd_elf_version_expr *);
 extern struct bfd_elf_version_deps *lang_add_vers_depend
index c80b5db13f8c92171790be6abc016a323dca1a1d..4e5d21726dbbc06d522ce696c097b676f946ca24 100644 (file)
@@ -1,3 +1,11 @@
+2005-10-13 Mark Mitchell  <mark@codesourcery.com>
+
+       * ld-elfvers/vers.exp: Add vers31.
+       * ld-elfvers/vers31.c: New file.
+       * ld-elfvers/vers31.dsym: Likewise.
+       * ld-elfvers/vers31.map: Likewise.
+       * ld-elfvers/vers31.ver: Likewise.
+
 2005-10-08  Paul Brook  <paul@codesourcery.com>
 
        * ld-arm/arm-rel31.d: Ignore Arm object attribute sections.
index bc115505e3c3c32df51aa2be8e16da9a9f855725..342613787dfacfca3f1d8a2ff109720b8f378b5d 100644 (file)
@@ -964,3 +964,6 @@ build_vers_lib_pic_flags "vers29" vers29.c vers29 "" "" vers29.ver vers29.dsym "
 # Test #30 - test handling of symbol names global, local and extern in the
 # version script.
 build_vers_lib_pic "vers30" vers30.c vers30 "" vers30.map vers30.ver vers30.dsym ""
+
+# Test #31 -- quoted strings in version sections.
+build_vers_lib_pic "vers31" vers31.c vers31 "" vers31.map vers31.ver vers31.dsym ""
diff --git a/ld/testsuite/ld-elfvers/vers31.c b/ld/testsuite/ld-elfvers/vers31.c
new file mode 100644 (file)
index 0000000..78d3927
--- /dev/null
@@ -0,0 +1,6 @@
+/* void f<int [3], char>(int (*) [3], char) */
+void _Z1fIA3_icEvPT_T0_() {}
+
+/* void f<double [3], long>(double (*) [3], long) */
+void _Z1fIA3_dlEvPT_T0_() {}
+
diff --git a/ld/testsuite/ld-elfvers/vers31.dsym b/ld/testsuite/ld-elfvers/vers31.dsym
new file mode 100644 (file)
index 0000000..8924ed8
--- /dev/null
@@ -0,0 +1,2 @@
+[0]* g    DO \*ABS\*   [0]*  VERS_31.0   VERS_31.0
+[0-9a-f]* g    DF (.text|\*ABS\*)      [0-9a-f]*  VERS_31.0   _Z1fIA3_icEvPT_T0
diff --git a/ld/testsuite/ld-elfvers/vers31.map b/ld/testsuite/ld-elfvers/vers31.map
new file mode 100644 (file)
index 0000000..e2d4baf
--- /dev/null
@@ -0,0 +1,5 @@
+VERS_31.0 {
+  extern "C++" {
+    "void f<int [3], char>(int (*) [3], char)";
+  };   
+};
diff --git a/ld/testsuite/ld-elfvers/vers31.ver b/ld/testsuite/ld-elfvers/vers31.ver
new file mode 100644 (file)
index 0000000..b79a5ab
--- /dev/null
@@ -0,0 +1,3 @@
+Version definitions:
+1 0x01 0x0966595f vers31.so
+2 0x00 0x07923ab0 VERS_31.0