디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

[CS:APP 13-2] Linking 2. 정적 링킹과 동적 링킹

츄럴(119.198) 2017.01.09 16:36:46
조회 590 추천 2 댓글 2
														

이전화 바로가기

-------------------------------------------------------------------------

[CS:APP 10] C/C++에서 아주 간단한 최적화...

https://gall.dcinside.com/board/view/?id=programming&no=668663&page=2&exception_mode=recommend

[CS:APP 11] The Memory Hierarchy

https://gall.dcinside.com/board/view/?id=programming&no=669079&page=2&exception_mode=recommend

[CS:APP 12] Cache Memories

https://gall.dcinside.com/board/view/?id=programming&no=670217&page=1&exception_mode=recommend

[CS:APP 12] 캐시메모리 추가내용

https://gall.dcinside.com/board/view/?id=programming&no=670219&page=1&exception_mode=recommend

-------------------------------------------------------------------------


식사는 하고 오셨읍니까!

시작합네다

----



링커가 1. symbol resolution을 무사히 끝마쳐서

여러개의 relocatable object file들에 있는 symbol reference들을 

단 하나의 symbol definition들에 각각 이름에 맞게 적절히 연결시켰다면


링커가 다음으로 수행할 2번째 일은 2. relocation이다.

relocation은 말 그대로 바이너리들의 위치를 바꾸는 일이다.

이를 이해하려면 먼저 실행파일들의 일반적인 format인 ELF에 대해 알아야 한다.


ELF는 Executable and Linkable Format의 약자로,

실행 파일, 혹은 링킹 가능한 파일들: executable, relocatable object file(.o), shared object file(.so)

이 모두 따르는 파일 포맷이다.


이에 대한 자세한 설명은 안 할거임 ^_^ CS:APP 사서 알아서 보세용 ^0^


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9d636b4c3f5d127831c95474



보면 .data 섹션에 초기화된 전역변수들이 저장된다 - 즉 strong symbol이 여기 저장됨.

그리고 .bss에는 초기화되지 않은 전역변수들이 저장된다. 악이다. 악. EVIL! 최대한 줄여라..

여튼 그래서 bss는 공간을 차지하지 않는다.

viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b956d3b1c3e014b2b31c95474

 

.rel .text 섹션과 .rel .data 섹션은 relocation에 대한 정보를 저장한다.

즉 실행파일을 만들 때 바꿔줘야하는 포인터들과 인스트럭션의 주소를 저장한다.


그리고 .symtab 섹션은 아까 몇번 언급한 symbol table이 저장되는 영역이다.

여기에 symbol들의 이름과 정의, 위치, 크기등이 struct의 배열로 저장되어 있다.



relocation은 컴파일러들이 생성한 relocatable object file(.o 파일)들에 있는 

.data와 .text 섹션을 각각 빼낸다음 executable file의 .text 섹션과 .data 섹션으로 만드는 것이다.


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9d31381a6f0a437e31c95474

 

여기서 이전에 제기했던 의문을 해결할 수 있다.


왜 .o 파일만으로는 실행이 불가능할까?

그것은 우리가 만든 main.o파일만으로 프로그램이 실행되는 것이 아니기 때문이다.


우리가 만든 응용프로그램은 운영체제 위에서 돌아가고

운영체제를 위한 코드와 데이터들이 바로 libc에서 제공하는 System code와 data들이다.

실제로는 system code에서 여러가지 일들을 응용프로그래머 모르게 처리해준 다음

(loader라는 게 해준다... 궁금하면 책 사서 읽으쇼 ^_^)


가장 마지막으로 main.o에 있는 main함수를 호출한다.

그때부터 우리가 만든 프로그램이 실행되는 것이다.


그리고 main함수가 반환되는 순간 다시 실행이 system code로 돌아가서

응용프로그래머 모르게 적절한 처리를 해준다.


그래서 링킹없이 relocatable object file만으로는 실행이 불가능하다.



그건 그렇구요.


링커가 수행하는 relocation 때문에, 컴파일러는 .o파일을 만들 때 

어떤 symbol이 어느 주소에 있을지 알 수가 없다.

viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9d31381a6f0a437e31c95474

그래서 컴파일러는 링커에게 "여기는 니(링커)가 나중에 symbol이 있을 주소를 알아서 적어 넣어줘"라는 요청을 한다.

그러한 명령을 컴파일러에게 내리는 인스트럭션이 있다.


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9d373a183e5c162931c95474

 

위의 괴상한 코드는 main.c를 컴파일하여 나온 main.o의 바이너리를 분석하여

어떤 어셈블리 코드가 사용되었는지 살펴본 것이다.


위의 암호같은 숫자들은 이진 파일의 주소: byte값 byte값... 이런 식으로 나와 있는 것이다.

