프로그램이 만들어지는 과정

  • Source 코드를 Compile하여 Object File을 만들고, Linker로 Executable File을 만든 뒤, 우리가 사용하는 하드웨어(Memory)에 적재시켜 Process화 한다.

컴파일러

  • 사람이 이해할 수 있는 프로그래밍 언어로 작성된 소스 코드를 컴퓨터(CPU)가 이해할 수 있는 기계어로 표현된 Object 파일 로 변환한다.

링커

  • 관련된 여러 Object 파일들과 라이브러리들을 연결하여, 메모리로 로드 될 수 있는 하나의 Executable로 변환한다. (심볼을 해석하는 과정)
    • 심볼
      • Global symbol : 다른 모듈에서 참조 가능
        • Strong symbol : 함수, 초기화된 전역 변수
        • weak symbol : 초기화되지않은 전역 변수
      • Local symbol : 해당 모듈에서만 참조
        • 정적함수, 정적변수, 파일명
    • 심볼 해석 규칙
      • 여러개의 strong symbol은 허락되지 않는다.
      • strong symbol과 weak symbol이 주어질 때, strong symbol을 선택한다.
      • 여러 개의 weak symbol이 있을 경우 아무거나 선택한다.
  • 정적 링커

    • 모든 라이브러리 모듈을 복사하는 방식
    • 빠르고 보안 좋지만 file size ↑
  • 동적 링커(default)

    • 링킹에 관한 정보만 부여하는 방식(참조)
    • 가볍지만 보안위협 있음(바꿔치기)

로더

  • 실행가능한 파일을 실제 메모리에 올려준다.
  • 정적 로딩

    • 실행 전에 모든 코드와 라이브러리를 메모리에 미리 로드하여 실행하는 방식
    • 정적 로더가 로딩(Loading) + 재배치(Relocation)를 수행한다.
  • 동적 로딩(default)

    • 실행 중에 필요한 코드나 라이브러리를 해당 위치에서 가져와 메모리에 올리는 방식
    • 동적 로더가 로딩(Loading) + 재배치(Relocation), 동적 링커가 재배치(Relocation) + 심볼 해석(Symbol Resolution)을 수행한다.
    • 정적 로더로 실행했어도 동적 라이브러리를 하나라도 사용한 경우, 동적 로딩이 진행된다.
    • 동적 로더 : 로딩 + 재배치
      1. .interp섹션을 참조하여 동적 링커를 메모리에 로딩한다.
      2. 동적 링커가 .dynamic섹션에 명시된 공유 라이브러리들을 차례로 로딩한다.
      3. 동적 링커가 RW- 세그먼트를 RW-, R—로 재배치한다.
    • 동적 링커 : 재배치 + 심볼 해석
      1. 함수를 실행하면 PLT 섹션을 참조하여 해당 함수의 실제 주소가 있는 GOT 섹션으로 간다.
      2. GOT섹션에는 동적 링커의 호출 주소가 들어 있다.
      3. 동적 링커가 공유 라이브러리에서 호출한 함수와 일치하는 이름을 strcmp로 찾는다.
      4. 찾은 함수의 실제 주소를 .got.plt에 저장한다.
      5. 이후 해당 함수가 다시 호출되면 2~4 단계를 반복하지않고 바로 실행된다.