맨위로가기

링커 (컴퓨팅)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

링커는 여러 개의 객체 파일과 라이브러리를 결합하여 실행 가능한 프로그램을 생성하는 컴퓨터 프로그램이다. 링킹에는 정적 링킹과 동적 링킹의 두 가지 주요 유형이 있다. 정적 링킹은 모든 라이브러리 루틴을 실행 이미지에 복사하여 이식성이 뛰어나지만, 프로그램 크기가 커지는 단점이 있다. 동적 링킹은 프로그램 실행 시 라이브러리를 로드하여 프로그램 크기를 줄이고 라이브러리 업데이트를 용이하게 하지만, DLL 지옥과 같은 문제점이 발생할 수 있다. 링커는 링킹 과정에서 주소 해결, 파일 연결, 운영체제 고유 코드 추가 등의 작업을 수행하며, GNU ld, lld, mold, link.exe 등이 주요 링커 구현체로 사용된다.

더 읽어볼만한 페이지

  • 유틸리티 소프트웨어 종류 - 데이터 압축
    데이터 압축은 디지털 데이터의 크기를 줄여 저장 공간을 절약하고 전송 속도를 향상시키는 기술로, 모르스 부호에서 시작하여 ZIP, JPEG, LZ77 등 다양한 방식으로 발전해 왔으며, 무손실 압축과 손실 압축으로 나뉘고 최근에는 인공지능 기술을 활용하여 효율성을 높여 다양한 분야에서 활용되고 있다.
  • 유틸리티 소프트웨어 종류 - 바이러스 검사 소프트웨어
    바이러스 검사 소프트웨어는 악성 소프트웨어의 감염을 탐지, 제거 또는 차단하는 소프트웨어로, 다양한 기술을 사용하여 악성코드를 식별하고 시스템을 감시하며, V3, 노턴 안티바이러스, 알약 등 다양한 종류가 존재한다.
  • 프로그래밍 언어 구현 - 어셈블리어
    어셈블리어는 사람이 이해하기 쉬운 니모닉 기호로 기계어 명령을 표현하는 저수준 프로그래밍 언어로서, 각 프로세서마다 사양이 다른 어셈블리어가 존재하며 하드웨어 직접 제어, 성능 최적화, 저수준 시스템 프로그래밍 등에 활용된다.
  • 프로그래밍 언어 구현 - 컴파일러
    컴파일러는 고급 프로그래밍 언어로 작성된 소스 코드를 컴퓨터가 이해할 수 있는 저급 언어로 변환하는 프로그램으로, 어휘 분석, 구문 분석, 의미 분석, 최적화, 코드 생성 등의 단계를 거쳐 목적 코드를 생성하며, 네이티브 컴파일러, 크로스 컴파일러 등으로 분류되어 다양한 분야에서 활용된다.
  • 컴파일러 - 바이너리 재컴파일러
  • 컴파일러 - GNU bison
    GNU Bison은 Yacc와 호환되면서 재진입성, 다양한 언어 코드 생성, 자동 반례 생성 등의 기능을 제공하는 파서 생성기로, 여러 프로젝트에서 Yacc를 대체하여 널리 사용되고 있으며, Bison으로 생성된 코드는 GPL과 호환되는 라이선스로 배포 가능하다.
링커 (컴퓨팅)
링커 (컴퓨팅)
유형시스템 소프트웨어
범주프로그래밍 도구
목적여러 개의 오브젝트 파일을 실행 가능한 하나의 파일로 결합
관련 용어로더
라이브러리
오브젝트 파일
실행 파일
상세 정보
기능심볼 해결
재배치
입력 파일오브젝트 파일, 라이브러리
출력 파일실행 파일, 라이브러리
사용 분야소프트웨어 개발
컴파일
추가 정보
플랫폼다양한 운영체제 및 아키텍처 지원
구현GNU 링커 (ld)
Microsoft Linker
LLVM Linker (lld)
관련 기술링킹
심볼 테이블
재배치 테이블
역사
초기 링커수동적인 오버레이 로더 형태
발전자동화된 링커의 등장 및 기능 확장

2. 링킹의 종류

컴퓨터 프로그램은 일반적으로 여러 부분 또는 모듈로 구성되며, 이들은 하나의 목적 파일에 모두 포함될 필요는 없다. 이 경우, 심볼을 사용하여 다른 모듈의 주소를 참조하고, 실행을 위해 링크될 때 메모리 주소에 매핑된다. 링커는 이러한 여러 목적 파일들을 하나의 실행 가능한 프로그램으로 합치고, 라이브러리에서 필요한 오브젝트들을 가져와 연결한다.

