인터럽트 프레임이란 무엇인지, 그리고 do_iret 에서는 어떤 일을 하는 건지 이제서야 조금 알 것 같아 별도로 글을 작성한다.

struct intr_frame

do_iret을 이해하려면 인터럽트 프레임 구조체의 크기와, 인터럽트 프레임 구조체 내의 gp_registers 구조체, 그리고 나머지 멤버변수들의 크기를 알고있어야 한다.

데이터 크기

각각의 사이즈를 모두 출력해보았다. (뭘 굳이 찍어봐야 아나 싶은 것들도 있지만 난 아직도 데이터 크기가 어렵다 😭 )

  printf( "인터럽트 프레임 사이즈: %d \\n", sizeof(struct intr_frame));
	printf( "gp_registers 사이즈: %d \\n", sizeof(struct gp_registers));
	printf( "uint16_t 사이즈: %d \\n", sizeof(uint16_t));
	printf( "uint32_t 사이즈: %d \\n", sizeof(uint32_t));
	printf( "uintptr_t 사이즈: %d \\n", sizeof(uintptr_t));

이렇게 찍으면 아래와 같이 출력된다. 이 정보들을 잘 기억하고 있자.

인터럽트 프레임 사이즈: 192
gp_registers 사이즈: 120
uint16_t 사이즈: 2
uint32_t 사이즈: 4
uintptr_t 사이즈: 8

intr_frame 구조체 정의

인터럽트 프레임 구조체는 아래와 같이 정의되어있다. 위에서 확인한 바와 같이 이 구조체는 192 바이트 크기를 가지고 있고, 첫번째 멤버변수는 gp_registers 라는 구조체는 120 바이트 크기를 가진다.

struct intr_frame {
	/* Pushed by intr_entry in intr-stubs.S.
	   These are the interrupted task's saved registers. */
	struct gp_registers R; // 범용 레지스터 - 120 바이트 
	uint16_t es;
	uint16_t __pad1;
	uint32_t __pad2;
	uint16_t ds; // 세그먼트 관리 
	uint16_t __pad3;
	uint32_t __pad4;
	/* Pushed by intrNN_stub in intr-stubs.S. */
	uint64_t vec_no; /* Interrupt vector number. 인터럽트 종류 */
/* Sometimes pushed by the CPU,
   otherwise for consistency pushed as 0 by intrNN_stub.
   The CPU puts it just under `eip', but we move it here. */
	uint64_t error_code;
/* Pushed by the CPU.
   These are the interrupted task's saved registers. */
	uintptr_t rip;  // pc
	uint16_t cs; // 세그먼트 관리 
	uint16_t __pad5;
	uint32_t __pad6;
	uint64_t eflags;// cpu 상태를 나타내는 정보 
	uintptr_t rsp; // 스택 포인터 
	uint16_t ss; 
	uint16_t __pad7;
	uint32_t __pad8;
} __attribute__((packed));

gp_registers 는 아래와 같이 정의된다.

/* Interrupt stack frame. */
struct gp_registers {
	uint64_t r15;
	uint64_t r14;
	uint64_t r13;
	uint64_t r12;
	uint64_t r11;
	uint64_t r10;
	uint64_t r9;
	uint64_t r8;
	uint64_t rsi;
	uint64_t rdi;
	uint64_t rbp;
	uint64_t rdx;
	uint64_t rcx;
	uint64_t rbx;
	uint64_t rax;
} __attribute__((packed));

자리에 리버싱 책이 있는 우리 반 신 교수님이 인터럽트 프레임 구조체의 모습을 그려놓은 게 있어서 허락을 받고 가져와봤다.

Untitled

do_iret 함수