Blame elf/dl-hwcaps.h

Packit 6c4009
/* Hardware capability support for run-time dynamic loader.
Packit 6c4009
   Copyright (C) 2017-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit Service 2bb319
#ifndef _DL_HWCAPS_H
Packit Service 2bb319
#define _DL_HWCAPS_H
Packit Service 2bb319
Packit Service 2bb319
#include <stdint.h>
Packit Service 2bb319
Packit 6c4009
#include <elf/dl-tunables.h>
Packit 6c4009
Packit 6c4009
#if HAVE_TUNABLES
Packit Service dfe651
# define GET_HWCAP_MASK() TUNABLE_GET (glibc, cpu, hwcap_mask, uint64_t, NULL)
Packit 6c4009
#else
Packit 6c4009
# ifdef SHARED
Packit 6c4009
#   define GET_HWCAP_MASK() GLRO(dl_hwcap_mask)
Packit 6c4009
# else
Packit 6c4009
/* HWCAP_MASK is ignored in static binaries when built without tunables.  */
Packit 6c4009
#  define GET_HWCAP_MASK() (0)
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit Service 2bb319
Packit Service 2bb319
#define GLIBC_HWCAPS_SUBDIRECTORY "glibc-hwcaps"
Packit Service 2bb319
#define GLIBC_HWCAPS_PREFIX GLIBC_HWCAPS_SUBDIRECTORY "/"
Packit Service 2bb319
Packit Service 2bb319
/* Used by _dl_hwcaps_split below, to split strings at ':'
Packit Service 2bb319
   separators.  */
Packit Service 2bb319
struct dl_hwcaps_split
Packit Service 2bb319
{
Packit Service 2bb319
  const char *segment;          /* Start of the current segment.  */
Packit Service 2bb319
  size_t length;                /* Number of bytes until ':' or NUL.  */
Packit Service 2bb319
};
Packit Service 2bb319
Packit Service 2bb319
/* Prepare *S to parse SUBJECT, for future _dl_hwcaps_split calls.  If
Packit Service 2bb319
   SUBJECT is NULL, it is treated as the empty string.  */
Packit Service 2bb319
static inline void
Packit Service 2bb319
_dl_hwcaps_split_init (struct dl_hwcaps_split *s, const char *subject)
Packit Service 2bb319
{
Packit Service 2bb319
  s->segment = subject;
Packit Service 2bb319
  /* The initial call to _dl_hwcaps_split will not skip anything.  */
Packit Service 2bb319
  s->length = 0;
Packit Service 2bb319
}
Packit Service 2bb319
Packit Service 2bb319
/* Extract the next non-empty string segment, up to ':' or the null
Packit Service 2bb319
   terminator.  Return true if one more segment was found, or false if
Packit Service 2bb319
   the end of the string was reached.  On success, S->segment is the
Packit Service 2bb319
   start of the segment found, and S->length is its length.
Packit Service 2bb319
   (Typically, S->segment[S->length] is not null.)  */
Packit Service 2bb319
_Bool _dl_hwcaps_split (struct dl_hwcaps_split *s) attribute_hidden;
Packit Service 2bb319
Packit Service 2bb319
/* Similar to dl_hwcaps_split, but with bit-based and name-based
Packit Service 2bb319
   masking.  */
Packit Service 2bb319
struct dl_hwcaps_split_masked
Packit Service 2bb319
{
Packit Service 2bb319
  struct dl_hwcaps_split split;
Packit Service 2bb319
Packit Service 2bb319
  /* For used by the iterator implementation.  */
Packit Service 2bb319
  const char *mask;
Packit Service 2bb319
  uint32_t bitmask;
Packit Service 2bb319
};
Packit Service 2bb319
Packit Service 2bb319
/* Prepare *S for iteration with _dl_hwcaps_split_masked.  Only HWCAP
Packit Service 2bb319
   names in SUBJECT whose bit is set in BITMASK and whose name is in
Packit Service 2bb319
   MASK will be returned.  SUBJECT must not contain empty HWCAP names.
Packit Service 2bb319
   If MASK is NULL, no name-based masking is applied.  Likewise for
Packit Service 2bb319
   BITMASK if BITMASK is -1 (infinite number of bits).  */
Packit Service 2bb319
static inline void
Packit Service 2bb319
_dl_hwcaps_split_masked_init (struct dl_hwcaps_split_masked *s,
Packit Service 2bb319
                              const char *subject,
Packit Service 2bb319
                              uint32_t bitmask, const char *mask)
