2000-11-13 H.J. Lu <hjl@gnu.org>

* config/obj-elf.c (elf_frob_symbol): Support
	".symver name,name2@@@nodename".
	(elf_frob_file_before_adjust): Likewise.

	* doc/as.texinfo: Updated for ".symver name,name2@@@nodename"
	and ".symver name,name2@@@nodename".
	Fix a typo.
This commit is contained in:
H.J. Lu
2000-11-13 21:23:34 +00:00
parent 158b3de091
commit 79082ff0c6
3 changed files with 93 additions and 32 deletions

View File

@ -1,3 +1,13 @@
2000-11-13 H.J. Lu <hjl@gnu.org>
* config/obj-elf.c (elf_frob_symbol): Support
".symver name,name2@@@nodename".
(elf_frob_file_before_adjust): Likewise.
* doc/as.texinfo: Updated for ".symver name,name2@@@nodename"
and ".symver name,name2@@@nodename".
Fix a typo.
2000-11-12 H.J. Lu (hjl@gnu.org) 2000-11-12 H.J. Lu (hjl@gnu.org)
* config/obj-elf.c (obj_elf_symver): Check missing version * config/obj-elf.c (obj_elf_symver): Check missing version

View File

@ -1658,6 +1658,11 @@ elf_frob_symbol (symp, puntp)
if (sy_obj->versioned_name != NULL) if (sy_obj->versioned_name != NULL)
{ {
char *p;
p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
know (p != NULL);
/* This symbol was given a new name with the .symver directive. /* This symbol was given a new name with the .symver directive.
If this is an external reference, just rename the symbol to If this is an external reference, just rename the symbol to
@ -1671,13 +1676,9 @@ elf_frob_symbol (symp, puntp)
if (! S_IS_DEFINED (symp)) if (! S_IS_DEFINED (symp))
{ {
char *p;
/* Verify that the name isn't using the @@ syntax--this is /* Verify that the name isn't using the @@ syntax--this is
reserved for definitions of the default version to link reserved for definitions of the default version to link
against. */ against. */
p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
know (p != NULL);
if (p[1] == ELF_VER_CHR) if (p[1] == ELF_VER_CHR)
{ {
as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"), as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
@ -1686,15 +1687,28 @@ elf_frob_symbol (symp, puntp)
} }
S_SET_NAME (symp, sy_obj->versioned_name); S_SET_NAME (symp, sy_obj->versioned_name);
} }
else
{
if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
{
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 else
{ {
symbolS *symp2; symbolS *symp2;
/* FIXME: Creating a new symbol here is risky. We're in the /* FIXME: Creating a new symbol here is risky. We're
final loop over the symbol table. We can get away with in the final loop over the symbol table. We can
it only because the symbol goes to the end of the list, get away with it only because the symbol goes to
where the loop will still see it. It would probably be the end of the list, where the loop will still see
better to do this in obj_frob_file_before_adjust. */ it. It would probably be better to do this in
obj_frob_file_before_adjust. */
symp2 = symbol_find_or_make (sy_obj->versioned_name); symp2 = symbol_find_or_make (sy_obj->versioned_name);
@ -1702,8 +1716,8 @@ elf_frob_symbol (symp, puntp)
S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp)); S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
/* Subtracting out the frag address here is a hack because /* Subtracting out the frag address here is a hack
we are in the middle of the final loop. */ because we are in the middle of the final loop. */
S_SET_VALUE (symp2, S_SET_VALUE (symp2,
(S_GET_VALUE (symp) (S_GET_VALUE (symp)
- symbol_get_frag (symp)->fr_address)); - symbol_get_frag (symp)->fr_address));
@ -1720,6 +1734,7 @@ elf_frob_symbol (symp, puntp)
S_SET_EXTERNAL (symp2); S_SET_EXTERNAL (symp2);
} }
} }
}
/* Double check weak symbols. */ /* Double check weak symbols. */
if (S_IS_WEAK (symp)) if (S_IS_WEAK (symp))
@ -1778,13 +1793,31 @@ elf_frob_file_before_adjust ()
symbolS *symp; symbolS *symp;
for (symp = symbol_rootP; symp; symp = symbol_next (symp)) for (symp = symbol_rootP; symp; symp = symbol_next (symp))
if (symbol_get_obj (symp)->versioned_name if (symbol_get_obj (symp)->versioned_name)
&& !S_IS_DEFINED (symp) {
&& symbol_used_p (symp) == 0 if (!S_IS_DEFINED (symp))
{
char *p;
/* The @@@ syntax is a special case. If the symbol is
not defined, 2 `@'s will be removed from the
versioned_name. */
p = strchr (symbol_get_obj (symp)->versioned_name,
ELF_VER_CHR);
know (p != NULL);
if (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_used_in_reloc_p (symp) == 0)
symbol_remove (symp, &symbol_rootP, &symbol_lastP); symbol_remove (symp, &symbol_rootP, &symbol_lastP);
} }
} }
}
}
/* It is required that we let write_relocs have the opportunity to /* It is required that we let write_relocs have the opportunity to
optimize away fixups before output has begun, since it is possible optimize away fixups before output has begun, since it is possible

View File

@ -4933,12 +4933,12 @@ There are cases where it may make sense to use this in objects to be bound
into an application itself so as to override a versioned symbol from a into an application itself so as to override a versioned symbol from a
shared library. shared library.
For ELF targets, the @code{.symver} directive is used like this: For ELF targets, the @code{.symver} directive can be used like this:
@smallexample @smallexample
.symver @var{name}, @var{name2@@nodename} .symver @var{name}, @var{name2@@nodename}
@end smallexample @end smallexample
If the symbol @var{name} is defined within the file If the symbol @var{name} is defined within the file
being assembled, the @code{.versym} directive effectively creates a symbol 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 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 just don't try and create a regular alias is that the @var{@@} character isn't
permitted in symbol names. The @var{name2} part of the name is the actual name permitted in symbol names. The @var{name2} part of the name is the actual name
@ -4956,6 +4956,24 @@ 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 references to @var{name} will be changed to @var{name2@@nodename}. If no
reference to @var{name} is made, @var{name2@@nodename} will be removed from the reference to @var{name} is made, @var{name2@@nodename} will be removed from the
symbol table. symbol table.
Another usage of the @code{.symver} directive is:
@smallexample
.symver @var{name}, @var{name2@@@@nodename}
@end smallexample
In this case, the symbol @var{name} must exist and be defined within
the file being assembled. It is similiar to @var{name2@@nodename}. The
difference is @var{name2@@@@nodename} will also be used to resolve
references to @var{name2} by the linker.
The third usage of the @code{.symver} directive is:
@smallexample
.symver @var{name}, @var{name2@@@@@@nodename}
@end smallexample
When @var{name} is not defined within the
file being assembled, it is treated as @var{name2@@nodename}. When
@var{name} is defined within the file being assembled, the symbol
name, @var{name}, will be changed to @var{name2@@@@nodename}.
@end ifset @end ifset
@ifset COFF @ifset COFF