ELF Relocations (AArch64)

 

ELF Relocations (AArch64)

ELF 규격의 실행 파일 또는 링커블 오브젝트 파일에서 수행하는 리로케이션 작업을 알아본다.

  • 컴파일 타임
    • static 선언된 함수들과 변수들은 컴파일 타임에 주소가 결정되므로 이들 주소에 대해 리로케이션 엔트리를 생성하지 않는다.
    • static 선언하지 않은 함수들과 변수들은 컴파일 타임에 주소를 결정하지 않아 리로케이션 엔트리를 .rela 섹션에 만들어 둔다.
  • 링크 타임
    • 스태틱 링킹 vs 다이나믹 링킹
      • 오브젝트 파일 및 외부 라이브러를 포함하여 스태틱 링킹을 수행할 때 재배치(relocations) 작업을 링커가 할 수가 있다.
      • 사용자의 요청에 따라 일부분은 로딩 타임에 다이나믹 링킹을 수행할 때 재배치(relocations) 작업을 하도록 결정할 수 있다.
    • 다이나믹 링킹을 할 외부 공유 라이브러리 심볼들에 대해서는 리로케이션 엔트리를 .rela 섹션에 만들어 둔다.
    • .got 섹션에 점프할 주소 영역을 만들어두고, .plt 섹션에 .got 테이블의 대응하는 해당 주소값을 알아와서 branch하는 코드를 생성한다.
  • 로딩 타임(다이나믹 링킹)
    • 외부 공유 라이브러리를 다이나믹 링크한 경우 호출할 주소가 결정되지 않았다. 이들을 위해 .rela 섹션에 만들어진 리로케이션 엔트리를 대상으로 호출할 공유 라이브러리의 각 함수 주소들을 결정하여 메모리에서 갱신한다.
    • got 섹션의 got 테이블에 사용할 공유 라이브러리의 심볼 주소가 갱신된다.

 

.rela 섹션

리로케이션 엔트리들은 .rela 섹션에 위치한다.

 

다음 그림은 링크 타임과 로드 타임에 .rela.* 섹션에 위치한 리로케이션 엔트리를 사용하여 주소 갱신을 수행하는 모습을 보여준다.

 

리로케이션 엔트리 구조

ELF32 규격의 경우 12 바이트 엔트리를 사용한다.

glibc/elf/elf.h – ELF32

typedef struct {
        Elf32_Addr r_offset;
        uint32_t   r_info;
        int32_t    r_addend;
} Elf32_Rela;
  • r_offset
    • 리로케이션할 offset 주소를 담는다.
  • r_info
    • 상위 3 바이트에 심볼 인덱스와 하위 1 바이트에 리로케이션 타입을 담는다.
    • 심볼 인덱스가 0인 경우 null 인덱스라고 한다.
  • r_addend
    • 리로케이션 타입에 따라 수행시 추가되어야 할 값을 담는다.

 

32비트 ELF 파일의 경우 4 바이트의 info 필드에서 상위 3 바이트를 심볼 인덱스가 사용하고, 나머지 하위 1 바이트를 타입으로 사용한다.

 

ELF64 규격의 경우 24 바이트 엔트리를 사용한다.

glibc/elf/elf.h – ELF64

typedef struct {
        Elf64_Addr r_offset;
        uint64_t   r_info;
        int64_t    r_addend;
} Elf64_Rela;
  • r_offset
    • 리로케이션할 offset 주소를 담는다.
  • r_info
    • 상위 4 바이트에 심볼 인덱스와 하위 4 바이트에 리로케이션 타입을 담는다.
    • 심볼 인덱스가 0인 경우 null 인덱스라고 한다.
  • r_addend
    • 리로케이션 타입에 따라 수행시 추가되어야 할 값을 담는다.

 

64비트 ELF 파일의 경우 8 바이트의 info 필드에서 상위 4 바이트를 심볼 인덱스가 사용하고, 나머지 하위 4 바이트를 타입으로 사용한다.

 

C 언어 데이타 타입 모델

GCC 및 Linux는 C 언어 데이터 타입 모델에서 64 비트 시스템은 LP64 모델을 사용하고, 32 비트 시스템은 ILP32를 사용한다.

 

리로케이션 기호 표기법

리로케이션 동작에 대한 기호 표시는 다음과 같다.

  • S
    • 심볼 주소
  • A
    • Addend 값
  • P
    • 리로케이트될 장소의 주소
  • X
    • 리로케이션 동작의 결과
  • Page(expr)
    • 페이지 단위의 주소로 하위 12비트가 0으로 클리어된다.
  • GOT
    • Global Offset Table로 다이나믹 링크(로드) 타임에 갱신된다.
  • GDAT(S+A)
    • GOT 내 64비트 엔트리가 S+A 로 동작한다.
  • G(expr)
    • GOT 내 64비트 엔트리 주소
  • Delta(S)
    • 스태틱 링크 타임에 결정된 프로그램 시작 주소와 실행 타임에 변경된 프로그램 시작 주소의 차이(Delta)를 기존 심볼 주소에 더해 반영한다.
      • S + delta
  • _NC
    • None Checking 리로케이션 타입으로 오버플로우 체크를 수행하지 않는다.

 

리로케이션 타입

ELF format for AArch64에서 사용하는 리로케이션 엔트리 타입들 다음과 같이 많은 종류가 있다.

glibc/elf/elf.h

/* ILP32 AArch64 relocs.  */
#define R_AARCH64_P32_ABS32                      1 /* Direct 32 bit.  */
#define R_AARCH64_P32_COPY                     180 /* Copy symbol at runtime.  */
#define R_AARCH64_P32_GLOB_DAT                 181 /* Create GOT entry.  */
#define R_AARCH64_P32_JUMP_SLOT                182 /* Create PLT entry.  */
#define R_AARCH64_P32_RELATIVE                 183 /* Adjust by program base.  */
#define R_AARCH64_P32_TLS_DTPMOD               184 /* Module number, 32 bit.  */
#define R_AARCH64_P32_TLS_DTPREL               185 /* Module-relative offset, 32 bit.  */
#define R_AARCH64_P32_TLS_TPREL                186 /* TP-relative offset, 32 bit.  */
#define R_AARCH64_P32_TLSDESC                  187 /* TLS Descriptor.  */
#define R_AARCH64_P32_IRELATIVE                188 /* STT_GNU_IFUNC relocation. */

 

/* LP64 AArch64 relocs.   */
/* 1. Static Data relocs. */
#define R_AARCH64_ABS64                        257 /* Direct 64 bit. */
#define R_AARCH64_ABS32                        258 /* Direct 32 bit.  */
#define R_AARCH64_ABS16                        259 /* Direct 16-bit.  */
#define R_AARCH64_PREL64                       260 /* PC-relative 64-bit.  */
#define R_AARCH64_PREL32                       261 /* PC-relative 32-bit.  */
#define R_AARCH64_PREL16                       262 /* PC-relative 16-bit.  */
#define R_AARCH64_MOVW_UABS_G0                 263 /* Dir. MOVZ imm. from bits 15:0.  */햬

GOT-relative 데이터 리로케이션 타입들이다.

  •  R_AARCH64_ABS64
    • 데이터 리로케이션 타입으로 S + A와 같이 동작한다.
  • R_AARCH64_ABS32
    • 데이터 리로케이션 타입으로 S + A와 같이 동작한다. 단 2^32 범위 내에서 사용되어야 한다.
  • R_AARCH64_PREL32
    • 데이터 리로케이션 타입으로 S + A – P와 같이 동작한다. 단 2^32 범위 내에서 사용되어야 한다.

 

/* 2. Static AArch64 relocs. */
/* 1) Group relocations to create a 16-, 32-, 48-, or 64-bit unsigned data value or address inline */
#define R_AARCH64_MOVW_UABS_G0_NC              264 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_UABS_G1                 265 /* Dir. MOVZ imm. from bits 31:16.  */
#define R_AARCH64_MOVW_UABS_G1_NC              266 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_UABS_G2                 267 /* Dir. MOVZ imm. from bits 47:32.  */
#define R_AARCH64_MOVW_UABS_G2_NC              268 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_UABS_G3                 269 /* Dir. MOV{K,Z} imm. from 63:48.  */

 

/* 2) Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */
#define R_AARCH64_MOVW_SABS_G0                 270 /* Dir. MOV{N,Z} imm. from 15:0. */
#define R_AARCH64_MOVW_SABS_G1                 271 /* Dir. MOV{N,Z} imm. from 31:16.  */
#define R_AARCH64_MOVW_SABS_G2                 272 /* Dir. MOV{N,Z} imm. from 47:32.  */

 

