일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 링커
- 선형대수학
- linear algebra
- Rust
- 재배치
- column space
- 동적링크
- rust 스터디
- 백준
- 구문트리
- 다이나믹 프로그래밍
- 다익스트라
- matrix
- 컴퓨터밑바닥의비밀
- 컴파일러
- unity
- 알고리즘
- CS정리
- 스레드전용리소스
- 심벌 해석
- vector
- eigenvalue
- 코드포스
- 대상파일
- 행렬
- 스레드전용저장소
- 벡터
- 정적링크
- 적재도구loader
- c++
- Today
- Total
개발_기록용
[컴퓨터 밑바닥의 비밀 내용정리] 1.4 링커의 일하는 방식 본문
0. 들어가며
- 굉장히 감명깊게 읽었던 [컴퓨터 밑바닥의 비밀] 책의 내용을 돌아보기 위해 정리글을 작성한다.
- 전공자로 어느정도 안다고 생각한 내용들에서도 부족한 부분이 보여 책을 다시 읽어보며 정리하고자 한다.
https://link.coupang.com/a/cdaqFv
컴퓨터 밑바닥의 비밀:컴퓨터 시스템의 본질을 알면 코드의 실마리가 보인다 - 보안과 해킹 | 쿠
쿠팡에서 4.3 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 3 제품도 바로 쿠팡에서 확인할 수 있습니다.
www.coupang.com
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
(본문 소개 링크로 도서 구입 시 일정액의 수수료를 제공받습니다.)
1. 주제
우리는 지난 내용에서 여러개의 대상 파일을 하나의 실행파일로 묶어주는 과정을
링크과정이며, 이를 링커가 담당한다고 배웠다.
여러개의 대상파일 → 하나의 실행파일 (exe, elf)
실제 링크의 전체 과정은 저자 여러명이 각각 특정부분을 맡아
장(Chapter)별로 따로 집필하고, 개별 장을 묶어 하나의 책을 출원하는 것과 비슷하다.
책의 특정 장이 다른 장의 내용을 참고할 경우
이는 우리가 작성하는 프로그램이 다른 모듈의 프로그래밍 인터페이스(API)
또는 변수를 참조하는 것과 같다. (이를 두 모듈 사이에 종속성이 있다고 표현한다.)
링커가 하는 일 중 하나는 이 종속성이 올바르게 설정되어 있는지,
다시 말해 인터페이스 구현이 종속된 모듈에서 사용 가능한지 확인하는 것이다.
→ 우리가 참조하고 있는 외부심벌에 대한 실제 구현이
어느 모듈이든지 반드시 존재해야 하며, 단 하나만 있어야 한다.
*심벌 : 전역변수와 함수 이름을 포함한 모든 변수의 이름들.
(지역변수는 모듈 내에서만 쓰이니 링커의 관심대상이 아님)
링커는 이를 찾아내 연결하는 작업을 하는데, 이를 '심벌 해석'이라 한다.
책의 어떤 하나의 장에서 다른 장의 내용을 인용할 때
책에서는 이 내용이 어디에 쓰여질지 모르니 일단 N쪽이라 해놓는다.
그리고 인용할 부분이 100쪽에 쓰였다면 원고를 뒤져 N쪽을 100쪽으로 고친다.
→ 이 과정을 재배치(relocation)이라 하며 코드 안에서도 똑같다.
→ 특정한 소스파일에서 다른 모듈에 정의된 print 함수를 참조할 때
컴파일러는 이 소스를 컴파일하는 시점에선 함수가 어느 메모리주소에 있을지 모른다.
그래서 컴파일러는 이 주소를 N이라 표시해놓고
링커가 실행파일 생성과정에서 N을 정확한 메모리주소로 고친다.
2. 대상 파일의 두가지 영역과 심벌테이블
자 그러면 생각을 해보자.
링커가 소스파일에서 관심을 갖는건 다음 2가지
- 소스파일에 다른 모듈에서 참조 가능한 심벌이 있는가
- 소스파일이 다른 모듈에서 정의한 심벌을 참조하는가
그러면 이 정보는 누가 링커에게 알려주냐면, 바로 컴파일러!
컴파일러가 코드 → 기계 명령어 번역 후 이를 대상 파일에 저장할 때
이 기계 명령어를 실행시키는 데이터도 생성되어 대상 파일에 함께 저장한다.
*참고로 로컬 변수는 프로그램이 실행되고 스택 영역에서 생성되고
사용하면 제거되므로 대상 파일에는 별도로 저장되지 않는다.
컴파일러는 컴파일 과정에서 외부에서 정의된 전역변수나 함수를 발견하면
해당 변수의 선언이 존재하는 한 그 변수가 실제로 정의되었는지 여부는 신경쓰지 않고 넘긴다.
→ 참조된 변수 정의를 찾는건 링커의 몫이기 때문이다.
근데, 이 넘긴다는게 소스파일마다 외부에서 참조 가능한 심벌이 어떤 것인지
그리고 반대로 어떤 외부 심벌을 참조하고 있는지도 기록해두는 것을 말하는데
이를 저장하는 표를 심벌 테이블이라 한다.
→ 컴파일러는 이 심벌 테이블을 대상 파일에 저장한다.
링커는 심벌 해석 과정에서 각 대상 파일에서 쓸 외부 심벌이
심벌 테이블에서 유일한 정의를 발견 가능한지 확인한다.
우리가 흔히 접하는 undefined reference to 'func' 같은 오류는
func 함수가 참조되었지만 정의되지 않은 심벌로 링커가 func 함수의 정의를 발견하지 못한 것이다.
'Computer Science' 카테고리의 다른 글
[컴퓨터 밑바닥의 비밀 내용 정리] 1.6 동적 라이브러리와 동적 링크 (0) | 2025.02.07 |
---|---|
[컴퓨터 밑바닥의 비밀 내용정리] 1.5 정적 라이브러리와 정적 링크 (1) | 2025.02.07 |
[컴퓨터 밑바닥의 비밀 내용정리] 1.3 컴파일러의 동작원리 (0) | 2025.02.07 |
[컴퓨터 밑바닥의 비밀 내용 정리] 1.2 인터프리터(가상머신) (0) | 2025.02.04 |
[컴퓨터 밑바닥의 비밀 내용 정리] 1.1 구문 트리 (0) | 2025.02.03 |