gas: Extend .symver directive

Extend .symver directive to update visibility of the original symbol and
assign one original symbol to different versioned symbols:

  .symver foo, foo@VERS_1, local    # Change foo to a local symbol.
  .symver foo, foo@VERS_2, hidden   # Change foo to a hidden symbol.
  .symver foo, foo@@VERS_3, remove  # Remove foo from symbol table.
  .symver foo, bar@V1               # Assign foo to bar@V1 and baz@V2.
  .symver foo, baz@V2

	PR gas/23840
	PR gas/25295
	* NEWS: Mention .symver extension.
	* config/obj-elf.c (obj_elf_find_and_add_versioned_name): New
	function.
	(obj_elf_symver): Call obj_elf_find_and_add_versioned_name to
	add a version name.  Add local, hidden and remove visibility
	support.
	(elf_frob_symbol): Handle the list of version names.  Update the
	original symbol to local, hidden or remove it from the symbol
	table.
	(elf_frob_file_before_adjust): Handle the list of version names.
	* config/obj-elf.h (elf_visibility): New.
	(elf_versioned_name_list): Likewise.
	(elf_obj_sy): Change local to bitfield. Add rename, bad_version
	and visibility.  Change versioned_name pointer to struct
	elf_versioned_name_list.
	* doc/as.texi: Update .symver directive.
	* testsuite/gas/symver/symver.exp: Run all *.d tests.  Add more
	error checking tests.
	* testsuite/gas/symver/symver6.d: New file.
	* testsuite/gas/symver/symver7.d: Likewise.
	* testsuite/gas/symver/symver7.s: Likewise.
	* testsuite/gas/symver/symver8.d: Likewise.
	* testsuite/gas/symver/symver8.s: Likewise.
	* testsuite/gas/symver/symver9.s: Likewise.
	* testsuite/gas/symver/symver9a.d: Likewise.
	* testsuite/gas/symver/symver9b.d: Likewise.
	* testsuite/gas/symver/symver10.s: Likewise.
	* testsuite/gas/symver/symver10a.d: Likewise.
	* testsuite/gas/symver/symver10b.d: Likewise.
	* testsuite/gas/symver/symver11.d: Likewise.
	* testsuite/gas/symver/symver11.s: Likewise.
	* testsuite/gas/symver/symver12.d: Likewise.
	* testsuite/gas/symver/symver12.s: Likewise.
	* testsuite/gas/symver/symver13.d: Likewise.
	* testsuite/gas/symver/symver13.s: Likewise.
	* testsuite/gas/symver/symver14.d: Likewise.
	* testsuite/gas/symver/symver14.l: Likewise.
	* testsuite/gas/symver/symver15.d: Likewise.
	* testsuite/gas/symver/symver15.l: Likewise.
	* testsuite/gas/symver/symver6.l: Removed.
	* testsuite/gas/symver/symver6.s: Updated.
This commit is contained in:
H.J. Lu
2020-04-21 05:33:04 -07:00
parent 6f6fd151cb
commit 6914be53bd
29 changed files with 472 additions and 124 deletions

View File

@ -1,3 +1,49 @@
2020-04-21 H.J. Lu <hongjiu.lu@intel.com>
PR gas/23840
PR gas/25295
* NEWS: Mention .symver extension.
* config/obj-elf.c (obj_elf_find_and_add_versioned_name): New
function.
(obj_elf_symver): Call obj_elf_find_and_add_versioned_name to
add a version name. Add local, hidden and remove visibility
support.
(elf_frob_symbol): Handle the list of version names. Update the
original symbol to local, hidden or remove it from the symbol
table.
(elf_frob_file_before_adjust): Handle the list of version names.
* config/obj-elf.h (elf_visibility): New.
(elf_versioned_name_list): Likewise.
(elf_obj_sy): Change local to bitfield. Add rename, bad_version
and visibility. Change versioned_name pointer to struct
elf_versioned_name_list.
* doc/as.texi: Update .symver directive.
* testsuite/gas/symver/symver.exp: Run all *.d tests. Add more
error checking tests.
* testsuite/gas/symver/symver6.d: New file.
* testsuite/gas/symver/symver7.d: Likewise.
* testsuite/gas/symver/symver7.s: Likewise.
* testsuite/gas/symver/symver8.d: Likewise.
* testsuite/gas/symver/symver8.s: Likewise.
* testsuite/gas/symver/symver9.s: Likewise.
* testsuite/gas/symver/symver9a.d: Likewise.
* testsuite/gas/symver/symver9b.d: Likewise.
* testsuite/gas/symver/symver10.s: Likewise.
* testsuite/gas/symver/symver10a.d: Likewise.
* testsuite/gas/symver/symver10b.d: Likewise.
* testsuite/gas/symver/symver11.d: Likewise.
* testsuite/gas/symver/symver11.s: Likewise.
* testsuite/gas/symver/symver12.d: Likewise.
* testsuite/gas/symver/symver12.s: Likewise.
* testsuite/gas/symver/symver13.d: Likewise.
* testsuite/gas/symver/symver13.s: Likewise.
* testsuite/gas/symver/symver14.d: Likewise.
* testsuite/gas/symver/symver14.l: Likewise.
* testsuite/gas/symver/symver15.d: Likewise.
* testsuite/gas/symver/symver15.l: Likewise.
* testsuite/gas/symver/symver6.l: Removed.
* testsuite/gas/symver/symver6.s: Updated.
2020-04-20 Sudakshina Das <sudi.das@arm.com>
* config/tc-aarch64.c (parse_barrier_psb): Update error messages

