실행 파일에 대한 동적 로더를 구성할 수 있습니까?

실행 파일에 대한 동적 로더를 구성할 수 있습니까?

실행 파일이 공유 라이브러리를 찾을 수 있도록 허용하는 방법을 찾고 있지만 동일한 공유 라이브러리의 다른 버전을 사용할 수 있는 패키지와의 충돌을 피하기 위해 이러한 라이브러리를 "개인 경로"(대신)에 유지하는 것을 선호합니다. /usr/lib).

가능한 방법은 다음과 같습니다.

  • 실행 파일에 rpath 포함
  • 실행 파일을 시작할 때 LD_LIBRARY_PATH를 설정하십시오.
  • ld.so.conf.d 파일의 ldconfig 구성에 라이브러리 경로를 추가합니다.

rpath는 대상 구조를 빌드에 연결하고, ld.so.conf.d는 시스템 경로를 구성하며, LD_LIBRARY_PATH는 호출자 프로세스가 이를 알아야 합니다.

그렇다면 실행 파일에만 적용되는 ld.so.conf.d(또는 유사한 로더 구성)를 사용할 수 있는지 궁금합니다.

답변1

쉬운 일이 아닙니다. ld.so.conf파일 형식은 매우 간단합니다. 단지 경로 목록일 뿐입니다.

다양한 방법을 사용하여 실행 파일을 빌드하면 몇 가지 작업을 수행할 수 있습니다.통역사; 일반 값은 /lib64/ld-linux-x86-64.so.21 과 같 으며 실제로 동적 연결을 수행합니다. 따라서 사용자 정의 동적 링커는 다르게 보이 ld.so.conf거나 무엇이든 할 수 있습니다. 그러나 이것은 rpath보다 훨씬 더 나쁜 것 같습니다!

더 간단한 해결책은 래퍼입니다. 바이너리를 으로 설치 program.real하거나, ​​다른 곳에 설치하는 것이 더 좋습니다 /usr/local/lib/(예: 가 아닌 $PATH). 그런 다음 간단한 쉘 스크립트를 입력하십시오 /usr/local/bin/program.

#!/bin/sh
export LD_LIBRARY_PATH=/path/to/libs
exec /usr/local/lib/program/program.real

이제 라이브러리 위치는 빌드와 관련이 없지만 호출자는 이에 대해 알 필요가 없습니다.




1 : 시스템에서 일반적으로 발견되는 항목을 찾는 빠른 방법: readelf /bin/bash -p .interp. 몇 가지 다른 실행 파일을 사용해 보면 최소한 32비트 및 64비트 프로그램이 서로 다른 프로그램을 사용한다는 것을 알 수 있습니다.

답변2

상대 rpath 를 사용할 수 있습니다 $ORIGIN.

-Wl,-rpath,'$ORIGIN/../lib'실행 파일이 설치를 찾을 수 있도록 하는 라이브러리 에 실행 파일을 연결합니다 .

  • 실행 파일은 다음 위치에 있습니다.<base>/bin/
  • 공유도서관의 위치는 다음과 같습니다.<base>/lib/

이렇게 진행하면 해당 실행 파일에 대해서만 이 링크를 구성할 수 있으며 디렉터리 <base>는 어디에나 위치할 수 있습니다.

답변3

filename인수는 dlopen절대 경로( /" "로 시작)일 수 있습니다.

따라서 "개인 경로"는 구성 파일에 저장되고 라이브러리의 전체 이름은 이 파일에서 빌드됩니다. 또는 개인 라이브러리가 실행 파일과 동일한 디렉터리에 있다는 것을 알고 있는 경우 실행 파일 경로에서 간단한 문자열 작업을 수행하여 찾습니다.

#include <dlfcn.h>
#include <unistd.h>
#include <string.h>

static int (*foo)();

/* ... */
char buf[BUFSIZ];
char *lastslash;
void *handle;

realpath(argv[0],buf);
lastslash = strrchr(buf,'/');
strcpy(lastslash,"foo." VERSION_BUILD ".so");
dlopen(buf,RTLD_LOCAL | RTLD_LAZY);
*(void **)(&foo) = dlsym(handle, "foo");

/* ... */
printf("%d\n",foo());

관련 정보