(root)/
glibc-2.38/
dlfcn/
dlinfo.c
       1  /* dlinfo -- Get information from the dynamic linker.
       2     Copyright (C) 2003-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <dlfcn.h>
      20  #include <link.h>
      21  #include <ldsodefs.h>
      22  #include <libintl.h>
      23  #include <dl-tls.h>
      24  #include <shlib-compat.h>
      25  
      26  struct dlinfo_args
      27  {
      28    void *handle;
      29    int request;
      30    void *arg;
      31  
      32    /* This is the value that is returned from dlinfo if no error is
      33       signaled.  */
      34    int result;
      35  };
      36  
      37  static void
      38  dlinfo_doit (void *argsblock)
      39  {
      40    struct dlinfo_args *const args = argsblock;
      41    struct link_map *l = args->handle;
      42  
      43    switch (args->request)
      44      {
      45      case RTLD_DI_CONFIGADDR:
      46      default:
      47        args->result = -1;
      48        _dl_signal_error (0, NULL, NULL, N_("unsupported dlinfo request"));
      49        break;
      50  
      51      case RTLD_DI_LMID:
      52        *(Lmid_t *) args->arg = l->l_ns;
      53        break;
      54  
      55      case RTLD_DI_LINKMAP:
      56        *(struct link_map **) args->arg = l;
      57        break;
      58  
      59      case RTLD_DI_SERINFO:
      60        _dl_rtld_di_serinfo (l, args->arg, false);
      61        break;
      62      case RTLD_DI_SERINFOSIZE:
      63        _dl_rtld_di_serinfo (l, args->arg, true);
      64        break;
      65  
      66      case RTLD_DI_ORIGIN:
      67        strcpy (args->arg, l->l_origin);
      68        break;
      69  
      70      case RTLD_DI_TLS_MODID:
      71        *(size_t *) args->arg = 0;
      72        *(size_t *) args->arg = l->l_tls_modid;
      73        break;
      74  
      75      case RTLD_DI_TLS_DATA:
      76        {
      77  	void *data = NULL;
      78  	if (l->l_tls_modid != 0)
      79  	  data = GLRO(dl_tls_get_addr_soft) (l);
      80  	*(void **) args->arg = data;
      81  	break;
      82        }
      83  
      84      case RTLD_DI_PHDR:
      85        *(const ElfW(Phdr) **) args->arg = l->l_phdr;
      86        args->result = l->l_phnum;
      87        break;
      88      }
      89  }
      90  
      91  static int
      92  dlinfo_implementation (void *handle, int request, void *arg)
      93  {
      94    struct dlinfo_args args = { handle, request, arg };
      95    _dlerror_run (&dlinfo_doit, &args);
      96    return args.result;
      97  }
      98  
      99  #ifdef SHARED
     100  int
     101  ___dlinfo (void *handle, int request, void *arg)
     102  {
     103    if (GLRO (dl_dlfcn_hook) != NULL)
     104      return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg);
     105    else
     106      return dlinfo_implementation (handle, request, arg);
     107  }
     108  versioned_symbol (libc, ___dlinfo, dlinfo, GLIBC_2_34);
     109  
     110  # if OTHER_SHLIB_COMPAT (libdl, GLIBC_2_3_3, GLIBC_2_34)
     111  compat_symbol (libc, ___dlinfo, dlinfo, GLIBC_2_3_3);
     112  # endif
     113  #else /* !SHARED */
     114  /* Also used with _dlfcn_hook.  */
     115  int
     116  __dlinfo (void *handle, int request, void *arg)
     117  {
     118    return dlinfo_implementation (handle, request, arg);
     119  }
     120  weak_alias (__dlinfo, dlinfo)
     121  #endif