View File

@ -1,5 +1,8 @@
-*- text -*-
* Extend .symver directive to update visibility of the original symbol
and assign one original symbol to different versioned symbols.
* Add support for Intel SERIALIZE and TSXLDTRK instructions.
* Add -mlfence-after-load=, -mlfence-before-indirect-branch= and

View File

@ -1515,6 +1515,70 @@ obj_elf_line (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
static struct elf_versioned_name_list *
obj_elf_find_and_add_versioned_name (const char *version_name,
const char *sym_name,
const char *ver,
struct elf_obj_sy *sy_obj)
{
struct elf_versioned_name_list *versioned_name;
const char *p;
for (p = ver + 1; *p == ELF_VER_CHR; p++)
;
/* NB: Since some tests in ld/testsuite/ld-elfvers have no version
names, we have to disable this. */
if (0 && *p == '\0')
{
as_bad (_("missing version name in `%s' for symbol `%s'"),
version_name, sym_name);
return NULL;
}
versioned_name = sy_obj->versioned_name;
switch (p - ver)
{
case 1:
case 2:
break;
case 3:
if (sy_obj->rename)
{
if (strcmp (versioned_name->name, version_name) == 0)
return versioned_name;
else
{
as_bad (_("only one version name with `@@@' is allowed "
"for symbol `%s'"), sym_name);
return NULL;
}
}
sy_obj->rename = TRUE;
break;
default:
as_bad (_("invalid version name '%s' for symbol `%s'"),
version_name, sym_name);
return NULL;
}
for (;
versioned_name != NULL;
versioned_name = versioned_name->next)
if (strcmp (versioned_name->name, version_name) == 0)
return versioned_name;
/* Add this versioned name to the head of the list, */
versioned_name = (struct elf_versioned_name_list *)
xmalloc (sizeof (*versioned_name));
versioned_name->name = xstrdup (version_name);
versioned_name->next = sy_obj->versioned_name;
sy_obj->versioned_name = versioned_name;
return versioned_name;
}
/* This handles the .symver pseudo-op, which is used to specify a
symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
@ -1525,9 +1589,12 @@ static void
obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
{
char *name;
const char *sym_name;
char c;
char old_lexat;
symbolS *sym;
struct elf_obj_sy *sy_obj;
char *p;
sym = get_sym_from_input_line_and_check ();
@ -1546,43 +1613,59 @@ obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
lex_type[(unsigned char) '@'] |= LEX_NAME;
c = get_symbol_name (& name);
lex_type[(unsigned char) '@'] = old_lexat;
sym_name = S_GET_NAME (sym);
if (S_IS_COMMON (sym))
{
as_bad (_("`%s' can't be versioned to common symbol '%s'"),
name, S_GET_NAME (sym));
name, sym_name);
ignore_rest_of_line ();
return;
}
if (symbol_get_obj (sym)->versioned_name == NULL)
p = strchr (name, ELF_VER_CHR);
if (p == NULL)
{
symbol_get_obj (sym)->versioned_name = xstrdup (name);
(void) restore_line_pointer (c);
if (strchr (symbol_get_obj (sym)->versioned_name,
ELF_VER_CHR) == NULL)
{
as_bad (_("missing version name in `%s' for symbol `%s'"),
symbol_get_obj (sym)->versioned_name,
S_GET_NAME (sym));
ignore_rest_of_line ();
return;
}
as_bad (_("missing version name in `%s' for symbol `%s'"),
name, sym_name);
ignore_rest_of_line ();
return;
}
else
{
if (strcmp (symbol_get_obj (sym)->versioned_name, name))
{
as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
name, symbol_get_obj (sym)->versioned_name,
S_GET_NAME (sym));
ignore_rest_of_line ();
return;
}
(void) restore_line_pointer (c);
sy_obj = symbol_get_obj (sym);
if (obj_elf_find_and_add_versioned_name (name, sym_name,
p, sy_obj) == NULL)
{
sy_obj->bad_version = TRUE;
ignore_rest_of_line ();
return;
}
(void) restore_line_pointer (c);
if (*input_line_pointer == ',')
{
char *save = input_line_pointer;
++input_line_pointer;
SKIP_WHITESPACE ();
if (strncmp (input_line_pointer, "local", 5) == 0)
{
input_line_pointer += 5;
sy_obj->visibility = visibility_local;
}
else if (strncmp (input_line_pointer, "hidden", 6) == 0)
{
input_line_pointer += 6;
sy_obj->visibility = visibility_hidden;
}
else if (strncmp (input_line_pointer, "remove", 6) == 0)
{
input_line_pointer += 6;
sy_obj->visibility = visibility_remove;
}
else
input_line_pointer = save;
}
demand_empty_rest_of_line ();
@ -2382,6 +2465,7 @@ elf_frob_symbol (symbolS *symp, int *puntp)
{
struct elf_obj_sy *sy_obj;
expressionS *size;
struct elf_versioned_name_list *versioned_name;
#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
@ -2409,73 +2493,47 @@ elf_frob_symbol (symbolS *symp, int *puntp)
sy_obj->size = NULL;
}
if (sy_obj->versioned_name != NULL)
versioned_name = sy_obj->versioned_name;
if (versioned_name)
{
char *p;
p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
if (p == NULL)
/* We will have already reported an error about a missing version. */
*puntp = TRUE;
/* This symbol was given a new name with the .symver directive.
If this is an external reference, just rename the symbol to
include the version string. This will make the relocs be
against the correct versioned symbol.
against the correct versioned symbol. */
If this is a definition, add an alias. FIXME: Using an alias
will permit the debugging information to refer to the right
symbol. However, it's not clear whether it is the best
approach. */
else if (! S_IS_DEFINED (symp))
/* We will have already reported an version error. */
if (sy_obj->bad_version)
*puntp = TRUE;
/* elf_frob_file_before_adjust only allows one version symbol for
renamed symbol. */
else if (sy_obj->rename)
S_SET_NAME (symp, versioned_name->name);
else if (S_IS_COMMON (symp))
{
/* Verify that the name isn't using the @@ syntax--this is
reserved for definitions of the default version to link
against. */
if (p[1] == ELF_VER_CHR)
{
as_bad (_("invalid attempt to declare external version name"
" as default in symbol `%s'"),
sy_obj->versioned_name);
*puntp = TRUE;
}
S_SET_NAME (symp, sy_obj->versioned_name);
as_bad (_("`%s' can't be versioned to common symbol '%s'"),
versioned_name->name, S_GET_NAME (symp));
*puntp = TRUE;
}
else
{
if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
asymbol *bfdsym;
elf_symbol_type *elfsym;
/* This is a definition. Add an alias for each version.
FIXME: Using an alias will permit the debugging information
to refer to the right symbol. However, it's not clear
whether it is the best approach. */
/* FIXME: Creating a new symbol here is risky. We're
in the final loop over the symbol table. We can
get away with it only because the symbol goes to
the end of the list, where the loop will still see
it. It would probably be better to do this in
obj_frob_file_before_adjust. */
for (; versioned_name != NULL;
versioned_name = versioned_name->next)
{
size_t l;
/* The @@@ syntax is a special case. It renames the
symbol name to versioned_name with one `@' removed. */
l = strlen (&p[3]) + 1;
memmove (&p[2], &p[3], l);
S_SET_NAME (symp, sy_obj->versioned_name);
}
else
{
symbolS *symp2;
/* FIXME: Creating a new symbol here is risky. We're
in the final loop over the symbol table. We can
get away with it only because the symbol goes to
the end of the list, where the loop will still see
it. It would probably be better to do this in
obj_frob_file_before_adjust. */
symp2 = symbol_find_or_make (sy_obj->versioned_name);
/* Now we act as though we saw symp2 = sym. */
if (S_IS_COMMON (symp))
{
as_bad (_("`%s' can't be versioned to common symbol '%s'"),
sy_obj->versioned_name, S_GET_NAME (symp));
*puntp = TRUE;
return;
}
symbolS *symp2 = symbol_find_or_make (versioned_name->name);
S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
@ -2498,6 +2556,27 @@ elf_frob_symbol (symbolS *symp, int *puntp)
if (S_IS_EXTERNAL (symp))
S_SET_EXTERNAL (symp2);
}
switch (symbol_get_obj (symp)->visibility)
{
case visibility_unchanged:
break;
case visibility_hidden:
bfdsym = symbol_get_bfdsym (symp);
elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym),
bfdsym);
elfsym->internal_elf_sym.st_other &= ~3;
elfsym->internal_elf_sym.st_other |= STV_HIDDEN;
break;
case visibility_remove:
/* Remove the symbol if it isn't used in relocation. */
if (!symbol_used_in_reloc_p (symp))
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
break;
case visibility_local:
S_CLEAR_EXTERNAL (symp);
break;
}
}
}
@ -2676,36 +2755,61 @@ elf_frob_file_before_adjust (void)
symbolS *symp;
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
if (!S_IS_DEFINED (symp))
{
if (symbol_get_obj (symp)->versioned_name)
{
char *p;
{
struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
int is_defined = !!S_IS_DEFINED (symp);
/* The @@@ syntax is a special case. If the symbol is
not defined, 2 `@'s will be removed from the
versioned_name. */
if (sy_obj->versioned_name)
{
char *p = strchr (sy_obj->versioned_name->name,
ELF_VER_CHR);
p = strchr (symbol_get_obj (symp)->versioned_name,
ELF_VER_CHR);
if (p != NULL && p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
{
size_t l = strlen (&p[3]) + 1;
memmove (&p[1], &p[3], l);
}
if (symbol_used_p (symp) == 0
&& symbol_used_in_reloc_p (symp) == 0)
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
}
if (sy_obj->rename)
{
/* The @@@ syntax is a special case. If the symbol is
not defined, 2 `@'s will be removed from the
versioned_name. Otherwise, 1 `@' will be removed. */
size_t l = strlen (&p[3]) + 1;
memmove (&p[1 + is_defined], &p[3], l);
}
/* If there was .weak foo, but foo was neither defined nor
used anywhere, remove it. */
if (!is_defined)
{
/* Verify that the name isn't using the @@ syntax--this
is reserved for definitions of the default version
to link against. */
if (!sy_obj->rename && p[1] == ELF_VER_CHR)
{
as_bad (_("invalid attempt to declare external "
"version name as default in symbol `%s'"),
sy_obj->versioned_name->name);
return;
}
else if (S_IS_WEAK (symp)
&& symbol_used_p (symp) == 0
&& symbol_used_in_reloc_p (symp) == 0)
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
}
/* Only one version symbol is allowed for undefined
symbol. */
if (sy_obj->versioned_name->next)
{
as_bad (_("multiple versions [`%s'|`%s'] for "
"symbol `%s'"),
sy_obj->versioned_name->name,
sy_obj->versioned_name->next->name,
S_GET_NAME (symp));
return;
}
sy_obj->rename = TRUE;
}
}
/* If there was .symver or .weak, but symbol was neither
defined nor used anywhere, remove it. */
if (!is_defined
&& (sy_obj->versioned_name || S_IS_WEAK (symp))
&& symbol_used_p (symp) == 0
&& symbol_used_in_reloc_p (symp) == 0)
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
}
}
}