링킹에는 크게 정적 링킹과 동적 링킹 두 가지 방식이 있다.


  • 정적 링킹: 프로그램에 필요한 모든 라이브러리 코드를 실행 파일에 포함시키는 방식이다. 동적 링킹에 비해 실행 파일의 크기가 커지지만, 외부 라이브러리에 대한 의존성이 없어 이식성이 높고 DLL 지옥 문제를 방지할 수 있다.
  • 동적 링킹: 실행 시점에 필요한 라이브러리를 연결하는 방식이다. 실행 파일의 크기가 작고, 여러 프로그램이 동일한 라이브러리를 공유할 수 있어 메모리를 절약할 수 있다. 하지만, 라이브러리 버전 호환성 문제(DLL 지옥)가 발생할 수 있다.

2. 1. 정적 링킹 (Static Linking)

정적 링킹은 링크 시 다른 객체나 라이브러리를 모두 하나의 파일로 결합하는 방법이다. 이 방법을 사용하면 완성된 프로그램은 단독으로 동작할 수 있다. 필요한 모든 라이브러리를 포함하기 때문에 완성된 프로그램은 그만큼 커진다.

정적 링킹은 링커가 프로그램에서 사용되는 모든 라이브러리 루틴을 실행 이미지에 복사하는 방식이다. 이는 동적 링킹보다 더 많은 디스크 공간과 메모리를 필요로 할 수 있지만, 실행되는 시스템에 라이브러리가 존재할 필요가 없으므로 이식성이 더 뛰어나다. 정적 링킹은 또한 각 프로그램이 필요로 하는 라이브러리 루틴의 정확한 버전을 포함하고 다른 프로그램과의 충돌이 없기 때문에 "DLL 지옥"을 방지한다. 라이브러리에서 몇 개의 루틴만 사용하는 프로그램은 전체 라이브러리를 설치할 필요가 없다.

2. 2. 동적 링킹 (Dynamic Linking)

많은 운영 체제 환경은 동적 링킹을 허용하여, 프로그램 실행 시까지 일부 정의되지 않은 심볼의 해석을 연기한다. 즉, 실행 가능한 코드는 여전히 정의되지 않은 심볼과 이러한 심볼에 대한 정의를 제공할 객체 또는 라이브러리의 목록을 포함한다. 프로그램을 로드하면 이러한 객체/라이브러리도 로드되고 최종 링킹이 수행된다. 동적 링킹은 링킹 시 라이브러리 참조를 이름만으로 해결하여 프로그램을 만드는 방법이다. 완성된 프로그램에는 라이브러리 부분의 프로그램이 포함되지 않는 것이 특징이다. 해당 프로그램 실행 시, 라이브러리 공간 상의 실제 프로그램과 결합하여 실행한다(이 작업은 통상 로더라고 불리는 프로그램이 수행한다).

이러한 접근 방식에는 두 가지 이점이 있다.

  • 자주 사용되는 라이브러리(예: 표준 시스템 라이브러리)는 모든 실행 파일에 중복 저장될 필요 없이 한 곳에만 저장되므로 제한된 메모리와 디스크 공간을 절약할 수 있다.
  • 라이브러리 함수의 버그가 라이브러리를 교체하거나 성능을 개선하여 수정된 경우, 동적으로 사용하는 모든 프로그램은 이를 다시 시작한 후 수정의 혜택을 받는다. 정적 링킹으로 이 함수를 포함한 프로그램은 먼저 다시 링킹해야 한다.


그러나 다음과 같은 단점도 존재한다.

  • Windows 플랫폼에서 "DLL 지옥"으로 알려진, 호환되지 않는 업데이트된 라이브러리는 이전 버전의 라이브러리 동작에 의존하는 실행 파일을 손상시킬 수 있다. 새 버전이 제대로 하위 호환성을 가지지 않는 경우이다.
  • 프로그램은 사용하는 라이브러리와 함께 패키지(예: 정확성, 문서 요구 사항 또는 성능)로 인증될 수 있지만, 구성 요소를 교체할 수 있는 경우에는 인증될 수 없다.


C 언어의 표준 런타임 라이브러리와 같은 범용 라이브러리는 동적 링킹하지만, 사용자 정의 라이브러리는 정적 링킹하거나, 범용 라이브러리는 정적 링킹하지만, 사용자 정의 라이브러리는 동적 링킹하거나, 둘 다 동적 링킹하거나, 둘 다 정적 링킹하는 등의 조합이 있으며, 용도에 따라 구분하여 사용하기도 한다. 완성된 프로그램의 크기가 작아지고, 프로그램을 다시 링킹하지 않아도 라이브러리만 교체할 수 있다는 등의 이점이 있어 현재 널리 사용된다.

3. 링킹 과정 (정적 링킹 기준)

