STUDY

[3주차 TIL] KnockOn Bootcamp Pre.Rev : 링커와 로더

da1seun9 2024. 12. 21. 21:17

개요

이번에는 프로그램이 실행되는 과정의 첫번째인 링커와 로더에 대해 공부했다.

링커

여러개의 Object File과 라이브러리를 연결하여 하나의 실행파일을 완성하는 프로그램

컴파일러가 소스코드를 컴파일하면, 생성되는 개별적인 목적파일들이 링커를 통해 결합됨.

정적링킹

  • 특징
    • 필요한 라이브러리 코드를 실행파일에 직접 포함
    • 실행 시 추가적인 라이브러리를 필요로 하지 않음.
  • 장점
    • 실행파일이 독립적이며, 배포가 간단
    • 라이브러리를 찾지 않아도 되서 실행 속도가 빠름
  • 단점
    • 라이브러리를 통째로 합쳐야해서 실행파일 크기가 커짐
    • 라이브러리가 업데이트 되어도 Object File에 포함시켜서 새 실행파일을 만들어야함

동적링킹

  • 특징
    • 실행파일에 라이브러리 코드를 포함하지 않고 실행 시 필요할 때 동적으로 로드할 수 있음
    • 동적라이브러리 파일이 필요하다.
    • Windows는 .dll, Linux는 .so
  • 장점
    • 실행 파일 크기가 작다.
    • 라이브러리를 변경하면 즉시 반영이 가능하다.
  • 단점
    • 라이브러리를 로드하는 추가 작업이 필요해 성능저하 발생

재배치

프로그램의 메모리 주소를 동적으로 조정하는 작업이다.

목적파일은 메모리 주소를 확정하지 않은 상태로 생성되며, 링커는 각 파일의 코드를 실행가능한 메모리 주소로 변경한다.

  • 필요성
    • 여러 목적파일이 결합할 때 메모리 주소 충돌을 방지
    • 동적 라이브러리와의 연계 시 메모리 위치를 동적으로 배정

.dll과 .so

  • .dll(Dynamic Link Library)
    • 윈도우 운영체제에서 사용하는 동적 라이브러리 파일
    • 실행 시 호출 프로그램에 의해 로드
  • .so(Shared Object)
    • 리눅스 및 유닉스 계열에서 사용하는 동적라이브러리 파일
    • 프로그램 실행 중 공유 메모리에 로드되어 여러 프로그램에서 동시에 사용 가능

로더(Loder)

컴퓨터 운영체제의 일부분으로 하드디스크와 같은 오프라인 저장장치에 있는 특정한 프로그램을 찾아서 주기억장치에 적재하고, 그 프로그램이 실행되도록 하는 역할을 담당한다.

작동방식

순서

  1. 주기억 장치 할당 : 프로그램이 적재될 주 기억장소(메모리) 내 공간을 확보한다.
  2. 연결 : 필요한 경우 여러 프로그램들과 기능 연동을 위해 저장 공간 주소 값을 공유한다.
  3. 재배치 : 할당 및 연결과정 후 실제 주 기억장소(메모리) 주소에 프로그램을 배치한다.
  4. 적재 : 주 기억장소(메모리)에 적재 후 프로그램을 읽어들인다.

기능

  • 절대로더
    • 프로그래머가 지정한 주소로 주기억장치에 적재하는 기능을 가지는 간단한 로더
    • 작업분담
      • 링크 : 링커
      • 기억장소 할당 : 운영체제
      • 재배치 : 어셈블러
      • 적재 : 로더
  • 재배치 로더
    • 주기억장치 상태에 따라 목적프로그램을 주기억장치의 임의공간에 적재할 수 있도록 하는 로더
    • 링커가 설정한 주소를 기반으로 실행 시점에 메모리 주소를 동적으로 조정
    • 작업분담
      • 링크 : 링커
      • 기억장소 할당 : 운영체제
      • 재배치 : 로더
      • 적재 : 로더
  • 동적 적재
    • 프로그램의 모든 부분을 주기억장치에 적재하지 않고 항상 필요한 부분만 주기억장치에 적재하고, 나머지는 보조기억장치에 저장해두는 기법

동적 라이브러리 로드 과정

  1. 라이브러리 검색
    • 운영체제는 실행파일이 필요로 하는 동적라이브러리를 찾음
    • 라이브러리 경로가 설정되지 않은 경우 실행 오류 발생
  2. 라이브러리 로드
    • 필요로 하는 .dll(.so) 파일을 메모리에 로드
    • 로드된 라이브러리는 운영체제에 의해 관리되며, 여러 프로세스에서 공유될 수 있음
  3. 심볼해석
    • 프로그램에서 호출한 함수나 변수 이름을 라이브러리에서 검색
    • 실행에 필요한 심볼의 실제 메모리 주소를 연결
  4. 사용
    • 프로그램 실행 중 라이브러리의 함수를 호출하거나 변수를 참조

링커, 로더, 재배치..?

링커와 로더의 재배치는 비슷한 듯 하지만 그 시기와 역할이 다르다.

  • 링커의 재배치
    • 링커는 컴파일 후 여러 개의 목적파일(Object File)을 결합하여 실행파일을 생성하는 과정에서 발생할 수 있는 주소충돌을 방지하기 위해 재배치를 수행
    • 목적파일 내 상대 주소 조정 : 각 목적파일에 포함된 코드와 데이터를 적절한 메모리 공간으로 이동
    • 심볼 결합 : 함수나 변수가 다른 목적파일에 있을 경우 이를 적절히 연결
    • ex) call func에서 링커가 func의 위치를 알고, call func의 명령을 call 0x400123처럼 재배치하여 실행파일에 저장
  • 로더의 재배치
    • 로더는 실행 시점에 재배치 작업을 수행한다.
    • 실행 파일이 메모리에 적재될 때, 고정된 메모리 주소를 사용할 수 없는 경우 실행환경에 맞춰 재배치 실시
    • 동적라이브러리와 결합 : 동적 라이브러리(.dll 또는 .so)에 정의된 함수나 변수를 호출하는 심볼을 실행시점에 바인딩
    • Base Address 조정 : 실행파일이나 라이브러리가 로드될 주소가 변경될 경우, 코드에서 사용되는 주소를 조정
    • ex) 실행파일이 메모리주소 0x400000에 로드되려 했으나, 시스템에서 0x500000에 로드되어야할 경우
      • 코드 내 절대 주소를 0x400123에서 0x500123으로 변경

정리

항목 링커 로더
역할 목적파일과 라이브러리를 연결해 실행파일 생성 실행파일을 메모리에 적재하고, 실행 준비 완료
작동시점 컴파일 이후, 실행파일 생성 단계에서 작동 프로그램 실행 시점에 작동
결과물 실행 가능한 파일 실행중인 프로그램(프로세스)
주요 작업 심볼해결, 재배치, 라이브러리 연결 메모리 적재, 동적라이브러리 로드, 재배치

끝.