Search code examples
memory-managementdriverskernelwdk

#pragma alloc_text(PAGE) code not page-aligned


I'm facing a (possible) problem with DDK (a quite old version: 3590) for WinXP 32 bit. My driver contains some static variables not inizialized (they should be assigned to .bss section, I suppose) and some functions in a pageable code section (marked with #pragma alloc_page(PAGE, func)). The pageable code is collected in a separate object file. I have discovered that the linker seems to assign the statics and the pageable code to the same page in the kernel address space (i.e. the variable is at 0xEFFCB0A0 and the function is at 0xEFFCB600 - verified with windbg). The static variables are used in an interrupt environment, so their pages must be locked in memory. But if the same page contains swappable code I am afraid the variables can suddenly disappear. The linker's map reports correctly that the pageable code is in a different section ("PAGE"), but the offset ("Rva+Base") is in the middle of a page that contains the statics.

How can I force the linker/loader to assign separate pages to the pageable code? Is there some "#pragma" to force the section alignment attibute? Am I doing something wrong?

PS: The driver loader is surely smart enough to put the page containg both variables and code out of the paged pool, but since the page contains variables it must be writable. I'd prefer that the executable code was in a read-only page. Wrong array accesses in kernel mode are yet so difficult to debug...

PPS: Added 4096 "nop"s before and after my function... ok, it works... nothing better to suggest?


Solution

  • Place your globals in their own data segment:

    #pragma data_seg("NONPAGE")
    // declare your globals here
    #pragma data_seg()
    

    source: MSDN link on data_seg

    By default your section will be created with read/write, and not paged flags.

    You can specify additional section options:

    #pragma comment(linker, "/section:NONPAGE,ERW")
    

    source: MSDN link on /SECTION

    or you can place your linker options in the SOURCES file:

    LINKER_FLAGS = $(LINKER_FLAGS) /SECTION:NONPAGE,ERW
    

    NOTE: if you are building a library, use LIBRARIAN_FLAGS instead