위에서 9: bf 00 00 00 00 부분을 주목해보면

bf는 값을 넣으라는 뜻이고 00 00 00 00은 그 값이다.


이 부분은 사실 전역변수인 array에 대한 참조가 머신코드로 번역된 부분이다.

컴파일러는 참조인 array가 어떤 주소를 가리킬지 알 수 없다.

컴파일을 할 당시에 .o파일의 코드와 데이터들이 있던 주소들은 실행파일로 합체되면서 완전히 달라지기 때문이다.


그래서 컴파일러는 모르는 참조(빨간 사각형)를 0으로 채워두고

a:R_X86_64_32 array라는 인스트럭션으로 링커에게 차후에 주소 a부터(빨간 사각형) 값을 채워넣으라는 것이다.

f:R_X86_64_PC32 sum-0x4도 대충 비슷한 의미로 주소 f부터 4바이트는 링커가 알아서 채워넣으라는 명령이다.


흠..? 그러면 링커가 진짜 일을 잘 했는지 알아보자.

다음은 main.o와 sum.o를 붙여 실행파일을 만든 다음

실행파일의 바이너리를 분석한 것이다.



viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9d6c6c4a6e0d102b31c95474

 

보면 main함수의 시작 위치가

주소 0에서 주소 0x4004d0로 바뀌었음을 알 수 있다. relocation이 일어났다.


그리고 원래의 main.o에서

000009: bf 00 00 00 00 였던 부분이

4004e3: bf 18 10 60 00 이 되었다! 링커가 일을 잘 해 주었다.


즉 relocation은 컴파일러와 링커의 협력하에 일어난다.

컴파일러가 링커에게 "여기는 심볼 참조니까 난 몰라 니가 알아서 주소 적어" 하고 요청하고

링커는 .o파일들을 쪼개서 실행파일을 만든다음 요청에 따라 적절한 주소를 적어 넣어 준다.


우리는 링커가 하는 일들을 모두 알았다.

그러면 이제는 lib와 DLL라이브러리에 대해 알아보자.


허구한날 쓰이는 함수들을 어떻게 패키지로 만들고 관리할까?

1. 모든 함수들을 하나의 .c소스파일로 만들고 .o파일로 만들어 둔다.

반론:

필요없는 함수까지 링크시켜야 한다

링킹시간, 공간(바이너리크기)낭비다

2. 각각의 함수들을 하나의 소스파일로 만든다

프로그래머어게 필요한 함수가 들어있는 .o파일만 링크시킨다.

반론:

효율적이나 드럽게 어렵다... 모든 함수가 어디에 있는지 알아야 하고

커맨드라인이 졸라 길어진다 ex) gcc -o prog sum.o log.o malloc.o .....사용하는 걸 다 써줘야 해!



이러한 문제점을 해결한 첫번째 방법이 lib, a(archive) 파일.

즉 static libraries다.


각각의 함수func 하나씩을 각각의 소스파일func.c로 만들고

제각각 컴파일하여 relocatable object file들func.o을 만든다.


그리고 이런 foo.o bar.o func.o ... 파일들을 인덱스 테이블과 함께

하나의 파일(libXXX.a)로 만든다


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9a303d183b0a452231c95474

 

그리고 새로운 실행파일(내꺼)을 만들 때 아카이브(.a)파일의 멤버중 참조가 있었던 .o파일만 빼내서

새로 만드는 실행파일의 .o와 링크시킨다. 


여러개의 아카이브 파일이 사용될 수도 있다.


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9b65341b345a427831c95474

 


만일 아카이브(.a파일)를 업데이트하려면 업데이트 하려는 .o파일만 재컴파일해서 다시 링크하면 된다.

간단함!


하지만 static library는 몇가지 단점이 있다.

1. 중복이 발생한다. printf를 쓰는 모든 실행파일들은 printf.o파일을 링크해서 가지고 있어야 한다.

   디스크 공간이 낭비된다.

2. 현재 실행되는 프로세스(메모리에 올려져 실행중인 프로그램)들 간에도 중복이 일어난다.

   현대적인 시스템은 보통 몇천개의 프로세스가 동시에 실행되고, 거의 대부분의 C 프로그램은 printf를 사용한다.

   printf는 쓸데없이 중복되어 메모리를 차지하게 되고 이는 분명한 메모리 공간 낭비다.

3. 시스템 라이브러리의 작은 버그 픽스가 일어난다면, 이를 사용하는 모든 프로그램들은 다시 링크되어야 한다.




viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11b952a5e9d7363338720a6518bd679e305b0c49c9d30e

 


현대적인 해결책은: Shared Library이다. 혹은 Dynamic Link Library. 즉 DLL이라고 불리기도 한다.

