OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elflink.c] - Diff between revs 148 and 161

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 148 Rev 161
Line 1078... Line 1078...
    {
    {
      *skip = TRUE;
      *skip = TRUE;
      return TRUE;
      return TRUE;
    }
    }
 
 
 
  /* Plugin symbol type isn't currently set.  Stop bogus errors.  */
 
  if (oldbfd != NULL && (oldbfd->flags & BFD_PLUGIN) != 0)
 
    *type_change_ok = TRUE;
 
 
  /* Check TLS symbol.  We don't check undefined symbol introduced by
  /* Check TLS symbol.  We don't check undefined symbol introduced by
     "ld -u".  */
     "ld -u".  */
  if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
  else if (oldbfd != NULL
      && ELF_ST_TYPE (sym->st_info) != h->type
      && ELF_ST_TYPE (sym->st_info) != h->type
      && oldbfd != NULL)
           && (ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS))
    {
    {
      bfd *ntbfd, *tbfd;
      bfd *ntbfd, *tbfd;
      bfd_boolean ntdef, tdef;
      bfd_boolean ntdef, tdef;
      asection *ntsec, *tsec;
      asection *ntsec, *tsec;
 
 
Line 1421... Line 1425...
 
 
  /* Skip weak definitions of symbols that are already defined.  */
  /* Skip weak definitions of symbols that are already defined.  */
  if (newdef && olddef && newweak)
  if (newdef && olddef && newweak)
    {
    {
      /* Don't skip new non-IR weak syms.  */
      /* Don't skip new non-IR weak syms.  */
      if (!((oldbfd->flags & BFD_PLUGIN) != 0
      if (!(oldbfd != NULL
 
            && (oldbfd->flags & BFD_PLUGIN) != 0
            && (abfd->flags & BFD_PLUGIN) == 0))
            && (abfd->flags & BFD_PLUGIN) == 0))
        *skip = TRUE;
        *skip = TRUE;
 
 
      /* Merge st_other.  If the symbol already has a dynamic index,
      /* Merge st_other.  If the symbol already has a dynamic index,
         but visibility says it should not be visible, turn it into a
         but visibility says it should not be visible, turn it into a
Line 2510... Line 2515...
  if (h->u.weakdef != NULL)
  if (h->u.weakdef != NULL)
    {
    {
      struct elf_link_hash_entry *weakdef;
      struct elf_link_hash_entry *weakdef;
 
 
      weakdef = h->u.weakdef;
      weakdef = h->u.weakdef;
      if (h->root.type == bfd_link_hash_indirect)
      while (h->root.type == bfd_link_hash_indirect)
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
 
      BFD_ASSERT (h->root.type == bfd_link_hash_defined
      BFD_ASSERT (h->root.type == bfd_link_hash_defined
                  || h->root.type == bfd_link_hash_defweak);
                  || h->root.type == bfd_link_hash_defweak);
      BFD_ASSERT (weakdef->def_dynamic);
      BFD_ASSERT (weakdef->def_dynamic);
Line 2614... Line 2619...
     wind up at different memory locations.  The tzset call will set
     wind up at different memory locations.  The tzset call will set
     _timezone, leaving timezone unchanged.  */
     _timezone, leaving timezone unchanged.  */
 
 
  if (h->u.weakdef != NULL)
  if (h->u.weakdef != NULL)
    {
    {
      /* If we get to this point, we know there is an implicit
      /* If we get to this point, there is an implicit reference to
         reference by a regular object file via the weak symbol H.
         H->U.WEAKDEF by a regular object file via the weak symbol H.  */
         FIXME: Is this really true?  What if the traversal finds
 
         H->U.WEAKDEF before it finds H?  */
 
      h->u.weakdef->ref_regular = 1;
      h->u.weakdef->ref_regular = 1;
 
 
 
      /* Ensure that the backend adjust_dynamic_symbol function sees
 
         H->U.WEAKDEF before H by recursively calling ourselves.  */
      if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif))
      if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif))
        return FALSE;
        return FALSE;
    }
    }
 
 
  /* If a symbol has no type and no size and does not require a PLT
  /* If a symbol has no type and no size and does not require a PLT
Line 3893... Line 3898...
      else
      else
        {
        {
          sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
          sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
          if (sec == NULL)
          if (sec == NULL)
            sec = bfd_abs_section_ptr;
            sec = bfd_abs_section_ptr;
          else if (sec->kept_section)
          else if (elf_discarded_section (sec))
            {
            {
              /* Symbols from discarded section are undefined.  We keep
              /* Symbols from discarded section are undefined.  We keep
                 its visibility.  */
                 its visibility.  */
              sec = bfd_und_section_ptr;
              sec = bfd_und_section_ptr;
              isym->st_shndx = SHN_UNDEF;
              isym->st_shndx = SHN_UNDEF;
