오브젝트 파일들은 세가지로 분류될 수 있다.
재배치 가능한 오브젝트 파일(Relocatable object file). 이것은 바이너리 코드와 데이터를 가지고 있으며, 실행가능한 오브젝트 파일을 만들기 위해 컴파일-타임때 재배치 가능한 다른 오브젝트 파일들과 결합될 수 있는 것을 가리킨다.
실행가능한 오브젝트 파일(Executable object file). 이것은 바이너리 코드와 데이터를 가지고 있으며, 메모리로 직접 로드되어 실행될 수 있는 것을 가리킨다.
공유 오브젝트 파일(Shared object file). 이것은 재배치 가능한 오브젝트 파일의 특별한 타입으로, 로드-타임이나 런-타임때 동적으로 메모리로 로드되고 링킹될 수 있는 것을 가리킨다.
컴파일러와 어셈블러는 재배치 가능한 오브젝트 파일을 생성한다(공유 오브젝트 파일도 또한 생성한다). 링커는 이러한 오브젝트 파일들을 합쳐 실행가능한 오브젝트 파일들을 생성한다.
오브젝트 파일들은 시스템에 따라 그 형식이 틀리다. 최초의 유닉스 시스템은 a.out 포맷을 사용하였다. System V의 초기 버전에서는 COFF(Common object file format)라는 것을 사용하였고, 윈도우즈 NT는 COFF의 변형인 PE(portable executable)라는 형식을 사용한다; IBM은 독자적인 IBM 360 형식을 사용한다. 리눅스와 솔라리스와 같은 현대적인 유닉스 시스템들은 유닉스 ELF(executable and linking format)포맷을 사용한다. 이 문서는 주로 ELF에 대해 다룬다.
표 1. 전형적인 재배치 가능한 ELF 오브젝트 파일의 형식
ELF Header |
.text |
.rodata |
.data |
.bss |
.symtab |
.rel.text |
.rel.data |
.debug |
.line |
.strtab |
ELF 헤더는 4-byte magic문자열(177ELF)로 시작한다. ELF 재배치 가능한 오브젝트 파일의 각 구간의 의미는 아래와 같다.
.text, 컴파일된 코드의 머신 코드가 들어있다.
.rodata, read-only 데이터가 들어있다, printf문의 문자열등이 이에 해당한다.
.data, 초기화된 전역 변수들이 들어있다.
.bss, 초기화되지 않은 전역 변수들이 들어있다. BSS는 block storage start의 이니셜이고, 이 구간은 실제적으로 오브젝트 파일에서 공간을 차지하지 않고 단지 공간을 확보하는 역할만 한다.
.symtab, 프로그램에서 정의된 전역 변수들과 함수들에 대한 참조 정보를 가지고 있다. 이 테이블은 지역 변수에 대한 것은 담고 있지 않다; 지역 변수들은 스택에 의해 유지된다.
.rel.text, .text에 들어있는 각 머신 코드의 위치를 나타낸다. 이것들은 나중에 링커가 이 오브젝트 파일을 다른 오브젝트 파일들과 연결시킬때 필요하다.
.rel.data, 현재의 파일에서는 정의되어 있지 않지만 참조되는 전역 변수에 대한 재배치 정보를 담고 있다.
.debug, 지역, 전역 변수들에 대한 디버깅 심볼들이 들어있다. 이 구간은 컴파일러가 -g 옵션과 함께 수행될 때 생성된다.
.line, .text에 들어있는 머신 코드와 실제 C 코드의 라인 넘버에 대한 메핑 정보가 들어있다. 디버거 프로그램이 이 정보를 필요로 한다.
.strtab, .symtab, .debug 구간에 있는 심볼 테이블에 들어있는 스트링들에 대한 테이블이다.