aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2000-11-13 21:23:34 +0000
committerH.J. Lu <hjl.tools@gmail.com>2000-11-13 21:23:34 +0000
commit79082ff0c6032d8e1e832fe35cc69b3b46d4bd91 (patch)
tree9192822960940b65af19449924b1a7aa14cc3c91 /gas
parent158b3de091284fe2c277ee56c5652195358ec202 (diff)
downloadgdb-79082ff0c6032d8e1e832fe35cc69b3b46d4bd91.zip
gdb-79082ff0c6032d8e1e832fe35cc69b3b46d4bd91.tar.gz
gdb-79082ff0c6032d8e1e832fe35cc69b3b46d4bd91.tar.bz2
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/obj-elf.c93
-rw-r--r--gas/doc/as.texinfo22
3 files changed, 93 insertions, 32 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8bd4fa5..9232f45 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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)
* config/obj-elf.c (obj_elf_symver): Check missing version
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 4698e82..2e99033 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -1658,6 +1658,11 @@ elf_frob_symbol (symp, puntp)
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.
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))
{
- char *p;
-
/* Verify that the name isn't using the @@ syntax--this is
reserved for definitions of the default version to link
against. */
- p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
- know (p != NULL);
if (p[1] == ELF_VER_CHR)
{
as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
@@ -1688,36 +1689,50 @@ elf_frob_symbol (symp, puntp)
}
else
{
- symbolS *symp2;
+ 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
+ {
+ 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. */
+ /* 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);
+ symp2 = symbol_find_or_make (sy_obj->versioned_name);
- /* Now we act as though we saw symp2 = sym. */
+ /* Now we act as though we saw symp2 = sym. */
- 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
- we are in the middle of the final loop. */
- S_SET_VALUE (symp2,
- (S_GET_VALUE (symp)
- - symbol_get_frag (symp)->fr_address));
+ /* Subtracting out the frag address here is a hack
+ because we are in the middle of the final loop. */
+ S_SET_VALUE (symp2,
+ (S_GET_VALUE (symp)
+ - symbol_get_frag (symp)->fr_address));
- symbol_set_frag (symp2, symbol_get_frag (symp));
+ symbol_set_frag (symp2, symbol_get_frag (symp));
- /* This will copy over the size information. */
- copy_symbol_attributes (symp2, symp);
+ /* This will copy over the size information. */
+ copy_symbol_attributes (symp2, symp);
- if (S_IS_WEAK (symp))
- S_SET_WEAK (symp2);
+ if (S_IS_WEAK (symp))
+ S_SET_WEAK (symp2);
- if (S_IS_EXTERNAL (symp))
- S_SET_EXTERNAL (symp2);
+ if (S_IS_EXTERNAL (symp))
+ S_SET_EXTERNAL (symp2);
+ }
}
}
@@ -1778,11 +1793,29 @@ elf_frob_file_before_adjust ()
symbolS *symp;
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
- if (symbol_get_obj (symp)->versioned_name
- && !S_IS_DEFINED (symp)
- && symbol_used_p (symp) == 0
- && symbol_used_in_reloc_p (symp) == 0)
- symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ if (symbol_get_obj (symp)->versioned_name)
+ {
+ 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_remove (symp, &symbol_rootP, &symbol_lastP);
+ }
+ }
}
}
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 2b73d3d..a45a561 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -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
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
.symver @var{name}, @var{name2@@nodename}
@end smallexample
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
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
@@ -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
reference to @var{name} is made, @var{name2@@nodename} will be removed from the
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
@ifset COFF