position-independent 하고 relocatable은 어떻게 다른가요?

Viz의 이미지

저의 짧은 지식으로는 특수한 상황이 아닌 경우 컴파일러를 통해 만들어지는 object file은 relocatable하다고 알고 있습니다.
기존의 a.out, coff, ELF 모두 말이죠.

저는 여기서 relocatable의 뜻을 메모리 어디나 재배치 할 수 있다, 즉 프로그램이 커널에 의해 로드되는 과정에서 메모리의 어느 곳으로도 로드될 수 있다라고 생각하고 있었습니다.

그런데 공유 라이브러리를 만들기 위한 gcc 옵션 -fPIC나 -fpic는 position-independent, 즉위치 독립적인 코드를 만든다고 하네요. 그리고 그 설명을 보면 역시 메모리의 어느 곳에서나 로드될 수 있는 코드라고 합니다.

무엇이 다른 것인가요? 당연히 모든 object는 relocatable한데 -fPIC는 무엇을 다르게 한다는 이야기인가요?

ps. 혹시, physical address와 virtual address의 말이 생략되서 제가 혼란스러운 것일지도 모르겠네요. relocatable은 physical address의 어느 곳에도 load할 수 있다는 뜻이고 position-independent는 virtual address 어느 곳에도 load될 수 있다.. 라는 뜻일까요?

kkojiband의 이미지

제가 정확하게 알고 있는건 아니니 제가 틀렸으면 다른 고수님께서 수정해주시기를 부탁드립니다...^^;

오브젝트 파일을 링킹 과정에서 재배치하는 것과 동적 라이브러리를 만드는 것은 차이가 있습니다...

오브젝트 파일에서의 재배치는 링킹 과정을 통해 자신이 속한 프로세스 내에서 고정된 가상 주소를 할당 받게 되고, 그 고정된 가상 주소를 할당 받은 심볼들을 참조하는 곳에다가 실제 주소를 써넣는 것을 말합니다. 예를 들어,

어떤 함수를 호출한다면,

call 실제 주소

이런 식으로 되야지 명령이 수행 될 겁니다. 하지만 이 주소는 링킹을 해서 고정된 가상 주소를 할당 받기 전에는 알수가 없는 주소입니다. 그래서 컴파일을 하고나면 call 뒤에는 실제 주소가 아닌 다른 숫자가 적혀있고, 재배치 정보란을 살펴보면 위의 완성되지 않은 명령의 주소가 추가되어있습니다.

이것을 링킹을 해서 오브젝트들을 재배치하고나면 위의 호출된 함수가 고정된 가상 주소를 할당받게 되고 그때서야 위의 명령어의 실제 주소란에 함수의 실제 주소가 쓰여지게 되는 것입니다...

하지만 동적 라이브러리라면 상황이 많이 다르겠지요...

동적 라이브러리가 실제로 리눅에서 어떤 식으로 구현되어 있는지 제가 정확히 몰라서 뭐라 말씀드릴순 없지만, 간단하게 말씀드리면,

동적 라이브러리의 의미는 코드의 공유가 목적입니다. 그래서 공유되고 있는 라이브러리는 메모리에 한번만 올라오게 되지요. 하지만 이것들이 실제 파일에 링킹 될때 의 주소를 살펴보면 파일마다 다릅니다. 님께서 말씀하신 위치 독립적인 코드는 아마 이걸두고 한 말일겁니다...

그리고 마지막에 물리 주소와 가상 주소를 언급하셨는데, 페이징 시스템에서는 물리 주소란 존재하지 않는 것과 다름없습니다. os 가 특정한 물리 주소에 접근할때도 페이지 테이블에 특정한 값을 집어넣어서 우회해서 그 물리 주소에 접근하는 것이지 따로 물리 주소에 접근할 수 있는 방법은 없습니다. 왜냐하면 cpu 가 내보내는 모든 주소를 mmu 에서 페이징시킨 다음에 내보내니까요...

그러니까 리눅스에서 눈에 보이는 주소는 모두 가상 주소입니다...

조금이나마 공부하는데 도움이 되었으면 합니다. 혹시 잘못된 내용 있다면 지적해주세요~ 저도 잘못된건 제대로 알고 넘어가야하니까요...^^;

그럼 안녕히~!!!

이제 졸업이다...사랑하는 SKKULUG 후배들아 안녕~

방준영의 이미지

재배치 가능하지만 위치 독립적이지 않은 오브젝트가 있습니다. 윈도의 PE 포맷과 유닉스의 ELF 포맷을 비교해 보면 쉽게 이해할 수 있습니다. 윈도 PE 포맷에서 DLL은 재배치 가능하긴 하지만 코드가 위치 독립적이지 않습니다. 따라서 임의의 위치에 배치를 하려면 코드 섹션상에서 메모리 참조 하는 부분을 전부 고쳐 주어야 합니다(픽스업이라고 합니다). 반면 ELF는 이 픽스업 과정을 코드 섹션이 아닌 데이터 섹션의 GOT에서만 하면 됩니다. 따라서 코드 자체는 항상 위치에 독립적입니다.

