Programming/OS2007. 9. 30. 23:40
 ELF는 실행 가능한 바이너리 또는 오브젝트 파일 등의 형식을 규정한 것이다. ELF파일은 ELF헤더가 맨 앞에 위치하고, 프로그램 헤더 테이블과 섹션 헤더 테이블이 그 뒤에 위치한다.

오브젝트 파일에는 다음과 같은 세가지 종류의 파일이 있다.
- 재배치 가능한 파일(relocatable file)
 코드와 데이타를 다른 오브젝트 파일과 링킹될 수 있도록 함
- 실행 파일(executable file)
 코드와 데이타를 타겟 운영체제에서 실행 시킬 수 있도록 함
- 공유 오브젝트 파일(shared object file)
 재할당 가능한 데이타를 정적 혹은 동적으로 다른 공유 오브젝트들과 공유 할 수 있도록 함

사용자 삽입 이미지

elf 파일 형식을 보기 위에서는 readelf명령어를 사용한다.

1. Elf Header

$readelf -h hello                          ; ELF헤더를 보는 명령어
사용자 삽입 이미지

ELF헤더는 다음과 같은 구조를 가지고 있다.

unsigned char e_ident[EI_NIDENT];      /*Magic number and other info */
ElfN_Half          e_type;                         /*Object file type */
ElfN_Half          e_machine;                   /* Architecture */
ElfN_Word        e_version;                     /* Object file version */
ElfN_Addr         e_entry;                       /* Entry point virtual address */
ElfN_Off            e_phoff;                       /* Program header table file offset */
ElfN_Off            e_shoff;                        /* Section headr table file offset */
ElfN_Word        e_flags;                        /* Processor-specific flags */
ElfN_Half          e_ehsize;                      /* ELF header size in bytes */
ElfN_Half          e_phentsize;                 /* Program header table entry size */
ElfN_Half          e_phnum;                    /* Program header entry count */
ElfN_Half          e_shentsize;                  /* Section header table entry size */
ElfN_Half          e_shnum;                      /* Sectino header table entry count */
ElfN_Half          shstrndx;                      /* Sectino header string table index */


2. Program Header
 프로그램 헤더 테이블은 ELF헤더의 e_phoff로 지정된 오프셋에서 시작하고 e_phentsize와 e_phnum으로 정해진 크기를 갖는 테이블이다. 프로그램 헤더 테이블의 전체 크기는 e_phnum * e_phentsize 바이트이다.

$readelf -l hello                                      ; 프로그램 헤더를 보는 명령
사용자 삽입 이미지

프로그램 헤더는 다음과 같은 구조를 갖는다.

ElfN_Word    p_type;                     /* Segment type */
ElfN_Off        p_offset;                   /* Segment file offset */
ElfN_Addr     p_vaddr;                  /* Segment virtual address */
ElfN_Addr     p_paddr;                  /* Segment physical address */
ElfN_Word    p_filesz;                    /* Segment size in file */
ElfN_Word    p_memsz;                /* Segment size in memory */
ElfN_Word     p_flags;                    /* Segment flags */
ElfN_Word     p_align;                    /* Segment alignment */


타입에는 다음과 같은 것이 있다.

         p_type                             값                              설명                                     
PT_LOAD                                    1                        로드된 프로그램 세그먼트
PT_DYNAMIC                              2                         동적 링크 정보
PT_INTERP                                 3                         프로그램 인터프리터
PT_NOTE                                    4                         추가 정보
PT_SHLIB                                   5                         공유 라이브러리(?) 정보
PT_PHDR                                    6                         프로그램 헤더 테이블 자신
PT_TLS                                       7                         스레드 지역 저장소
PT_GNU_EH_FRAME            0x6474e550             GNU .eh_frame_hdr 세그먼트
PT_GNU_STACK                   0x6474e551            스택 실행 가능성(?)


3. Section Header

$ readelf -S hello                       ; 섹션 헤더 보는 명령

사용자 삽입 이미지

섹션 헤더는 다음과 같은 구조를 같는다.

