From: Mark Mitchell Date: Thu, 13 Oct 2005 22:14:23 +0000 (+0000) Subject: Issue #439 X-Git-Tag: binutils-csl-sourcerygxx-3_4_4-25~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2adcb11fe8caed452526847034b349004375babe;p=thirdparty%2Fbinutils-gdb.git Issue #439 Backport: 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. --- diff --git a/ChangeLog.csl b/ChangeLog.csl index 15652c6ecef..10d39340976 100644 --- a/ChangeLog.csl +++ b/ChangeLog.csl @@ -1,3 +1,18 @@ +2005-10-13 Mark Mitchell + + Issue #439 + Backport: + 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-08-30 Mark Mitchell * ld/ldmain.c (main): Use expandargv. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 29f637fe5e5..e5144edbba5 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -4224,6 +4224,10 @@ VERS_1.2 @{ VERS_2.0 @{ bar1; bar2; + extern "C++" @{ + ns::*; + "int f(int, double)"; + @} @} VERS_1.2; @end smallexample @@ -4235,6 +4239,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} @@ -4344,6 +4350,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 23151d8f6b0..61e1259341e 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -1215,11 +1215,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 '{' { diff --git a/ld/ldlang.c b/ld/ldlang.c index c38423ea4c6..1e3fb9c6ad1 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -5615,8 +5615,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: @@ -5627,8 +5627,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: @@ -5639,8 +5639,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: @@ -5653,10 +5653,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; @@ -5668,7 +5671,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: @@ -5723,21 +5725,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; @@ -6021,7 +6026,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; } @@ -6031,7 +6036,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 eb54a59ae01..758292b99eb 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -569,7 +569,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/ld-elfvers/vers.exp b/ld/testsuite/ld-elfvers/vers.exp index e4a6e81db93..94b41957805 100644 --- a/ld/testsuite/ld-elfvers/vers.exp +++ b/ld/testsuite/ld-elfvers/vers.exp @@ -960,3 +960,6 @@ build_vers_lib_pic "vers28a" vers28a.c vers28a "" "" vers28a.ver vers28a.dsym "" build_vers_lib_pic "vers28b" vers28b.c vers28b "" vers28b.map vers28b.ver vers28b.dsym "" build_vers_lib_pic "vers28c" vers28c.c vers28c "vers28b.so vers28a.so" "" vers28c.ver vers28c.dsym "" build_vers_lib_pic_flags "vers29" vers29.c vers29 "" "" vers29.ver vers29.dsym "" "--default-symver" + +# Test #31 -- quoted strings in version sections. +build_vers_lib_pic "vers31" vers31.c vers31 "" vers31.map vers31.ver vers31.dsym ""