From 79082ff0c6032d8e1e832fe35cc69b3b46d4bd91 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 13 Nov 2000 21:23:34 +0000 Subject: [PATCH] 2000-11-13 H.J. Lu * 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. --- gas/ChangeLog | 10 +++++ gas/config/obj-elf.c | 93 ++++++++++++++++++++++++++++++-------------- gas/doc/as.texinfo | 22 ++++++++++- 3 files changed, 93 insertions(+), 32 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 8bd4fa59c0b..9232f455754 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2000-11-13 H.J. Lu + + * 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 4698e82fb41..2e9903316db 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; - /* 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. */ + /* 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; - symp2 = symbol_find_or_make (sy_obj->versioned_name); + /* 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. */ - /* Now we act as though we saw symp2 = sym. */ + symp2 = symbol_find_or_make (sy_obj->versioned_name); - S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp)); + /* Now we act as though we saw symp2 = sym. */ - /* 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)); + S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp)); - symbol_set_frag (symp2, symbol_get_frag (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)); - /* This will copy over the size information. */ - copy_symbol_attributes (symp2, symp); + symbol_set_frag (symp2, symbol_get_frag (symp)); - if (S_IS_WEAK (symp)) - S_SET_WEAK (symp2); + /* This will copy over the size information. */ + copy_symbol_attributes (symp2, symp); - if (S_IS_EXTERNAL (symp)) - S_SET_EXTERNAL (symp2); + if (S_IS_WEAK (symp)) + S_SET_WEAK (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 2b73d3dbfe6..a45a561f7ed 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