/* 3) Relocations to generate 19, 21 and 33 bit PC-relative addresses */
#define R_AARCH64_LD_PREL_LO19                 273 /* PC-rel. LD imm. from bits 20:2.  */
#define R_AARCH64_ADR_PREL_LO21                274 /* PC-rel. ADR imm. from bits 20:0.  */
#define R_AARCH64_ADR_PREL_PG_HI21             275 /* Page-rel. ADRP imm. from 32:12.  */
#define R_AARCH64_ADR_PREL_PG_HI21_NC          276 /* Likewise; no overflow check.  */
#define R_AARCH64_ADD_ABS_LO12_NC              277 /* Dir. ADD imm. from bits 11:0.  */
#define R_AARCH64_LDST8_ABS_LO12_NC            278 /* Likewise for LD/ST; no check. */
  • R_AARCH64_ADR_PREL_PG_HI21
    • Page(S + A) – Page(P)
    • ADRP 명령을 사용하여 4K 페이지 단위의 PC 기반 relative offset 주소(범위는 +-4GB)를 참조한다. 이 값을 4K로 나누어 hi21 필드에 사용한다.
      • 예) adrp x0, var1
      • C 예) value = *ptr; object 파일 내부의 포인터 변수 참조
  • R_AARCH64_ADD_ABS_LO12_NC
    • S + A
    • ADD 명령을 사용하여 PC 기반 relative offset 주소의 하위 12비트 절대 주소를 참조한다. 이 값은 lo12 필드에 사용한다.
      • 예) add x0, var1
      • C 예) value = *ptr; object 파일 내부의 포인터 변수 참조

 

/* 4) Relocations for control-flow instructions - all offsets are a multiple of 4 */
#define R_AARCH64_TSTBR14                      279 /* PC-rel. TBZ/TBNZ imm. from 15:2.  */
#define R_AARCH64_CONDBR19                     280 /* PC-rel. cond. br. imm. from 20:2. */
#define R_AARCH64_JUMP26                       282 /* PC-rel. B imm. from bits 27:2.  */
#define R_AARCH64_CALL26                       283 /* Likewise for CALL.  */
  • R_AARCH64_JUMP26
    • S + A – P
      • PC + relative offset 주소(범위는 +-128MB)를 참조한다. 이 값을 4로 나누어 imm26 필드에 사용한다.
  • R_AARCH64_CALL26
    • PC + relative offset 주소(범위는 +-128MB)를 참조한다. 이 값을 4로 나누어 imm26 필드에 사용한다.
      • 예) bl sub1     <- .globl 선언 함수
      • C 예) sub1(); <- static 선언하지 않은 함수

 

/* 3)에 포함 */
#define R_AARCH64_LDST16_ABS_LO12_NC           284 /* Dir. ADD imm. from bits 11:1.  */
#define R_AARCH64_LDST32_ABS_LO12_NC           285 /* Likewise for bits 11:2.  */
#define R_AARCH64_LDST64_ABS_LO12_NC           286 /* Likewise for bits 11:3.  */
  • R_AARCH64_LDST64_ABS_LO12_NC
    • S + A
    • 주소를 LD/ST 명령의 상수 값을 imm9 필드에 사용한다.

 

/* 5) Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */
#define R_AARCH64_MOVW_PREL_G0                 287 /* PC-rel. MOV{N,Z} imm. from 15:0.  */
#define R_AARCH64_MOVW_PREL_G0_NC              288 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_PREL_G1                 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */
#define R_AARCH64_MOVW_PREL_G1_NC              290 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_PREL_G2                 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */
#define R_AARCH64_MOVW_PREL_G2_NC              292 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_PREL_G3                 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */
#define R_AARCH64_LDST128_ABS_LO12_NC          299 /* Dir. ADD imm. from bits 11:4. */ 

 

/* 6) Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */
#define R_AARCH64_MOVW_GOTOFF_G0               300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */
#define R_AARCH64_MOVW_GOTOFF_G0_NC            301 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_GOTOFF_G1               302 /* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
#define R_AARCH64_MOVW_GOTOFF_G1_NC            303 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_GOTOFF_G2               304 /* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
#define R_AARCH64_MOVW_GOTOFF_G2_NC            305 /* Likewise for MOVK; no check.  */
#define R_AARCH64_MOVW_GOTOFF_G3               306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */

 

/* 7) GOT-relative data relocations */
#define R_AARCH64_GOTREL64                     307 /* GOT-relative 64-bit.  */
#define R_AARCH64_GOTREL32                     308 /* GOT-relative 32-bit. */

 

/* 8) GOT-relative instruction relocations */
#define R_AARCH64_GOT_LD_PREL19                309 /* PC-rel. GOT off. load imm. 20:2.  */
#define R_AARCH64_LD64_GOTOFF_LO15             310 /* GOT-rel. off. LD/ST imm. 14:3.  */
#define R_AARCH64_ADR_GOT_PAGE                 311 /* P-page-rel. GOT off. ADRP 32:12.  */
#define R_AARCH64_LD64_GOT_LO12_NC             312 /* Dir. GOT off. LD/ST imm. 11:3.  */
#define R_AARCH64_LD64_GOTPAGE_LO15            313 /* GOT-page-rel. GOT off. LD/ST 14:3 */
  • R_AARCH64_ADR_GOT_PAGE
    • Page(G(GDAT(S + A))) – Page(P)
    • 오브젝트 파일 외부 주소를 참조하기 위해 GOT 엔트리에 대해 R_AARCH64_ADR_PREL_PG_HI21 타입과 동일하게 동작한다.
      • 예0 adrp x0, var2 (extern)
      • C 예) value = *ptr; (extern)
  • R_AARCH64_LD64_GOT_LO12_NC
    • G(GDAT(S + A))
    • 오브젝트 파일 외부 주소를 참조하기 위해 GOT 엔트리에 대해 R_AARCH64_ADD_ABS_LO12_NC타입과 동일하게 동작한다.
      • 예) add x0, var1 (extern)
      • C 예) value = *ptr; (extern)

 

/* 3. Relocations for thread-local storage */
/* 1) General Dynamic TLS relocations      */
#define R_AARCH64_TLSGD_ADR_PREL21             512 /* PC-relative ADR imm. 20:0.  */
#define R_AARCH64_TLSGD_ADR_PAGE21             513 /* page-rel. ADRP imm. 32:12.  */
#define R_AARCH64_TLSGD_ADD_LO12_NC            514 /* direct ADD imm. from 11:0.  */
#define R_AARCH64_TLSGD_MOVW_G1                515 /* GOT-rel. MOV{N,Z} 31:16.  */
#define R_AARCH64_TLSGD_MOVW_G0_NC             516 /* GOT-rel. MOVK imm. 15:0.  */

 

/* 2) Local Dynamic TLS relocations */
#define R_AARCH64_TLSLD_ADR_PREL21             517 /* Like 512; local dynamic model.  */
#define R_AARCH64_TLSLD_ADR_PAGE21             518 /* Like 513; local dynamic model.  */
#define R_AARCH64_TLSLD_ADD_LO12_NC            519 /* Like 514; local dynamic model.  */
#define R_AARCH64_TLSLD_MOVW_G1                520 /* Like 515; local dynamic model.  */
#define R_AARCH64_TLSLD_MOVW_G0_NC             521 /* Like 516; local dynamic model.  */
#define R_AARCH64_TLSLD_LD_PREL19              522 /* TLS PC-rel. load imm. 20:2.  */
#define R_AARCH64_TLSLD_MOVW_DTPREL_G2         523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
#define R_AARCH64_TLSLD_MOVW_DTPREL_G1         524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC      525 /* Likewise; MOVK; no check.  */
#define R_AARCH64_TLSLD_MOVW_DTPREL_G0         526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC      527 /* Likewise; MOVK; no check.  */
#define R_AARCH64_TLSLD_ADD_DTPREL_HI12        528 /* DTP-rel. ADD imm. from 23:12. */
#define R_AARCH64_TLSLD_ADD_DTPREL_LO12        529 /* DTP-rel. ADD imm. from 11:0.  */
#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC     530 /* Likewise; no ovfl. check.  */
#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12      531 /* DTP-rel. LD/ST imm. 11:0.  */
#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC   532 /* Likewise; no check.  */
#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12     533 /* DTP-rel. LD/ST imm. 11:1.  */
#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC  534 /* Likewise; no check.  */
#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12     535 /* DTP-rel. LD/ST imm. 11:2.  */
#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC  536 /* Likewise; no check.  */
#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12     537 /* DTP-rel. LD/ST imm. 11:3.  */
#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC  538 /* Likewise; no check.  */

 

/* 3) Initial Exec TLS relocations */
#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1       539 /* GOT-rel. MOV{N,Z} 31:16.  */
#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC    540 /* GOT-rel. MOVK 15:0.  */
#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21    541 /* Page-rel. ADRP 32:12.  */
#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC  542 /* Direct LD off. 11:3.  */
#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19     543 /* PC-rel. load imm. 20:2.  */

 

