책/CSAPP

CSAPP 7, 7.1, 7.4

에린_1 2024. 2. 2. 00:41
728x90

CSAPP

7. 링커Linking

  • 링킹(linking)은 여러개의 코드와 데이터를 모아서 연결하여 메모리에 로드 될 수 있고 실행 될 수 있는 한 개의 파일로 만드는 작업이다. 링킹은 컴파일 시에 수행 할 수 있으며, 이때 소스코드는 머신코드로 번역된다. 프로그램이 메모리에 로드되고, 로더에 의해서 실행될 때는 로드타임에 응용 프로그램에 의해서 심지어 실행시에도 수행될 수 있다.
  • 링커는 독립적인 컴파일을 가능하게 한다. 큰 규모의 응용 프로그램을 한 개의 소스 파일로 구성하는 대신 별도로 수정할 수 있고, 컴파일 할 수 있는 보다 관리할 만한 규모의 더 작은 모듈들로 나눌 수 있다. 이 모듈 중에 한 개를 변경할 때, 이 파일만을 간단히 재 컴파일하고 다른 파일들을 재 컴파일할 필요 없이 이 응용을 다시 링크한다.
  • 링킹에 대해 배워야 하는 이유
    • 큰 프로그램을 작성하는데 도움이 된다. 다양한 이유로 링커 에러가 발생하는데 이런 오류를 이해하지 못하면 혼란스럽고 당혹스러울 것이다.
    • 위험한 프로그래밍 에러를 피할 수 있게 된다. 리눅스 링커가 심볼 참조를 해결할 때 하는 결정들을 프로그램의 정확성에 미미한 영향을 줄 수 있다.
    • 어떻게 언어의 변수 규칙이 구현 되었는지 이해하는데 도움이 된다.
    • 다른 중요한 시스템 개념을 이해할 수 있게 된다.
    • 공유 라이브러리에 대해 이해할 수 있다.

7.1 컴파일러 드라이버

  • 드라이버는 먼저 C전처리기 (cpp)를 돌리고, 이것은 main.c를 ASCII 중간 파일인 main.i로 번역한다.
  • 드라이버는 C컴파일러는 (cc1)을 돌려서 main.i를 ASCII 어셈블리 언어 파일인 main.s로 번역해준다.
  • 드라이버는 어셈블러를(as) 돌려서, main.s를 재배치 가능한 바이너리 목적 파일인 main.o로 번역한다.
  • 드라이버는 sum.o를 생성하기 위해서 동일한 과정을 수행한다. 마지막으로, 링커 프로그램 ld를 실행하는데, 이것은 필요한 시스템 목적 파일들과 함께 실행가능 목적파일 prog를 생성하기 위해 main.o와 sum.o를 생성한다.
  • 쉘은 로더라고 부르는 운영체제 내의 함수를 호출하며, 로더는 실행파일 prog의 코드와 데이터를 메모리로 복사하고, 제어를 프로그램의 시작 부분으로 전환한다.

7.4 재배치 가능 목적파일

  • 전형적인 ELF(Executable and linkable format) 재배치 가능 목적파일의 포맷이다. ELF 헤더는 이 파일을 생성한 워드 크기와 시스템 바이트 순서를 나타내는 16바이트 배열로 시작한다. ELF 헤더의 나머지는 링커가 목적파일 구문분석하고, 해석하도록 하는 정보를 포함하고 있다. 여기에는 ELF 헤더 크기, 목적파일 타입 재배치 가능, 실행 가능, 공유, 머신타입(예, x86-64), 섹션 헤더 테이블의 파일 오프셋, 섹션 헤더 테이블의 크기와 엔트리 수가 들어 있다. 여러가지 섹션들의 위치와 크기는 섹션헤더 테이블로 나타내며, 이 테이블은 목적파일의 각 섹션에 대해 고정된 크기의 엔트리를 갖는다.
  • ELF 헤더와 섹션 헤더 테이블 사이에 섹션 내용이 들어있다.
    • .text : 컴파일 된 프로그램의 머신코드
    • .rodata : printf 문장의 포맷 스트링, switch문의 점프 테이블과 같은 읽기-허용 데이터
    • .data : 초기화 된 전역변수 및 정적변수, 지역변수들은 런타임에 스택에 저장되며 data,bss섹션에는 나타나지 않는다
    • .bss : 초기화 되지 않은 전역변수와 정적변수 그리고 0으로 초기화 된 전역변수 및 정적변수, 이 섹션은 목적 파일에 실제 공간을 차지하지는 않는다; 이것은 단순히 위치를 표시하는 것이다. 목적파일 포맷은 공간 효율성을 위해 초기화 한 공간과 초기화 하지 않은 변수들을 구분한다 : 초기화 하지 않은 변수들은 목적파일에서 실제 디스크 공간을 차지할 필요가 없다. 런타임에 이 변수들은 메모리에 0으로 초기화 되어 할당된다.
    • .symtab : 프로그램에서 정의되고 참조되는 전역변수들과 함수에 대한 정보를 가지고 있는 심볼 테이블. 모든 재배치 가능 목적 파일은 .symtab에 심볼 테이블을 가지고 있다. 그러나 컴파일러 내부의 심볼 테이블과는 달리, .symtab 심볼 테이블은 지역변수에 대한 엔트리를 가지고 있지 않다.
    • .rel.text : 링커가 이 목적파일을 다른 파일들과 연결할 때 수정되어야 하는 .text 섹션 내 위치들의 리스트. 일반적으로 외부함수를 호출하거나 전역변수를 참조하는 인스트럭션들은 모두 수정되어야 한다. 반면에, 지역 함수를 호출하는 인스트럭션들은 수정될 필요가 없다. 재배치 정보는 실행 가능 목적파일에는 필요하지 않으며, 사용자가 링커에게 명시적으로 이것을 포함하라고 지시하기 전에는 대개 이 정보는 빠진다는 점에 유의해야 한다.
    • .rel.data : 이 모듈에 의해 정의되거나 참조되는 전역변수들에 대한 재배치정보. 일반적으로 초기값이 전역변수 또는 외부에 정의된 함수의 주소인 초기화된 전역변수들 모두는 수정되어야 한다.
    • .debug : 프로그램내에서 정의된 지역변수들과 typedef, 프로그램과 최초 c소스 파일에서 정의되고 참조되는 전역변수를 위한 엔트리를 갖는 디버깅 심볼 테이블 컴파일러 드라이버가 -g옵션을 불린 경우 생성된다.
    • .line : 최초 c소스 프로그램과 .text 섹션 내 머신코드 인스트럭션 내 라인 번호들 간의 매핑. 이것은 컴파일러 드라이버가 -g 옵션으로 호출된 경우에만 생긴다
    • .strtab : .strtab과 .debug 섹션들 내에 있는 심볼 테이블과 섹션 헤더들에 있는 섹션 이름들을 위한 스트링 테이블. 스트링 테이블은 널 문자로 종료된 스트링의 배열이다.
728x90

' > CSAPP' 카테고리의 다른 글

CSAPP 8.1, 8.1.1  (0) 2024.02.04
CSAPP 7.4, 7.9, 8  (0) 2024.02.03
CSAPP 9.9.4 - 9.9.7  (2) 2024.01.31
CSAPP 9.8 - 9.9.3  (0) 2024.01.30
CSAPP 9.6 - 9.7  (1) 2024.01.29