Packit Service 2bb319
{
Packit Service 2bb319
  _dl_hwcaps_split_init (&s->split, subject);
Packit Service 2bb319
  s->bitmask = bitmask;
Packit Service 2bb319
  s->mask = mask;
Packit Service 2bb319
}
Packit Service 2bb319
Packit Service 2bb319
/* Like _dl_hwcaps_split, but apply masking.  */
Packit Service 2bb319
_Bool _dl_hwcaps_split_masked (struct dl_hwcaps_split_masked *s)
Packit Service 2bb319
  attribute_hidden;
Packit Service 2bb319
Packit Service 2bb319
/* Returns true if the colon-separated HWCAP list HWCAPS contains the
Packit Service 2bb319
   capability NAME (with length NAME_LENGTH).  If HWCAPS is NULL, the
Packit Service 2bb319
   function returns true.  */
Packit Service 2bb319
_Bool _dl_hwcaps_contains (const char *hwcaps, const char *name,
Packit Service 2bb319
                           size_t name_length) attribute_hidden;
Packit Service 2bb319
Packit Service 2bb319
/* Colon-separated string of glibc-hwcaps subdirectories, without the
Packit Service 2bb319
   "glibc-hwcaps/" prefix.  The most preferred subdirectory needs to
Packit Service 2bb319
   be listed first.  Up to 32 subdirectories are supported, limited by
Packit Service 2bb319
   the width of the uint32_t mask.  */
Packit Service 2bb319
extern const char _dl_hwcaps_subdirs[] attribute_hidden;
Packit Service 2bb319
Packit Service 2bb319
/* Returns a bitmap of active subdirectories in _dl_hwcaps_subdirs.
Packit Service 2bb319
   Bit 0 (the LSB) corresponds to the first substring in
Packit Service 2bb319
   _dl_hwcaps_subdirs, bit 1 to the second substring, and so on.
Packit Service 2bb319
   There is no direct correspondence between HWCAP bitmasks and this
Packit Service 2bb319
   bitmask.  */
Packit Service 2bb319
uint32_t _dl_hwcaps_subdirs_active (void) attribute_hidden;
Packit Service 2bb319
Packit Service 2bb319
/* Returns a bitmask that marks the last ACTIVE subdirectories in a
Packit Service 2bb319
   _dl_hwcaps_subdirs_active string (containing SUBDIRS directories in
Packit Service 2bb319
   total) as active.  Intended for use in _dl_hwcaps_subdirs_active
Packit Service 2bb319
   implementations (if a contiguous tail of the list in
Packit Service 2bb319
   _dl_hwcaps_subdirs is selected).  */
Packit Service 2bb319
static inline uint32_t
Packit Service 2bb319
_dl_hwcaps_subdirs_build_bitmask (int subdirs, int active)
Packit Service 2bb319
{
Packit Service 2bb319
  /* Leading subdirectories that are not active.  */
Packit Service 2bb319
  int inactive = subdirs - active;
Packit Service 2bb319
  if (inactive == 32)
Packit Service 2bb319
    return 0;
Packit Service 2bb319
Packit Service 2bb319
  uint32_t mask;
Packit Service 2bb319
  if (subdirs != 32)
Packit Service 2bb319
    mask = (1U << subdirs) - 1;
Packit Service 2bb319
  else
Packit Service 2bb319
    mask = -1;
Packit Service 2bb319
  return mask ^ ((1U << inactive) - 1);
Packit Service 2bb319
}
Packit Service 2bb319
Packit Service ef9500
/* Pre-computed glibc-hwcaps subdirectory priorities.  Used in
Packit Service ef9500
   dl-cache.c to quickly find the proprieties for the stored HWCAP
Packit Service ef9500
   names.  */
Packit Service ef9500
struct dl_hwcaps_priority
Packit Service ef9500
{
Packit Service ef9500
  /* The name consists of name_length bytes at name (not necessarily
Packit Service ef9500
     null-terminated).  */
Packit Service ef9500
  const char *name;
Packit Service ef9500
  uint32_t name_length;
Packit Service ef9500
Packit Service ef9500
  /* Priority of this name.  A positive number.  */
Packit Service ef9500
  uint32_t priority;
Packit Service ef9500
};
Packit Service ef9500
Packit Service ef9500
/* Pre-computed hwcaps priorities.  Set up by
Packit Service ef9500
   _dl_important_hwcaps.  */
Packit Service ef9500
extern struct dl_hwcaps_priority *_dl_hwcaps_priorities attribute_hidden;
Packit Service ef9500
extern uint32_t _dl_hwcaps_priorities_length attribute_hidden;
Packit Service ef9500
Packit Service 2bb319
#endif /* _DL_HWCAPS_H */