컴퓨터 프로그램은 일반적으로 여러 부분 또는 모듈로 구성되며, 이들은 하나의 목적 파일 안에 있을 필요는 없다. 이 경우, 실행을 위해 링크될 때 기호(symbol)를 사용하여 다른 모듈 안의 주소를 참조한다.

일반적으로 목적 파일은 세 가지 종류의 기호를 포함할 수 있다.


  • 정의된 "외부" 기호: 다른 모듈에서 호출할 수 있도록 허용하는 기호로, "공개" 또는 "진입" 기호라고도 한다.
  • 정의되지 않은 "외부" 기호: 이 기호가 정의된 다른 모듈을 참조한다.
  • 지역 기호: 재배치를 위해 목적 파일 안에서 내부적으로 사용된다.


대부분의 컴파일러에서 각 목적 파일은 하나의 입력 소스 코드 파일을 컴파일한 결과이다. 프로그램이 여러 개의 목적 파일로 구성될 때, 링커는 이 파일들을 하나의 통합된 실행 가능한 프로그램으로 합치고, 이 과정에서 기호들을 해결(resolve)한다.

링커는 라이브러리 또는 런타임 라이브러리라고 하는 모음에서 오브젝트들을 가져올 수 있다. 대부분의 링커는 전체 라이브러리를 출력 파일에 포함시키지 않고, 다른 오브젝트 파일이나 라이브러리가 참조하는 파일들만 포함한다. 라이브러리 링킹은 반복적인 과정일 수 있으며, 참조된 모듈이 추가적인 모듈을 필요로 할 수 있다.

링커는 프로그램의 주소 공간 안의 오브젝트들을 배열하는 일도 책임진다. 이 과정에서 특정 베이스 주소를 다른 베이스로 가정하는 코드를 ''재배치''할 수 있다. 컴파일러는 오브젝트의 위치를 모르기 때문에, 보통 0과 같은 고정된 베이스 주소를 가정한다. 기계 코드를 재배치하는 것은 절대 주소로 점프하는 코드와 로드, 스토어의 목적 주소를 바꾸는 것을 포함할 수 있다.

링커가 만드는 최종 실행 파일은 (실행 직전에) 메모리에 최종적으로 올라가기 전에 또 다른 재배치 과정을 필요로 할 수 있다. 이 과정은 가상 메모리를 지원하는 하드웨어에서는 생략될 수 있다. 모든 프로그램이 자체 주소 공간에 배치되어 충돌이 발생하지 않기 때문이다. 이 과정은 위치 독립 실행 파일일 때에도 생략될 수 있다.

정적 링킹에서는 대략 다음 처리가 수행된다.

  • 파일 연결: 분할 컴파일로 인해 오브젝트 파일이 여러 개 있는 경우, 연결하여 단일 파일로 만든다.
  • 라이브러리 내 파일 연결: 라이브러리의 함수를 호출하는 경우, 라이브러리 내의 오브젝트 파일도 연결된다.
  • OS 고유 코드 추가: OS에 의해 결정된 시작 코드나 메타 정보를 추가한다.
  • 주소 해결: 소스 내에서 사용된 함수나 변수의 이름은 최종적으로 모두 메모리 주소로 대체된다. 재배치 가능한 프로그램에서는 프로그램 시작 등에서의 상대 주소가 되지만, 프로그램 전체 크기를 알기 전까지는 상대 주소를 결정할 수 없으므로, 이 처리는 링킹 시에 수행된다.

4. 동적 링킹과 로더

많은 운영 체제 환경은 동적 링킹을 허용하여, 프로그램이 실행될 때까지 일부 정의되지 않은 기호의 해결을 연기한다. 즉, 실행 코드에는 여전히 정의되지 않은 기호와 이러한 기호의 정의를 제공하는 오브젝트나 라이브러리의 목록이 포함되어 있다. 프로그램을 로드하면 이러한 오브젝트나 라이브러리도 로드되고 최종 링킹이 수행된다. 동적 링킹에는 링커가 필요 없다.

이러한 접근 방식에는 두 가지 이점이 있다.


  • 자주 사용되는 라이브러리 (예: 표준 시스템 라이브러리)는 한 위치에만 저장되어 있으며, 여러 실행 파일에 중복 저장될 필요 없이 메모리와 디스크 공간을 절약할 수 있다.
  • 라이브러리 함수의 오류가 라이브러리 파일 교체로 수정되면, 모든 프로그램은 다시 시작할 때 동적으로 이러한 수정 사항을 적용받을 수 있다. 정적 링킹으로 이 함수를 포함한 프로그램은 먼저 다시 연결해야 한다.