Line 5518... Line 5523...
           inputobj;
           inputobj;
           inputobj = inputobj->link_next)
           inputobj = inputobj->link_next)
        {
        {
          asection *s;
          asection *s;
 
 
          if (inputobj->flags & (DYNAMIC | EXEC_P | BFD_LINKER_CREATED))
          if (inputobj->flags
 
              & (DYNAMIC | EXEC_P | BFD_PLUGIN | BFD_LINKER_CREATED))
            continue;
            continue;
          s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
          s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
          if (s)
          if (s)
            {
            {
              if (s->flags & SEC_CODE)
              if (s->flags & SEC_CODE)
Line 11631... Line 11637...
    }
    }
 
 
  return ret;
  return ret;
}
}
 
 
 
/* Keep debug and special sections.  */
 
 
 
bfd_boolean
 
_bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
 
                                 elf_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED)
 
{
 
  bfd *ibfd;
 
 
 
  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
 
    {
 
      asection *isec;
 
      bfd_boolean some_kept;
 
 
 
      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
 
        continue;
 
 
 
      /* Ensure all linker created sections are kept, and see whether
 
         any other section is already marked.  */
 
      some_kept = FALSE;
 
      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
 
        {
 
          if ((isec->flags & SEC_LINKER_CREATED) != 0)
 
            isec->gc_mark = 1;
 
          else if (isec->gc_mark)
 
            some_kept = TRUE;
 
        }
 
 
 
      /* If no section in this file will be kept, then we can
 
         toss out debug sections.  */
 
      if (!some_kept)
 
        continue;
 
 
 
      /* Keep debug and special sections like .comment when they are
 
         not part of a group.  */
 
      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
 
        if (elf_next_in_group (isec) == NULL
 
            && ((isec->flags & SEC_DEBUGGING) != 0
 
                || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0))
 
          isec->gc_mark = 1;
 
    }
 
  return TRUE;
 
}
 
 
/* Sweep symbols in swept sections.  Called via elf_link_hash_traverse.  */
/* Sweep symbols in swept sections.  Called via elf_link_hash_traverse.  */
 
 
struct elf_gc_sweep_symbol_info
struct elf_gc_sweep_symbol_info
{
{
  struct bfd_link_info *info;
  struct bfd_link_info *info;
Line 11688... Line 11737...
          if (o->flags & SEC_GROUP)
          if (o->flags & SEC_GROUP)
            {
            {
              asection *first = elf_next_in_group (o);
              asection *first = elf_next_in_group (o);
              o->gc_mark = first->gc_mark;
              o->gc_mark = first->gc_mark;
            }
            }
          else if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
 
                   || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
 
            {
 
              /* Keep debug and special sections.  */
 
              o->gc_mark = 1;
 
            }
 
 
 
          if (o->gc_mark)
          if (o->gc_mark)
            continue;
            continue;
 
 
          /* Skip sweeping sections already excluded.  */
          /* Skip sweeping sections already excluded.  */
Line 11964... Line 12007...
      asection *o;
      asection *o;
 
 
      if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
      if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
        continue;
        continue;
 
 
      /* Also keep SHT_NOTE sections.  */
      /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
 
         Also treat note sections as a root, if the section is not part
 
         of a group.  */
      for (o = sub->sections; o != NULL; o = o->next)
      for (o = sub->sections; o != NULL; o = o->next)
        if ((o->flags & SEC_EXCLUDE) == 0
        if (!o->gc_mark
 
            && (o->flags & SEC_EXCLUDE) == 0
            && ((o->flags & SEC_KEEP) != 0
            && ((o->flags & SEC_KEEP) != 0
                || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE)
                || (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
            && !o->gc_mark)
                    && elf_next_in_group (o) == NULL )))
 
          {
          if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
          if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
            return FALSE;
            return FALSE;
    }
    }
 
    }
 
 
  /* Allow the backend to mark additional target specific sections.  */
  /* Allow the backend to mark additional target specific sections.  */
  if (bed->gc_mark_extra_sections)
 
    bed->gc_mark_extra_sections (info, gc_mark_hook);
    bed->gc_mark_extra_sections (info, gc_mark_hook);
 
 
  /* ... and mark SEC_EXCLUDE for those that go.  */
  /* ... and mark SEC_EXCLUDE for those that go.  */
  return elf_gc_sweep (abfd, info);
  return elf_gc_sweep (abfd, info);
}
}
Line 12119... Line 12166...
  h->vtable->used[addend >> log_file_align] = TRUE;
  h->vtable->used[addend >> log_file_align] = TRUE;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
 
