¿Hay alguna forma de inspeccionar el rpath actual en Linux?


83

Soy consciente de que es posible usarlo readelf -d <elf> | grep RPATHpara inspeccionar un binario dado desde el shell, pero ¿es posible hacer esto dentro de un proceso?

Algo como (mi llamada al sistema completamente inventada):

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

Estoy tratando de diagnosticar algunos problemas sospechosos de vinculación de SO en nuestra base de código y me gustaría inspeccionar el RPATH de esta manera si es posible (prefiero no tener que generar un script externo).


1
Tenga en cuenta que al diagnosticar problemas de bibliotecas compartidas, también debe inspeccionar la etiqueta RUNPATH. Por lo tanto, debería grep PATHhacerlo. Depende del vinculador si se usa RPATH o RUNPATH, y existen diferencias sutiles pero importantes entre los dos: stackoverflow.com/a/52020177
Nicolas Capens

Respuestas:


54
#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;
}

1
es brillante, pero no funciona con $ ORIGIN. $ ORIGIN no se interpreta y la función lo devuelve tal cual. ¿Hay alguna forma de agregar la interpretación $ ORIGIN?
Jérôme

5
@ Jérôme Si está ejecutando en un entorno donde /procestá montado, entonces expandir $ORIGINes tan simple como readlink("/proc/self/exe", ...)luego terminar en NUL en la última barra.
Empleado ruso

Si bien la pregunta era específicamente sobre RPATH, me gustaría señalar que es igualmente importante verificar la DT_RUNPATHetiqueta si uno desea saber las rutas desde las que un binario podría estar cargando sus bibliotecas compartidas.
Nicolas Capens

154

Para el registro, aquí hay un par de comandos que mostrarán el rpathencabezado.

objdump -x binary-or-library |grep RPATH

Quizás una forma aún mejor de hacerlo es la siguiente:

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

El segundo comando también enumera las dependencias directas de otras bibliotecas seguidas de rpath.


7
En ubuntu 15.04 tengo que usar: objdump -x binary-or-library | grep RUNPATH
Andreas Roth


11
Esta respuesta no tiene nada que ver con la pregunta que se hizo (y está contenida en la pregunta en sí).
Empleado ruso


1

Esto es lo que uso por conveniencia, como función de shell:

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

Esto consume la eu-readelfsalida de elfutilscomo:

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

y emite

 /some/path/to/lib

Debería funcionar bien con binutils en readelflugar de elfutils eu-readelftambién.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.