[CSAPP 7장 완전 정복] 7.5~7.6 심볼 테이블과 심볼 해석, 링커의 두뇌를 들여다보다

2025. 4. 17. 19:31·크래프톤 정글/컴퓨터구조(CSAPP)

심볼 테이블과 심볼 해석, 링커의 두뇌를 들여다보다

링커의 본질적인 역할은 심볼(Symbol) 을 해석하고 연결하는 일인데요. 우리가 C 코드에서 흔히 사용하는 함수 이름이나 전역 변수 이름 같은 것들은, 컴파일러가 .c 파일을 오브젝트 파일(.o)로 변환한 이후에도 여전히 주소가 확정되지 않은 심볼에 불과합니다.

 

이번 글에서는 CSAPP 7.5~7.6절 내용을 바탕으로, 심볼 테이블이 어떻게 구성되는지, 그리고 링커가 이 심볼들을 어떻게 처리해 최종 실행 파일을 만드는지 그 핵심 내용을 정리해보겠습니다.

 

 

7.5 이름과 주소를 연결하는 지도, 심볼과 심볼 테이블

오브젝트 파일(.o)에는 심볼 테이블(Symbol Table)이라는 구조가 포함되어 있는데요. 여기에는 코드와 데이터에서 등장하는 모든 심볼이 정리되어 있습니다.

 

심볼 테이블 항목 예시

항목 의미
심볼 이름 함수명, 변수명 등
섹션 이름 심볼이 속한 섹션 이름(.text, .data, .bss 등)
심볼 타입 함수, 객체 등
오프셋 해당 섹션 내 위치
바인딩 정보 local, global, weak 등

이러한 항목들의 정확한 정보는 readelf 또는 nm 명령어를 통해 확인할 수 있습니다.

# 목적 파일에 들어 있는 심볼 정보를 확인하는 두 가지 도구
readelf -s main.o    # ELF 내부 구조 기준, 상세한 심볼 테이블 출력
nm main.o            # 간단한 요약 형태로 심볼 이름과 타입만 출력

 

링커가 처리하는 심볼의 분류

구분 선언 방식 의미 링커 해석 대상 여부
global symbol 기본 (함수/전역 변수) 다른 파일에서도 참조 가능 ✔️ (해석 대상)
local symbol static이 붙은 함수/전역변수 파일 내부 전용, 외부 노출 안 됨 ❌ (무시됨)
undefined symbol extern 참조 (정의는 없음) 다른 파일에서 정의돼야 함 ✔️ (해석 대상. 따로 찾아야 함)

실제 코드로 예시를 들면 다음과 같습니다.

// a.c (예제 C 파일)
static int x = 1;      // local → 링커 해석 안 함
int y = 2;             // global → 링커 해석 대상
// b.c (예제 C 파일)
extern int y;          // undefined → a.o(a.c의 목적 파일)에서 찾음
extern int x;          // x는 static이라 a.o에서 외부 노출 불가 → 오류

책에서는 이러한 구분을 통해 "왜 어떤 심볼은 못 찾는 것인지", "왜 static으로 감추면 충돌을 막을 수 있는지" 등을 설명합니다.

 

 

7.6 누가 진짜로 정의했나, 심볼 해석(Symbol Resolution)

링커는 각 오브젝트 파일들이 가지고 있는 심볼 참조와 정의를 연결하게 되는데, 이를 심볼 해석(Symbol Resolution)이라고 합니다.

심볼 해석 기본 규칙

  • 각 전역 심볼(global symbol)은 프로그램 전체에서 단 하나만 정의할 수 있다.
  • 여러 파일에서 참조가 있더라도, 정의는 딱 한 곳에 있어야 한다.
  • 초기화된 전역 변수나 함수는 strong symbol, 초기화되지 않은 전역 변수는 weak symbol로 처리된다.
  • 링커는 여러 정의가 있을 경우 다음의 우선순위에 따라 심볼을 선택한다.
    • 우선순위 1: strong과 strong이 충돌하면 에러(multiple definition)가 발생한다.
    • 우선순위 2: strong과 weak가 함께 있으면 strong을 선택한다.
    • 우선순위 3: weak만 여러 개 있으면 임의로 하나를 선택한다. (비결정적)
  • static으로 선언된 함수나 변수는 로컬 심볼(local symbol)로 간주되어 해석 대상에서 제외된다.