/* Map an ELF section header flag to its corresponding string.  */
 
typedef struct
 
{
 
  char *flag_name;
 
  flagword flag_value;
 
} elf_flags_to_name_table;
 
 
 
static elf_flags_to_name_table elf_flags_to_names [] =
 
{
 
  { "SHF_WRITE", SHF_WRITE },
 
  { "SHF_ALLOC", SHF_ALLOC },
 
  { "SHF_EXECINSTR", SHF_EXECINSTR },
 
  { "SHF_MERGE", SHF_MERGE },
 
  { "SHF_STRINGS", SHF_STRINGS },
 
  { "SHF_INFO_LINK", SHF_INFO_LINK},
 
  { "SHF_LINK_ORDER", SHF_LINK_ORDER},
 
  { "SHF_OS_NONCONFORMING", SHF_OS_NONCONFORMING},
 
  { "SHF_GROUP", SHF_GROUP },
 
  { "SHF_TLS", SHF_TLS },
 
  { "SHF_MASKOS", SHF_MASKOS },
 
  { "SHF_EXCLUDE", SHF_EXCLUDE },
 
};
 
 
 
void
 
bfd_elf_lookup_section_flags (struct bfd_link_info *info,
 
                              struct flag_info *finfo)
 
{
 
  bfd *output_bfd = info->output_bfd;
 
  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
 
  struct flag_info_list *tf = finfo->flag_list;
 
  int with_hex = 0;
 
  int without_hex = 0;
 
 
 
  for (tf = finfo->flag_list; tf != NULL; tf = tf->next)
 
    {
 
      int i;
 
      if (bed->elf_backend_lookup_section_flags_hook)
 
        {
 
          flagword hexval =
 
             (*bed->elf_backend_lookup_section_flags_hook) ((char *) tf->name);
 
 
 
          if (hexval != 0)
 
            {
 
              if (tf->with == with_flags)
 
                with_hex |= hexval;
 
              else if (tf->with == without_flags)
 
                without_hex |= hexval;
 
              tf->valid = TRUE;
 
              continue;
 
            }
 
        }
 
      for (i = 0; i < 12; i++)
 
        {
 
          if (!strcmp (tf->name, elf_flags_to_names[i].flag_name))
 
            {
 
              if (tf->with == with_flags)
 
                with_hex |= elf_flags_to_names[i].flag_value;
 
              else if (tf->with == without_flags)
 
                without_hex |= elf_flags_to_names[i].flag_value;
 
              tf->valid = TRUE;
 
              continue;
 
            }
 
        }
 
      if (tf->valid == FALSE)
 
        {
 
          info->callbacks->einfo
 
                (_("Unrecognized INPUT_SECTION_FLAG %s\n"), tf->name);
 
          return;
 
        }
 
    }
 
 finfo->flags_initialized = TRUE;
 
 finfo->only_with_flags |= with_hex;
 
 finfo->not_with_flags |= without_hex;
 
 
 
 return;
 
}
 
 
struct alloc_got_off_arg {
struct alloc_got_off_arg {
  bfd_vma gotoff;
  bfd_vma gotoff;
  struct bfd_link_info *info;
  struct bfd_link_info *info;
};
};
 
 
Line 12376... Line 12500...
    ret = TRUE;
    ret = TRUE;
 
 
  return ret;
  return ret;
}
}
 
 
/* For a SHT_GROUP section, return the group signature.  For other
bfd_boolean
   sections, return the normal section name.  */
