Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
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
Tags
more
Archives
Today
Total
관리 메뉴

개발블로그

Linker 본문

카테고리 없음

Linker

학교옆메추리 2020. 5. 28. 22:35

Linking이란?

Symbol Resolving &Relocation

어떤 object file이 어떤 symbol을 포함하는지 결정

object code들을 합병하여 하나의 수행파일로 만듦

symbol의 location을 결정 및 실제 주소에 배치

 

Symbol이란 전역변수나 함수의 이름들을 지칭한다.

 

 

Static vs Dynamic Linking

static linking이란 필요한 모든 심볼들을 수행파일에 병합하여 만드는 방식이다.

라이브러리의 함수를 사용했다면, 수행파일이 생성될 때 해당 라이브러리 파일의 함수부분이 수행파일에 복사됩니다.

그렇기 때문에 수행파일의 크기가 굉장히 크다는 단점이 있습니다.

 

dynamic linking이란

수행파일에 라이브러리 코드가 포함되지 않으며, 필요로 할 때 load되고, linking된다.

따라서 수행파일이 작아지지만, runtime시에 코드를 load하므로 overhead가 커진다.

 

 

 

gcc는 내부적으로 4단계를 거친다.

1. Preprocessor (cpp)

gcc -E

.i 파일 생성

2. C compiler (cc1)

gcc -S

.s 파일 생성 (어셈블리파일)

3. assembler (as)

gcc -c

.o 파일 생성 (오브젝트파일)

4. Linker( ld)\

gcc

a.out (수행파일)

 

 

 

Linker의 장점

1. Modularity

프로그램이 작은 소스파일들의 조합으로 작성될 수 있음 (하나의 거대한 파일의 반대)

 

2. Efficiency

한 파일이 바뀌면, 해당 파일에 대해서만(다른파일은 건드리지 않아도 됨) 재컴파일 후 relink하므로 시간적 효율성을 가짐.

수행파일과 실행중의 메모리 이미지가 실제로 사용하는 함수에 대한 코드만을 가지므로 공간적 효율성을 가짐

 

 

Relocation

여러 object file들이 합쳐질 때, 주소가 그에 따라 수정되어야 함.

Relocation Bit로 재배치가 필요한 명령어를 표시함

Relocation Dictionary(RLD)에 재배치가 필요한 명령어 또는 데이터 위치를 기록함

=> 재배치 사전의 크기가 커지는 현상이 발생하여 기준이 되는 Base Register를 사용하여 동적으로 재배치함으로써 메모리를 액세스하는 명령어의 주소배치를 해결할 수 있음.

하지만, 여전히 주소 상수에 대한 재배치는 해결되지 않음.

 

 

 Linker가 하는 일

1. Symbol resolution - 심볼(전역변수 및 함수)들을 정의하고 참조한다.

이 단계에서 linker는 각 심볼 참조에 대해 단 하나의 심볼 정의를 매칭시킨다.

쉽게 말해, 함수/전역변수의 정의부를 찾는다.

void swap() {...}  // 심볼 swap 정의
swap();  // 심볼 swap 참조
int *xp = &x;  // 심볼 xp 정의 및 x참조

심볼들의 정의는 오브젝트 파일의 심볼 테이블에 저장된다. 심볼 테이블은 structs array로 되어있으며, 각각의 stucts는 이름, 크기, 심볼의 위치 등의 entry를 가진다.

 

2. Relocation - 분리된 코드와 데이터 섹션들을 하나의 섹션으로 병합한다.

여러 오브젝트 파일 심볼들의 최종 절대 경로를 결정하고, 주소를 재배치한다.

 

 

Object file의 종류

Relocatable object file (.o file) - symbol relocation이 진행되기 전의 오브젝트 파일

Executable object file (a.out) - Linker를 통해 symnbol relocation이 진행된 수행파일

Shared obeject file(.so file) - relocatable object file의 한 종류. load/link이 load/run time에 동적으로 수행된다.

 

 

Executable and Linkable Format(ELF)

.rel .text section

.text 섹션에 대한 relocation info가 저장되어 있음

수정 또는 수행해야 할 명령어들의 주소들.

 

.rel .data section

.data 섹션에 대한 relocation info가 저장되어있음.

수정되고, 수행파일에 병합되어야 할 pointer 데이터의 주소

 

 

 

Linker Symbols

Global symbols - 모듈 m에 정의되어있는 심볼로써, 다른 모듈에서 참조된다. (non-static 함수/전역변수)

External symbols - 모듈 m에서 참조하지만, 다른 모듈에 정의되어 있는 global symbol (extern 변수)

Local symbols - 모듈 m에서 정의/참조되는 심볼. 다른 파일에서 접근할 수 없으며, 로컬변수는 로컬심볼이 아니다. (static 함수/전역변수)

 

 

 

Linker는 중복된 심볼 정의에 대해 어떻게 Resolve하는가?

프로그램 심볼은 strong(함수, 초기화된 전역변수), weak(초기화되지 않은 전역변수)로 나뉜다.

Linker's Symbol Rules

1. 중복된 strong 심볼은 허용되지 않는다. 에러를 반환한다.

2. strong 심볼과 중복된 weak 심볼이 있다면, strong 심볼을 선택한다.

3. 중복된 weak이 여러개 있다면, 무작위로 선택한다.

 

이러한 규칙들 때문에 여러가지 에러가 발생할 수 있다.

이를 피하려면,

1. global 변수 대신 static변수를 사용하여 원치않는 파일의 심볼이 resolve되는것을 줄이자.

2. global 변수를 선언해야 한다면 초기화를 꼭 해주자. strong 심볼이 여러개면 컴파일 에러를 얻을 수 있으므로 원치않는 오류를 방지할 수 있다.

3. 외부 전역변수에 접근하고 싶다면 extern을 사용(명시)해라.

 

 

 

Relocation Steps

- 주어진 모듈들을 병합하고, resolved된 심볼에 대한 run-time주소(메모리의 동적 영역. stack, heap 등) 재배치

 

1. 섹션과 심볼 정의를 재배치

주어진 여러 모듈들의 같은 섹션들을 병합함.

ex: 여러 모듈의 .data section들을 병합하여 하나의 .data section으로 만든다.

 

여러 모듈들에서 정의된 심볼과 병합된 섹션에 대해 run-time주소를 할당한다.

 

각각의 함수와 전역변수는 유니크한 주소를 가지게 된다!

 

2. 심볼 참조를 재배치

relocation entries를 사용하여, 링커가 code와 data섹션에 있는 모든 심볼들의 주소를 알맞은 run-time주소로 수정한다!

 

Relocation Entries

오브젝트 파일들을 병합할 때 링커가 참조들을 어떻게 수정해야 할 지에 대한 정보가 들어있음.

offset: 섹션의 시작점

symbol: 심볼의 이름

type: relocate 방식

addend: 양의 상수. 주소 재배치 후 더해져야 할 bias값이며 relocate 방식(type)에 따라 달라짐.