summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-10-13 17:29:57 +0000
committerMark Mitchell <mark@codesourcery.com>2005-10-13 17:29:57 +0000
commit86043bbbd53f965b6f2003af2f96f55c6702d0de (patch)
tree7d60692bd4cfd11bcc87add6bf515321c42c27cb /ld
parent16451949d7083391405bb46c06a2fadac01f5c42 (diff)
downloadbinutils-gdb-86043bbbd53f965b6f2003af2f96f55c6702d0de.tar.gz
* 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. * 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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog12
-rw-r--r--ld/ld.texinfo16
-rw-r--r--ld/ldgram.y24
-rw-r--r--ld/ldlang.c33
-rw-r--r--ld/ldlang.h2
-rw-r--r--ld/testsuite/ChangeLog8
-rw-r--r--ld/testsuite/ld-elfvers/vers.exp3
-rw-r--r--ld/testsuite/ld-elfvers/vers31.c6
-rw-r--r--ld/testsuite/ld-elfvers/vers31.dsym2
-rw-r--r--ld/testsuite/ld-elfvers/vers31.map5
-rw-r--r--ld/testsuite/ld-elfvers/vers31.ver3
11 files changed, 91 insertions, 23 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 4d7d34da26a..dfa7317dca7 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index a95a329a1f7..238fde94cc4 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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
diff --git a/ld/ldgram.y b/ld/ldgram.y
index f6e2aa22151..3829e6ae00a 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -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);
}
;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index fa01216dffc..3ff4d819b0a 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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);
}
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 8ce312db318..168caecf476 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -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
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index c80b5db13f8..4e5d21726db 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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.
diff --git a/ld/testsuite/ld-elfvers/vers.exp b/ld/testsuite/ld-elfvers/vers.exp
index bc115505e3c..342613787df 100644
--- a/ld/testsuite/ld-elfvers/vers.exp
+++ b/ld/testsuite/ld-elfvers/vers.exp
@@ -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
index 00000000000..78d3927cd28
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers31.c
@@ -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
index 00000000000..8924ed8e6d8
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers31.dsym
@@ -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
index 00000000000..e2d4baf82a6
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers31.map
@@ -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
index 00000000000..b79a5ab9d49
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers31.ver
@@ -0,0 +1,3 @@
+Version definitions:
+1 0x01 0x0966595f vers31.so
+2 0x00 0x07923ab0 VERS_31.0