2013. 1. 3. 18:32ㆍProgramming/윈도우 드라이버
컴파일러에게 코드를 특정한 섹션에 두라고 지시하는 전통적인 방법은 alloc_text라는 pragma를 이용하는 것이다.
모든 컴파일러가 pragma를 다 지원하는 것은 아니기 때문에, DDK 헤더에서는 이 pragma의 지원여부를 알려주기 위해 ALLOC_PRAGMA 상수를 정의할 수도 있고 정의하지 않을 수도 있다.
드라이버의 개별 서브루틴에서 아래와 같이 pragma를 호출해서 섹션의 위치를 지정한다
[역주 주: pragma 이후에 오는 문장들은 C/C++ 표준 문법이 아니며 각 개별 컴파일러가 하드웨어나 O/S에 의존적인 부분의 차이를 위해 자체적으로 지원하는 기능이다.]
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DeviceEntry)
#endif
위처럼 INIT 섹션에 위치한 함수는 수행을 마치고 복귀하면 시스템은 이들 함수가 차지한 메모리를 해제한다.
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, AddDevice)
#pragma alloc_text(PAGE, DispatchPnp)
#endif
이 코드는 AddDevice와 DispatchPnp 함수를 paged pool로 지정한다.
Microsoft C/C++ 컴파일러는 alloc_text를 사용하는데 있어 두 가지 제한 사항을 두었다.
● pragma는 함수의 선언보다는 뒤에 있으되 정의보다는 앞에 있어야 한다. 이 법칙을 준수하는 한 가지 방법은 드라이버내의 함수를 표준 헤더 파일에 선언하고, 이 함수가 포함되어 있는 소스파일에서 헤더를 include하고 나서 바로 alloc_text를 부르는 것이다.
● pragma는 C-linkage를 가지고 있는 함수에서만 사용할 수 있다. 즉 클래스 멤버 함수나 extern "C"로 선언되어 있지 않은 C++소스파일 상에서는 동작하지 않을 것이다. 데이터 변수의 위치를 지정하기 위해서는 다른 pragma를 사용해야 한다.
#ifdef ALLOC_DATA_PRAGMA
#pragma data_seg("PAGEDATA")
#endif
data_seg pragma는 pragma 선언 이후에 소스 모듈에서 선언된 static 데이터 변수를 paged pool에 두도록 지정한다. 이 pragma는 기본적인 방식에서 alloc_text와는 달리 페이지 가능한 섹션은 #pragma data_seg("PAGEDATA")가 있는 곳에서 시작되고, 짝이 되는 #pragma data_seg()가 있는 곳에서 끝난다.
alloc_text는 반면, 기술된 해당 함수에 대해서만 적용된다.
ex) 별도의 함수 선언없이 함수 정의하고 속성을 줄 때
#pragma code_seg("PAGE")
NTSTATUS
DriverEntry(
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath)
{
...
}
#pragma code_seq()
ex) 전역 데이터를 페이지블 섹션에 위치시킬 때
#ifdef ALLOC_DATA_PRAGMA
#pragma data_seg("PAGE")
#endif
... 전역 데이터
#ifdef ALLOC_DATA_PRAGMA
#pragma data_seg()
#endif