그러나 다음과 같은 단점도 존재한다.

  • 윈도우 플랫폼에서 비호환 업데이트 DLL로 불리는 DLL 지옥은 이전 DLL의 동작에 의존했던 실행 파일의 실행을 막을 수 있다. 새 버전이 제대로 하위 호환성을 가지지 않는 경우이다.
  • 프로그램과 라이브러리는 함께 검증이 필요할 수 있다. (정확성, 문서 요구 사항, 성능 등) 구성 요소를 교체할 수 있는 경우에는 인증될 수 없다. (이는 중요한 시스템에서 자동 OS 업데이트에도 반대되는 주장이다. 두 경우 모두 OS 및 라이브러리는 "자격 있는" 환경의 일부를 형성한다.)

5. 추가 기능

컴퓨터 프로그램은 일반적으로 여러 모듈로 구성되며, 이 모듈들은 서로 기호(symbol)를 통해 참조한다. 링커는 이러한 모듈들을 결합하고 기호를 해석하여 실행 가능한 프로그램을 만든다. 링커는 라이브러리에서 필요한 오브젝트 파일만 선택적으로 포함하며, 프로그램의 주소 공간을 배열하고 코드를 재배치하는 역할도 수행한다.

IBM System/360 메인프레임 환경에서는 링커를 ''링커 에디터''라고 부르며, 개별 프로그램 섹션을 추가, 교체, 삭제하는 기능을 제공한다. 이를 통해 프로그램 유지 보수를 효율적으로 수행할 수 있으며, 업데이트를 작은 파일 형태로 배포할 수 있다.

''링커 편집''은 링커 에디터가 다양한 조각을 재배치 가능한 바이너리로 결합하는 행위를 의미하며, 대상 주소로의 로드 및 재배치는 별도의 단계로 간주된다.

링커 제어 스크립트를 사용하여 세그먼트의 기본 주소를 정의하는 등 출력 객체 파일 생성을 제어할 수 있다.

일부 링커는 다음과 같은 추가 기능을 제공하기도 한다.


  • 증분 링크: 이전 링크에서 변경된 부분만 처리하여 링크 속도를 높이는 기능.
  • 디버거와의 연계: 실행 파일에 디버거용 보조 정보를 포함하는 기능.

6. 주요 링커 구현체

7. 링커와 관련된 문제점

컴퓨터 프로그램은 일반적으로 여러 부분 또는 모듈로 구성되며, 이러한 부분/모듈은 단일 오브젝트 파일 내에 포함될 필요가 없다. 이러한 경우 실행을 위해 연결될 때 다른 모듈의 주소를 심볼을 사용하여 서로를 참조한다. 링킹 프로세스는 이러한 독립적인 부분을 결합하기 위한 것이지만, 소스 수준에서 별도로 개발해야 하는 많은 이유가 있다. 이러한 이유 중에는 모놀리식 전체보다 여러 개의 작은 부분을 쉽게 구성할 수 있으며, 각 개별 부분의 목적과 책임을 더 잘 정의할 수 있다는 점이 있는데, 이는 복잡성을 관리하고 소프트웨어 아키텍처에서 장기적인 유지 관리를 향상시키는 데 필수적이다.

Windows 플랫폼에서 "DLL 지옥"으로 알려진, 호환되지 않는 업데이트된 라이브러리는 이전 버전의 라이브러리 동작에 의존하는 실행 파일을 손상시킬 수 있다. 새 버전이 제대로 하위 호환성을 가지지 않는 경우이다. 프로그램은 사용하는 라이브러리와 함께 패키지(예: 정확성, 문서 요구 사항 또는 성능)로 인증될 수 있지만, 구성 요소를 교체할 수 있는 경우에는 인증될 수 없다. 컨테이너화 또는 가상 환경은 시스템 관리자가 이러한 개별 장단점을 완화하거나 절충할 수 있도록 할 수 있다.

객체 파일 형식은 처리계 고유하며, 다른 처리계에서 생성된 객체 파일을 정적 링크하는 것은 일반적으로 불가능하다. 이 때문에 컴파일러와 링키지 에디터는 세트로 제공되는 경우가 많다.

참조

[1] 웹사이트 LLD - The LLVM Linker — lld 14 documentation https://lld.llvm.org[...]
[2] 웹사이트 GCC 12 Adds Support For Using The Mold Linker https://www.phoronix[...]
[3] 웹사이트 リンカ(リンケージエディタ / 連係編集プログラム)とは - 意味をわかりやすく - IT用語辞典 e-Words https://e-words.jp/w[...]
[4] 웹사이트 MSVC linker reference | Microsoft Learn https://learn.micros[...]
[5] 간행물 rui314/mold https://github.com/r[...] 2024-09-17
[6] 서적 BRF-LINKER User Manual ND-60.196.01 1984-08



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com