-이 방식에서 링킹은 동적으로 일어난다. 즉 load-time이나 run-time에도 일어날 수 있다.

-프로그램이 메모리에 올려지는 순간이 load-time으로, 이 때 dynamic linker에 의해 자동적으로 링킹이 된다.

-프로그램이 실행중인 순간이 run-time으로, 이 경우는 소스파일에서 ​dlopen()​을 사용하여 명시적으로 링크할 수 있다.

-shared library를 링크하는 방식은 현재 실행중인 여러 process에서 동시에 사용할 수 있어 

 하나의 라이브러리를 노나묵을 수 있다.


아 너무 멋있다... 근데 dynamic linking동적 링킹은 어떻게 일어나길래 이렇게 멋있는가?


dynamic linking의 핵심은 

1. 실행 파일을 만들 때 부분적으로 링킹을 해준다.

2. 프로그램 실행시에 loader가 실행파일을 메모리에 올린 후 dynamic linker를 호출하고 컨트롤을 넘겨준다.

3. dynamic linker는 사용하려는 shared library(.so파일)을 메모리에 올려 링킹을 완료한다.


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9c373c1b3f0b457831c95474

 


부분 링킹은 relocation과 symbol table에 대한 정보만을 포함하여 실행파일에 링킹한다.

이를 통해 실행파일에서 나중에 어떤 라이브러리의 어떤 심볼을 참조할 지 알 수 있다.

그러나 이 때 .so 파일의 코드나 데이터는 복사되지 않는다.(즉, .text나 .data 섹션은 복사되지 않는다)


완전한 링킹은 Dynamic linker에 의해서 이루어진다.

Dynamic linker는 shared library(.so)의 코드와 데이터를 메모리의 어떤 위치에 로드한다(.text, .data섹션들)


여기까지가 ​load-time​에 자동으로 이루어지는 동적링킹이고



다음은 ​run-time​에 명시적으로 이루어지는 동적 링킹이다.


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9e306b1f3a5f152d31c95474


​dlopen​이라는 함수를 통해 런타임에 .so파일을 열고

viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b28677a16fb3dab004c86b6fae7cfdc6a7b48ad935a3d6c73a38b39e2d84d4388d11f70ef685df36343e776c2342db1b9d326c4a3f584b2c31c95474


​dlsym​이라는 함수에 사용하려는 ​함수 이름​을 먹여서 반환된 ​함수 포인터​를 받아

.so파일의 함수를 사용할 수 있다.





----

library interpositioning을 설명하려다 말았다

넘 힘드렁

궁금하면 검색하라우



이거 정리 하는 거 졸라 오래 걸리네 ㅋㅋㅋ

책은 거의 못읽음 ㅋㅋㅋㅋㅋ


엑박 고쳤엉 ㅠ

추천 비추천

2