_bfd_elf_section_already_linked (bfd *abfd,
 
                                 asection *sec,
static const char *
 
section_signature (asection *sec)
 
{
 
  if ((sec->flags & SEC_GROUP) != 0
 
      && elf_next_in_group (sec) != NULL
 
      && elf_group_name (elf_next_in_group (sec)) != NULL)
 
    return elf_group_name (elf_next_in_group (sec));
 
  return sec->name;
 
}
 
 
 
void
 
_bfd_elf_section_already_linked (bfd *abfd, asection *sec,
 
                                 struct bfd_link_info *info)
                                 struct bfd_link_info *info)
{
{
  flagword flags;
  flagword flags;
  const char *name, *p;
  const char *name, *key;
  struct bfd_section_already_linked *l;
  struct bfd_section_already_linked *l;
  struct bfd_section_already_linked_hash_entry *already_linked_list;
  struct bfd_section_already_linked_hash_entry *already_linked_list;
 
 
  if (sec->output_section == bfd_abs_section_ptr)
  if (sec->output_section == bfd_abs_section_ptr)
    return;
    return FALSE;
 
 
  flags = sec->flags;
  flags = sec->flags;
 
 
  /* Return if it isn't a linkonce section.  A comdat group section
  /* Return if it isn't a linkonce section.  A comdat group section
     also has SEC_LINK_ONCE set.  */
     also has SEC_LINK_ONCE set.  */
  if ((flags & SEC_LINK_ONCE) == 0)
  if ((flags & SEC_LINK_ONCE) == 0)
    return;
    return FALSE;
 
 
  /* Don't put group member sections on our list of already linked
  /* Don't put group member sections on our list of already linked
     sections.  They are handled as a group via their group section.  */
     sections.  They are handled as a group via their group section.  */
  if (elf_sec_group (sec) != NULL)
  if (elf_sec_group (sec) != NULL)
    return;
    return FALSE;
 
 
  /* FIXME: When doing a relocatable link, we may have trouble
 
     copying relocations in other sections that refer to local symbols
 
     in the section being discarded.  Those relocations will have to
 
     be converted somehow; as of this writing I'm not sure that any of
 
     the backends handle that correctly.
 
 
 
     It is tempting to instead not discard link once sections when
 
     doing a relocatable link (technically, they should be discarded
 
     whenever we are building constructors).  However, that fails,
 
     because the linker winds up combining all the link once sections
 
     into a single large link once section, which defeats the purpose
 
     of having link once sections in the first place.
 
 
 
     Also, not merging link once sections in a relocatable link
 
     causes trouble for MIPS ELF, which relies on link once semantics
 
     to handle the .reginfo section correctly.  */
 
 
 
  name = section_signature (sec);
 
 
 
 
  /* For a SHT_GROUP section, use the group signature as the key.  */
 
  name = sec->name;
 
  if ((flags & SEC_GROUP) != 0
 
      && elf_next_in_group (sec) != NULL
 
      && elf_group_name (elf_next_in_group (sec)) != NULL)
 
    key = elf_group_name (elf_next_in_group (sec));
 
  else
 
    {
 
      /* Otherwise we should have a .gnu.linkonce.<type>.<key> section.  */
  if (CONST_STRNEQ (name, ".gnu.linkonce.")
  if (CONST_STRNEQ (name, ".gnu.linkonce.")
      && (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
          && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
    p++;
        key++;
  else
  else
    p = name;
        /* Must be a user linkonce section that doesn't follow gcc's
 
           naming convention.  In this case we won't be matching
 
           single member groups.  */
 
        key = name;
 
    }
 
 
  already_linked_list = bfd_section_already_linked_table_lookup (p);
  already_linked_list = bfd_section_already_linked_table_lookup (key);
 
 
  for (l = already_linked_list->entry; l != NULL; l = l->next)
  for (l = already_linked_list->entry; l != NULL; l = l->next)
    {
    {
      /* We may have 2 different types of sections on the list: group
      /* We may have 2 different types of sections on the list: group
         sections and linkonce sections.  Match like sections.  */
         sections with a signature of <key> (<key> is some string),
      if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
         and linkonce sections named .gnu.linkonce.<type>.<key>.
          && strcmp (name, section_signature (l->sec)) == 0
         Match like sections.  LTO plugin sections are an exception.
          && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
         They are always named .gnu.linkonce.t.<key> and match either
 
         type of section.  */
 
      if (((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
 
           && ((flags & SEC_GROUP) != 0
 
               || strcmp (name, l->sec->name) == 0))
 
          || (l->sec->owner->flags & BFD_PLUGIN) != 0)
        {
        {
          /* The section has already been linked.  See if we should
          /* The section has already been linked.  See if we should
             issue a warning.  */
             issue a warning.  */
          switch (flags & SEC_LINK_DUPLICATES)
          if (!_bfd_handle_already_linked (sec, l, info))
            {
            return FALSE;
            default:
 
              abort ();
 
 
 
            case SEC_LINK_DUPLICATES_DISCARD:
 
              break;
 
 
 
            case SEC_LINK_DUPLICATES_ONE_ONLY:
 
              (*_bfd_error_handler)
 
                (_("%B: ignoring duplicate section `%A'"),
 
                 abfd, sec);
 
              break;
 
 
 
            case SEC_LINK_DUPLICATES_SAME_SIZE:
 
              if (sec->size != l->sec->size)
 
                (*_bfd_error_handler)
 
                  (_("%B: duplicate section `%A' has different size"),
 
                   abfd, sec);
 
              break;
 
 
 
            case SEC_LINK_DUPLICATES_SAME_CONTENTS:
 
              if (sec->size != l->sec->size)
 
                (*_bfd_error_handler)
 
                  (_("%B: duplicate section `%A' has different size"),
 
                   abfd, sec);
 
              else if (sec->size != 0)
 
                {
 
                  bfd_byte *sec_contents, *l_sec_contents;
 
 
 
                  if (!bfd_malloc_and_get_section (abfd, sec, &sec_contents))
 
                    (*_bfd_error_handler)
 
                      (_("%B: warning: could not read contents of section `%A'"),
 
                       abfd, sec);
 
                  else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec,
 
                                                        &l_sec_contents))
 
                    (*_bfd_error_handler)
 
                      (_("%B: warning: could not read contents of section `%A'"),
 
                       l->sec->owner, l->sec);
 
                  else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0)
 
                    (*_bfd_error_handler)
 
                      (_("%B: warning: duplicate section `%A' has different contents"),
 
                       abfd, sec);
 
 
 
                  if (sec_contents)
 
                    free (sec_contents);
 
                  if (l_sec_contents)
 
                    free (l_sec_contents);
 
                }
 
              break;
 
            }
 
 
 
          /* Set the output_section field so that lang_add_section
 
             does not create a lang_input_section structure for this
 
             section.  Since there might be a symbol in the section
 
             being discarded, we must retain a pointer to the section
 
             which we are really going to use.  */
 
          sec->output_section = bfd_abs_section_ptr;
 
          sec->kept_section = l->sec;
 
 
 
          if (flags & SEC_GROUP)
          if (flags & SEC_GROUP)
            {
            {
              asection *first = elf_next_in_group (sec);
              asection *first = elf_next_in_group (sec);
              asection *s = first;
              asection *s = first;
Line 12527... Line 12581...
                  if (s == first)
                  if (s == first)
                    break;
                    break;
                }
                }
            }
            }
 
 
          return;
          return TRUE;
        }
        }
    }
    }
 
 
  /* A single member comdat group section may be discarded by a
  /* A single member comdat group section may be discarded by a
     linkonce section and vice versa.  */
     linkonce section and vice versa.  */
 
 
  if ((flags & SEC_GROUP) != 0)
  if ((flags & SEC_GROUP) != 0)
    {
    {
      asection *first = elf_next_in_group (sec);
      asection *first = elf_next_in_group (sec);
 
 
      if (first != NULL && elf_next_in_group (first) == first)
      if (first != NULL && elf_next_in_group (first) == first)
        /* Check this single member group against linkonce sections.  */
        /* Check this single member group against linkonce sections.  */
        for (l = already_linked_list->entry; l != NULL; l = l->next)
        for (l = already_linked_list->entry; l != NULL; l = l->next)
          if ((l->sec->flags & SEC_GROUP) == 0
          if ((l->sec->flags & SEC_GROUP) == 0
              && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL
 
              && bfd_elf_match_symbols_in_sections (l->sec, first, info))
              && bfd_elf_match_symbols_in_sections (l->sec, first, info))
            {
            {
              first->output_section = bfd_abs_section_ptr;
              first->output_section = bfd_abs_section_ptr;
              first->kept_section = l->sec;
              first->kept_section = l->sec;
              sec->output_section = bfd_abs_section_ptr;
              sec->output_section = bfd_abs_section_ptr;
Line 12593... Line 12645...
        }
        }
 
 
  /* This is the first section with this name.  Record it.  */
  /* This is the first section with this name.  Record it.  */
  if (! bfd_section_already_linked_table_insert (already_linked_list, sec))
  if (! bfd_section_already_linked_table_insert (already_linked_list, sec))
    info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
    info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
 
  return sec->output_section == bfd_abs_section_ptr;
}
}
 
 
bfd_boolean
bfd_boolean
_bfd_elf_common_definition (Elf_Internal_Sym *sym)
_bfd_elf_common_definition (Elf_Internal_Sym *sym)
{
{

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.