Viz의 이미지

흐음... 좋은 답변 감사합니다.

그럼에도 아직 풀리지 않은 의문이 있는데... 위치 독립적인 코드는 어떠한 코드인가... 라는 의문 입니다.

그런 코드에서는 symbol(혹은 name이라고 하는 것)이 어떻게 주소로 바뀌게 되는 것인가요? link 할때에서 symbol들이 address로 치환 되는 과정이 이루어지지 않고 run time으로 보류되는 것인가요?

친구와의 이야기 해본 결과 function call 이나 분기 등에서는 현재 PC에 대한 상대 주소만을 사용하므로서 가능할 것이다. 라는 결론을 얻긴 했는데 방준영 님께서 언급하신 GOT를 다루는 부분은 이해하기가 쉽지 않네요.

쉽게 이해하는데 도움을 줄 만한 문서 등이 있으면 추천해 주시면 감사하겠습니다. 직접 설명해 주시면 더욱 감사하겠지만요... (욕심이.. :) )

아 그리고... relocatable의 정의에 대해서는 저의 착각이 있었네요.

시험 때문에 공룡책을 보고 있자니 어느 부분에서는 relocatable의 개념을 physical memory의 어디든지 load될 수 있다.. 라는 의미로 적어둬서요(예전에는 그런 의미로 쓰였을 것이 분명하지요 :D )

ELF(executable & Linkable format) 등에서 말하는 relocatable은 linker가 object들을 link할 때 어떤 주소에도 위치할 수 있다는 의미지요.

My Passion for the Vision!

방준영의 이미지

Viz wrote:
흐음... 좋은 답변 감사합니다.

그럼에도 아직 풀리지 않은 의문이 있는데... 위치 독립적인 코드는 어떠한 코드인가... 라는 의문 입니다.

그런 코드에서는 symbol(혹은 name이라고 하는 것)이 어떻게 주소로 바뀌게 되는 것인가요? link 할때에서 symbol들이 address로 치환 되는 과정이 이루어지지 않고 run time으로 보류되는 것인가요?

친구와의 이야기 해본 결과 function call 이나 분기 등에서는 현재 PC에 대한 상대 주소만을 사용하므로서 가능할 것이다. 라는 결론을 얻긴 했는데 방준영 님께서 언급하신 GOT를 다루는 부분은 이해하기가 쉽지 않네요.

쉽게 이해하는데 도움을 줄 만한 문서 등이 있으면 추천해 주시면 감사하겠습니다. 직접 설명해 주시면 더욱 감사하겠지만요... (욕심이.. :) )


자세한 원리는 System V Application Binary Interface라는 문서에 나와 있습니다.

Quote:
아 그리고... relocatable의 정의에 대해서는 저의 착각이 있었네요.

시험 때문에 공룡책을 보고 있자니 어느 부분에서는 relocatable의 개념을 physical memory의 어디든지 load될 수 있다.. 라는 의미로 적어둬서요(예전에는 그런 의미로 쓰였을 것이 분명하지요 :D )

ELF(executable & Linkable format) 등에서 말하는 relocatable은 linker가 object들을 link할 때 어떤 주소에도 위치할 수 있다는 의미지요.


링커의 종류는 컴파일 타임 링커뿐만 아니라 동적 링커도 있기 때문에 재배치란 용어는 ELF에서 약간 모호하게 사용되고 있습니다. 재배치 가능이란 표현은 "재배치 가능한 오브젝트"에서 쓰이고, 재배치란 표현은 동적 링커가 공유 오브젝트를 메모리상의 임의의 위치에 로드할 때 씁니다.
pynoos의 이미지

방준영 wrote:
링커의 종류는 컴파일 타임 링커뿐만 아니라 동적 링커도 있기 때문에 재배치란 용어는 ELF에서 약간 모호하게 사용되고 있습니다. 재배치 가능이란 표현은 "재배치 가능한 오브젝트"에서 쓰이고, 재배치란 표현은 동적 링커가 공유 오브젝트를 메모리상의 임의의 위치에 로드할 때 씁니다.

따라서, 저도 링커라는 말보다는 링크 에디터와 로더라는 말을 좋아합니다.

링크에디터 하면 일반적인 링크 에디터인 ld를 말하고, 로더라는 말은 ld.so 를 말하는데, 요놈들이 링커라는 이름으로 사용될 때는.. 대략.. 정황을 살펴야만되지요.. :lol:

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.