링커를 사용하는 이유
모듈화
자주쓰는 코드는 모듈화 시켜서 갖다쓰면 편하다.
공간적 : 하나의 모듈만 존재하면 여러 실행파일에서 가져다 쓸 수 있다.
시간적 : 바꾸고 싶은 라이브러리 부분이 있다면 거기만 바꿔서 링킹을 진행하면 된다, 전체를 다시 컴파일할 필요가 없다.
오브젝트 파일의 종류
relocatable object file (a.o)
- string, 어셈블리어, 전역변수 같은 프로그램 코드, 다른 오브젝트 파일과 합처져 실행파일을 만들 수 있음
Executable object file (a.out)
- relocatable object file을 재배치해서 실행 가능하게 만든 파일
shared object file (a.so)
실행할 때 동적으로 프로그램에 들어가는 파일 can be loaded into memory and liked dynamically load time or run time
세 오브젝트 파일의 공통된 포맷
ELF(excutable and linkable format)

elf header
- word size, byte ordering, file type, machine type
segment header table
- page size, virtual addresses meomory segment, segment size
text section
- code (어셈이 기계어로 변환된 기계어 코드)
rodata section
- 바뀌지 않을 데이터들 (string in printf, jump tables)
data section
- initialized global variables (초기화된 전역변수, static 변수)
bss section
- uninitialized global variables, Block symbol
symtab section
- symbol table
rel.txt section
- relocation info for .text section (심볼의 상대적인 위치)
rel.data section
- relocation info for .data section
what is relationship of symbol and linker
1. symbol resuoltion
프로그램은 심볼의 위치를 정의하거나 참조해야 한다.
심볼은 오브젝트 파일에 심볼 테이블로 정의되어있다.
링커는 symbol resolution 단계에서 각 심볼이 참조하고 있는 테이블과 심볼을 연결한다.
2. relocation
분리되어있는 코드와 데이터 section을 하나의 section으로 병합한다.
.o 파일 안의 상대적인 심볼 위치를 .out 파일으로 바꿀 때 절대 주소로 바꿔준다.
symbol resuoltion

local symbol

만약 f만 존재한다면 컴파일러는 .data section에 x를 위치시킨다.
f, g 가 동시에 존재한다면 컴파일러는 x.1, x.2로 symbol table을 만든다.
링커는 중복된 이름의 심볼을 구분하는지?
링커는 심볼들의 위치를 컴파일 시에 중복된 이름의 심볼이 있으면 어떤 것을 가져와 심볼에 끼워야 하는지 선택해야 한다.
• Strong: procedures and initialized globals
- 구현된 함수, 초기화된 전역변수 (심볼이 채워져있는)
• Weak: uninitialized globals
- 초기화 하지 않은 함수, 변수 (심볼이 비어있는)

rule 1 : 두개의 stong이면 심볼의 이름이 같으면 lnker error
rule 2 : week 심볼이 이름이 같은 아무 strong 심볼을 참조한다.
rule 3 : 여러 week symbol이 존재하면 아무거나 선택된다.
Relocation

loading Executable Object file

링킹 후 만들어진 실행파일을 메모리에 로드
static library
링킹 시에 합쳐지는 라이브러리
만약 하나의 소스 코드 파일에 모든 기능이 다 들어있을 때 특정 기능을 수정하면 그 파일 전체를 재컴파일 해야하고,
만약 모든 기능을 여러 소스코드로 만들었을 때 너무 세분화하면 관리도 힘들 뿐더러 링킹시 용량이 커지고 오류를 찾기 힘들다.
아카이브 파일이란 개념을 도입하여 관련 기능들을 모아놓은 개별 .o 파일을 모아놓는다.
인덱스로 특정 .o 파일을 찾아 가져올 수 있다.
-> 최대한 관련있는 것들로만 라이브러리를 구성하여 링크 할 때 효율을 높인다.
우리가 자주 볼 수 있는 static library :
libc.a (the C standard library)
• 4.6 MB archive of 1496 object files.
• I/O, memory allocation, signal handling, string handling, data and time, random numbers, integer math
libm.a (the C math library)
• 2 MB archive of 444 object files.
• floating point math (sin, cos, tan, log, exp, sqrt, …)
static labrary를 사용한 링킹 과정

하지만 이 방식은 여러 프로그램에서 같은 라이브러리를 사용할 때 단점이 생긴다.
만약 같은 기능을 사용하는 여러 프로세스를 한꺼번에 사용하면 중복되는 코드가 메모리 상에서 발생할 수 밖에 없다.
디스크, 메모리 효율 낮아짐
또한 printf 같은 기능이 수정됐을 때 해당 프로그램은 다시 링킹을 해야한다.
shared Libraries
로드나 런타임에 공유되는 라이브러리로 static librarie 방식을 대체하여 사용되고 있다.
컴파일 하기 전까지 symbol을 비워놓고 프로그램을 로드할 때 불러온다. 더 심하면 런타임에 불러와서 함수가 호출되기 전까지 호출한 함수 코드가 메모리에 존재하지 않을 수 있다. 현대에는 이 방식을 사용한다.
1. 실행할 때 올리는 거라서 기존 링커 말고 dynamic 링커가 필요하다.
2. DLL(Dynamic Link Library) 파일을 사용 업데이트시 이 파일을 바꾸면 된다 -> 프로그램 전체를 재링킹할 필요없음
3. 메모리 특정 영역안에 띄워놓으면 여러 프로세스에서 가져다가 쓸 수 있다. -> shared librarie section에 들어감

링킹 과정
.static labrarie 방식으로 컴파일된 프로그램은 다른 오브젝트 파일 없이도 실행가능하지만
dynamic lybrarie 방식으로 컴파일된 프로그램은 so 파일이 없으면 프로그램을 실행하지 못한다는 단점도 존재한다.
(런타임에 so 파일을 참조하기 때문에)