Blame elf/tst-libc_dlvsym.h

Packit Service 82fcde
/* Compare dlvsym and __libc_dlvsym results.  Common code.
Packit Service 82fcde
   Copyright (C) 2017 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/* compare_vsyms is the main entry point for these tests.
Packit Service 82fcde
Packit Service 82fcde
   Indirectly, It calls __libc_dlvsym (from libc.so; internal
Packit Service 82fcde
   interface) and dlvsym (from libdl.so; public interface) to compare
Packit Service 82fcde
   the results for a selected set of symbols in libc.so which
Packit Service 82fcde
   typically have more than one symbol version.  The two functions are
Packit Service 82fcde
   implemented by somewhat different code, and this test checks that
Packit Service 82fcde
   their results are the same.
Packit Service 82fcde
Packit Service 82fcde
   The versions are generated to range from GLIBC_2.0 to GLIBC_2.Y,
Packit Service 82fcde
   with Y being the current __GLIBC_MINOR__ version plus two.  In
Packit Service 82fcde
   addition, there is a list of special symbol versions of the form
Packit Service 82fcde
   GLIBC_2.Y.Z, which were used for some releases.
Packit Service 82fcde
Packit Service 82fcde
   Comparing the two dlvsym results at versions which do not actually
Packit Service 82fcde
   exist does not test much, but it will not contribute to false test
Packit Service 82fcde
   failures, either.  */
Packit Service 82fcde
Packit Service 82fcde
#include <array_length.h>
Packit Service 82fcde
#include <gnu/lib-names.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <support/check.h>
Packit Service 82fcde
#include <support/xdlfcn.h>
Packit Service 82fcde
Packit Service 82fcde
/* Run consistency check for versioned symbol NAME@VERSION.  NB: We
Packit Service 82fcde
   may execute in a shared object, so exit on error for proper error
Packit Service 82fcde
   reporting.  */
Packit Service 82fcde
static void
Packit Service 82fcde
compare_vsyms_0 (void *libc_handle, const char *name, const char *version,
Packit Service 82fcde
                 bool *pfound)
Packit Service 82fcde
{
Packit Service 82fcde
  void *dlvsym_address = dlvsym (libc_handle, name, version);
Packit Service 82fcde
  void *libc_dlvsym_address
Packit Service 82fcde
    = __libc_dlvsym (libc_handle, name, version);
Packit Service 82fcde
  if (dlvsym_address != libc_dlvsym_address)
Packit Service 82fcde
    FAIL_EXIT1 ("%s@%s mismatch: %p != %p",
Packit Service 82fcde
                name, version, dlvsym_address, libc_dlvsym_address);
Packit Service 82fcde
  if (dlvsym_address != NULL)
Packit Service 82fcde
    *pfound = true;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Run consistency check for versioned symbol NAME at multiple symbol
Packit Service 82fcde
   version.  */
Packit Service 82fcde
static void
Packit Service 82fcde
compare_vsyms_1 (void *libc_handle, const char *name)
Packit Service 82fcde
{
Packit Service 82fcde
  bool found = false;
Packit Service 82fcde
Packit Service 82fcde
  /* Historic versions which do not follow the usual GLIBC_2.Y
Packit Service 82fcde
     pattern, to increase test coverage.  Not all architectures have
Packit Service 82fcde
     those, but probing additional versions does not hurt.  */
Packit Service 82fcde
  static const char special_versions[][12] =
Packit Service 82fcde
    {
Packit Service 82fcde
      "GLIBC_2.1.1",
Packit Service 82fcde
      "GLIBC_2.1.2",
Packit Service 82fcde
      "GLIBC_2.1.3",
Packit Service 82fcde
      "GLIBC_2.1.4",
Packit Service 82fcde
      "GLIBC_2.2.1",
Packit Service 82fcde
      "GLIBC_2.2.2",
Packit Service 82fcde
      "GLIBC_2.2.3",
Packit Service 82fcde
      "GLIBC_2.2.4",
Packit Service 82fcde
      "GLIBC_2.2.5",
Packit Service 82fcde
      "GLIBC_2.2.6",
Packit Service 82fcde
      "GLIBC_2.3.2",
Packit Service 82fcde
      "GLIBC_2.3.3",
Packit Service 82fcde
      "GLIBC_2.3.4",
Packit Service 82fcde
    };
Packit Service 82fcde
  for (int i = 0; i < array_length (special_versions); ++i)
Packit Service 82fcde
    compare_vsyms_0 (libc_handle, name, special_versions[i], &found);
Packit Service 82fcde
Packit Service 82fcde
  /* Iterate to an out-of-range version, to cover some unused symbols
Packit Service 82fcde
     as well.  */
Packit Service 82fcde
  for (int minor_version = 0; minor_version <= __GLIBC_MINOR__ + 2;
Packit Service 82fcde
       ++minor_version)
Packit Service 82fcde
    {
Packit Service 82fcde
      char version[30];
Packit Service 82fcde
      snprintf (version, sizeof (version), "GLIBC_%d.%d",
Packit Service 82fcde
                __GLIBC__, minor_version);
Packit Service 82fcde
      compare_vsyms_0 (libc_handle, name, version, &found);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (!found)
Packit Service 82fcde
    FAIL_EXIT1 ("symbol %s not found at any version", name);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Run consistency checks for various symbols which usually have
Packit Service 82fcde
   multiple versions.  */
Packit Service 82fcde
static void
Packit Service 82fcde
compare_vsyms (void)
Packit Service 82fcde
{
Packit Service 82fcde
  /* The minor version loop in compare_vsyms_1 needs updating in case
Packit Service 82fcde
     we ever switch to glibc 3.0.  */
Packit Service 82fcde
  if (__GLIBC__ != 2)
Packit Service 82fcde
    FAIL_EXIT1 ("unexpected glibc major version: %d", __GLIBC__);
Packit Service 82fcde
Packit Service 82fcde
  /* __libc_dlvsym does not recognize the special RTLD_* handles, so
Packit Service 82fcde
     obtain an explicit handle for libc.so.  */
Packit Service 82fcde
  void *libc_handle = xdlopen (LIBC_SO, RTLD_LAZY | RTLD_NOLOAD);
Packit Service 82fcde
Packit Service 82fcde
  compare_vsyms_1 (libc_handle, "_sys_errlist");
Packit Service 82fcde
  compare_vsyms_1 (libc_handle, "_sys_siglist");
Packit Service 82fcde
  compare_vsyms_1 (libc_handle, "quick_exit");
Packit Service 82fcde
Packit Service 82fcde
  xdlclose (libc_handle);
Packit Service 82fcde
}