예를 들어보겠습니다.

// sum.c
int sum(int x, int y) {
    return x + y;
}

// main.c
extern int sum(int, int);
int main() {
    return sum(1, 2);
}

위의 C 파일들을 컴파일하게 되면, main.o에는 sum 심볼이 참조만 있는 상태입니다. 그리고 sum.o에는 sum 심볼이 정의되어 있죠. 따라서 링커는 두 파일을 연결하면서, main.o의 sum() 참조를 sum.o의 정의와 연결합니다.

 

이때 두 C 파일 모두에서 sum을 정의하고 있다면, multiple definition 에러가 발생합니다.

 

심볼 충돌 사례

다음과 같은 C 파일 a, b가 있다고 해보겠습니다.

// a.c
int x = 3;

// b.c
int x = 5;

이를 아래 명령어를 통해 컴파일하게 되면,

gcc -c a.c  # a.o
gcc -c b.c  # b.o
gcc a.o b.o -o prog

multiple definition of 'x' 라는 오류가 발생하게 되는데요. 이는 링커가 같은 이름의 전역 심볼을 두 번 발견했기 때문에 일어나게 됩니다.

 

 

핵심 요약

  • 심볼 테이블은 함수/변수 이름의 위치 정보를 연결하는 표이다.
  • global symbol은 프로그램 전체(모든 파일)에서 공유되는 심볼이다.
  • local symbol은 해당 파일 내부에서만 유효한 심볼(static)이다.
  • 심볼 해석은 참조된 심볼과 정의된 심볼을 연결하는 링커의 핵심 작업이다.
  • 충돌 방지를 위해, 동일한 이름의 전역 심볼은 하나만 정의되어야 한다.
저작자표시 비영리 변경금지 (새창열림)

'크래프톤 정글 > 컴퓨터구조(CSAPP)' 카테고리의 다른 글

[CSAPP 7장 완전 정복] 7.10~7.11 정적 링크 vs 동적 링크, 라이브러리 연결의 두 방식  (0) 2025.04.18
[CSAPP 7장 완전 정복] 7.7~7.9 링커의 마지막 퍼즐 - 재배치, 실행 가능 목적 파일, 그리고 로딩  (0) 2025.04.18
[CSAPP 7장 완전 정복] 7.3~7.4 오브젝트 파일과 재배치 가능 오브젝트 파일  (0) 2025.04.17
[CSAPP 7장 완전 정복] 7.1~7.2 컴파일러 드라이버와 정적 링킹  (0) 2025.04.17
[CSAPP 3장 완전 정복] 3.11 부동소수점 연산은 어떻게 이루어질까?  (0) 2025.04.09
'크래프톤 정글/컴퓨터구조(CSAPP)' 카테고리의 다른 글
  • [CSAPP 7장 완전 정복] 7.10~7.11 정적 링크 vs 동적 링크, 라이브러리 연결의 두 방식
  • [CSAPP 7장 완전 정복] 7.7~7.9 링커의 마지막 퍼즐 - 재배치, 실행 가능 목적 파일, 그리고 로딩
  • [CSAPP 7장 완전 정복] 7.3~7.4 오브젝트 파일과 재배치 가능 오브젝트 파일
  • [CSAPP 7장 완전 정복] 7.1~7.2 컴파일러 드라이버와 정적 링킹
그냥사람_
그냥사람_
IT 관련 포스팅을 합니다. 크래프톤 정글 8기 정경호
  • 그냥사람_
    그냥코딩
    그냥사람_
  • 전체
    오늘
    어제
    • 글 전체보기 N
      • 크래프톤 정글
        • 로드 투 정글(입학시험)
        • CS기초(키워드, 개념정리)
        • 컴퓨터구조(CSAPP)
        • Code 정글(C언어)
        • Equipped in 정글(나만무)
        • 마이 정글(WIL, 에세이)
      • 자료구조&알고리즘
        • 자료구조
        • 알고리즘
      • Flutter N
      • 일상
  • 블로그 메뉴

    • 홈
  • 링크

    • Github
  • hELLO· Designed By정상우.v4.10.3
그냥사람_
[CSAPP 7장 완전 정복] 7.5~7.6 심볼 테이블과 심볼 해석, 링커의 두뇌를 들여다보다
상단으로

티스토리툴바