..
컴퓨터 구조 CS:APP 7장
링커와 로더의 역할
- 링커는 여러 개의 오브젝트 파일을 하나의 실행 파일로 결합하며, 이 과정에서 기호 해석과 재배치가 일어남
- 로더는 실행 시에 메모리에 프로그램을 올리고, 가상 주소 -> 실제 주소 매핑과 실행 준비를 함
정적 연결
- 기호 해석(Symbol Resolution)
- 함수나 전역 변수와 같이 여러 파일에 걸쳐 사용되는 이름을 정확히 하나로 매칭
- 재배치(Relocation)
- 각 오브젝트 파일은 독립적인 주소를 가지므로, 이를 통합된 주소 공간에 맞게 재조정해야 함
- .text, .data, .bss 등 섹션들이 링크 시점 또는 실행 시점에 재배치됨
목적 파일
- 재배치 가능 목적 파일(.o)
- 실행 가능 목적 파일(.out)
- 공유 목적 파일(.so)
목적 파일의 내부 구조
- .text: 기계어 명령어
- .data: 초기화된 전역 변수
- .bss: 초기화되지 않은 전역 변수
- .symtab: 심볼 테이블
- .rel.text, .rel.data: 재배치 정보
- .debug: 디버깅 정보
정적 링크 vs 동적 링크
- 정적 링크: 필요한 모든 코드와 데이터를 실행 파일에 포함시킴
- 동적 링크: 실행 시점에 공유 라이브러리를 로드
GOT(Global Offset Table) / PLT(Procedure Linkage Table)
- 동적 링크에서 함수를 호출하거나 전역 변수에 접근할 때 필요한 주소 정보를 저장
- 이를 통해 위치 독립적 코드(Position Independent Code, PIC)를 구현 가능하게 함
Library Interpositioning
- 런타임에 라이브러리 함수의 동작을 가로채서 수정할 수 있는 고급 기법
- malloc() 같은 함수를 오버라이딩하여 메모리 할당 추적
심볼과 심볼 테이블
- 각 리로케이션 가능 오브젝트 파일에는 .symtab 섹션에 심볼 테이블이 존재함
- 이 테이블은 해당 모듈에서 정의하거나 참조하는 함수와 전역 변수에 대한 정보를 저장
- 심볼의 3가지 종류
- 전역 심볼(Global symbols): 다른 모듈에서도 참조 가능한 함수나 전역 변수
- 외부 심볼(External symbols): 현재 모듈에서는 참조만 하고, 다른 모듈에서 정의된 전역 심볼
- 로컬 심볼(Local symbols): static으로 선언된 함수/변수 등, 현재 모듈 내부에서만 사용 가능
- 주의할 점은, 로컬 자동 변수(local nonstatic variable)은 심볼 테이블에 나타나지 않으며 런타임에서 스택으로 관리된다는 것
- static 지역 변수는 .data 또는 .bss 영역에 저장되며, 심볼 테이블에서는 서로 다른 이름으로 나타남
심볼 이름 충돌 해결: 심볼 결합
- 링커는 참조된 심볼을 정의된 심볼과 연결하기 위해 각 오브젝트 파일의 심볼 테이블을 스캔
- 강한 심볼 vs 약한 심볼
- 강한 심볼(strong): 함수, 초기화된 전역 변수
- 약한 심볼(weak): 초기화되지 않은 전역 변수
- 중복 심볼 처리 규칙:
- 강한 심볼이 둘 이상이면 오류
- 강한 + 약한 -> 강한 선택
- 약한 + 약한 -> 아무거나 선택 (컴파일러가 정함)
- COMMON - 초기화되지 않은 전역 변수
0으로 초기화된 경우 .bss
명시적으로 값이 있는 경우 .data
심볼 테이블 포맷과 ELF 구조
- ELF 형식에서는 심볼 테이블 항목을 Elf64_Symbol 구조체로 나타낸다
- name: 심볼 이름(문자열 테이블 오프셋)
- type: 함수인지 데이터인지
- binding: local 또는 global
- section: .text/.data/.bss/COMMON 등
- value: 위치(주소 또는 오프셋)
- size: 크기 (바이트)
- 특수 섹션
- ABS: 절대 주소, relocation 없음
- UNDEF: 정의되지 않은 참조 심볼
- COMMON: 초기화되지 않은 전역 변수
링커 동작 요약 및 주의할 점
- 링커는 각 오브젝트 파일을 좌->우 순서로 처리, 심볼이 해결되지 않았을 경우 오류
- 라이브러리를 사용할 때는 참조하는 쪽이 먼저 등장해야 제대로 링크
- 심볼 이름이 같고 자료형이 다를 경우 예기치 않은 런타임 버그가 발생