/* 4) Local Exec TLS relocations */ 
#define R_AARCH64_TLSLE_MOVW_TPREL_G2          544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
#define R_AARCH64_TLSLE_MOVW_TPREL_G1          545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC       546 /* Likewise; MOVK; no check.  */
#define R_AARCH64_TLSLE_MOVW_TPREL_G0          547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC       548 /* Likewise; MOVK; no check.  */
#define R_AARCH64_TLSLE_ADD_TPREL_HI12         549 /* TP-rel. ADD imm. 23:12.  */
#define R_AARCH64_TLSLE_ADD_TPREL_LO12         550 /* TP-rel. ADD imm. 11:0.  */
#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC      551 /* Likewise; no ovfl. check.  */
#define R_AARCH64_TLSLE_LDST8_TPREL_LO12       552 /* TP-rel. LD/ST off. 11:0.  */
#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC    553 /* Likewise; no ovfl. check. */
#define R_AARCH64_TLSLE_LDST16_TPREL_LO12      554 /* TP-rel. LD/ST off. 11:1.  */
#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC   555 /* Likewise; no check.  */
#define R_AARCH64_TLSLE_LDST32_TPREL_LO12      556 /* TP-rel. LD/ST off. 11:2.  */
#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC   557 /* Likewise; no check.  */
#define R_AARCH64_TLSLE_LDST64_TPREL_LO12      558 /* TP-rel. LD/ST off. 11:3.  */
#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC   559 /* Likewise; no check.  */

 

/* 5) TLS descriptor relocations */
#define R_AARCH64_TLSDESC_LD_PREL19            560 /* PC-rel. load immediate 20:2.  */
#define R_AARCH64_TLSDESC_ADR_PREL21           561 /* PC-rel. ADR immediate 20:0.  */
#define R_AARCH64_TLSDESC_ADR_PAGE21           562 /* Page-rel. ADRP imm. 32:12.  */
#define R_AARCH64_TLSDESC_LD64_LO12            563 /* Direct LD off. from 11:3.  */
#define R_AARCH64_TLSDESC_ADD_LO12             564 /* Direct ADD imm. from 11:0.  */
#define R_AARCH64_TLSDESC_OFF_G1               565 /* GOT-rel. MOV{N,Z} imm. 31:16.  */
#define R_AARCH64_TLSDESC_OFF_G0_NC            566 /* GOT-rel. MOVK imm. 15:0; no ck.  */
#define R_AARCH64_TLSDESC_LDR                  567 /* Relax LDR.  */
#define R_AARCH64_TLSDESC_ADD                  568 /* Relax ADD.  */
#define R_AARCH64_TLSDESC_CALL                 569 /* Relax BLR.  */

 

/* 2)에 포함 */
#define R_AARCH64_TLSLE_LDST128_TPREL_LO12     570 /* TP-rel. LD/ST off. 11:4.  */
#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC  571 /* Likewise; no check.  */

 

/* 4)에 포함 */
#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12    572 /* DTP-rel. LD/ST imm. 11:4. */
#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */

 

/* 4. Dynamic relocs. */
#define R_AARCH64_COPY                        1024 /* Copy symbol at runtime.  */
#define R_AARCH64_GLOB_DAT                    1025 /* Create GOT entry.  */
#define R_AARCH64_JUMP_SLOT                   1026 /* Create PLT entry.  */
#define R_AARCH64_RELATIVE                    1027 /* Adjust by program base.  */
#define R_AARCH64_TLS_DTPMOD                  1028 /* Module number, 64 bit.  */
#define R_AARCH64_TLS_DTPREL                  1029 /* Module-relative offset, 64 bit.  */
#define R_AARCH64_TLS_TPREL                   1030 /* TP-relative offset, 64 bit.  */
#define R_AARCH64_TLSDESC                     1031 /* TLS Descriptor.  */
#define R_AARCH64_IRELATIVE                   1032 /* STT_GNU_IFUNC relocation.  */

런타임에 다이나믹 리로케이션시 사용되는 리로케이션 타입들이다.

  •  R_AARCH64_GLOB_DAT
    • GOT 엔트리를 생성한다.
    • S + A
  • R_AARCH64_JUMP_SLOT
    • PLT 엔트리를 생성한다.
    • S + A
  • R_AARCH64_RELATIVE
    • 스태틱 링크 타임에 결정한 주소와 다이나믹 링크 타임에 결정한 주소가 달라지면 그 차이만큼을 더해서 갱신해야 하는 경우 사용된다.
    • 프로그램 로딩 후 시작 주소가 달라지면 변경되어야 하는 항목에 사용된다.
    • Delta(S) + A
      • = S + Delta + A
    • 리눅스 커널 이미지
      • 보안을 위해 리눅스 커널 이미지가 매핑되는 가상 주소가 랜덤하게 달라질 수 있다. 이러한 경우 커널에서 외부로 export 된 심볼들의 주소들도 바뀌어야 한다. 이들을 지원하기 위해 커널 역시 특별한 리로케이션 엔트리가 준비되어 있다. 이들 타입에 해당하는 모든 주소들을 바뀐 가상 주소 offset을 더해 변경한다.

 

PLT(Program Linkage Table)

PLT 엔트리는 실행 파일의 바깥쪽 멀리 있는 목적지 주소로 브랜치(long-branch)하기 위한 코드가 구현된다.

  • 일반적으로 목적지의 이름은 알고 있지만, 주소는 모르는 경우 이를 imported symbol이라고 불리운다.
  • PLT 엔트리는 일반적으로 GOT 엔트리로 부터 목적지 주소를 읽어오도록 구현한다.

 

GOT(Global Object Table)

GOT 엔트리는 다이나믹 링크 타임에 갱신되는 8 바이트 주소가 담긴다.

  • SysV-based Dynamic Shared Objects (DSOs), 즉 공유 라이브러리 함수들에 대한 접근은 프로그램이 로딩되어 다이나믹 링크 타임에 목적지 주소를 알 수 있게된다.

 

PLT(Program Linkage Table) 및 GOT(Global Object Table) 연동

실행 파일이 로딩되어 다이나믹 링크가 수행될 때 사용할 공유 라이브러리의 심볼 주소를 .got 섹션의 got 테이블에 갱신한다. 이 주소는 실행 코드 -> PLT 엔트리 코드가 -> GOT 엔트리에 있는 주소를 통해 long-branch 할 수 있게 한다.

  • .text 섹션에 위치한 printf() 호출 코드는 bl <label> 형태의 어셈블리 코드를 통해 +-128M 범위내에 위치한 .plt 섹션에 생성된 코드를 호출한다.
  • .plt 섹션에 위치한 코드는 .got 섹션에 있는 8 바이트 주소를 읽어와서 br <Xd> 형태의 어셈블리 코드를 통해 범위 제한 없이 호출할 수 있다.
  • .got 섹션에 위치한 8 바이트 주소는 실행 파일을 로딩하고 다이나믹 링크가 수행될 때 사용할 공유 라이브러리의 심볼 주소로 갱신된다.

 

Relocatable vs PIC(Position Independent Code)

  • Relocatable
    • 링킹 타임에 스태틱 링킹에 의해 실행 주소 및 각 심볼들에 대한 주소가 결정되어 재배치한다.
    • 로딩 타임에 다이나믹 링킹에 실행 주소의 변경 또는 사용하는 외부 공유 라이브러리의 심볼 주소들에 주소가 결정되어 재배치한다.
  • PIC
    • 링커에 의해 실행된 주소가 의미가 없어 어느 공간에든 위치할 수 있도록 코드를 구성하게 한다.
    • 공유 라이브러리를 빌드하는 경우에도 일반적으로 -fPIC 옵션을 사용하여야 한다.

 


샘플 C 소스

main.c에서 몇 개의 주소를 참조한다.

  • 내부의 var1 변수 주소를 참조한다.
  • 외부 파일 sub.c에 존재하는 함수 sub1()과 변수 var2 주소를 참조한다.
  • 외부 공유 라이브러리에 있는 출력 함수 printf() 주소를 참조한다.

main.c

#include <stdio.h>

extern int sub1();
extern int var2;

int var1 = 10;
void main()
{
        sub1();
        printf("hello. var1=%d, var2=%d\n", var1, var2);
}

 

sub.c 파일에서는 아무 조소도 참조하지 않게 하였다.

sub.c

int var2 = 20;

int sub1()
{
        return 1;
}

 

main.c 파일을 컴파일한 후 main.o 파일의 섹션을 알아본다.

  • 코드 내에서 주소들을 참조하므로 .rela.text 섹션이 생성된 것을 확인할 수 있다.
$ gcc -c main.c
$ readelf -S main.o
There are 11 section headers, starting at offset 0x398:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       000000000000003c  0000000000000000  AX       0     0     4
  [ 2] .rela.text        RELA             0000000000000000  00000280
       00000000000000c0  0000000000000018   I       8     1     8
  [ 3] .data             PROGBITS         0000000000000000  0000007c
       0000000000000004  0000000000000000  WA       0     0     4
  [ 4] .bss              NOBITS           0000000000000000  00000080
       0000000000000000  0000000000000000  WA       0     0     1
  [ 5] .rodata           PROGBITS         0000000000000000  00000080
       0000000000000019  0000000000000000   A       0     0     8
  [ 6] .comment          PROGBITS         0000000000000000  00000099
       0000000000000031  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000ca
       0000000000000000  0000000000000000           0     0     1
  [ 8] .symtab           SYMTAB           0000000000000000  000000d0
       0000000000000180  0000000000000018           9    11     8
  [ 9] .strtab           STRTAB           0000000000000000  00000250
       0000000000000029  0000000000000000           0     0     1
  [10] .shstrtab         STRTAB           0000000000000000  00000340
       0000000000000052  0000000000000000           0     0     1

 