고정닉 2

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 뛰어난 운동 신경으로 남자와 싸워도 이길 것 같은 여자 스타는? 운영자 25/11/24 - -
AD 대학생 필수템! What's in my Bag 운영자 25/11/21 - -
공지 프로그래밍 갤러리 이용 안내 [97] 운영자 20.09.28 48749 65
2904407 Claude cli 오늘 첨 써봤는데 개발자 왜 필요하냐 프갤러(101.235) 04:26 0 0
2904389 Clair.IO.Poller: 이번에 설계했다가 gg친 API ㅋㅋ 나르시갤로그로 이동합니다. 02:59 27 0
2904375 진짜 프로그래머들 ㅈㄴ부럽다 [3] ㅅ스맨갤로그로 이동합니다. 02:18 55 0
2904367 코딩 걍 첨부터 막히는데 어캄 [2] ㅅ스맨갤로그로 이동합니다. 01:54 43 0
2904364 자바 언어 좋지.. 추억과 낭만이 깃들인 언어 ㅋㅋ [1] 나르시갤로그로 이동합니다. 01:45 37 0
2904363 거래소 api들 잘 다루고 싶으면 뭐 부터 배우면 될까요 선배님들 [3] 프갤러(114.204) 01:43 34 0
2904362 7번국도 드라이빙 때 좋을만한 브금 chironpractor갤로그로 이동합니다. 01:31 16 0
2904359 0x [1] 루도그담당(58.233) 01:22 21 0
2904358 접시 ㅇㅅㅇ [6] 헤르 미온느갤로그로 이동합니다. 01:12 40 0
2904357 태연 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 01:09 18 0
2904356 하루 한 번 헤르미온느 찬양 헤르 미온느갤로그로 이동합니다. 01:08 23 0
2904324 오픈소스 프로젝트를 하나 해볼까 [12] 에이도비갤로그로 이동합니다. 00:02 82 0
2904320 고 언어 음 좋지 나쁘지 않고 효율적이고 음 근데 [6] 프갤러(110.8) 11.23 52 0
2904316 www.basic4mcu.com 11월까지 서비스 종료 발명도둑잡기(118.216) 11.23 17 0
2904313 카리나가 맛집이넹 ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.23 49 0
2904309 그러고 보니 프갤에서 고랭 팬은 못본거 같은데 [3] chironpractor갤로그로 이동합니다. 11.23 43 0
2904303 클라우드 엔지니어 희망하는데 [2] 프갤러(118.235) 11.23 31 0
2904298 cursor 대체할만한거 있어? [2] ㅇㅇ(124.48) 11.23 41 0
2904295 개발만한 취미가 없는 것 같음 프갤러(61.73) 11.23 54 0
2904294 살면서 잘 한 일... 후배한테 노트북 키스킨 딱 맞는 카라스스킨 5천원 넥도리아(220.74) 11.23 13 0
2904291 에구궁.. 나님 일욜밤까지 모임하구와서 배불러양 [2] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.23 44 0
2904289 웹디자인은 이미 AI때문에 망한듯 [1] 프갤러(220.70) 11.23 44 0
2904285 왜 극좌들은 하나같이 왕따 당하는걸까? [4] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.23 43 0
2904266 인공지능 댓글 검사기 발명도둑잡기(118.216) 11.23 25 0
2904265 배달기사 레전드네 진짜; [7] 루도그담당(58.233) 11.23 68 0
2904264 [긴급속보] 한국 연구진이 노벨상 근거를 뒤집자 현재 난리난 천문학계 발명도둑잡기(118.216) 11.23 27 0
2904262 왕따재명 안쓰럽네 ㅠ ㅅ ㅠ [2] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.23 44 1
2904261 소프트웨어 이름으로 이렁 거 어때? [4] 나르시갤로그로 이동합니다. 11.23 51 0
2904259 긴sql도 셸스크립트도 보기 싫은데 [10] 슈퍼막코더(116.64) 11.23 64 0
2904256 이거 이직 중인데 두개중 어디가야하노 [2] 프갤러(58.231) 11.23 39 0
2904255 베린이평가좀 [1] ㅇㅇ(39.7) 11.23 35 0
2904247 간철수도 어셈블리어한다는데 [2] 타이밍뒷.통수한방(1.213) 11.23 58 0
2904245 국비조언좀요 [2] 프갤러(220.86) 11.23 55 0
2904244 어셈 짜는 중인데 헷갈린다 이기 [12] 루도그담당(58.233) 11.23 84 0
2904243 폴리글랏 툴체인이 나오면 프갤에 평화가 오려나? [10] chironpractor갤로그로 이동합니다. 11.23 63 0
2904242 베이스 ㅍㅌㅊ? ㅇㅇ(203.232) 11.23 35 0
2904240 나 불렀서? ㅇㅅㅇ [6] 프갤러(49.165) 11.23 60 0
2904237 탑 클라스 명문대 진학 퍼펙트 합격 가이드!T 프갤러(121.142) 11.23 34 1
2904232 ❤✨☀⭐⚡☘⛩☃나님 시작합니당☃⛩☘⚡⭐☀✨❤ [3] ♥냥덩이의우웅한하룽♥갤로그로 이동합니다. 11.23 54 0
2904231 이제 러스트 빠돌이 프갤에 안 오겠군 ㅋㅋ [1] 나르시갤로그로 이동합니다. 11.23 45 0
2904230 언어 선택권도 수저순일텐데 [2] chironpractor갤로그로 이동합니다. 11.23 58 0
2904229 파이선 얼마나 개떡 같은데 ㅎㅎ [10] 나르시갤로그로 이동합니다. 11.23 65 0
2904226 언어에 자아의탁하는거? 뭐 그럴수 있음 [16] 박민준갤로그로 이동합니다. 11.23 137 2
2904222 좇센 노무 살기좋은 나라이긴해 타이밍뒷.통수한방(1.213) 11.23 32 0
2904221 파이썬 패키지 설치를 못해? [4] ㅇㅇ(211.234) 11.23 82 3
2904220 백화점 상품권 시세 크롤링하는건 불법일까요? [1] 프갤러(14.32) 11.23 31 0
2904217 요즘가수 머리 90년대같지 않습니까? [4] 헬마스터갤로그로 이동합니다. 11.23 58 0
2904209 러스트도 못배우는 저능아랑 얘기해봤자 별로 소득이 없어 [10] 프갤러(110.8) 11.23 94 0
2904205 ❤✨☀⭐⚡☘⛩☃나님 시작합니당☃⛩☘⚡⭐☀✨❤ [3] ♥HERO냥덩♥갤로그로 이동합니다. 11.23 50 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

디시미디어

디시이슈

1/2