C 소스 파일을 컴파일하면 object 파일 (*.o) 가 생성된다. 보통은 -c 옵션을 생략하기도 하고, Makefile에서 생성되긴 하지만 별 관심없이 그냥 넘어가곤 한다. 갑자기 object 파일 안에는 무슨 내용이 있을까 궁금해져서 역시나 형님께 여쭤봤다.

먼저, 아래 캡쳐 그림은 object 파일들을 각각 다른 컴파일러로 컴파일한 내용이다. 첫번째 그림은 gcc 로 컴파일한 결과이다.

gcc

 

아래 그림은 arm-none-eabi 컴파일러로 object를 생성한 결과이다.

arm-none-eabi

 

C 소스 코드를 컴파일하여 생성된 **Object 파일(객체 파일)**에는 컴파일된 바이너리 코드와 함께 프로그램 실행에 필요한 다양한 메타데이터가 포함됩니다. Object 파일은 기계어 코드로 변환된 **섹션(section)**과 심볼(symbol) 정보를 포함하며, 이 정보는 링크 단계에서 사용됩니다.


Object 파일의 구성 요소

1. 헤더(Header)

  • Object 파일의 기본 정보를 포함.
  • 파일 형식(예: ELF, COFF, PE), 아키텍처, 엔디안, 버전 정보 등을 정의.

헤더에 포함된 정보:

  • 파일 타입: 실행 파일, 재배치 가능 파일(Object 파일), 공유 라이브러리 등.
  • 아키텍처: 타겟 CPU(예: x86, ARM).
  • 엔디안: Little-endian 또는 Big-endian.
  • 섹션 오프셋: 각 섹션의 시작 위치.

2. 섹션(Sections)

Object 파일은 여러 섹션으로 나뉘며, 각각 특정 유형의 데이터를 포함합니다.

주요 섹션:

  1. .text
    • 기계어 코드(실제 실행되는 코드)를 포함.
    • 읽기 전용.
    • 예: 함수의 기계어 명령어.
  2. .data
    • 초기화된 전역 및 정적 변수를 포함.
    • 읽기 및 쓰기 가능.
    • 예: int x = 10;
  3. .bss
    • 초기화되지 않은 전역 및 정적 변수를 포함.
    • 파일 크기를 줄이기 위해, 메모리에서만 초기화됨(값은 0으로 초기화).
    • 예: int y;
  4. .rodata
    • 읽기 전용 데이터(예: 상수, 문자열 리터럴)를 포함.
    • 예: const char *str = "Hello";
  5. .rel.text / .rela.text
    • 재배치 정보. 링크 시 동적으로 주소를 수정하기 위해 사용.
  6. .symtab
    • 심볼 테이블. 함수, 변수, 객체 등의 심볼 정보를 포함.
  7. .strtab
    • 심볼 이름을 저장하는 문자열 테이블.

3. 심볼 테이블(Symbol Table)

  • Object 파일에 정의된 함수 및 변수의 이름과 위치 정보를 포함.
  • 각 심볼에는 다음과 같은 정보가 포함됩니다:
    • 이름: 변수나 함수의 이름.
    • 섹션: 심볼이 속한 섹션(예: .text, .data).
    • 주소: 심볼의 시작 주소.
    • 유형: 함수, 변수, 재배치 심볼 등.

4. 재배치 정보(Relocation Entries)

  • Object 파일의 주소를 재배치하는 데 필요한 정보.
  • 링크 시, 다른 오브젝트 파일이나 라이브러리의 주소와 결합하여 올바른 실행 파일을 생성.

주요 항목:

  • 심볼 참조: 외부 또는 내부 심볼 참조.
  • 오프셋: 수정해야 할 메모리 주소.
  • 재배치 유형: 수정 방법(절대 주소, 상대 주소 등).

5. 디버그 정보(선택적)

  • 디버깅 도구(GDB 등)에서 사용되는 추가 정보.
  • 컴파일 시 -g 옵션을 활성화하면 생성.
  • 주요 구성:
    • 소스 코드와 바이너리 코드 간의 매핑 정보.
    • 함수 이름, 변수 이름, 파일 라인 번호 등.

Object 파일의 실제 예시

1. 컴파일

다음 C 코드를 gcc -c example.c 명령으로 컴파일하면 Object 파일이 생성됩니다.

// example.c
#include <stdio.h>

int x = 10;
const char *message = "Hello, World!";

void printMessage() {
    printf("%s\n", message);
}

2. Object 파일 분석

readelf 명령어를 사용하여 Object 파일을 분석할 수 있습니다.

헤더 정보:

$ readelf -h example.o
ELF Header:
  Class:                             ELF32
  Data:                              2's complement, little endian
  Type:                              REL (Relocatable file)
  Machine:                           ARM

섹션 정보:

$ readelf -S example.o
Section Headers:
  [Nr] Name              Type             Address          Offset
  [ 0] .text             PROGBITS         00000000         0x0000
  [ 1] .data             PROGBITS         00000000         0x0040
  [ 2] .bss              NOBITS           00000000         0x0050
  [ 3] .rodata           PROGBITS         00000000         0x0060
  [ 4] .symtab           SYMTAB           00000000         0x0080
  [ 5] .strtab           STRTAB           00000000         0x00c0

Object 파일의 링크 과정

  1. 개별 Object 파일 생성:
    • 소스 파일을 컴파일하여 각각의 Object 파일 생성.
  2. 링커(Linker):
    • 여러 Object 파일과 라이브러리를 결합하여 실행 파일 생성.
    • 재배치 정보를 사용하여 심볼을 올바르게 연결.
  3. 실행 파일 생성:
    • 최종적으로 실행 가능한 바이너리 파일 생성.

결론

Object 파일은 다음과 같은 요소로 구성됩니다:

  • 헤더: 파일 정보.
  • 섹션: .text, .data, .bss 등 프로그램 데이터.
  • 심볼 테이블: 함수와 변수의 이름 및 위치 정보.
  • 재배치 정보: 링크 시 주소 수정에 필요한 정보.

Object 파일은 컴파일된 코드와 프로그램 실행에 필요한 메타데이터를 포함하여, 링커가 실행 파일을 생성하는 데 필요한 중요한 역할을 합니다. 

'C' 카테고리의 다른 글

길이가 0인 배열  (0) 2025.04.15
나만의 assert 만들기  (0) 2025.04.14
세그먼트  (0) 2023.04.13
Why is the number of array elements smaller than minus value?  (0) 2023.04.06
array length as parameter  (0) 2022.11.09

+ Recent posts