2024년 8월 1일 TIL

John Jean·2024년 8월 2일

week5

목록 보기
1/5

📍 키와도

7.1 링킹

  • 컴파일시 수행되는 과정. 링커에 의해 실행된다.
  • 코드와 데이터를 모아 실행 가능하게 만들어줌.
  • 링커를 이해하면 지금 당장은 그다지 도움이 되지 않을지 몰라도, 나중에 큰 프로그램을 작성할 때 도움이 될것이다.

<그림1>

이전에 공부했던 컴파일 과정 맨 마지막에 있는 아이임.

컴파일과 뭐가 다를까.

➡️링킹은 컴파일러가 실행되는 과정에 있지만, 링킹을 사용하는 이유는 따로 있다.

큰 응용 프로그램을 작은 규모로 나눠 관리하기 쉽게 함.
무슨 말이냐, 모듈 하나를 컴파일 했을 때 다른 파일을 재컴파일 할 필요가 없다.

  • 만약 main.c 파일과 sum.c 파일을 링크하고싶다,
    gcc를 사용해 두 파일을 호출한다.
    gcc -Og -o prog(merged file name) main.c sum.c
    이후 <그림1>에 Assembler까지 독립적으로 컴파일이 수행된 뒤, 링커에서 하나의 파일로 합쳐진다(링커에선 1. 심볼해석 2. 재배치 과정이 일어남.).

목적 파일

목적 파일은 3가지 형태가 있다.

  1. Relocatable Object File: 재배치 가능 목적 파일로, 다른 재배치 가능 목적 파일과 결합하게 된다. -> 컴파일러와 어셈블리에서
  2. Executable Object File: 실행 가능한 목적 파일로, 메모리에 직접 복사가 가능하고 실행이 가능하다. 링커에서
  3. Shared Object File: 로드타임 또는 런타임시 동적으로 링크되고, 메모리에 로드될 수 있다.

컴파일러와 어셈블러를 통해 Relocatable Object File을 만들고, 링커는 Executable Object File을 만든다


7.4 🏷️ 재배치가능 목적파일(Relocatable Object File)

  • <그림1>의 컴파일러와 어셈블리에서 재배치 가능 목적파일을 생성함. 형식은 ELF.
  • ELF 파일 = ELF 헤더 + 섹션 헤더 테이블 + 섹션 정보.

  • 최상단 ELF 헤더는 파일을 생성한 워드 크기와 시스템의 바이트 순서를 나타내는 16바이트 배열로 시작.
  • 이후로는 링커가 목적파일을 구문분석하고 해석 가능하도록 하는 정보를 포함하고 있음.
  • 섹션 헤더 테이블은 여러 섹션들의 위치와 크기를 담음.

섹션 정보(참고만 하자)

.text: 컴파일 된 프로그램의 머신코드
.data: 초기화 된 전역변수와 정적변수
.bss: 초기화 되지 않은 전역변수와 정적변수 or 0으로 초기화 된 전역변수, 정적 변수
.symtab: 프로그램에서 정의되고 참조되는 전역변수들과 함수에 대한 정보를 가지고 있는 테이블(지역변수 제외)
.rel.text: 다른 목적파일과 링킹할 때 수정되어야 하는 .text 섹션 내의 위치 리스트
.rel.data: 모듈에 의해 정의되거나 참조되는 전역변수들에 대한 재배치 정보
.debug: 디버깅 목적에 활용할 수 있게 지역변수, 전역변수, 구조체 등에 대한 정보를 담는 테이블. 컴파일러에 -g 옵션을 추가할 경우에만 재배치 가능 목적파일에 담긴다.
.line: 소스프로그램과 .text 섹션 내의 머신코드의 각 라인 매핑 정보. -g 옵션으로 컴파일 시에만 담김
.strab: strtab, .debug, 섹션 헤더에 담긴 이름들을 위한 문자열 형태의 테이블. 목적파일에서 이름들을 문자열 형태로 별도로 관리하여 필요할 때 이름을 참조하기 위함.

심볼테이블 ➡️ 어셈블러에 의해 만들어진다.

심볼테이블 이란, 전역변수, 함수, 정적 변수 심볼에 대한 중요정보를 저장하는 테이블이다. 심블 테이블은 심블의 이름을 저장하고 심볼과 메모리 주소를 연결해주며 심볼의 속성(타입, 범위, 접근성)정보를 담고 있다. 심볼 테이블은 링킹 시, 디버깅 시 그리고 동적 링킹시 사용된다.

