본문 바로가기
Programming/윈도우 드라이버

#pragma alloc_text(PAGE, XXX)

by 유주원 2013. 1. 3.

컴파일러에게 코드를 특정한 섹션에 두라고 지시하는 전통적인 방법은 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