120 votes

Puis-je changer 'rpath' dans un binaire déjà compilé ?

J'ai un ancien exécutable qui est prévu pour la casse, mais il n'y est pas encore. Il s'appuie sur certaines librairies qui ont été supprimées de mon environnement, mais j'ai quelques librairies stub quelque part où il fonctionne bien. J'aimerais faire pointer cet exécutable vers ces librairies. Oui, je pourrais définir LD_LIBRARY_PATH, mais cet exécutable est appelé à partir de nombreux scripts, et de nombreux utilisateurs et j'aimerais le corriger en un seul endroit.

Je n'ai pas de source pour cela, et il serait difficile de l'obtenir. Je pensais - puis-je modifier ce fichier, en utilisant un éditeur compatible ELF, et ajouter un simple PATH à rpath pour qu'il trouve les nouvelles librairies ? Est-ce possible, ou une fois que vous créez un binaire ELF, vous fixez les choses à des emplacements et ils ne peuvent pas être déplacés ?

204voto

user1047788 Points 80

Il existe un outil plus universel que chrpath appelé patchelf . Il a été créé à l'origine pour être utilisé dans la création de paquets pour Nix et NixOS (système de paquets et une distribution GNU/Linux).

Dans le cas où il n'y a pas de rpath dans un binaire (appelé ici rdsamp), chrpath échoue :

chrpath -r '$ORIGIN/../lib64' rdsamp 
rdsamp: no rpath or runpath tag found.

D'un autre côté,

patchelf --set-rpath '$ORIGIN/../lib64' rdsamp

réussit très bien.

87voto

TomH Points 3681

Il existe un outil appelé chrpath qui peut faire cela - il est probablement disponible dans les paquets de votre distribution.

34voto

Daniel Trugman Points 5189

Comme l'a dit @user7610, la bonne façon de procéder est la suivante patchelf outil.

Mais je pense pouvoir donner une réponse plus complète, couvrant toutes les commandes dont on a besoin pour faire exactement cela.

Pour un article complet sur le sujet, cliquez aquí

Tout d'abord, de nombreux développeurs parlent de RPATH mais ils signifient en fait RUNPATH . Il s'agit de deux sections dynamiques optionnelles différentes, et le chargeur les traite très différemment. Vous pouvez en savoir plus sur la différence entre elles dans le lien que j'ai mentionné précédemment.

Pour l'instant, rappelez-vous :

  • Si RUNPATH est réglé, RPATH est ignoré
  • RPATH est déprécié et doit être évité
  • RUNPATH est préférée parce qu'elle peut être remplacée par l'option LD_LIBRARY_PATH

Voir le R[UN]PATH actuel

readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"

Effacer le R[UN]PATH

patchelf --remove-rpath <path-to-elf>

Notes :

  • Supprime les deux RPATH y RUNPATH

Ajouter des valeurs à R[UN]PATH

patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>

Notes :

  • <desired-path> est une liste de répertoires séparés par deux points, par exemple /my/libs:/my/other/libs
  • Si vous spécifiez --force-rpath , sets RPATH sinon, l'ensemble RUNPATH

0voto

vikram kedlaya Points 71

Cela a fonctionné pour moi, en remplaçant XORIGIN par $ORIGIN.

chrpath -r '\$\ORIGIN/../lib64' httpd

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