링킹이란
다양한 조각들의 code와 data를 하나의 file에 모으고 결합하는 과정. 이로 인해 이 file은 memory에 load하고 실행 가능해도록 한다.
링킹은 여러 단계에서 실행될 수 있다.
- at compile-time : source code가 machine code로 번역되는 시간에
- at load-time : program이 memory에 로드되고 loader에 의해 실행되는 시간에
- at run-time : 응용프로그램에 의해
어떠한 시간에 어떻게 linking해야 하는지는 linker에 의해 자동적으로 수행이 된다.
링킹을 알아야 하는 이유
- 1.큰 program을 build하는 데에 도움이 된다.(펼치기)
- 큰 program에서의 에러는 다음과 같다.
- missing module
- missing libraries
- incompatible library versions
- 등등
- 우리는 큰 프로그램을 빌드할 때 linking을 알면 다음과 같은 도움을 얻을 수 있다
- linker가 어떻게 참조들을 resolve(해석?) 하는지
- library가 무엇인지
- linker가 reference들을 resolve하는 데에 이 library를 어떻게 사용하는지
- 큰 program에서의 에러는 다음과 같다.
- 2.위험한 에러를 피하는데에 도움이 된다.(펼치기)
- symbol reference(변수 및 함수 이름등이라고 생각하면 됨)들을 resolve할 때 linux linker가 내리는 결정이 program의 정확성에 영향이 갈 수 있다
- 이를 어떻게 피할지를 알게 된다.
- 3.언어의 scoping rule의 구현에 대해 알게 된다.(펼치기)
- local 변수와 global 변수들의 차이점 등에 대해 알게 될 것
- static attribute를 사용한 변수 또는 함수의 의미에 대해 알게 될 것
- 4.중요한 system의 개념을 이해하게 된다.(펼치기)
- 실행 가능한 object files
- loading and running programs
- 가상 메모리
- 페이징(paging)
- memory mappaing
- 등등을 알게 될 것
- 5.shared library를 마음껏 이용 가능하다.
이번 7장에서 다루는 내용들은
- linking의 모든 측면에 대한 논의
- 전통적인 static linking
- load time에서의 shared library들에 대한 dynamic linking
- run time에서의 shared library들에 대한 dynamic linking
- 확실한 이해를 돕기 위해 x86-64 system과 Linux 운영체제, 그리고 ELF-64 표준(object file format)을 이용해서 설명할 것이다.
- 하지만 linking은 OS나 ISA, 그리고 object file format에 종속적인 것은 아니다.
7.1 Compiler Drivers(컴파일러 드라이버)
대부분의 compilation system에서는 compiler driver 라는 것이 있다. 이 driver는 언어의 preprocessor, compiler, assembler, 그리고 linker를 실행시키는 역할을 한다.
다음의 예시를 봐보자.
gcc -Og -o prog main.c sum.c -v 실행 시
이렇게 하면 prog 라는 executable object file이 생성된다. 즉, ascii로 된 file에서 object file이 나온 것이다. 조금 더 자세히 과정을 들여다 보면 다음과 같다.
- cpp [other arguments] main.c /tmp/main.i
- 먼저 driver는 C preprocessor(cpp)를 실행시켜 소스 파일들을 번역시켜 아스키 중간 file인 main.i 라는 file을 생성한다.
- cc1 /tmp/main.i -Og [other arguments] -o /tmp/main.s
- driver는 C compiler(cc1)을 실행시켜서 main.i file을 어셈블리어로 된 main.s 파일로 번역한다.
- as [other arguments] -o /tmp/main.o /tmp/main.s
- main.s 를 binary relocatable object file 인 main.o 로 번역한다.
이와 같은 과정을 sum.c에도 똑같이 진행하여 sum.o 파일을 생성하게끔 한다.
- ld -o prog [system object files and args] /tmp/main.o /tmp/sum.o
- 마지막으로, driver는 linker 프로그램인 ld 를 실행시켜 main.o와 sum.o를 필요한 system의 object file들과 함께 결합하여 executable object file인 prog라는 프로그램을 생성할 수 있다.
- linux> ./prog
- 이제 다음과 같이 shell에 입력을 하면, os에서 loader 라는 함수를 호출하고, 이 loader는 prog에 있는 code와 data를 memory에 복사한다. 이후 프로그램의 시작부분으로 control을 이동시킨다(아마 이후에 스케쥴러에 의해 PC가 이 시작부분 주소가 설정이 되면서 프로그램이 실행될 것이다).
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[CSAPP] 7.3 Object Files(목적 파일) (0) | 2023.02.15 |
---|---|
[CSAPP] 7.2 Static Linking(정적연결) (0) | 2023.02.15 |
[CSAPP] 6.6 Putting It Together: The Impact of Caches on Program Performance(프로그램 성능에 대한 캐시의 영향) (0) | 2023.02.15 |
[CSAPP] 6.5 Writing Cache-Friendly Code(캐시 친화적 코드 작성) (0) | 2023.02.15 |
[CSAPP] 6.4 Cache Memories (캐시 메모리) (0) | 2023.02.10 |