Blame elf/dl-hwcaps_split.c

Packit Service 2bb319
/* Hardware capability support for run-time dynamic loader.  String splitting.
Packit Service 2bb319
   Copyright (C) 2020 Free Software Foundation, Inc.
Packit Service 2bb319
   This file is part of the GNU C Library.
Packit Service 2bb319
Packit Service 2bb319
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 2bb319
   modify it under the terms of the GNU Lesser General Public
Packit Service 2bb319
   License as published by the Free Software Foundation; either
Packit Service 2bb319
   version 2.1 of the License, or (at your option) any later version.
Packit Service 2bb319
Packit Service 2bb319
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 2bb319
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 2bb319
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 2bb319
   Lesser General Public License for more details.
Packit Service 2bb319
Packit Service 2bb319
   You should have received a copy of the GNU Lesser General Public
Packit Service 2bb319
   License along with the GNU C Library; if not, see
Packit Service 2bb319
   <https://www.gnu.org/licenses/>.  */
Packit Service 2bb319
Packit Service 2bb319
#include <dl-hwcaps.h>
Packit Service 2bb319
#include <stdbool.h>
Packit Service 2bb319
#include <string.h>
Packit Service 2bb319
Packit Service 2bb319
_Bool
Packit Service 2bb319
_dl_hwcaps_split (struct dl_hwcaps_split *s)
Packit Service 2bb319
{
Packit Service 2bb319
  if (s->segment == NULL)
Packit Service 2bb319
    return false;
Packit Service 2bb319
Packit Service 2bb319
  /* Skip over the previous segment.   */
Packit Service 2bb319
  s->segment += s->length;
Packit Service 2bb319
Packit Service 2bb319
  /* Consume delimiters.  This also avoids returning an empty
Packit Service 2bb319
     segment.  */
Packit Service 2bb319
  while (*s->segment == ':')
Packit Service 2bb319
    ++s->segment;
Packit Service 2bb319
  if (*s->segment == '\0')
Packit Service 2bb319
    return false;
Packit Service 2bb319
Packit Service 2bb319
  /* This could use strchrnul, but we would have to link the function
Packit Service 2bb319
     into ld.so for that.  */
Packit Service 2bb319
  const char *colon = strchr (s->segment, ':');
Packit Service 2bb319
  if (colon == NULL)
Packit Service 2bb319
    s->length = strlen (s->segment);
Packit Service 2bb319
  else
Packit Service 2bb319
    s->length = colon - s->segment;
Packit Service 2bb319
  return true;
Packit Service 2bb319
}
Packit Service 2bb319
Packit Service 2bb319
_Bool
Packit Service 2bb319
_dl_hwcaps_split_masked (struct dl_hwcaps_split_masked *s)
Packit Service 2bb319
{
Packit Service 2bb319
  while (true)
Packit Service 2bb319
    {
Packit Service 2bb319
      if (!_dl_hwcaps_split (&s->split))
Packit Service 2bb319
        return false;
Packit Service 2bb319
      bool active = s->bitmask & 1;
Packit Service 2bb319
      s->bitmask >>= 1;
Packit Service 2bb319
      if (active && _dl_hwcaps_contains (s->mask,
Packit Service 2bb319
                                         s->split.segment, s->split.length))
Packit Service 2bb319
        return true;
Packit Service 2bb319
    }
Packit Service 2bb319
}
Packit Service 2bb319
Packit Service 2bb319
_Bool
Packit Service 2bb319
_dl_hwcaps_contains (const char *hwcaps, const char *name, size_t name_length)
Packit Service 2bb319
{
Packit Service 2bb319
  if (hwcaps == NULL)
Packit Service 2bb319
    return true;
Packit Service 2bb319
Packit Service 2bb319
  struct dl_hwcaps_split split;
Packit Service 2bb319
  _dl_hwcaps_split_init (&split, hwcaps);
Packit Service 2bb319
  while (_dl_hwcaps_split (&split))
Packit Service 2bb319
    if (split.length == name_length
Packit Service 2bb319
        && memcmp (split.segment, name, name_length) == 0)
Packit Service 2bb319
      return true;
Packit Service 2bb319
  return false;
Packit Service 2bb319
}