sub.c 파일을 컴파일한 후 sub.o 파일의 섹션을 알아본다.

  • 코드 내에서 하나의 주소 참조도 없어 .rela.text 섹션이 생성되지 않은 것을 확인할 수 있다.
$ gcc -c main.c
$ readelf -S sub.o
There are 9 section headers, starting at offset 0x1e8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000008  0000000000000000  AX       0     0     4
  [ 2] .data             PROGBITS         0000000000000000  00000048
       0000000000000004  0000000000000000  WA       0     0     4
  [ 3] .bss              NOBITS           0000000000000000  0000004c
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .comment          PROGBITS         0000000000000000  0000004c
       0000000000000031  0000000000000001  MS       0     0     1
  [ 5] .note.GNU-stack   PROGBITS         0000000000000000  0000007d
       0000000000000000  0000000000000000           0     0     1
  [ 6] .symtab           SYMTAB           0000000000000000  00000080
       0000000000000108  0000000000000018           7     9     8
  [ 7] .strtab           STRTAB           0000000000000000  00000188
       0000000000000017  0000000000000000           0     0     1
  [ 8] .shstrtab         STRTAB           0000000000000000  0000019f
       0000000000000045  0000000000000000           0     0     1

 

test 실행 파일의 섹션을 알아본다.

  • .rela.dyn 및 .rela.plt 섹션이 생성되었음을 확인한다.
  • 또한 새롭게 추가된 .plt 및 .got 섹션을 확인한다.
$ strip test; readelf -S test
There are 25 section headers, starting at offset 0x1128:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000000200  00000200
       000000000000001b  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             000000000000021c  0000021c
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             000000000000023c  0000023c
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000000260  00000260
       000000000000001c  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           0000000000000280  00000280
       00000000000000f0  0000000000000018   A       6     3     8
  [ 6] .dynstr           STRTAB           0000000000000370  00000370
       0000000000000089  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           00000000000003fa  000003fa
       0000000000000014  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000000410  00000410
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000000430  00000430
       0000000000000108  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000000538  00000538
       0000000000000078  0000000000000018  AI       5    20     8
  [11] .init             PROGBITS         00000000000005b0  000005b0
       0000000000000014  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         00000000000005d0  000005d0
       0000000000000070  0000000000000010  AX       0     0     16
  [13] .text             PROGBITS         0000000000000640  00000640
       00000000000001cc  0000000000000000  AX       0     0     8
  [14] .fini             PROGBITS         000000000000080c  0000080c
       0000000000000010  0000000000000000  AX       0     0     4
  [15] .rodata           PROGBITS         0000000000000820  00000820
       0000000000000021  0000000000000000   A       0     0     8
  [16] .eh_frame         PROGBITS         0000000000000844  00000844
       0000000000000004  0000000000000000   A       0     0     4
  [17] .init_array       INIT_ARRAY       0000000000010d78  00000d78
       0000000000000008  0000000000000008  WA       0     0     8
  [18] .fini_array       FINI_ARRAY       0000000000010d80  00000d80
       0000000000000008  0000000000000008  WA       0     0     8
  [19] .dynamic          DYNAMIC          0000000000010d88  00000d88
       00000000000001f0  0000000000000010  WA       6     0     8
  [20] .got              PROGBITS         0000000000010f78  00000f78
       0000000000000088  0000000000000008  WA       0     0     8
  [21] .data             PROGBITS         0000000000011000  00001000
       0000000000000018  0000000000000000  WA       0     0     8
  [22] .bss              NOBITS           0000000000011018  00001018
       0000000000000008  0000000000000000  WA       0     0     1
  [23] .comment          PROGBITS         0000000000000000  00001018
       0000000000000030  0000000000000001  MS       0     0     1
  [24] .shstrtab         STRTAB           0000000000000000  00001048
       00000000000000dc  0000000000000000           0     0     1

 

리로케이션 덤프 분석

 

main.o 파일에 대한 디스어셈블 코드

아래 주황색 및 파란색 부분은 주소를 참조하는 부분이며 링커를 사용하지 않은 상태이므로 엔코딩된 명령문에서 주소에 관련된 필드가 0인 상태로 아직 완성되지 않았다.

$ objdump -d -D main.o

main.o:     file format elf64-littleaarch64

Disassembly of section .text:

