TL;DR
- Itanium은 함수의 첫 번들을 덮어쓰는 방식으로 핫 패칭(hot-patching)을 수행하며, 별도의 여유 공간이 필요하지 않음.
- Itanium의 명령어는 세 개씩 고정 크기 번들(bundle)에 배치되며, 함수 첫 명령어에는 핫 패칭 제약이 없음.
- 핫 패칭 시 첫 번들을
nop과 64비트 대상 주소를 받는brl.cond.sptk로 덮어씀. brl은 번들 슬롯 두 개를 차지하는 긴 분기(long branch) 명령어이므로, 번들에는 명령어 두 개만 들어감.- 함수 앞에 보이는 중단점 명령어 번들은 핫 패칭용이 아니라 함수 시작을 32바이트 경계에 맞추는 패딩임.
Itanium의 핫 패칭 방식
- 이전에는 64비트 ARM(AArch64)의 Windows 핫 패칭을 살펴봤으며, Itanium도 고정 크기 명령어, 더 정확히는 명령어 세 개를 인코딩하는 고정 크기 번들을 사용함.
- 고정 크기 번들이므로 AArch64와 마찬가지로 함수의 첫 명령어에는 핫 패칭 제약이 없음.
- 실제로 Itanium에는 핫 패칭을 위한 여유 공간이 전혀 없으며, 그 공간이 필요하지도 않음.
- 핫 패칭 중에는 명령어의 첫 번들을
nop과brl.cond.sptk target64로 덮어씀.
긴 분기 명령어와 번들 슬롯
- 두 번째 명령어인
brl은 64비트 대상 주소를 받는 긴 분기 명령어임.¹ brl은 번들 슬롯 두 개를 차지하는 더블 와이드(double-wide) 명령어이므로 해당 번들에는 명령어 두 개만 들어감.- 처음에는 AArch64 경험을 바탕으로 64비트 주소를 불러오는
movl r8 = target64와br.cond.sptk r8의 조합에 가까울 것으로 생각함. - 하지만 범용 레지스터를 통한 간접 점프는 불가능하며, 먼저 주소를 분기 레지스터로 옮겨야 함.
movl이 슬롯 두 개를 차지하는 상황에서 분기 레지스터로 옮기는 명령어까지 포함하면 총 네 슬롯이 필요해 번들 용량을 초과함.
함수 앞에 보이는 번들
- 오래된 Itanium 바이너리에서는 여러 함수 앞에 다음과 같은 여유 번들처럼 보이는 구성이 나타남.
break.m 0break.i 0break.i 0- 이 번들은 중단점(breakpoint) 명령어로 채워져 있어 처음에는 핫 패칭용 공간처럼 보일 수 있음.
- 그러나 일부 함수에는 이 번들이 없으며, 자세히 살펴보면 핫 패칭 공간이 아니라 모든 함수의 시작을 32바이트 경계에 맞추는 패딩임.
각주
- ¹ 형식상 이는
p0를 조건자로 사용하는 조건부 긴 분기 명령어이며, 정적으로 분기 실행으로 예측됨. p0레지스터는 참으로 고정되어 있으므로 어셈블러는 디스어셈블리에서p0를 생략함.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요