View File

@ -55,18 +55,41 @@ extern int mips_flag_mdebug;
#endif
#endif
enum elf_visibility
{
visibility_unchanged = 0,
visibility_local,
visibility_hidden,
visibility_remove
};
struct elf_versioned_name_list
{
char *name;
struct elf_versioned_name_list *next;
};
/* Additional information we keep for each symbol. */
struct elf_obj_sy
{
/* Whether the symbol has been marked as local. */
int local;
unsigned int local : 1;
/* Whether the symbol has been marked for rename with @@@. */
unsigned int rename : 1;
/* Whether the symbol has a bad version name. */
unsigned int bad_version : 1;
/* Whether visibility of the symbol should be changed. */
ENUM_BITFIELD (elf_visibility) visibility : 2;
/* Use this to keep track of .size expressions that involve
differences that we can't compute yet. */
expressionS *size;
/* The name specified by the .symver directive. */
char *versioned_name;
/* The list of names specified by the .symver directive. */
struct elf_versioned_name_list *versioned_name;
#ifdef ECOFF_DEBUGGING
/* If we are generating ECOFF debugging information, we need some

View File

@ -4509,7 +4509,7 @@ Some machine configurations provide additional directives.
* Struct:: @code{.struct @var{expression}}
@ifset ELF
* SubSection:: @code{.subsection}
* Symver:: @code{.symver @var{name},@var{name2@@nodename}}
* Symver:: @code{.symver @var{name},@var{name2@@nodename}[,@var{visibility}]}
@end ifset
@ifset COFF
@ -7112,9 +7112,9 @@ shared library.
For ELF targets, the @code{.symver} directive can be used like this:
@smallexample
.symver @var{name}, @var{name2@@nodename}
.symver @var{name}, @var{name2@@nodename}[ ,@var{visibility}]
@end smallexample
If the symbol @var{name} is defined within the file
If the original symbol @var{name} is defined within the file
being assembled, the @code{.symver} directive effectively creates a symbol
alias with the name @var{name2@@nodename}, and in fact the main reason that we
just don't try and create a regular alias is that the @var{@@} character isn't
@ -7127,7 +7127,15 @@ function is being mentioned. The @var{nodename} portion of the alias should be
the name of a node specified in the version script supplied to the linker when
building a shared library. If you are attempting to override a versioned
symbol from a shared library, then @var{nodename} should correspond to the
nodename of the symbol you are trying to override.
nodename of the symbol you are trying to override. The optional argument
@var{visibility} updates the visibility of the original symbol. The valid
visibilities are @code{local}, @code {hidden}, and @code {remove}. The
@code{local} visibility makes the original symbol a local symbol
(@pxref{Local}). The @code{hidden} visibility sets the visibility of the
original symbol to @code{hidden} (@pxref{Hidden}). The @code{remove}
visibility removes the original symbol from the symbol table if it isn't
used in relocation. If visibility isn't specified, the original symbol
is unchanged.
If the symbol @var{name} is not defined within the file being assembled, all
references to @var{name} will be changed to @var{name2@@nodename}. If no

View File

@ -46,8 +46,13 @@ if { [is_elf_format] } then {
return
}
run_dump_test "symver0"
run_dump_test "symver1"
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
foreach t $test_list {
# We need to strip the ".d", but can leave the dirname.
verbose [file rootname $t]
run_dump_test [file rootname $t]
}
run_error_test "symver2" ""
run_error_test "symver3" ""
# We have to comment out symver4 and symver5, which check the
@ -56,5 +61,6 @@ if { [is_elf_format] } then {
# version name.
# run_error_test "symver4" ""
# run_error_test "symver5" ""
run_error_test "symver6" ""
run_error_test "symver14" ""
run_error_test "symver15" ""
}

View File

@ -0,0 +1,8 @@
.data
.globl foo
.type foo,%object
foo:
.byte 0
.size foo,.-foo
.symver foo,foo@@version2,remove
.symver foo,foo@version1

View File

@ -0,0 +1,8 @@
#source: symver10.s
#readelf: -sW
#name: symver symver10a
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@version1
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@@version2
#pass

View File

@ -0,0 +1,8 @@
#source: symver10.s
#readelf: -sW
#name: symver symver10b
#failif
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo
#pass

View File

@ -0,0 +1,8 @@
#readelf: -rsW
#name: symver symver11
#...
[0-9a-f]+ +[0-9a-f]+ +R_.* +[0-9a-f]+ +foo *.*
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo
#pass

View File

@ -0,0 +1,9 @@
.data
.globl foo
.type foo,%object
foo:
.byte 0
.size foo,.-foo
.symver foo,foo@@version2,remove
.symver foo,foo@version1
.dc.a foo

View File

@ -0,0 +1,9 @@
#readelf: -sW
#name: symver symver12
#...
+[0-9]+: +0+d +1 +FUNC +GLOBAL +DEFAULT +[0-9]+ +foo
+[0-9]+: +0+d +1 +FUNC +GLOBAL +DEFAULT +[0-9]+ +foo@VERS_2
+[0-9]+: +0+d +1 +FUNC +GLOBAL +DEFAULT +[0-9]+ +foo@VERS_1
+[0-9]+: +0+d +1 +FUNC +GLOBAL +DEFAULT +[0-9]+ +foo@@VERS_2
#pass

View File

@ -0,0 +1,10 @@
.text
.space 13
.symver foo, foo@@VERS_2
.symver foo, foo@VERS_1
.symver foo, foo@VERS_2
.globl foo
.type foo, %function
foo:
.byte 0
.size foo,.-foo

View File

@ -0,0 +1,9 @@
#readelf: -sW
#name: symver symver13
#...
+[0-9]+: +0+d +1 +FUNC +GLOBAL +HIDDEN +[0-9]+ +foo
+[0-9]+: +0+d +1 +FUNC +GLOBAL +HIDDEN +[0-9]+ +foo@VERS_1
+[0-9]+: +0+d +1 +FUNC +GLOBAL +HIDDEN +[0-9]+ +foo@@VERS_2
+[0-9]+: +0+d +1 +FUNC +GLOBAL +HIDDEN +[0-9]+ +foo@VERS_2
#pass

View File

@ -0,0 +1,11 @@
.text
.space 13
.globl foo
.type foo, %function
foo:
.byte 0
.symver foo, foo@VERS_2
.symver foo, foo@@VERS_2
.symver foo, foo@VERS_1
.hidden foo
.size foo,.-foo

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Error: only one version name with `@@@' is allowed for symbol `foo'

View File

@ -0,0 +1,6 @@
.data
.global foo
foo:
.byte 1
.symver foo,foo@@@version1
.symver foo,foo@@@version2

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*: Error: multiple versions \[`foo@version2'|`foo@version1'\] for symbol `foo'

View File

@ -0,0 +1,3 @@
.data
.symver foo,foo@version1
.symver foo,foo@version2

View File

@ -0,0 +1,11 @@
#nm: -n
#name: symver symver6
#
#...
[ ]+U foo
#...
0+00000.. D foo1
0+0000000 D foo@@version1
0+00000.. D foo@version1
0+00000.. d L_foo1

View File

@ -1,3 +0,0 @@
.*: Assembler messages:
.*:7: Error: multiple versions \[`foo@version1'|`foo@@version1'\] for symbol `foo'
#pass

View File

@ -3,7 +3,7 @@
.type foo1,object
foo1:
.long foo
.symver foo,foo@@version1
.symver foo,foo@version1
.symver foo1,foo@@version1
.symver foo1,foo@version1
L_foo1:
.size foo1,L_foo1-foo1

View File

@ -0,0 +1,8 @@
#readelf: -sW
#name: symver symver7
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +HIDDEN +[0-9]+ +foo
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@version1
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@@version2
#pass

View File

@ -0,0 +1,8 @@
.data
.globl foo
.type foo,%object
foo:
.byte 0
.size foo,.-foo
.symver foo,foo@@version2,local
.symver foo,foo@version1,hidden

View File

@ -0,0 +1,9 @@
#readelf: -sW
#name: symver symver8
#...
+[0-9]+: +0+ +1 +OBJECT +LOCAL +DEFAULT +[0-9]+ +foo
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@version1
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@@version2
#pass

View File

@ -0,0 +1,8 @@
.data
.globl foo
.type foo,%object
foo:
.byte 0
.size foo,.-foo
.symver foo,foo@@version2,hidden
.symver foo,foo@version1,local

View File

@ -0,0 +1,8 @@
.data
.globl foo
.type foo,%object
foo:
.byte 0
.size foo,.-foo
.symver foo,foo@@version2
.symver foo,foo@version1,remove

View File

@ -0,0 +1,8 @@
#source: symver9.s
#readelf: -sW
#name: symver symver9a
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@version1
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@@version2
#pass

View File

@ -0,0 +1,8 @@
#source: symver9.s
#readelf: -sW
#name: symver symver9b
#failif
#...
+[0-9]+: +0+ +1 +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo
#pass