Blame elf/dl-usage.c

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