From: Mark Mitchell Date: Thu, 13 Oct 2005 17:29:57 +0000 (+0000) Subject: * ld.texino: Describe double-quoted string syntax for version X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=86043bbbd53f965b6f2003af2f96f55c6702d0de;p=binutils-gdb.git * 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. --- 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 + + * 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 * 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 + + * 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 * 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) */ +void _Z1fIA3_icEvPT_T0_() {} + +/* void f(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)"; + }; +}; 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