심볼 이란, 소스 코드에서 사용되는 이름이다. 이름은 변수, 함수, 배열, 클래스 등에 할당되며 프로그래머가 요소를 참조할 때 사용한다. 즉, 변수 이름, 함수 이름, 클래스 이름이 심볼에 해당한다. 심볼은 프로그램의 가독성과 관리를 도와주며 컴파일러에 의해 처리가 되어 실행 가능한 코드가 된다. 컴파일러는 심볼을 통해 소스코드 내의 각 요소를 어떻게 처리할 지 결정하고 기계어로 변환한다.


🏷️ 7.9 실행가능 목적파일의 로딩

./prog ➡️ 쉘상에서 prog는 cd, ls 같이 명령어가 아니다. 명령어가 아닌 입력값은 실행파일 명으로 인식, prog를 실행함.

  • prog를 디스크에서 메모리로 복사, prog의 첫번째 인스트럭션(엔트리 포인트)로 점프, 프로그램을 실행.
  • 이와같이 프로그램을 메모리로 복사, 실행하는 과정을 로딩 이라고 함.

<리눅스 x86-64 런타임 메모리 이미지>


📍 예외 상황

  • 시스템은 프로그램에서 표현되지 않은 시스템 상태의 변화에도 대응할 수 있어야함.
  • 이 상태의 변화에 어떻게 대응하느냐에 대한 내용이 이번 챕터에서 다루는 부분.

➡️ 컴퓨터가 돌고 있을때 프로그램카운터는 항상 실행중인 프로세스를 나타냄.
인스트럭션 : I, 대응되는 주소: a

a0 a1 a2.......a(n-1)
I0 I1 I2..........I(n-1)

➡️ 특정 인스트럭션을 실행중 예외상황이 발생하였다(프로세서가 이벤트가 발생했다는 것을 감지했다).
-> 예외 테이블이라 하는 점프테이블을 통해 이 특정 종류의 이벤트를 처리하기 위해 특별히 설계된 운영체제 서브루틴(예외처리 핸들러)으로 간접 프로시저 콜을 하게됨. (아래 사진 참고)

➡️ 예외처리 핸들러가 처리를 마치면, 예외처리를 발생시킨 이벤트에 따라 다음의 세 가지중 한가지 일이 발생함.

  1. 핸들러는 제어권을 현재 인스트럭션으로 돌려줌. 즉 예외상황 발생했을 때 실행되고 있던 인스트럭션.
  2. 예외 상황 발생시 실행되던 인스트럭션 다음의 인스트럭션을 돌려줌.
  3. 핸들러는 중단된 프로그램을 종료함.

📍 예외의 종류

🏷️ 인터럽트

  1. 발생원인: 인터럽트는 주로 하드웨어 장치에서 발생함. 특정 이벤트가 발생하면 해당장치는 cpu에게 인터럽트를 발생시킴.
  2. 목적: 인터럽트는 cpu가 특정 하드웨어 이벤트를 처리할 수 있게 함. 이를 통해 시스템이 다양한 외부장치와 상호작용할 수 있음.
  3. 처리과정
    • 하드웨어 장치가 인터럽트를 발생.
    • cpu는 실행 중인 작업을 중단하고, 예외 테이블을 참조해 적절한 인터럽트 서비스 루틴을 호출함.
    • isr이 실행된 후, cpu는 중단된 작업을 재개함.

🏷️ 트랩

  1. 발생원인: 트랩은 주로 소프트웨어나 프로세서 내부에서 발생함. 이는 사용자 프로그램의 예외 상황이나 시스템 호출로 인해 발생함.
  2. 목적: 트랩은 주로 예외 처리를 수행하거나, 사용자 프로그램이 우녕ㅇ체제의 기능을 요청할 때 사용됨.
  3. 처리과정:
    • 예외 상황이 발생하거나 시스템 호출이 실행되면 트랩이 발생.
    • cpu는 실행 중인 작업을 중단하고, 예외 테이블을 참조해 적절한 트랩 핸들러를 호출.
    • 트랩 핸들러가 실행된 후, 필요에 따라 중단된 작업을 재개하거나, 작업을 종료.

🏷️ 오류(fault)

오류는 핸들러가 정정할 가능성이 있는 에러조건으로부터 발생함.
핸들러가 에러 조건을 정정할 수 있다면, 제어를 오류를 발생시킨 인스트럭션으로 돌려주고, 그렇지 않다면 abort루틴으로 리턴해 응용 프로그램을 종료함.

profile
크래프톤 6기 정글러

0개의 댓글