+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;
+}
+