이번 섹션은 지금 현재로선 아주 적은 내용만을 가지고 있다. ELF 하우투 문서를 발췌함으로써 그 내용이 계속적으로 늘어나게 될 것이다.
리눅스는 공유 라이브러리를 가지고 있다. 이 글 전체를 읽는 동안 이제는 이런 말 듣는 것도 질렸을 것이다. 전통적으로 프로그램 링크 과정에서 행한 작업은 로딩 과정에서 그 반대 과정을 거쳐야 한다.
can't load library: /lib/libxxx.so, Incompatible version
a.out 에서만 일어나는데, 이 말은 여러분의 라이브러리 메이저 버전이 틀리다는 말이다. 다른 버전을 가지고 있다고 해서 눈가림식으로 심볼릭 링크하는 것으로 안된다. 된다 할지라도 결국엔 세그폴트를 일으킬 것이다. 새로운 버전을 가져오라.ELF에서도 비스한 메세지가 나온다.
ftp: can't load library 'libreadline.so.2'
warning using incompatible library version xxx
a.out의 경우이다. 프로그램 컴파일한 사람보다 낮은 마이너 버전의 라이브러리를 갖고 있기 때문에 발생하는 경고 메세지이다. 프로그램이 실행되기는 할 것이다. 업그레이드하는 것이 어떨까?
많은 환경 변수들이 동적 로더에 관계한다. 대부분은 일반 사용자보다는
ldd
에게 유용하다. ldd
에 다양한 스위치를 줌으로써 쉽게 세팅할 수 있다.
LD_BIND_NOW
--- 일반적으로 함수가 호출되기 전까지는 라이브러리에서
찾아보지 않는다. 이 플래그를 세팅해주면 라이브러리 적재시에 모든 체크를 하게
되고 시작은 상당히 느리게 된다. 이것은 여러분이 만든 프로그램이 모든 것들과
제대로 링크가 되었는지 시험해볼 때 유용하다.
LD_PRELOAD
--- overriding 함수 정의를 가지고 있는 화일에 세팅될 수
있다. 예를 들어서 메모리 할당 방법을 테스팅하려고 하며, malloc를 교체하려고 할
때는 여러분이 원하는 루틴으로 만든 후에 교체할 수가 있다. malloc.o
라는
이름으로 컴파일한 후 다음과 같이 해보자.
$ LD_PRELOAD=malloc.o; export LD_PRELOAD
$ some_test_program
LD_ELF_PRELOAD
와 LD_AOUT_PRELOAD
이 둘은 비슷하다. 하지만 각각 특정
형태에만 관계한다. 만약 LD_ELF_PRELOAD
와 LD_PRELOAD
가 둘 다
사용되었다면 좀 더 자세히 지정한 전자 LD_ELF_PRELOAD
가 사용된다.
LD_LIBRARY_PATH
--- 이것은 공유 라이브러리를 찾을 때 참고할
디렉토리를 콜론(:)을 분리자로 써서 표현한 리스트이다. 그것은 ld에 영향을 주지는
못한다. 단지 실행시에만 관계한다. 또한 setuid나 setgid를 갖는 프로그램에
대해서는 무용지물이다. 마찬가지로 LD_ELF_LIBRARY_PATH
와
LD_AOUT_LIBRARY_PATH
는 각각의 바이너리 형식에만 적용되도록 하고 있다.
LD_LIBRARY_PATH
는 정상적인 경우 그렇게 필요하진 않다. 대신에
/etc/ld.so.conf/
에 디렉토리를 추가하고 ldconfig를 다시 한 번
실행시키는게 좋다.
LD_NOWARN
--- 이는 a.out에만 적용된다. 예를 들어 다음과 같이
세팅하면 LD_NOWARN=true; export LD_NOWARN
) 마이너 버전이 다르다든지 하는,
크게 심각하지 않는 경고를 표시하지 않도록 한다.
LD_WARN
--- 이는 ELF에만 해당된다. 세팅되면 일반적으로 ``Can't find
library''와 같은 심각한 에러를 경고로 바꾸어준다. 별로 필요없는 옵션이다.
LD_TRACE_LOADED_OBJECTS
--- ELF에만 적용된다. 프로그램으로 하여금
ldd
하에서 실행되고 있다고 생각하게끔 만든다.
$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
이는 솔라리스 2.x의 동적 로딩 지원이 이뤄지는 방식과 매우 흡사하다. H J Lu의
ELF 프로그래밍 문서에 자세히 나와 있으며 dlopen(3)
맨페이지에 아주 잘
나와 있다. 맨페이지는 ld.so 패키지에 들어있다. 다음 프로그램을 -ldl
옵션을 주고 링크하라.
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call=dlsym(libc,"printf");
(*printf_call)("hello, world\n");
}
}