+ else if (strcmp (type_name, "common") == 0
+ || strcmp (type_name, "5") == 0
+ || strcmp (type_name, "STT_COMMON") == 0)
+ {
+ type = BSF_OBJECT;
+
+ if (! S_IS_COMMON (sym))
+ {
+ if (S_IS_VOLATILE (sym))
+ {
+ sym = symbol_clone (sym, 1);
+ S_SET_SEGMENT (sym, bfd_com_section_ptr);
+ S_SET_VALUE (sym, 0);
+ S_SET_EXTERNAL (sym);
+ symbol_set_frag (sym, &zero_address_frag);
+ S_CLEAR_VOLATILE (sym);
+ }
+ else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
+ as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
+ else
+ {
+ /* FIXME: Is it safe to just change the section ? */
+ S_SET_SEGMENT (sym, bfd_com_section_ptr);
+ S_SET_VALUE (sym, 0);
+ S_SET_EXTERNAL (sym);
+ }
+ }
+ }
+ else if (strcmp (type_name, "gnu_indirect_function") == 0
+ || strcmp (type_name, "10") == 0
+ || strcmp (type_name, "STT_GNU_IFUNC") == 0)
+ {
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (stdoutput);
+ if (!(bed->elf_osabi == ELFOSABI_LINUX
+ /* GNU/Linux is still using the default value 0. */
+ || bed->elf_osabi == ELFOSABI_NONE))
+ as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
+ type_name);
+ type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
+ }
+ else if (strcmp (type_name, "gnu_unique_object") == 0)
+ {
+ struct elf_backend_data *bed;
+
+ bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
+ if (!(bed->elf_osabi == ELFOSABI_LINUX
+ /* GNU/Linux is still using the default value 0. */
+ || bed->elf_osabi == ELFOSABI_NONE))
+ as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
+ type_name);
+ type = BSF_OBJECT | BSF_GNU_UNIQUE;
+ /* PR 10549: Always set OSABI field to LINUX for objects containing unique symbols. */
+ bed->elf_osabi = ELFOSABI_LINUX;
+ }