ElfN_Word        sh_name;                 // 섹션 이름
ElfN_Word        sh_type;                   // 섹션 타입
ElfN_Word        sh_flags;                  // 섹션 플래그
ElfN_Addr        sh_addr;                   // 실행시 섹션 가상 주소(virtual address)
ElfN_Off           sh_offset;                 // 섹션의 오프셋 위치
ElfN_Word        sh_size;                   // 섹션의 크기
ElfN_Word        sh_link;                   // 다른 섹션으로의 링크(테이블 인덱스)
ElfN_Word        sh_info;                   // 섹션 추가 정보
ElfN_Word        sh_addralign;          // 섹션 정렬 단위
ElfN_Word        sh_entsize;              // 가지고 있는 고정크기의 entry 들의 크기
      

섹션의 종류
1) .bss
 이 섹션은 초기화 되지 않은 데이터들을 가지고 있다. 프로그램이 시작할때 여기에 있는 데이터들은 0으로 초기화 된다. 이 섹션은 파일 공간을 차지 하지 않는다.
2) .comment
 버전 정보를 포함한다.
3) .data 와 .data1
 이 섹션은 초기화된 데이터들을 가지고 있다.
4) .debug
 심볼릭 디버깅을 위한 정보를 가지고 있다.
5) .dynamic
 동적 링킹 정보를 가지고 있다.
6) .dynstr
 동적 링킹을 위한 문자열을 가지고 있다. 일반적으로 이름을 표현하는 문자열들은 심볼 테이블 항목과 관련이 있다.(?)
7) .dynsym
 동적 링킹 심볼 테이블을 가지고 있다.
8) .fini
 프로세스가 종료에 기여하는(?) 실행 가능 코드를 가지고 있다. 프로그램이 정상적으로 종료 되었을때, 시스템은 이 섹션에 있는 코드 실행을 준비한다.
9) .got
 global offet table
10) .hash
 심볼 해쉬 테이블을 가지고 있다.
11) .init
 프로그램이 초기화 할때 수행하는 실행 가능한 명령어 들이다.
12) .interp
 프로그램 해석기의 경로명을 가진다.
13) .line
 심볼 디버깅을 위한 라인넘버 정보를 가진다. 이 정보는 소스와 기계어 사이의 일치하는 부분을 설명한다.
14) .note
 "Note Section"의 형식을 가진 정보를 포함한다.
15) .plt
 프로시저의 링크 테이블을 가진다.
16) .rel"NAME" 과 .rela"NAME"
 재배치 가능 정보를 포함하는 섹션으로서 만일 파일이 재배치 정보를 가지는 적재가능한 세그먼트를 포함하고 있다면 이 섹션의 속성은 SHF_ALLOC을 가지게 될 것이다. 만일 그렇지 않으면 이 bit는 사용되지 않을 것이다.
17) .rodata 와 .rodata1
 read-only 데이터를 가진다. 쓰기 불가 세그먼트가 만들어질때 사용된다.
18) .shstrtab
 섹션들의 이름을 가진다.
19) .strtab
20) .symtab
 이 섹션에 있는 “Symbol Table”이 기술하는 것과 같은 심벌 테이블을 가지는 섹션이다. 만약 파일이 적재가능한 세그먼트를 가지고, 그 세그먼트가 심벌 테이블을 포함한다면, 섹션의 성질들은 SHF_ALLOC bit를 포함할 것이다. 그렇지 않다면 이 bit는 OFF된다.
21) .text
 "text"를 가지며, 실행 가능한 명령어를 포함한다.


 이 문서 작성 도중에 인터넷에서 한글로 된 괜찮은 elf 문서를 찾아서 첨부합니다. 이걸 먼저 찾았더라면 아마 이글을 쓰지도 않았을 텐데-_-
 
Posted by lotus

댓글을 달아 주세요

  1. 좋은 글과 자료 감사합니다^^

    2008.09.13 15:49 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 책과 인터넷 문서에 있는것을 정리한것인데 도움이 되었다니 다행입니다. :)

      2008.09.15 12:17 신고 [ ADDR : EDIT/ DEL ]
  2. 차차

    아~정말 딱 필요했던 자료네요!! 감사합니다

    2008.09.16 20:28 [ ADDR : EDIT/ DEL : REPLY ]