C
Object file..
GunwooYun
2025. 1. 14. 00:10
C 소스 파일을 컴파일하면 object 파일 (*.o) 가 생성된다. 보통은 -c 옵션을 생략하기도 하고, Makefile에서 생성되긴 하지만 별 관심없이 그냥 넘어가곤 한다. 갑자기 object 파일 안에는 무슨 내용이 있을까 궁금해져서 역시나 형님께 여쭤봤다.
먼저, 아래 캡쳐 그림은 object 파일들을 각각 다른 컴파일러로 컴파일한 내용이다. 첫번째 그림은 gcc 로 컴파일한 결과이다.
아래 그림은 arm-none-eabi 컴파일러로 object를 생성한 결과이다.
C 소스 코드를 컴파일하여 생성된 **Object 파일(객체 파일)**에는 컴파일된 바이너리 코드와 함께 프로그램 실행에 필요한 다양한 메타데이터가 포함됩니다. Object 파일은 기계어 코드로 변환된 **섹션(section)**과 심볼(symbol) 정보를 포함하며, 이 정보는 링크 단계에서 사용됩니다.
Object 파일의 구성 요소
1. 헤더(Header)
- Object 파일의 기본 정보를 포함.
- 파일 형식(예: ELF, COFF, PE), 아키텍처, 엔디안, 버전 정보 등을 정의.
헤더에 포함된 정보:
- 파일 타입: 실행 파일, 재배치 가능 파일(Object 파일), 공유 라이브러리 등.
- 아키텍처: 타겟 CPU(예: x86, ARM).
- 엔디안: Little-endian 또는 Big-endian.
- 섹션 오프셋: 각 섹션의 시작 위치.
2. 섹션(Sections)
Object 파일은 여러 섹션으로 나뉘며, 각각 특정 유형의 데이터를 포함합니다.
주요 섹션:
- .text
- 기계어 코드(실제 실행되는 코드)를 포함.
- 읽기 전용.
- 예: 함수의 기계어 명령어.
- .data
- 초기화된 전역 및 정적 변수를 포함.
- 읽기 및 쓰기 가능.
- 예: int x = 10;
- .bss
- 초기화되지 않은 전역 및 정적 변수를 포함.
- 파일 크기를 줄이기 위해, 메모리에서만 초기화됨(값은 0으로 초기화).
- 예: int y;
- .rodata
- 읽기 전용 데이터(예: 상수, 문자열 리터럴)를 포함.
- 예: const char *str = "Hello";
- .rel.text / .rela.text
- 재배치 정보. 링크 시 동적으로 주소를 수정하기 위해 사용.
- .symtab
- 심볼 테이블. 함수, 변수, 객체 등의 심볼 정보를 포함.
- .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 파일의 링크 과정
- 개별 Object 파일 생성:
- 소스 파일을 컴파일하여 각각의 Object 파일 생성.
- 링커(Linker):
- 여러 Object 파일과 라이브러리를 결합하여 실행 파일 생성.
- 재배치 정보를 사용하여 심볼을 올바르게 연결.
- 실행 파일 생성:
- 최종적으로 실행 가능한 바이너리 파일 생성.
결론
Object 파일은 다음과 같은 요소로 구성됩니다:
- 헤더: 파일 정보.
- 섹션: .text, .data, .bss 등 프로그램 데이터.
- 심볼 테이블: 함수와 변수의 이름 및 위치 정보.
- 재배치 정보: 링크 시 주소 수정에 필요한 정보.
Object 파일은 컴파일된 코드와 프로그램 실행에 필요한 메타데이터를 포함하여, 링커가 실행 파일을 생성하는 데 필요한 중요한 역할을 합니다.