Blame elf/dl-usage.c

Packit Service d73a27
/* Print usage information and help for ld.so.
Packit Service d73a27
   Copyright (C) 1995-2020 Free Software Foundation, Inc.
Packit Service d73a27
   This file is part of the GNU C Library.
Packit Service d73a27
Packit Service d73a27
   The GNU C Library is free software; you can redistribute it and/or
Packit Service d73a27
   modify it under the terms of the GNU Lesser General Public
Packit Service d73a27
   License as published by the Free Software Foundation; either
Packit Service d73a27
   version 2.1 of the License, or (at your option) any later version.
Packit Service d73a27
Packit Service d73a27
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service d73a27
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d73a27
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service d73a27
   Lesser General Public License for more details.
Packit Service d73a27
Packit Service d73a27
   You should have received a copy of the GNU Lesser General Public
Packit Service d73a27
   License along with the GNU C Library; if not, see
Packit Service d73a27
   <https://www.gnu.org/licenses/>.  */
Packit Service d73a27
Packit Service d73a27
#include <dl-cache.h>
Packit Service d73a27
#include <dl-main.h>
Packit Service d73a27
#include <ldsodefs.h>
Packit Service 3a78c0
#include <unistd.h>
Packit Service b6e805
#include "version.h"
Packit Service d73a27
Packit Service bc6275
#include <dl-procinfo.h>
Packit Service b9c773
#include <dl-hwcaps.h>
Packit Service b9c773
Packit Service d73a27
void
Packit Service 3a78c0
_dl_usage (const char *argv0, const char *wrong_option)
Packit Service d73a27
{
Packit Service 3a78c0
  if (wrong_option != NULL)
Packit Service 3a78c0
    _dl_error_printf ("%s: unrecognized option '%s'\n", argv0, wrong_option);
Packit Service 3a78c0
  else
Packit Service 3a78c0
    _dl_error_printf ("%s: missing program name\n", argv0);
Packit Service 3a78c0
  _dl_error_printf ("Try '%s --help' for more information.\n", argv0);
Packit Service 3a78c0
  _exit (EXIT_FAILURE);
Packit Service 3a78c0
}
Packit Service 3a78c0
Packit Service 3a78c0
void
Packit Service b6e805
_dl_version (void)
Packit Service b6e805
{
Packit Service b6e805
  _dl_printf ("\
Packit Service b6e805
ld.so " PKGVERSION RELEASE " release version " VERSION ".\n\
Packit Service b6e805
Copyright (C) 2020 Free Software Foundation, Inc.\n\
Packit Service b6e805
This is free software; see the source for copying conditions.\n\
Packit Service b6e805
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
Packit Service b6e805
PARTICULAR PURPOSE.\n\
Packit Service b6e805
");
Packit Service b6e805
  _exit (EXIT_SUCCESS);
Packit Service b6e805
}
Packit Service b6e805
Packit Service 0b289c
/* Print part of the library search path (from a single source).  */
Packit Service 0b289c
static void
Packit Service 0b289c
print_search_path_for_help_1 (struct r_search_path_elem **list)
Packit Service 0b289c
{
Packit Service 0b289c
  if (list == NULL || list == (void *) -1)
Packit Service 0b289c
    /* Path is missing or marked as inactive.  */
Packit Service 0b289c
    return;
Packit Service 0b289c
Packit Service 0b289c
  for (; *list != NULL; ++list)
Packit Service 0b289c
    {
Packit Service 0b289c
      _dl_write (STDOUT_FILENO, "  ", 2);
Packit Service 0b289c
      const char *name = (*list)->dirname;
Packit Service 0b289c
      size_t namelen = (*list)->dirnamelen;
Packit Service 0b289c
      if (namelen == 0)
Packit Service 0b289c
        {
Packit Service 0b289c
          /* The empty string denotes the current directory.  */
Packit Service 0b289c
          name = ".";
Packit Service 0b289c
          namelen = 1;
Packit Service 0b289c
        }
Packit Service 0b289c
      else if (namelen > 1)
Packit Service 0b289c
        /* Remove the trailing slash.  */
Packit Service 0b289c
        --namelen;
Packit Service 0b289c
      _dl_write (STDOUT_FILENO, name, namelen);
Packit Service 0b289c
      _dl_printf (" (%s)\n", (*list)->what);
Packit Service 0b289c
    }
Packit Service 0b289c
}
Packit Service 0b289c
Packit Service 0b289c
/* Prints the library search path.  See _dl_init_paths in dl-load.c
Packit Service 0b289c
   how this information is populated.  */
Packit Service 0b289c
static void
Packit Service 0b289c
print_search_path_for_help (struct dl_main_state *state)
Packit Service 0b289c
{
Packit Service 0b289c
  if (__rtld_search_dirs.dirs == NULL)
Packit Service 0b289c
    /* The run-time search paths have not yet been initialized.  */
Packit Service 358832
    call_init_paths (state);
Packit Service 0b289c
Packit Service 0b289c
  _dl_printf ("\nShared library search path:\n");
Packit Service 0b289c
Packit Service 0b289c
  /* The print order should reflect the processing in
Packit Service 0b289c
     _dl_map_object.  */
Packit Service 0b289c
Packit Service 0b289c
  struct link_map *map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
Packit Service 0b289c
  if (map != NULL)
Packit Service 0b289c
    print_search_path_for_help_1 (map->l_rpath_dirs.dirs);
Packit Service 0b289c
Packit Service 0b289c
  print_search_path_for_help_1 (__rtld_env_path_list.dirs);
Packit Service 0b289c
Packit Service 0b289c
  if (map != NULL)
Packit Service 0b289c
    print_search_path_for_help_1 (map->l_runpath_dirs.dirs);
Packit Service 0b289c
Packit Service 0b289c
  _dl_printf ("  (libraries located via %s)\n", LD_SO_CACHE);
Packit Service 0b289c
Packit Service 0b289c
  print_search_path_for_help_1 (__rtld_search_dirs.dirs);
Packit Service 0b289c
}
Packit Service 0b289c
Packit Service b9c773
/* Helper function for printing flags associated with a HWCAP name.  */
Packit Service b9c773
static void
Packit Service b9c773
print_hwcap_1 (bool *first, bool active, const char *label)
Packit Service b9c773
{
Packit Service b9c773
  if (active)
Packit Service b9c773
    {
Packit Service b9c773
      if (*first)
Packit Service b9c773
        {
Packit Service b9c773
          _dl_printf (" (");
Packit Service b9c773
          *first = false;
Packit Service b9c773
        }
Packit Service b9c773
      else
Packit Service b9c773
        _dl_printf (", ");
Packit Service b9c773
      _dl_printf ("%s", label);
Packit Service b9c773
    }
Packit Service b9c773
}
Packit Service b9c773
Packit Service b9c773
/* Called after a series of print_hwcap_1 calls to emit the line
Packit Service b9c773
   terminator.  */
Packit Service b9c773
static void
Packit Service b9c773
print_hwcap_1_finish (bool *first)
Packit Service b9c773
{
Packit Service b9c773
  if (*first)
Packit Service b9c773
    _dl_printf ("\n");
Packit Service b9c773
  else
Packit Service b9c773
    _dl_printf (")\n");
Packit Service b9c773
}
Packit Service b9c773
Packit Service 358832
/* Print the header for print_hwcaps_subdirectories.  */
Packit Service 358832
static void
Packit Service 358832
print_hwcaps_subdirectories_header (bool *nothing_printed)
Packit Service 358832
{
Packit Service 358832
  if (*nothing_printed)
Packit Service 358832
    {
Packit Service 358832
      _dl_printf ("\n\
Packit Service 358832
Subdirectories of glibc-hwcaps directories, in priority order:\n");
Packit Service 358832
      *nothing_printed = false;
Packit Service 358832
    }
Packit Service 358832
}
Packit Service 358832
Packit Service 358832
/* Print the HWCAP name itself, indented.  */
Packit Service 358832
static void
Packit Service 358832
print_hwcaps_subdirectories_name (const struct dl_hwcaps_split *split)
Packit Service 358832
{
Packit Service 358832
  _dl_write (STDOUT_FILENO, "  ", 2);
Packit Service 358832
  _dl_write (STDOUT_FILENO, split->segment, split->length);
Packit Service 358832
}
Packit Service 358832
Packit Service 358832
/* Print the list of recognized glibc-hwcaps subdirectories.  */
Packit Service 358832
static void
Packit Service 358832
print_hwcaps_subdirectories (const struct dl_main_state *state)
Packit Service 358832
{
Packit Service 358832
  bool nothing_printed = true;
Packit Service 358832
  struct dl_hwcaps_split split;
Packit Service 358832
Packit Service 358832
  /* The prepended glibc-hwcaps subdirectories.  */
Packit Service 358832
  _dl_hwcaps_split_init (&split, state->glibc_hwcaps_prepend);
Packit Service 358832
  while (_dl_hwcaps_split (&split))
Packit Service 358832
    {
Packit Service 358832
      print_hwcaps_subdirectories_header (&nothing_printed);
Packit Service 358832
      print_hwcaps_subdirectories_name (&split);
Packit Service 358832
      bool first = true;
Packit Service 358832
      print_hwcap_1 (&first, true, "searched");
Packit Service 358832
      print_hwcap_1_finish (&first);
Packit Service 358832
    }
Packit Service 358832
Packit Service 358832
  /* The built-in glibc-hwcaps subdirectories.  Do the filtering
Packit Service 358832
     manually, so that more precise diagnostics are possible.  */
Packit Service 358832
  uint32_t mask = _dl_hwcaps_subdirs_active ();
Packit Service 358832
  _dl_hwcaps_split_init (&split, _dl_hwcaps_subdirs);
Packit Service 358832
  while (_dl_hwcaps_split (&split))
Packit Service 358832
    {
Packit Service 358832
      print_hwcaps_subdirectories_header (&nothing_printed);
Packit Service 358832
      print_hwcaps_subdirectories_name (&split);
Packit Service 358832
      bool first = true;
Packit Service 358832
      print_hwcap_1 (&first, mask & 1, "supported");
Packit Service 358832
      bool listed = _dl_hwcaps_contains (state->glibc_hwcaps_mask,
Packit Service 358832
                                         split.segment, split.length);
Packit Service 358832
      print_hwcap_1 (&first, !listed, "masked");
Packit Service 358832
      print_hwcap_1 (&first, (mask & 1) && listed, "searched");
Packit Service 358832
      print_hwcap_1_finish (&first);
Packit Service 358832
      mask >>= 1;
Packit Service 358832
    }
Packit Service 358832
Packit Service 358832
  if (nothing_printed)
Packit Service 358832
    _dl_printf ("\n\
Packit Service 358832
No subdirectories of glibc-hwcaps directories are searched.\n");
Packit Service 358832
}
Packit Service 358832
Packit Service b9c773
/* Write a list of hwcap subdirectories to standard output.  See
Packit Service b9c773
 _dl_important_hwcaps in dl-hwcaps.c.  */
Packit Service b9c773
static void
Packit Service b9c773
print_legacy_hwcap_directories (void)
Packit Service b9c773
{
Packit Service b9c773
  _dl_printf ("\n\
Packit Service b9c773
Legacy HWCAP subdirectories under library search path directories:\n");
Packit Service b9c773
Packit Service b9c773
  const char *platform = GLRO (dl_platform);
Packit Service b9c773
  if (platform != NULL)
Packit Service b9c773
    _dl_printf ("  %s (AT_PLATFORM; supported, searched)\n", platform);
Packit Service b9c773
Packit Service b9c773
  _dl_printf ("  tls (supported, searched)\n");
Packit Service b9c773
Packit Service b9c773
  uint64_t hwcap_mask = GET_HWCAP_MASK();
Packit Service b9c773
  uint64_t searched = GLRO (dl_hwcap) & hwcap_mask;
Packit Service b9c773
  for (int n = 63; n >= 0; --n)
Packit Service b9c773
    {
Packit Service b9c773
      uint64_t bit = 1ULL << n;
Packit Service b9c773
      if (HWCAP_IMPORTANT & bit)
Packit Service b9c773
        {
Packit Service b9c773
          _dl_printf ("  %s", _dl_hwcap_string (n));
Packit Service b9c773
          bool first = true;
Packit Service b9c773
          print_hwcap_1 (&first, GLRO (dl_hwcap) & bit, "supported");
Packit Service b9c773
          print_hwcap_1 (&first, !(hwcap_mask & bit), "masked");
Packit Service b9c773
          print_hwcap_1 (&first, searched & bit, "searched");
Packit Service b9c773
          print_hwcap_1_finish (&first);
Packit Service b9c773
        }
Packit Service b9c773
    }
Packit Service b9c773
}
Packit Service b9c773
Packit Service b6e805
void
Packit Service 3a78c0
_dl_help (const char *argv0, struct dl_main_state *state)
Packit Service 3a78c0
{
Packit Service 3a78c0
  _dl_printf ("\
Packit Service 3a78c0
Usage: %s [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
Packit Service c3e483
You have invoked 'ld.so', the program interpreter for dynamically-linked\n\
Packit Service c3e483
ELF programs.  Usually, the program interpreter is invoked automatically\n\
Packit Service c3e483
when a dynamically-linked executable is started.\n\
Packit Service c3e483
\n\
Packit Service c3e483
You may invoke the program interpreter program directly from the command\n\
Packit Service c3e483
line to load and run an ELF executable file; this is like executing that\n\
Packit Service c3e483
file itself, but always uses the program interpreter you invoked,\n\
Packit Service c3e483
instead of the program interpreter specified in the executable file you\n\
Packit Service c3e483
run.  Invoking the program interpreter directly provides access to\n\
Packit Service c3e483
additional diagnostics, and changing the dynamic linker behavior without\n\
Packit Service c3e483
setting environment variables (which would be inherited by subprocesses).\n\
Packit Service d73a27
\n\
Packit Service d73a27
  --list                list all dependencies and how they are resolved\n\
Packit Service d73a27
  --verify              verify that given object really is a dynamically linked\n\
Packit Service d73a27
                        object we can handle\n\
Packit Service d73a27
  --inhibit-cache       Do not use " LD_SO_CACHE "\n\
Packit Service d73a27
  --library-path PATH   use given PATH instead of content of the environment\n\
Packit Service d73a27
                        variable LD_LIBRARY_PATH\n\
Packit Service 358832
  --glibc-hwcaps-prepend LIST\n\
Packit Service 358832
                        search glibc-hwcaps subdirectories in LIST\n\
Packit Service 358832
  --glibc-hwcaps-mask LIST\n\
Packit Service 358832
                        only search built-in subdirectories if in LIST\n\
Packit Service d73a27
  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names\n\
Packit Service d73a27
                        in LIST\n\
Packit Service d73a27
  --audit LIST          use objects named in LIST as auditors\n\
Packit Service d73a27
  --preload LIST        preload objects named in LIST\n\
Packit Service 3a78c0
  --argv0 STRING        set argv[0] to STRING before running\n\
Packit Service 3a78c0
  --help                display this help and exit\n\
Packit Service b6e805
  --version             output version information and exit\n\
Packit Service e60b7d
\n\
Packit Service e60b7d
This program interpreter self-identifies as: " RTLD "\n\
Packit Service 3a78c0
",
Packit Service 3a78c0
              argv0);
Packit Service 0b289c
  print_search_path_for_help (state);
Packit Service 358832
  print_hwcaps_subdirectories (state);
Packit Service b9c773
  print_legacy_hwcap_directories ();
Packit Service 3a78c0
  _exit (EXIT_SUCCESS);
Packit Service d73a27
}