0000000000000000 <main>:
   0:   a9bf7bfd        stp     x29, x30, [sp, #-16]!
   4:   910003fd        mov     x29, sp
   8:   94000000        bl      0 <sub1>           ; sub1() 호출
   c:   90000000        adrp    x0, 0 <main>       ; va1 값
  10:   91000000        add     x0, x0, #0x0
  14:   b9400001        ldr     w1, [x0]
  18:   90000000        adrp    x0, 0 <var2>       ; var2 값
  1c:   f9400000        ldr     x0, [x0]
  20:   b9400002        ldr     w2, [x0]
  24:   90000000        adrp    x0, 0 <main>       ; const 문자열
  28:   91000000        add     x0, x0, #0x0
  2c:   94000000        bl      0 <printf>         ; printf() 호출
  30:   d503201f        nop
  34:   a8c17bfd        ldp     x29, x30, [sp], #16
  38:   d65f03c0        ret

Disassembly of section .data:

0000000000000000 <var1>:
   0:   0000000a        .word   0x0000000a

Disassembly of section .rodata:

 

main.o 파일의 리로케이션 엔트리

.text 섹션내에서 총 8개의 리로케이션 엔트리가 사용됨을 알 수 있다. 이들은 링크 타임에서 주소 갱신을 위해 활용된다.

  • .rodata 영역에는 const 문자열이 포함되어 있다.
$ objdump -r main.o

main.o:     file format elf64-littleaarch64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE                           VALUE
0000000000000008 R_AARCH64_CALL26               sub1
000000000000000c R_AARCH64_ADR_PREL_PG_HI21     var1
0000000000000010 R_AARCH64_ADD_ABS_LO12_NC      var1
0000000000000018 R_AARCH64_ADR_GOT_PAGE         var2
000000000000001c R_AARCH64_LD64_GOT_LO12_NC     var2
0000000000000024 R_AARCH64_ADR_PREL_PG_HI21     .rodata
0000000000000028 R_AARCH64_ADD_ABS_LO12_NC      .rodata
000000000000002c R_AARCH64_CALL26               printf

 

test 실행 파일의 리로케이션 엔트리

.rela.dyn 및 .rela.plt 섹션에서 총 16개의 주소 참조가 발생하였다.

  • 이 엔트리들은 런타임에 외부 공유 라이브러리 등과 연결될 때 주소 갱신을 위해 사용된다.
$ gcc main.c sub.c; strip test; readelf -r test

Relocation section '.rela.dyn' at offset 0x430 contains 11 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000010d78  000000000403 R_AARCH64_RELATIV                    740
000000010d80  000000000403 R_AARCH64_RELATIV                    6f8
000000010fc0  000000000403 R_AARCH64_RELATIV                    808
000000010fd0  000000000403 R_AARCH64_RELATIV                    11014
000000010fe8  000000000403 R_AARCH64_RELATIV                    788
000000010ff0  000000000403 R_AARCH64_RELATIV                    744
000000011008  000000000403 R_AARCH64_RELATIV                    11008
000000010fc8  000300000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_deregisterTMClone + 0
000000010fd8  000400000401 R_AARCH64_GLOB_DA 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0
000000010fe0  000600000401 R_AARCH64_GLOB_DA 0000000000000000 __gmon_start__ + 0
000000010ff8  000800000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_registerTMCloneTa + 0

Relocation section '.rela.plt' at offset 0x538 contains 5 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000010f90  000400000402 R_AARCH64_JUMP_SL 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0
000000010f98  000500000402 R_AARCH64_JUMP_SL 0000000000000000 __libc_start_main@GLIBC_2.17 + 0
000000010fa0  000600000402 R_AARCH64_JUMP_SL 0000000000000000 __gmon_start__ + 0
000000010fa8  000700000402 R_AARCH64_JUMP_SL 0000000000000000 abort@GLIBC_2.17 + 0
000000010fb0  000900000402 R_AARCH64_JUMP_SL 0000000000000000 printf@GLIBC_2.17 + 0

 

main 실행 파일 로드 전의 디스어셈블 코드

아래 파란색상의 글씨는 링크 프로세스를 수행한 후에 갱신된 부분이다.

Disassembly of section .text:

0000000000000744 <main>:
 744:   a9bf7bfd        stp     x29, x30, [sp, #-16]!
 748:   910003fd        mov     x29, sp
 74c:   9400000d        bl      780 <sub1>                         ; R_AARCH64_CALL26               sub1
 750:   b0000080        adrp    x0, 11000 <__data_start>           ; R_AARCH64_ADR_PREL_PG_HI21     var1
 754:   91004000        add     x0, x0, #0x10                      ; R_AARCH64_ADD_ABS_LO12_NC      var1
 758:   b9400001        ldr     w1, [x0]
 75c:   90000080        adrp    x0, 10000 <__FRAME_END__+0xf7bc>   ; R_AARCH64_ADR_GOT_PAGE         var2
 760:   f947e800        ldr     x0, [x0, #4048]                    ; R_AARCH64_LD64_GOT_LO12_NC     var2
 764:   b9400002        ldr     w2, [x0]
 768:   90000000        adrp    x0, 0 <_init-0x5b0>                ; R_AARCH64_ADR_PREL_PG_HI21     .rodata
 76c:   9120a000        add     x0, x0, #0x828                     ; R_AARCH64_ADD_ABS_LO12_NC      .rodata
 770:   97ffffb0        bl      630 <printf@plt>                   ; R_AARCH64_CALL26               printf
 774:   d503201f        nop
 778:   a8c17bfd        ldp     x29, x30, [sp], #16
 77c:   d65f03c0        ret

 

다음 .plt 섹션에는 런타임에 외부 공유 라이브러리와의 연결에 사용되는 .got 섹션의 엔트리들을 가리키도록 코드가 생성된다.

  • 실행파일내의 모든 printf() 호출 부분은 printf@plt 레이블에 생성된 코드를 통한다.
$ objdump -d -D test
Disassembly of section .plt:

(...생략...)

0000000000000620 <abort@plt>:
(...생략...)

0000000000000630 <printf@plt>:
 630:   90000090        adrp    x16, 10000 <printf@plt+0xf9d0>
 634:   f947da11        ldr     x17, [x16, #4016]
 638:   913ec210        add     x16, x16, #0xfb0
 63c:   d61f0220        br      x17

외부 공유 라이브러리에 존재하는 printf() 함수를 호출한다.

  • .got 섹션에 있는 .got 엔트리중 0x10fb0 offset 주소에 담긴 외부 printf() 주소를 x17에 알아온 후 이 루틴을 호출한다.

 

다음 .got 섹션에는 외부 공유 라이브러리와 함수 또는 변수의 절대 주소를 담고 있다.

  • 아래 값은 실행파일이 로드될 때 주 메모리에서만 엔트리가 갱신된다.
Disassembly of section .got:

0000000000010f78 <.got>:
        ...
   10fb0:       000005d0        .inst   0x000005d0 ; undefined
   10fb4:       00000000        .inst   0x00000000 ; undefined

 

main 실행 파일 로드 후의 디스어셈블 코드

다음은 실행 파일을 로드한 후 동작하기 직전의 디스어셈블 코드이다.

  • 모든 offset 로드된 가상 주소로 변경되었다.
  • got 엔트리의 printf() 함수에 대한 주소가 0x7ff7ec49a0로 변경되어 있음을 알 수 있다.
Disassembly of section .plt:

0x0000005555555630 <printf@plt>:
   0x0000005555555630 <+0>:     adrp    x16, 0x5555565000
   0x0000005555555634 <+4>:     ldr     x17, [x16, #4016]
   0x0000005555555638 <+8>:     add     x16, x16, #0xfb0
   0x000000555555563c <+12>:    br      x17


Disassembly of section .text:

0x0000005555555744 <main>:
   0x0000005555555744 <+0>:     stp     x29, x30, [sp, #-16]!
   0x0000005555555748 <+4>:     mov     x29, sp
   0x000000555555574c <+8>:     bl      0x5555555780 <sub1>
   0x0000005555555750 <+12>:    adrp    x0, 0x5555566000
   0x0000005555555754 <+16>:    add     x0, x0, #0x10
   0x0000005555555758 <+20>:    ldr     w1, [x0]
   0x000000555555575c <+24>:    adrp    x0, 0x5555565000
   0x0000005555555760 <+28>:    ldr     x0, [x0, #4048]
   0x0000005555555764 <+32>:    ldr     w2, [x0]
   0x0000005555555768 <+36>:    adrp    x0, 0x5555555000
   0x000000555555576c <+40>:    add     x0, x0, #0x828
   0x0000005555555770 <+44>:    bl      0x5555555630 <printf@plt>
   0x0000005555555774 <+48>:    nop
   0x0000005555555778 <+52>:    ldp     x29, x30, [sp], #16
   0x000000555555577c <+56>:    ret


Disassembly of section .got:

0x0000005555565f78 <.got>:
        ...
   0x0000005555565fb0:       0xf7ec49a0        .inst   0xf7ec49a0  
   0x0000005555565fb8:       0x0000007f        .inst   0x0000007f 
        ...

 

 


head.o 주소 참조부 ELF 분석

 

다음은 커널의 어셈블리 파트 시작을 담당하는 head.S를 어셈블한 파일의 섹션들을 살펴본다.

$ readelf -S head.o
There are 29 section headers, starting at offset 0x22350:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000000  0000000000000000  AX       0     0     1
  [ 2] .data             PROGBITS         0000000000000000  00000040
       0000000000000000  0000000000000000  WA       0     0     1
  [ 3] .bss              NOBITS           0000000000000000  00000040
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .head.text        PROGBITS         0000000000000000  00010000
       0000000000010000  0000000000000000  AX       0     0     65536
  [ 5] .rela.head.text   RELA             0000000000000000  00021720
       0000000000000180  0000000000000018   I      26     4     8
  [ 6] .init.text        PROGBITS         0000000000000000  00020000
       00000000000003a8  0000000000000000  AX       0     0     4
  [ 7] .rela.init.text   RELA             0000000000000000  000218a0
       00000000000004e0  0000000000000018   I      26     6     8
  [ 8] .rodata           PROGBITS         0000000000000000  000203a8
       0000000000000008  0000000000000000   A       0     0     1
  [ 9] .rela.rodata      RELA             0000000000000000  00021d80
       0000000000000018  0000000000000018   I      26     8     8
  [10] ___ksymtab+kimage PROGBITS         0000000000000000  000203b0
       000000000000000c  0000000000000000   A       0     0     4
  [11] .rela___ksymtab+k RELA             0000000000000000  00021d98
       0000000000000030  0000000000000018   I      26    10     8
  [12] __ksymtab_strings PROGBITS         0000000000000000  000203bc
       000000000000000d  0000000000000001 AMS       0     0     1
  [13] .idmap.text       PROGBITS         0000000000000000  000203d0
       0000000000000340  0000000000000000 WAX       0     0     8
  [14] .rela.idmap.text  RELA             0000000000000000  00021dc8
       00000000000002b8  0000000000000018   I      26    13     8
  [15] .mmuoff.data.writ PROGBITS         0000000000000000  00020710
       0000000000000010  0000000000000000  WA       0     0     1
  [16] .debug_line       PROGBITS         0000000000000000  00020720
       000000000000019b  0000000000000000           0     0     1
  [17] .rela.debug_line  RELA             0000000000000000  00022080
       0000000000000048  0000000000000018   I      26    16     8
  [18] .debug_info       PROGBITS         0000000000000000  000208bb
       0000000000000022  0000000000000000           0     0     1
  [19] .rela.debug_info  RELA             0000000000000000  000220c8
       0000000000000090  0000000000000018   I      26    18     8
  [20] .debug_abbrev     PROGBITS         0000000000000000  000208dd
       0000000000000012  0000000000000000           0     0     1
  [21] .debug_aranges    PROGBITS         0000000000000000  000208f0
       0000000000000050  0000000000000000           0     0     16
  [22] .rela.debug_arang RELA             0000000000000000  00022158
       0000000000000060  0000000000000018   I      26    21     8
  [23] .debug_str        PROGBITS         0000000000000000  00020940
       0000000000000040  0000000000000001  MS       0     0     1
  [24] .debug_ranges     PROGBITS         0000000000000000  00020980
       0000000000000050  0000000000000000           0     0     16
  [25] .rela.debug_range RELA             0000000000000000  000221b8
       0000000000000090  0000000000000018   I      26    24     8
  [26] .symtab           SYMTAB           0000000000000000  000209d0
       0000000000000900  0000000000000018          27    48     8
  [27] .strtab           STRTAB           0000000000000000  000212d0
       0000000000000450  0000000000000000           0     0     1
  [28] .shstrtab         STRTAB           0000000000000000  00022248
       0000000000000108  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

 

head.S에서 주소 참조된 엔트리들을 살펴본다.

$ objdump -r head.o

head.o:     file format elf64-littleaarch64

RELOCATION RECORDS FOR [.head.text]:
OFFSET           TYPE              VALUE
0000000000000004 R_AARCH64_JUMP26  primary_entry
0000000000000010 R_AARCH64_ABS32   _kernel_size_le_lo32
0000000000000014 R_AARCH64_ABS32   _kernel_size_le_hi32
0000000000000018 R_AARCH64_ABS32   _kernel_flags_le_lo32
000000000000001c R_AARCH64_ABS32   _kernel_flags_le_hi32
000000000000005c R_AARCH64_PREL32  __initdata_begin-0x000000000000ffa4
0000000000000060 R_AARCH64_ABS32   __pecoff_data_size
0000000000000068 R_AARCH64_PREL32  __efistub_efi_pe_entry+0x0000000000000068
000000000000007c R_AARCH64_ABS32   PECOFF_FILE_ALIGNMENT
0000000000000090 R_AARCH64_PREL32  _end+0x0000000000000090
0000000000000100 R_AARCH64_PREL32  __initdata_begin-0x000000000000ff00
0000000000000108 R_AARCH64_PREL32  __initdata_begin-0x000000000000fef8
0000000000000128 R_AARCH64_ABS32   __pecoff_data_size
000000000000012c R_AARCH64_PREL32  __initdata_begin+0x000000000000012c
0000000000000130 R_AARCH64_ABS32   __pecoff_data_rawsize
0000000000000134 R_AARCH64_PREL32  __initdata_begin+0x0000000000000134


RELOCATION RECORDS FOR [.init.text]:
OFFSET           TYPE              VALUE
0000000000000004 R_AARCH64_CALL26  el2_setup
0000000000000008 R_AARCH64_ADR_PREL_PG_HI21  _text
0000000000000010 R_AARCH64_CALL26  .idmap.text+0x0000000000000180
0000000000000018 R_AARCH64_CALL26  __cpu_setup
000000000000001c R_AARCH64_JUMP26  .idmap.text+0x0000000000000310
0000000000000024 R_AARCH64_ADR_PREL_PG_HI21  boot_args
0000000000000028 R_AARCH64_ADD_ABS_LO12_NC  boot_args
000000000000003c R_AARCH64_JUMP26  __inval_dcache_area
0000000000000044 R_AARCH64_ADR_PREL_PG_HI21  init_pg_dir
0000000000000048 R_AARCH64_ADR_PREL_PG_HI21  init_pg_end
0000000000000050 R_AARCH64_CALL26  __inval_dcache_area
0000000000000054 R_AARCH64_ADR_PREL_PG_HI21  init_pg_dir
0000000000000058 R_AARCH64_ADR_PREL_PG_HI21  init_pg_end
000000000000007c R_AARCH64_ADR_PREL_PG_HI21  idmap_pg_dir
0000000000000080 R_AARCH64_ADR_PREL_PG_HI21  __idmap_text_start
0000000000000088 R_AARCH64_ADR_PREL_PG_HI21  vabits_actual
000000000000008c R_AARCH64_ADD_ABS_LO12_NC  vabits_actual
000000000000009c R_AARCH64_ADR_PREL_PG_HI21  __idmap_text_end
00000000000000ac R_AARCH64_ADR_PREL_PG_HI21  idmap_t0sz
00000000000000b0 R_AARCH64_ADD_ABS_LO12_NC  idmap_t0sz
00000000000000c4 R_AARCH64_ADR_PREL_PG_HI21  idmap_ptrs_per_pgd
00000000000000c8 R_AARCH64_LDST64_ABS_LO12_NC  idmap_ptrs_per_pgd
00000000000000cc R_AARCH64_ADR_PREL_PG_HI21  idmap_ptrs_per_pgd
00000000000000d0 R_AARCH64_LDST64_ABS_LO12_NC  idmap_ptrs_per_pgd
00000000000000d8 R_AARCH64_ADR_PREL_PG_HI21  __idmap_text_end
00000000000000dc R_AARCH64_ADD_ABS_LO12_NC  __idmap_text_end
00000000000001e0 R_AARCH64_ADR_PREL_PG_HI21  init_pg_dir
00000000000001f8 R_AARCH64_ADR_PREL_PG_HI21  _end
00000000000001fc R_AARCH64_ADR_PREL_PG_HI21  _text
000000000000030c R_AARCH64_ADR_PREL_PG_HI21  idmap_pg_dir
0000000000000310 R_AARCH64_ADR_PREL_PG_HI21  idmap_pg_end
0000000000000318 R_AARCH64_CALL26  __inval_dcache_area
000000000000031c R_AARCH64_ADR_PREL_PG_HI21  init_pg_dir
0000000000000320 R_AARCH64_ADR_PREL_PG_HI21  init_pg_end
0000000000000328 R_AARCH64_CALL26  __inval_dcache_area
0000000000000330 R_AARCH64_ADR_PREL_PG_HI21  init_thread_union
0000000000000338 R_AARCH64_ADR_PREL_PG_HI21  init_task
000000000000033c R_AARCH64_ADD_ABS_LO12_NC  init_task
0000000000000344 R_AARCH64_ADR_PREL_PG_HI21  vectors
0000000000000348 R_AARCH64_ADD_ABS_LO12_NC  vectors
000000000000035c R_AARCH64_ADR_PREL_PG_HI21  __fdt_pointer
0000000000000360 R_AARCH64_LDST64_ABS_LO12_NC  __fdt_pointer
0000000000000364 R_AARCH64_ADR_PREL_PG_HI21  kimage_vaddr
0000000000000368 R_AARCH64_LDST64_ABS_LO12_NC  kimage_vaddr
0000000000000370 R_AARCH64_ADR_PREL_PG_HI21  kimage_voffset
0000000000000374 R_AARCH64_LDST64_ABS_LO12_NC  kimage_voffset
0000000000000378 R_AARCH64_ADR_PREL_PG_HI21  __bss_start
000000000000037c R_AARCH64_ADD_ABS_LO12_NC  __bss_start
0000000000000384 R_AARCH64_ADR_PREL_PG_HI21  __bss_stop
0000000000000388 R_AARCH64_ADD_ABS_LO12_NC  __bss_stop
0000000000000390 R_AARCH64_CALL26  __pi_memset
00000000000003a4 R_AARCH64_JUMP26  start_kernel


RELOCATION RECORDS FOR [.rodata]:
OFFSET           TYPE              VALUE
0000000000000000 R_AARCH64_ABS64   _text


RELOCATION RECORDS FOR [___ksymtab+kimage_vaddr]:
OFFSET           TYPE              VALUE
0000000000000000 R_AARCH64_PREL32  kimage_vaddr
0000000000000004 R_AARCH64_PREL32  __kstrtab_kimage_vaddr


RELOCATION RECORDS FOR [.idmap.text]:
OFFSET           TYPE              VALUE
0000000000000160 R_AARCH64_ADR_PREL_PG_HI21  __hyp_stub_vectors
0000000000000164 R_AARCH64_ADD_ABS_LO12_NC  __hyp_stub_vectors
0000000000000180 R_AARCH64_ADR_PREL_PG_HI21  __boot_cpu_mode
0000000000000184 R_AARCH64_ADD_ABS_LO12_NC  __boot_cpu_mode
00000000000001a4 R_AARCH64_CALL26  el2_setup
00000000000001c0 R_AARCH64_ADR_PREL_PG_HI21  secondary_holding_pen_release
00000000000001c4 R_AARCH64_ADD_ABS_LO12_NC  secondary_holding_pen_release
00000000000001dc R_AARCH64_CALL26  el2_setup
00000000000001e8 R_AARCH64_CALL26  __cpu_secondary_check52bitva
00000000000001ec R_AARCH64_CALL26  __cpu_setup
00000000000001f0 R_AARCH64_ADR_PREL_PG_HI21  swapper_pg_dir
00000000000001f4 R_AARCH64_CALL26  __enable_mmu
0000000000000200 R_AARCH64_ADR_PREL_PG_HI21  vectors
0000000000000204 R_AARCH64_ADD_ABS_LO12_NC  vectors
0000000000000210 R_AARCH64_ADR_PREL_PG_HI21  secondary_data
0000000000000214 R_AARCH64_ADD_ABS_LO12_NC  secondary_data
0000000000000238 R_AARCH64_JUMP26  secondary_start_kernel
000000000000025c R_AARCH64_ADR_PREL_PG_HI21  __early_cpu_boot_status
0000000000000260 R_AARCH64_ADD_ABS_LO12_NC  __early_cpu_boot_status
0000000000000270 R_AARCH64_ADR_PREL_PG_HI21  idmap_pg_dir
00000000000002a8 R_AARCH64_ADR_PREL_PG_HI21  __early_cpu_boot_status
00000000000002ac R_AARCH64_ADD_ABS_LO12_NC  __early_cpu_boot_status
0000000000000310 R_AARCH64_ADR_PREL_PG_HI21  init_pg_dir
0000000000000314 R_AARCH64_CALL26  __enable_mmu
0000000000000320 R_AARCH64_ADR_PREL_PG_HI21  _text
0000000000000328 R_AARCH64_ABS32   __rela_offset
000000000000032c R_AARCH64_ABS32   __rela_size
0000000000000330 R_AARCH64_ABS64   .idmap.text+0x0000000000000200
0000000000000338 R_AARCH64_ABS64   .init.text+0x0000000000000330


RELOCATION RECORDS FOR [.debug_line]:
OFFSET           TYPE              VALUE
000000000000003c R_AARCH64_ABS64   .head.text
0000000000000052 R_AARCH64_ABS64   .init.text
00000000000000d1 R_AARCH64_ABS64   .idmap.text


RELOCATION RECORDS FOR [.debug_info]:
OFFSET           TYPE              VALUE
0000000000000006 R_AARCH64_ABS32   .debug_abbrev
000000000000000c R_AARCH64_ABS32   .debug_line
0000000000000010 R_AARCH64_ABS32   .debug_ranges
0000000000000014 R_AARCH64_ABS32   .debug_str
0000000000000018 R_AARCH64_ABS32   .debug_str+0x0000000000000019
000000000000001c R_AARCH64_ABS32   .debug_str+0x0000000000000034


RELOCATION RECORDS FOR [.debug_aranges]:
OFFSET           TYPE              VALUE
0000000000000006 R_AARCH64_ABS32   .debug_info
0000000000000010 R_AARCH64_ABS64   .head.text
0000000000000020 R_AARCH64_ABS64   .init.text
0000000000000030 R_AARCH64_ABS64   .idmap.text


RELOCATION RECORDS FOR [.debug_ranges]:
OFFSET           TYPE              VALUE
0000000000000010 R_AARCH64_ABS64   .head.text
0000000000000018 R_AARCH64_ABS64   .head.text+0x0000000000010000
0000000000000020 R_AARCH64_ABS64   .init.text
0000000000000028 R_AARCH64_ABS64   .init.text+0x00000000000003a8
0000000000000030 R_AARCH64_ABS64   .idmap.text
0000000000000038 R_AARCH64_ABS64   .idmap.text+0x0000000000000340

 


ELF64 포맷 분석

 

간단한 어셈블리 샘플 프로그램 test.S

.text
.globl _start
.align 2

_start:
        adrp x0, msg
        add x0, x0, :lo12:msg   // 어셈블 타임에 msg2 주소의 하위 12비트를 취해 더함.

        adr x1, msg

        ldr x2, msg

        ldr x3, =msg

        /* sys_exit 코드 */
        mov x0, 123
        mov x8, 93
        svc #0

.data

msg:
        .quad 10

 

위의 test.S를 빌드한 후 hexdump 한 값들을 보여준다.

$ hexdump -S test
[ELF Header]
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 b7 00 01 00 00 00  b0 00 40 00 00 00 00 00  |..........@.....|
00000020  40 00 00 00 00 00 00 00  58 04 00 00 00 00 00 00  |@.......X.......|
00000030  00 00 00 00 40 00 38 00  02 00 40 00 0b 00 0a 00  |....@.8...@.....|

[Program Header]
[0]
00000040  01 00 00 00 05 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 40 00 00 00 00 00  00 00 40 00 00 00 00 00  |..@.......@.....|
00000060  d8 00 00 00 00 00 00 00  d8 00 00 00 00 00 00 00  |................|
00000070  00 00 01 00 00 00 00 00  

[1]
				   01 00 00 00 06 00 00 00  |................|
00000080  d8 00 00 00 00 00 00 00  d8 00 41 00 00 00 00 00  |..........A.....|
00000090  d8 00 41 00 00 00 00 00  04 00 00 00 00 00 00 00  |..A.............|
000000a0  04 00 00 00 00 00 00 00  00 00 01 00 00 00 00 00  |................|

[Section]
[.text: virt=0x4000b0]
000000b0  80 00 00 90 00 60 03 91  01 01 08 10 e2 00 08 58  |.....`.........X|
000000c0  83 00 00 58 60 0f 80 d2  a8 0b 80 d2 01 00 00 d4  |...X`...........|
000000d0  d8 00 41 00 00 00 00 00  

[.data: virt=0x4100d8]
000000d8                           0a 00 00 00 00 00 00 00  |..A.............|

[.debug_arranges]
000000e0  2c 00 00 00 02 00 00 00  00 00 08 00 00 00 00 00  |,...............|
000000f0  b0 00 40 00 00 00 00 00  28 00 00 00 00 00 00 00  |..@.....(.......|
00000100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|


[.debug_info]
00000110  2a 00 00 00 02 00 00 00  00 00 08 01 00 00 00 00  |*...............|
00000120  b0 00 40 00 00 00 00 00  d8 00 40 00 00 00 00 00  |..@.......@.....|
00000130  00 00 00 00 07 00 00 00  21 00 00 00 01 80 

[.debug_abbrev]
                                                     01 11  |........!.......|
00000140  00 10 06 11 01 12 01 03  0e 1b 0e 25 0e 13 05 00  |...........%....|
00000150  00 00 

[.debug_line]
                3b 00 00 00 02 00  1d 00 00 00 04 01 fb 0e  |..;.............|
00000160  0d 00 01 01 01 01 00 00  00 01 00 00 01 00 74 65  |..............te|
00000170  73 74 2e 53 00 00 00 00  00 00 09 02 b0 00 40 00  |st.S..........@.|
00000180  00 00 00 00 17 21 22 22  22 23 21 21 02 03 00 01  |.....!"""#!!....|
00000190  01 

[.debug_str]
             74 65 73 74 2e 53 00  2f 72 6f 6f 74 2f 77 6f  |.test.S./root/wo|
000001a0  72 6b 73 70 61 63 65 2f  74 65 73 74 2f 61 73 6d  |rkspace/test/asm|
000001b0  35 00 47 4e 55 20 41 53  20 32 2e 33 30 00 

[.symtab]
                                                     00 00  |5.GNU AS 2.30...|
000001c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001d0  00 00 00 00 00 00 00 00  00 00 00 00 03 00 01 00  |................|
000001e0  b0 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00  |..@.............|
000001f0  00 00 00 00 03 00 02 00  d8 00 41 00 00 00 00 00  |..........A.....|
00000200  00 00 00 00 00 00 00 00  00 00 00 00 03 00 03 00  |................|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000220  00 00 00 00 03 00 04 00  00 00 00 00 00 00 00 00  |................|
00000230  00 00 00 00 00 00 00 00  00 00 00 00 03 00 05 00  |................|
00000240  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000250  00 00 00 00 03 00 06 00  00 00 00 00 00 00 00 00  |................|
00000260  00 00 00 00 00 00 00 00  00 00 00 00 03 00 07 00  |................|
00000270  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000280  01 00 00 00 04 00 f1 ff  00 00 00 00 00 00 00 00  |................|
00000290  00 00 00 00 00 00 00 00  08 00 00 00 00 00 01 00  |................|
000002a0  b0 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00  |..@.............|
000002b0  0b 00 00 00 00 00 02 00  d8 00 41 00 00 00 00 00  |..........A.....|
000002c0  00 00 00 00 00 00 00 00  0f 00 00 00 00 00 01 00  |................|
000002d0  d0 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00  |..@.............|
000002e0  21 00 00 00 10 00 02 00  dc 00 41 00 00 00 00 00  |!.........A.....|
000002f0  00 00 00 00 00 00 00 00  12 00 00 00 10 00 02 00  |................|
00000300  dc 00 41 00 00 00 00 00  00 00 00 00 00 00 00 00  |..A.............|
00000310  20 00 00 00 10 00 02 00  dc 00 41 00 00 00 00 00  | .........A.....|
00000320  00 00 00 00 00 00 00 00  31 00 00 00 10 00 01 00  |........1.......|
00000330  b0 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00  |..@.............|
00000340  2c 00 00 00 10 00 02 00  dc 00 41 00 00 00 00 00  |,.........A.....|
00000350  00 00 00 00 00 00 00 00  38 00 00 00 10 00 02 00  |........8.......|
00000360  e0 00 41 00 00 00 00 00  00 00 00 00 00 00 00 00  |..A.............|
00000370  40 00 00 00 10 00 02 00  dc 00 41 00 00 00 00 00  |@.........A.....|
00000380  00 00 00 00 00 00 00 00  47 00 00 00 10 00 02 00  |........G.......|
00000390  e0 00 41 00 00 00 00 00  00 00 00 00 00 00 00 00  |..A.............|

000003a0  00 74 65 73 74 2e 6f 00  24 78 00 6d 73 67 00 24  |.test.o.$x.msg.$|
000003b0  64 00 5f 5f 62 73 73 5f  73 74 61 72 74 5f 5f 00  |d.__bss_start__.|
000003c0  5f 5f 62 73 73 5f 65 6e  64 5f 5f 00 5f 5f 62 73  |__bss_end__.__bs|
000003d0  73 5f 73 74 61 72 74 00  5f 5f 65 6e 64 5f 5f 00  |s_start.__end__.|
000003e0  5f 65 64 61 74 61 00 5f  65 6e 64 00 00 2e 73 79  |_edata._end...sy|
000003f0  6d 74 61 62 00 2e 73 74  72 74 61 62 00 2e 73 68  |mtab..strtab..sh|
00000400  73 74 72 74 61 62 00 2e  74 65 78 74 00 2e 64 61  |strtab..text..da|
00000410  74 61 00 2e 64 65 62 75  67 5f 61 72 61 6e 67 65  |ta..debug_arange|
00000420  73 00 2e 64 65 62 75 67  5f 69 6e 66 6f 00 2e 64  |s..debug_info..d|
00000430  65 62 75 67 5f 61 62 62  72 65 76 00 2e 64 65 62  |ebug_abbrev..deb|
00000440  75 67 5f 6c 69 6e 65 00  2e 64 65 62 75 67 5f 73  |ug_line..debug_s|
00000450  74 72 00 00 00 00 00 00                           |tr......

[Section Header]
00000458  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000458  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000458  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000458  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000498  1b 00 00 00 01 00 00 00  06 00 00 00 00 00 00 00  |................|
000004a8  b0 00 40 00 00 00 00 00  b0 00 00 00 00 00 00 00  |..@.............|
000004b8  28 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |(...............|
000004c8  08 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000004d8  21 00 00 00 01 00 00 00  03 00 00 00 00 00 00 00  |!...............|
000004e8  d8 00 41 00 00 00 00 00  d8 00 00 00 00 00 00 00  |..A.............|
000004f8  04 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000508  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000518  27 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |'...............|
00000528  00 00 00 00 00 00 00 00  e0 00 00 00 00 00 00 00  |................|
00000538  30 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |0...............|
00000548  10 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000558  36 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |6...............|
00000568  00 00 00 00 00 00 00 00  10 01 00 00 00 00 00 00  |................|
00000578  2e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000588  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000598  42 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |B...............|
000005a8  00 00 00 00 00 00 00 00  3e 01 00 00 00 00 00 00  |........>.......|
000005b8  14 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000005c8  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000005d8  50 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |P...............|
000005e8  00 00 00 00 00 00 00 00  52 01 00 00 00 00 00 00  |........R.......|
000005f8  3f 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |?...............|
00000608  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

00000618  5c 00 00 00 01 00 00 00  30 00 00 00 00 00 00 00  |\.......0.......|
00000628  00 00 00 00 00 00 00 00  91 01 00 00 00 00 00 00  |................|
00000638  2d 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |-...............|
00000648  01 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|

00000658  01 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
00000668  00 00 00 00 00 00 00 00  c0 01 00 00 00 00 00 00  |................|
00000678  e0 01 00 00 00 00 00 00  09 00 00 00 0c 00 00 00  |................|
00000688  08 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|

00000698  09 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
000006a8  00 00 00 00 00 00 00 00  a0 03 00 00 00 00 00 00  |................|
000006b8  4c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |L...............|
000006c8  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

000006d8  11 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
000006e8  00 00 00 00 00 00 00 00  ec 03 00 00 00 00 00 00  |................|
000006f8  67 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |g...............|
00000708  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000718

 

다음은 위의 test 파일에 대해 자세히 출력한다.

$ readelf -a test
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:                              EXEC (Executable file)
  Machine:                           AArch64
  Version:                           0x1
  Entry point address:               0x4000b0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          1112 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         2
  Size of section headers:           64 (bytes)
  Number of section headers:         11
  Section header string table index: 10

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         00000000004000b0  000000b0
       0000000000000028  0000000000000000  AX       0     0     8
  [ 2] .data             PROGBITS         00000000004100d8  000000d8
       0000000000000004  0000000000000000  WA       0     0     1
  [ 3] .debug_aranges    PROGBITS         0000000000000000  000000e0
       0000000000000030  0000000000000000           0     0     16
  [ 4] .debug_info       PROGBITS         0000000000000000  00000110
       000000000000002e  0000000000000000           0     0     1
  [ 5] .debug_abbrev     PROGBITS         0000000000000000  0000013e
       0000000000000014  0000000000000000           0     0     1
  [ 6] .debug_line       PROGBITS         0000000000000000  00000152
       000000000000003f  0000000000000000           0     0     1
  [ 7] .debug_str        PROGBITS         0000000000000000  00000191
       000000000000002d  0000000000000001  MS       0     0     1
  [ 8] .symtab           SYMTAB           0000000000000000  000001c0
       00000000000001e0  0000000000000018           9    12     8
  [ 9] .strtab           STRTAB           0000000000000000  000003a0
       000000000000004c  0000000000000000           0     0     1
  [10] .shstrtab         STRTAB           0000000000000000  000003ec
       0000000000000067  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000000d8 0x00000000000000d8  R E    0x10000
  LOAD           0x00000000000000d8 0x00000000004100d8 0x00000000004100d8
                 0x0000000000000004 0x0000000000000004  RW     0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text
   01     .data

There is no dynamic section in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type AArch64 is not currently supported.

Symbol table '.symtab' contains 20 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000004000b0     0 SECTION LOCAL  DEFAULT    1
     2: 00000000004100d8     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7
     8: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS test.o
     9: 00000000004000b0     0 NOTYPE  LOCAL  DEFAULT    1 $x
    10: 00000000004100d8     0 NOTYPE  LOCAL  DEFAULT    2 msg
    11: 00000000004000d0     0 NOTYPE  LOCAL  DEFAULT    1 $d
    12: 00000000004100dc     0 NOTYPE  GLOBAL DEFAULT    2 _bss_end__
    13: 00000000004100dc     0 NOTYPE  GLOBAL DEFAULT    2 __bss_start__
    14: 00000000004100dc     0 NOTYPE  GLOBAL DEFAULT    2 __bss_end__
    15: 00000000004000b0     0 NOTYPE  GLOBAL DEFAULT    1 _start
    16: 00000000004100dc     0 NOTYPE  GLOBAL DEFAULT    2 __bss_start
    17: 00000000004100e0     0 NOTYPE  GLOBAL DEFAULT    2 __end__
    18: 00000000004100dc     0 NOTYPE  GLOBAL DEFAULT    2 _edata
    19: 00000000004100e0     0 NOTYPE  GLOBAL DEFAULT    2 _end

No version information found in this file.

 

구조체

elf32_hdr 구조체 – ELF32 헤더

glibc/elf/elf.h

typedef struct elf32_hdr{
  unsigned char e_ident[EI_NIDENT];
  Elf32_Half    e_type;
  Elf32_Half    e_machine;
  Elf32_Word    e_version;
  Elf32_Addr    e_entry;  /* Entry point */
  Elf32_Off     e_phoff;
  Elf32_Off     e_shoff;
  Elf32_Word    e_flags;
  Elf32_Half    e_ehsize;
  Elf32_Half    e_phentsize;
  Elf32_Half    e_phnum;
  Elf32_Half    e_shentsize;
  Elf32_Half    e_shnum;
  Elf32_Half    e_shstrndx;
} Elf32_Ehdr;

 

elf64_hdr 구조체 – ELF64 헤더

glibc/elf/elf.h

typedef struct elf64_hdr {
  unsigned char e_ident[EI_NIDENT];     /* ELF "magic number" */
  Elf64_Half e_type;
  Elf64_Half e_machine;
  Elf64_Word e_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;
  Elf64_Half e_ehsize;
  Elf64_Half e_phentsize;
  Elf64_Half e_phnum;
  Elf64_Half e_shentsize;
  Elf64_Half e_shnum;
  Elf64_Half e_shstrndx;
} Elf64_Ehdr;

 

 

Elf32_Shdr – ELF32 섹션 헤더

glibc/elf/elf.h

typedef struct
{
  Elf32_Word    sh_name;                /* Section name (string tbl index) */
  Elf32_Word    sh_type;                /* Section type */
  Elf32_Word    sh_flags;               /* Section flags */
  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
  Elf32_Off     sh_offset;              /* Section file offset */
  Elf32_Word    sh_size;                /* Section size in bytes */
  Elf32_Word    sh_link;                /* Link to another section */
  Elf32_Word    sh_info;                /* Additional section information */
  Elf32_Word    sh_addralign;           /* Section alignment */
  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
} Elf32_Shdr;

 

Elf32_Shdr – ELF64 섹션 헤더

glibc/elf/elf.h

typedef struct
{
  Elf64_Word    sh_name;                /* Section name (string tbl index) */
  Elf64_Word    sh_type;                /* Section type */
  Elf64_Xword   sh_flags;               /* Section flags */
  Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
  Elf64_Off     sh_offset;              /* Section file offset */
  Elf64_Xword   sh_size;                /* Section size in bytes */
  Elf64_Word    sh_link;                /* Link to another section */
  Elf64_Word    sh_info;                /* Additional section information */
  Elf64_Xword   sh_addralign;           /* Section alignment */
  Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
} Elf64_Shdr;

 

Elf32_Phdr – ELF32 프로그램 헤더

glibc/elf/elf.h

typedef struct
{
  Elf32_Word    p_type;                 /* Segment type */
  Elf32_Off     p_offset;               /* Segment file offset */
  Elf32_Addr    p_vaddr;                /* Segment virtual address */
  Elf32_Addr    p_paddr;                /* Segment physical address */
  Elf32_Word    p_filesz;               /* Segment size in file */
  Elf32_Word    p_memsz;                /* Segment size in memory */
  Elf32_Word    p_flags;                /* Segment flags */
  Elf32_Word    p_align;                /* Segment alignment */
} Elf32_Phdr;

 

Elf32_Phdr – ELF64 프로그램 헤더

glibc/elf/elf.h

typedef struct
{
  Elf64_Word    p_type;                 /* Segment type */
  Elf64_Word    p_flags;                /* Segment flags */
  Elf64_Off     p_offset;               /* Segment file offset */
  Elf64_Addr    p_vaddr;                /* Segment virtual address */
  Elf64_Addr    p_paddr;                /* Segment physical address */
  Elf64_Xword   p_filesz;               /* Segment size in file */
  Elf64_Xword   p_memsz;                /* Segment size in memory */
  Elf64_Xword   p_align;                /* Segment alignment */
} Elf64_Phdr;

 

참고

 

 

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다