99 votes

Existe-t-il un moyen programmatique d'inspecter le rpath actuel sous Linux ?

Je suis conscient qu'il est possible d'utiliser readelf -d <elf> | grep RPATH pour inspecter un binaire donné depuis le shell, mais est-il possible de le faire dans un processus ?

Quelque chose comme (mon appel système complètement inventé) :

  /* get a copy of current rpath into buffer */
  sys_get_current_rpath(&buffer);

J'essaie de diagnostiquer certains problèmes suspects de liaison SO dans notre base de code, et j'aimerais inspecter le RPATH de cette façon si possible (je préférerais ne pas avoir à générer un script externe).

171voto

Michael Dillon Points 18741

Pour mémoire, voici quelques commandes qui afficheront l'en-tête rpath.

objdump -x binary-or-library |grep RPATH

Peut-être une meilleure façon de le faire est la suivante :

readelf -d binary-or-library |head -20

La deuxième commande répertorie également les dépendances directes sur d'autres bibliothèques suivies de rpath.

61voto

Employed Russian Points 50479
#include <stdio.h>
#include <elf.h>
#include <link.h>

int main()
{
  const ElfW(Dyn) *dyn = _DYNAMIC;
  const ElfW(Dyn) *rpath = NULL;
  const char *strtab = NULL;
  for (; dyn->d_tag != DT_NULL; ++dyn) {
    if (dyn->d_tag == DT_RPATH) {
      rpath = dyn;
    } else if (dyn->d_tag == DT_STRTAB) {
      strtab = (const char *)dyn->d_un.d_val;
    }
  }

  if (strtab != NULL && rpath != NULL) {
    printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
  }
  return 0;
}

16voto

Oscar Andreasson Points 319

Vous pouvez également utiliser :

chrpath -l binary-or-library

1voto

Craig Ringer Points 72371

Voici ce que j'utilise pour la commodité, en tant que fonction shell :

function getrpath {
    eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}

Cela consomme eu-readelf de sortie de elfutils comme :

Type              Value
NEEDED            Shared library: [libpq.so.5]
NEEDED            Shared library: [libc.so.6]
RUNPATH           Library runpath: [/some/path/to/lib]
....

et émet

 /some/path/to/lib

Il devrait fonctionner bien avec binutils readelf au lieu d'elfutils eu-readelf aussi.

-1voto

Daniel Points 79

Il y a un moyen. Suivez l'exemple de code en man dlinfo [1], mais utilisez NULL comme premier paramètre de dlopen().

[1] https://man7.org/linux/man-pages/man3/dlinfo.3.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X