---
# System prepended metadata

title: ELF Header
tags: [ELF-Format]

---

# ELF Header

이 글은 [wikipedia](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)를 참고하여 작성하였다.

![image](https://hackmd.io/_uploads/Hy5oa2jZ-l.png)

ELF의 헤더에 대해서 알아보자.

## /usr/include/elf.h
일단 ELF Header에 해당하는 구조체는 아래와 같다.
```cpp
typedef struct
{
  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
  Elf64_Half	e_type;			/* Object file type */
  Elf64_Half	e_machine;		/* Architecture */
  Elf64_Word	e_version;		/* Object file version */
  Elf64_Addr	e_entry;		/* Entry point virtual address */
  Elf64_Off	e_phoff;		/* Program header table file offset */
  Elf64_Off	e_shoff;		/* Section header table file offset */
  Elf64_Word	e_flags;		/* Processor-specific flags */
  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
  Elf64_Half	e_phentsize;		/* Program header table entry size */
  Elf64_Half	e_phnum;		/* Program header table entry count */
  Elf64_Half	e_shentsize;		/* Section header table entry size */
  Elf64_Half	e_shnum;		/* Section header table entry count */
  Elf64_Half	e_shstrndx;		/* Section header string table index */
} Elf64_Ehdr;
```
## Explanation

**ELF Header**는 ELF 파일의 맨 앞에 있는 구조로, 이 파일이 어떤 형태(32/64비트, 엔디언), 어떤 아키텍처용인지, 엔트리 포인트가 어디인지, 프로그램·섹션 헤더들이 파일 안에서 어디에 있는지 등을 정의하는 부분이다.
:::info
32-bit와 64bit는 `/`로 구분하였다.
:::
| Offset | Size | Field | Purpose |
| ------ | ---- | ----- | ------- |
| 0x0 | 4 | e_ident[EI_MAG0..3] | ELF 파일의 Magic number. ELF 파일 형식을 식별하는데 사용된다. |
| 0x4 | 1 | e_ident[EI_CLASS] | 0x1이면 32bit, 0x2이면 64bit를 나타낸다. | 
| 0x5 | 1 | e_ident[EI_DATA] | Little endian(0x1)인지, Big endian(0x2)인지를 나타낸다. |
| 0x6 | 1 | e_ident[EI_VERSION] | ELF 포맷 버전이다. 현재 값은 1. |
| 0x7 | 1 | e_ident[EI_OSABI] | 대상 운영체제의 ABI를 식별한다.\*(ABI 표 참조) |
| 0x8 | 1 | e_ident[EI_ABIVERSION] | ABI 버전 또는 특성 수준을 더 구체적으로 나타낸다. |
| 0x9 | 7 | e_ident[EI_PAD] | 현재 사용되지 않는다. 예약된 패딩 바이트를 의미한다. 값은 0 |
| 0x10 | 2 | e_type | 개체 파일 유형을 식별한다.\*(e_type 표 참조) |
| 0x12 | 2 | e_machine | 대상 명령어 집합(ISA)을 지정한다(예: x86, ARM, RISC-V 등). |
| 0x14 | 4 | e_version | 객체 파일 버전. 일반적으로 1로 설정된다. |
| 0x18 | 4 / 8 | e_entry | 프로그램 entry point의 VA(Virtual Address) |
| 0x1C / 0x20 | 4 / 8 | e_phoff | 프로그램 헤더 테이블을 가리킨다. | 
| 0x20 / 0x28 | 4 / 8 | e_shoff | 섹션 헤더 테이블을 가리킨다. |
| 0x24 / 0x30 | 4 | e_flags | 아키텍처별로 정의되는 플래그 필드 |
| 0x28 / 0x34 | 2 | e_ehsize | ELF 헤더 전체 크기 | 
| 0x2A / 0x36 | 2 | e_phentsize | 프로그램 헤더 테이블 엔트리 하나의 크기 |
| 0x2C / 0x38 | 2 | e_phnum | 프로그램 헤더 테이블에 포함된 엔트리 개수 |
| 0x2E / 0x3A | 2 | e_shentsize | 섹션 헤더 테이블 엔트리 하나의 크기 |
| 0x30 / 0x3C | 2 | e_shnum | 섹션 헤더 테이블에 포함된 섹션 헤더 엔트리 개수 | 
| 0x32 / 0x3E | 2 | e_shstrndx | 섹션 이름 문자열 테이블을 담고 있는 섹션 헤더의 인덱스 |
| 0x34 / 0x40 | - | - | ELF Header의 끝 |

### \* ABI표.
| Value | ABI |
| ---- | --- |
| 0x00 | [System V](https://en.wikipedia.org/wiki/UNIX_System_V) |
| 0x01 | [HP-UX](https://en.wikipedia.org/wiki/HP-UX) |
| 0x02 | [NetBSD](https://en.wikipedia.org/wiki/NetBSD) |
| 0x03 | [Linux](https://en.wikipedia.org/wiki/Linux) |
| 0x04 | [GNU Hurd](https://en.wikipedia.org/wiki/GNU_Hurd) |
| 0x06 | [Solaris](https://en.wikipedia.org/wiki/Oracle_Solaris)
| 0x07 | [AIX](https://en.wikipedia.org/wiki/IBM_AIX) (Monterey)
| 0x08 | [IRIX](https://en.wikipedia.org/wiki/IRIX)
| 0x09 | [FreeBSD](https://en.wikipedia.org/wiki/FreeBSD)
| 0x0A | [Tru64](https://en.wikipedia.org/wiki/Tru64)
| 0x0B | Novell Modesto
| 0x0C | [OpenBSD](https://en.wikipedia.org/wiki/OpenBSD)
| 0x0D | [OpenVMS](https://en.wikipedia.org/wiki/OpenVMS)
| 0x0E | [NonStop Kernel](https://en.wikipedia.org/wiki/NonStop_(server_computers))
| 0x0F | [AROS](https://en.wikipedia.org/wiki/AROS_Research_Operating_System)
| 0x10 | FenixOS
| 0x11 | Nuxi [CloudABI](https://en.wikipedia.org/wiki/CloudABI)
| 0x12 | [Stratus Technologies OpenVOS](https://en.wikipedia.org/wiki/Stratus_VOS)

### \* e_type표.
| Value | Type | Meaning |
| ----- | ---- | ------- |
| 0x00 | ET_NONE | Unknown |
| 0x01 | ET_REL | Relocatable file. |
| 0x02 | ET_EXEC | Executable file. |
| 0x03 | ET_DYN | Shared object. |
| 0x04 | ET_CORE | Core file. |
| 0xFE00 | ET_LOOS | Reserved inclusive range. Operating system specific. |
| 0xFEFF | ET_HIOS | Reserved inclusive range. Operating system specific. |
| 0xFF00 | ET_LOPROC | Reserved inclusive range. Processor specific. |
| 0xFFFF | ET_HIPROC | Reserved inclusive range. Processor specific. |


## Example Hexdump
다음은 예시 ELF 64-bit Header이다.
```shell
➜  Hello_World readelf -h main
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x78b0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          3971992 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         14
  Size of section headers:           64 (bytes)
  Number of section headers:         40
  Section header string table index: 39
```
```=
00000000  7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00  |.ELF............|
00000010  03 00 3E 00 01 00 00 00 B0 78 00 00 00 00 00 00  |..>.....°x......|
00000020  40 00 00 00 00 00 00 00 98 9B 3C 00 00 00 00 00  |@.......˜›<.....|
00000030  00 00 00 00 40 00 38 00 0E 00 40 00 28 00 27 00  |....@.8...@.(.'.|

0x00  7F 45 4C 46              | Magic
0x04  02                       | Class
0x05  01                       | Data
0x06  01                       | Version
0x07  00                       | OS/ABI
0x08  00                       | ABI Version
0x09  00 00 00 00 00 00 00     | Pad
0x10  03 00                    | Type
0x12  3E 00                    | Machine
0x14  01 00 00 00              | Version
0x18  B0 78 00 00 00 00 00 00  | Entry
0x20  40 00 00 00 00 00 00 00  | e_phoff
0x28  98 9B 3C 00 00 00 00 00  | e_shoff
0x30  00 00 00 00              | e_flags
0x34  40 00                    | e_ehsize
0x36  38 00                    | e_phentsize
0x38  0E 00                    | e_phnum
0x3A  40 00                    | e_shentsize
0x3C  28 00                    | e_shnum
0x3E  27 00                    | e_shstrndx
```
