동적 라이브러리

achrom의 이미지

안녕하세요.
저는 공부삼아서, 리눅스 부팅 디스켓을 직접 만들고 있습니다.
인터넷 여기저기를 돌아다니다가, 미리 만들어진 디스켓 이미지를 찾았습니다.
그런데, 그 이미지로 부팅해보면, 커널도 꽤 옛날 것이고, /lib에 있는 라이브러리들도 옛날 것이라서 크기가 아주 작답니다.
저는 wowlinux 7.3을 쓰고 있는데, 커널도 크고, /lib 버전도 높고 크기도 큽니다.
만약, 제 시스템의 커널과 라이브러리를 사용해서 같은 형태의 부팅 디스켓을 만든다면, 크기가 너무 커져서, 두장의 디스켓에 넣어야 할 것 같습니다.
그래서, 부팅 디스켓은 옛날 커널과 옛날 라이브러리로 구성하고, 몇가지 제가 필요한 프로그램은 wowlinux7.3 에서 컴파일해서 디스켓에 넣고 싶습니다.
문제는 제 pc에서 hello.c 프로그램을 컴파일해서, 옛날 커널, 옛날 라이브러리가 있는 디스켓 부팅 후에 실행해보면, segmentation fault 가 납니다.
커널 버전이 달라서 문제인것 같지는 않고, 라이브러리가 달라서 문제인것 같은데요...
제 시스템을 아주 옛날 것으로 되돌릴 수는 없고...
그래서 제가 궁금한 것은,
1. 높은 버전의 라이브러리가 설치된 곳에서 컴파일한 실행 파일은 낲은 버전의 라이브러리가 설치된 시스템에서는 실행할 수가 없나요?
2. 저의 시스템에서 여러 버전의 라이브러리를 설치해놓고, 컴파일할 때 어느 버전의 라이브러리와 동적으로 링크할 지를 결정할 수 있을 까요?

익명 사용자의 이미지

bluebayou wrote:
문제는 제 pc에서 hello.c 프로그램을 컴파일해서, 옛날 커널, 옛날 라이브러리가 있는 디스켓 부팅 후에 실행해보면, segmentation fault 가 납니다.
커널 버전이 달라서 문제인것 같지는 않고, 라이브러리가 달라서 문제인것 같은데요...

혹시 낮은 버전의 리눅스가 ELF 기반이 아닌 a.out 포맷 기반은 아닙니까? ELF와 a.out은 섞어 쓸 수 없습니다.

Quote:
1. 높은 버전의 라이브러리가 설치된 곳에서 컴파일한 실행 파일은 낮은 버전의 라이브러리가 설치된 시스템에서는 실행할 수가 없나요?

높은 버전의 라이브러리에 있는 함수가 낮은 버전과 semantics가 동일하다면(리턴값, 인수 타입, 개수 등등), 실행할 수 있습니다.

Quote:
2. 저의 시스템에서 여러 버전의 라이브러리를 설치해놓고, 컴파일할 때 어느 버전의 라이브러리와 동적으로 링크할 지를 결정할 수 있을 까요?

ld(1)에 -rpath 옵션을 주면 됩니다. 제 매뉴얼 페이지에는 다음과 같이 나와 있군요:

Quote:
-rpath directory
Add a directory to the runtime library search path.
This is used when linking an ELF executable with
shared objects. All -rpath arguments are concate-
nated and passed to the runtime linker, which uses
them to locate shared objects at runtime. The
-rpath option is also used when locating shared ob-
jects which are needed by shared objects explicitly
included in the link; see the description of the
-rpath-link option. If -rpath is not used when
linking an ELF executable, the contents of the en-
vironment variable LD_RUN_PATH will be used if it
is defined.

예를 들어 /usr/lib에 라이브러리 새 버전이, /usr/old/lib에 구 버전이 들어 있다면, 링크할 때 -rpath /usr/old/lib라고 지정해주면, 링커가 ELF 바이너리 안에 있는 DYNAMIC 섹션의 RPATH 필드에다 /usr/old/lib을 기록해 넣습니다. 그러면 나중에 동적 링커가 라이브러리를 로드할 때 이 정보를 참조하게 되죠. 그리고 이 값은 나중에 LD_LIBRARY_PATH 환경 변수를 통해 override가 가능합니다(별로 권장하는 방법은 아닙니다만).

한가지더, ld(1) 말고 gcc(1)에다 옵션을 줄 때에는 -Wl,-rpath,/usr/old/lib처럼 준다는 점을 잊지 마시길...:D

mushim의 이미지

Quote:
그리고 이 값은 나중에 LD_LIBRARY_PATH 환경 변수를 통해 override가 가능합니다(별로 권장하는 방법은 아닙니다만).

리눅스 glibc 2.2 에서 테스트를 해보니, 언제나 override 되는것이 아니고 rpath 에 해당하는 라이브러리가 없는 경우에만 LD_LIBRARY_PATH 를 찾는것 같습니다.

참고로 man ld 의 -rpath, -rpath-link 부분을 참고해보면 로딩될때 공유라이브러리를 찾는 순서를 알 수 있습니다.

익명 사용자의 이미지

mushim wrote:
리눅스 glibc 2.2 에서 테스트를 해보니, 언제나 override 되는것이 아니고 rpath 에 해당하는 라이브러리가 없는 경우에만 LD_LIBRARY_PATH 를 찾는것 같습니다.

으악, mushim님 말씀이 맞았습니다. ELF 바이너리내에 있는 DT_RPATH 필드를 먼저 찾아보고 없으면 LD_LIBRARY_PATH를 찾는군요(그러니 제가 override한다고 쓴 것도 어폐가 있었습니다). 지적에 감사드립니다. :D

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.