ReactOS  0.4.13-dev-563-g0561610
pgflt.c File Reference
#include "remods.h"
#include "precomp.h"
Include dependency graph for pgflt.c:

Go to the source code of this file.

Functions

void NewInt31Handler (void)
 
ULONG HandleInDebuggerFault (FRAME *ptr, ULONG address)
 
ULONG HandlePageFault (FRAME *ptr)
 
 __asm__ ("\n\t \ NewIntEHandler:\n\t \ pushfl\n\t \ cli\n\t \ cld\n\t \ pushal\n\t \ pushl %ds\n\t \ \n\t \ // setup default data selectors\n\t \ movw %ss,%ax\n\t \ movw %ax,%ds\n\t \ \n\t \ /*\n\t \ * Load the PCR selector.\n\t \ */\n\t \ movl %fs, %eax\n\t \ movl %eax, _OLD_PCR\n\t \ movl _PCR_SEL, %eax\n\t \ movl %eax, %fs\n\t \ \n\t \ // get frame ptr\n\t \ lea 40(%esp),%eax\n\t \ pushl %eax\n\t \ call _HandlePageFault\n\t \ addl $4,%esp\n\t \ \n\t \ pushl %eax\n\t \ movl _OLD_PCR, %eax\n\t \ movl %eax, %fs\n\t \ popl %eax\n\t \ \n\t \ cmpl $0,%eax\n\t \ je call_old_inte_handler\n\t \ \n\t \ cmpl $2,%eax\n\t \ je call_handler_unknown_reason\n\t \ \n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_PAGEFAULT) "\n\t \ jmp NewInt31Handler\n\t \ \n\t \ call_old_inte_handler:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // chain to old handler\n\t \ .byte 0x2e\n\t \ jmp *_OldIntEHandler\n\t \ \n\t \ call_handler_unknown_reason:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_INTERNAL_ERROR) "\n\t \ jmp NewInt31Handler\n\t \ ")
 
void InstallIntEHook (void)
 
void DeInstallIntEHook (void)
 

Variables

char tempPageFault [1024]
 
ULONG OldIntEHandler =0
 
ULONG error_code
 
BOOLEAN bInPageFaultHandler = FALSE
 
static ULONG PCR_SEL = PCR_SELECTOR
 
static ULONG OLD_PCR
 

Function Documentation

◆ __asm__()

__asm__ ( "\n\t \NewIntEHandler:\n\t \ pushfl\n\t \ cli\n\t \ cld\n\t \ pushal\n\t \ pushl %ds\n\t \\n\t \ // setup default data selectors\n\t \ movw %  ss,
%ax\n\t \ movw %  ax,
%ds\n\t \\n\t \/*\n\t \ *Load the PCR selector.\n\t \ */\n\t \ movl fs,
%eax\n\t \ movl eax,
_OLD_PCR\n\t \ movl  _PCR_SEL,
%eax\n\t \ movl eax,
%fs\n\t \\n\t \//get frame ptr\n\t \ lea   40%esp,
%eax\n\t \ pushl %eax\n\t \ call _HandlePageFault\n\t \ addl  $4,
%esp\n\t \\n\t \ pushl %eax\n\t \ movl  _OLD_PCR,
%eax\n\t \ movl eax,
%fs\n\t \ popl %eax\n\t \\n\t \ cmpl  $0,
%eax\n\t \ je call_old_inte_handler\n\t \\n\t \ cmpl  $2,
%eax\n\t \ je call_handler_unknown_reason\n\t \\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \//remove error code. will be restored later when we call\n\t \//original handler again.\n\t \ addl  $4,
%esp\n\t \//call debugger loop\n\t \ pushl $" STR(REASON_PAGEFAULT) "\n\t \ jmp NewInt31Handler\n\t \\n\t \call_old_inte_handler:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \//chain to old handler\n\t \ .byte 0x2e\n\t \ jmp *_OldIntEHandler\n\t \\n\t \call_handler_unknown_reason:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \//remove error code. will be restored later when we call\n\t \//original handler again.\n\t \ addl  $4,
%esp\n\t \//call debugger loop\n\t \ pushl $" STR(REASON_INTERNAL_ERROR) "\n\t \ jmp NewInt31Handler\n\t \ "   
)

◆ DeInstallIntEHook()

void DeInstallIntEHook ( void  )

Definition at line 389 of file pgflt.c.

390 {
391  ENTER_FUNC();
392 
393  MaskIrqs();
394  if(OldIntEHandler)
395  {
397  OldIntEHandler=0;
398  }
399  UnmaskIrqs();
400 
401  LEAVE_FUNC();
402 }
ULONG OldIntEHandler
Definition: pgflt.c:46
ULONG SetGlobalInt(ULONG dwInt, ULONG NewIntHandler)
Definition: hooks.c:95
#define LEAVE_FUNC()
Definition: debug.h:43
void MaskIrqs(void)
Definition: hooks.c:68
unsigned int ULONG
Definition: retypes.h:1
#define ENTER_FUNC()
Definition: debug.h:42
void UnmaskIrqs(void)
Definition: hooks.c:82

Referenced by CleanUpPICE().

◆ HandleInDebuggerFault()

ULONG HandleInDebuggerFault ( FRAME ptr,
ULONG  address 
)

Definition at line 60 of file pgflt.c.

61 {
62  PEPROCESS tsk;
63 
64  ENTER_FUNC();
65 
66  DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while inside debugger, eip: %x\n",address, ptr->eip));
67 
68  // fault in this page fault handler
70  {
71  DPRINT((0,"HandleInDebuggerFault(): ###### page fault @ %.8X while in page fault handler\n",address));
72 
73  DPRINT((0,"!!! machine is halted !!!\n"));
74  __asm__ __volatile__ ("hlt");
75 
76  LEAVE_FUNC();
77  return 0;
78  }
79 
81 
82  // when we come here from DebuggerShell() we live on a different stack
83  // so the current task is different as well
84  tsk = IoGetCurrentProcess();
85 
86  DPRINT((0,"%.8X (%.4X:%.8X %.8X %s %s %s task=%.8X )\n",
87  address,
88  ptr->cs,
89  ptr->eip,
90  ptr->eflags,
91  (ptr->error_code&1)?"PLP":"NP",
92  (ptr->error_code&2)?"WRITE":"READ",
93  (ptr->error_code&4)?"USER-MODE":"KERNEL-MODE",
94  (ULONG)tsk));
95 
96  if(!bInPrintk)
97  {
98  DPRINT((0,"HandleInDebuggerFault(): unexpected pagefault in command handler!\n",address));
99  }
100  else
101  {
102  DPRINT((0,"HandleInDebuggerFault(): unexpected pagefault in command handler while in PrintkCallback()!\n",address));
103  }
104 
105  if(tsk)
106  {
107  PULONG pPGD;
108  PULONG pPTE;
109 
110  pPGD = ADDR_TO_PDE(address);
111 
112  DPRINT((0,"PGD for %.8X @ %.8X = %.8X\n",address,(ULONG)pPGD,(ULONG)(*pPGD) ));
113 
114  if(pPGD && (*pPGD)&_PAGE_PRESENT)
115  {
116  // not large page
117  if(!((*pPGD)&_PAGE_4M))
118  {
119  pPTE = ADDR_TO_PTE(address);
120  if(pPTE)
121  {
122  DPRINT((0,"PTE for %.8X @ %.8X = %.8X\n",address,(ULONG)pPTE,(ULONG)(*pPTE) ));
123  }
124  }
125  }
126  }
127 
129 
130  DPRINT((0,"!!! machine is halted !!!\n"));
131  __asm__ __volatile__ ("hlt");
132 
133  LEAVE_FUNC();
134 
135  return 2;
136 }
#define TRUE
Definition: types.h:120
#define _PAGE_4M
Definition: utils.h:268
ULONG ulRealStackPtr
Definition: shell.c:82
BOOLEAN bInPrintk
Definition: output.c:54
#define LEAVE_FUNC()
Definition: debug.h:43
#define ADDR_TO_PTE(v)
Definition: parse.h:181
static PVOID ptr
Definition: dispmode.c:27
void DPRINT(...)
Definition: polytest.cpp:61
#define _PAGE_PRESENT
Definition: compat.h:67
void IntelStackWalk(ULONG pc, ULONG ebp, ULONG esp)
Definition: utils.c:1530
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
BOOLEAN bInPageFaultHandler
Definition: pgflt.c:48
GLuint address
Definition: glext.h:9393
#define ADDR_TO_PDE(v)
Definition: parse.h:179
ULONG CurrentEBP
Definition: shell.c:115
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define ENTER_FUNC()
Definition: debug.h:42
__asm__("\n\t \ NewIntEHandler:\n\t \ pushfl\n\t \ cli\n\t \ cld\n\t \ pushal\n\t \ pushl %ds\n\t \ \n\t \ // setup default data selectors\n\t \ movw %ss,%ax\n\t \ movw %ax,%ds\n\t \ \n\t \ /*\n\t \ * Load the PCR selector.\n\t \ */\n\t \ movl %fs, %eax\n\t \ movl %eax, _OLD_PCR\n\t \ movl _PCR_SEL, %eax\n\t \ movl %eax, %fs\n\t \ \n\t \ // get frame ptr\n\t \ lea 40(%esp),%eax\n\t \ pushl %eax\n\t \ call _HandlePageFault\n\t \ addl $4,%esp\n\t \ \n\t \ pushl %eax\n\t \ movl _OLD_PCR, %eax\n\t \ movl %eax, %fs\n\t \ popl %eax\n\t \ \n\t \ cmpl $0,%eax\n\t \ je call_old_inte_handler\n\t \ \n\t \ cmpl $2,%eax\n\t \ je call_handler_unknown_reason\n\t \ \n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_PAGEFAULT) "\n\t \ jmp NewInt31Handler\n\t \ \n\t \ call_old_inte_handler:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // chain to old handler\n\t \ .byte 0x2e\n\t \ jmp *_OldIntEHandler\n\t \ \n\t \ call_handler_unknown_reason:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_INTERNAL_ERROR) "\n\t \ jmp NewInt31Handler\n\t \ ")

Referenced by HandlePageFault().

◆ HandlePageFault()

ULONG HandlePageFault ( FRAME ptr)

Definition at line 146 of file pgflt.c.

147 {
148  PVOID address;
149  PEPROCESS tsk, tsk1;
150  PMADDRESS_SPACE vma;
151  PLIST_ENTRY current_entry;
153  ULONG value;
154  PKTHREAD CurrentThread;
155  PETHREAD CurrentEThread;
156 
157  // get linear address of page fault
158  __asm__ __volatile__("movl %%cr2,%0"
159  :"=r" (address));
160 
161  DPRINT((0,"\nPageFault: bInDebShell: %d, error: %d, addr: %x\n", bInDebuggerShell, ptr->error_code, address));
162 
163  // there's something terribly wrong if we get a fault in our command handler
164  if(bInDebuggerShell)
165  {
166  DPRINT((0,"return handleindebuggerfault\n"));
168  }
169 
171  // remember error code so we can push it back on the stack
172  error_code = ptr->error_code;
173 
174  //ei Check IRQL here!!!
175 /*
176  if(in_interrupt())
177  {
178  Print(OUTPUT_WINDOW,"pICE: system is currently processing an interrupt!\n");
179  return 1;
180  }
181 */
182  // current process
183  tsk = IoGetCurrentProcess();
184  DPRINT((0,"tsk: %x\t", tsk));
185  if( !tsk || !(IsAddressValid((ULONG)tsk))){
186  DPRINT((0,"tsk address not valid: tsk: %x\n", tsk));
187  return 0;
188  }
189 
190  // lookup VMA for this address
191  if( (ULONG)address > KERNEL_BASE )
192  vma = my_init_mm; // use kernel mem area for kernel addresses
193  else vma = &(tsk->AddressSpace); // otherwise, use user memory area
194 
195  if( !vma ){
196  DPRINT((0,"vma not valid: vma: %x\n", vma));
197  return 0;
198  }
199 
200  current_entry = vma->MAreaListHead.Flink;
201  ASSERT(current_entry);
202  DPRINT((0,"vma: %x, current_entry: %x, kernel arena: %x\n", vma, current_entry, my_init_mm));
203  while(current_entry != &vma->MAreaListHead)
204  {
205  ASSERT(current_entry);
206  ASSERT(IsAddressValid((ULONG)current_entry));
207  current = CONTAINING_RECORD(current_entry,
208  MEMORY_AREA,
209  Entry);
210 
211 
212  if( (address >= current->BaseAddress) && (address <= current->BaseAddress + current->Length ))
213  {
214  DPRINT((0,"address: %x %x - %x Attrib: %x, Type: %x\n", address, current->BaseAddress, current->BaseAddress + current->Length, current->Attributes, current->Type));
215  //page not present
216  if( !(error_code & 1) ){
217  //check it is in pageable area
218  if( current->Type == MEMORY_AREA_SECTION_VIEW ||
219  current->Type == MEMORY_AREA_VIRTUAL_MEMORY ||
220  current->Type == MEMORY_AREA_PAGED_POOL ||
221  current->Type == MEMORY_AREA_SHARED_DATA
222  ){
223  //ei too much output Print(OUTPUT_WINDOW,"pICE: VMA Pageable Section.\n");
224  //ei DPRINT((0,"return 0 1\n"));
225  return 0; //let the system handle this
226  }
227  Print(OUTPUT_WINDOW,"pICE: VMA Page not present in non-pageable Section!\n");
228  //ei DPRINT((0,"Type: currenttype: %x return 1 2\n", current->Type));
229  return 0;
230  }
231  else{ //access violation
232 
233  if( error_code & 4 )
234  { //user mode
235  if( (ULONG)address >= KERNEL_BASE )
236  {
237  Print(OUTPUT_WINDOW,"pICE: User mode program trying to access kernel memory!\n");
238  //DPRINT((0,"return 0 3\n"));
239  return 1;
240  }
241  //DPRINT((0,"return 0 4\n"));
242  return 0;
243  }
244  /*
245  if(error_code & 2)
246  {
247  //on write
248  if(!(current->Attributes & PAGE_READONLY))
249  {
250  Print(OUTPUT_WINDOW,"pICE: virtual memory arena is not writeable!\n");
251  return 1;
252  }
253  }
254  // READ ACCESS
255  else
256  {
257  // test EXT bit in error code
258  if (error_code & 1)
259  {
260  Print(OUTPUT_WINDOW,"pICE: page-level protection fault!\n");
261  return 1;
262  }
263  //
264  */
265  /*
266  if (!(current->Attributes & PAGE_EXECUTE_READ))
267  {
268  Print(OUTPUT_WINDOW,"pICE: VMA is not readable!\n");
269  return 1;
270  }
271  */
272 
273  // let the system handle it
274  //DPRINT((0,"return 0 5\n"));
275  return 0;
276  }
277  }
278  current_entry = current_entry->Flink;
279  }
280 
281  Print(OUTPUT_WINDOW,"pICE: no virtual memory arena at this address!\n");
282  DPRINT((0,"return 0 6\n"));
283  return 1;
284 
285  // let the system handle it
286 // return 0;
287 }
ULONG error_code
Definition: pgflt.c:47
volatile BOOLEAN bInDebuggerShell
Definition: shell.c:79
void Print(USHORT Window, LPSTR p)
Definition: hardware.c:797
PMADDRESS_SPACE my_init_mm
Definition: utils.h:300
static PVOID ptr
Definition: dispmode.c:27
void DPRINT(...)
Definition: polytest.cpp:61
#define MEMORY_AREA_SECTION_VIEW
Definition: mm.h:71
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
GLuint address
Definition: glext.h:9393
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
GLsizei const GLfloat * value
Definition: glext.h:6069
ULONG HandleInDebuggerFault(FRAME *ptr, ULONG address)
Definition: pgflt.c:60
unsigned int ULONG
Definition: retypes.h:1
__asm__("\n\t \ NewIntEHandler:\n\t \ pushfl\n\t \ cli\n\t \ cld\n\t \ pushal\n\t \ pushl %ds\n\t \ \n\t \ // setup default data selectors\n\t \ movw %ss,%ax\n\t \ movw %ax,%ds\n\t \ \n\t \ /*\n\t \ * Load the PCR selector.\n\t \ */\n\t \ movl %fs, %eax\n\t \ movl %eax, _OLD_PCR\n\t \ movl _PCR_SEL, %eax\n\t \ movl %eax, %fs\n\t \ \n\t \ // get frame ptr\n\t \ lea 40(%esp),%eax\n\t \ pushl %eax\n\t \ call _HandlePageFault\n\t \ addl $4,%esp\n\t \ \n\t \ pushl %eax\n\t \ movl _OLD_PCR, %eax\n\t \ movl %eax, %fs\n\t \ popl %eax\n\t \ \n\t \ cmpl $0,%eax\n\t \ je call_old_inte_handler\n\t \ \n\t \ cmpl $2,%eax\n\t \ je call_handler_unknown_reason\n\t \ \n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_PAGEFAULT) "\n\t \ jmp NewInt31Handler\n\t \ \n\t \ call_old_inte_handler:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // chain to old handler\n\t \ .byte 0x2e\n\t \ jmp *_OldIntEHandler\n\t \ \n\t \ call_handler_unknown_reason:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_INTERNAL_ERROR) "\n\t \ jmp NewInt31Handler\n\t \ ")
base of all file and directory entries
Definition: entries.h:82
BOOLEAN IsAddressValid(ULONG address)
Definition: utils.c:611
struct task_struct * current
Definition: linux.c:32

◆ InstallIntEHook()

void InstallIntEHook ( void  )

Definition at line 365 of file pgflt.c.

366 {
367  ULONG LocalIntEHandler;
368 
369  ENTER_FUNC();
370 
371  MaskIrqs();
372  if(!OldIntEHandler)
373  {
374  __asm__ __volatile__("mov $NewIntEHandler,%0"
375  :"=r" (LocalIntEHandler)
376  :
377  :"eax");
378  OldIntEHandler=SetGlobalInt(0x0E,(ULONG)LocalIntEHandler);
379  }
380  UnmaskIrqs();
381  DPRINT((0,"OldIntE @ %x\n", OldIntEHandler));
382  LEAVE_FUNC();
383 }
ULONG OldIntEHandler
Definition: pgflt.c:46
ULONG SetGlobalInt(ULONG dwInt, ULONG NewIntHandler)
Definition: hooks.c:95
#define LEAVE_FUNC()
Definition: debug.h:43
void DPRINT(...)
Definition: polytest.cpp:61
void MaskIrqs(void)
Definition: hooks.c:68
unsigned int ULONG
Definition: retypes.h:1
#define ENTER_FUNC()
Definition: debug.h:42
__asm__("\n\t \ NewIntEHandler:\n\t \ pushfl\n\t \ cli\n\t \ cld\n\t \ pushal\n\t \ pushl %ds\n\t \ \n\t \ // setup default data selectors\n\t \ movw %ss,%ax\n\t \ movw %ax,%ds\n\t \ \n\t \ /*\n\t \ * Load the PCR selector.\n\t \ */\n\t \ movl %fs, %eax\n\t \ movl %eax, _OLD_PCR\n\t \ movl _PCR_SEL, %eax\n\t \ movl %eax, %fs\n\t \ \n\t \ // get frame ptr\n\t \ lea 40(%esp),%eax\n\t \ pushl %eax\n\t \ call _HandlePageFault\n\t \ addl $4,%esp\n\t \ \n\t \ pushl %eax\n\t \ movl _OLD_PCR, %eax\n\t \ movl %eax, %fs\n\t \ popl %eax\n\t \ \n\t \ cmpl $0,%eax\n\t \ je call_old_inte_handler\n\t \ \n\t \ cmpl $2,%eax\n\t \ je call_handler_unknown_reason\n\t \ \n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_PAGEFAULT) "\n\t \ jmp NewInt31Handler\n\t \ \n\t \ call_old_inte_handler:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // chain to old handler\n\t \ .byte 0x2e\n\t \ jmp *_OldIntEHandler\n\t \ \n\t \ call_handler_unknown_reason:\n\t \ popl %ds\n\t \ popal\n\t \ popfl\n\t \ // remove error code. will be restored later when we call\n\t \ // original handler again.\n\t \ addl $4,%esp\n\t \ // call debugger loop\n\t \ pushl $" STR(REASON_INTERNAL_ERROR) "\n\t \ jmp NewInt31Handler\n\t \ ")
void UnmaskIrqs(void)
Definition: hooks.c:82

Referenced by InitPICE().

◆ NewInt31Handler()

void NewInt31Handler ( void  )

Variable Documentation

◆ bInPageFaultHandler

BOOLEAN bInPageFaultHandler = FALSE

Definition at line 48 of file pgflt.c.

Referenced by HandleInDebuggerFault().

◆ error_code

ULONG error_code

Definition at line 47 of file pgflt.c.

Referenced by HandlePageFault().

◆ OLD_PCR

ULONG OLD_PCR
static

Definition at line 50 of file pgflt.c.

◆ OldIntEHandler

ULONG OldIntEHandler =0

Definition at line 46 of file pgflt.c.

Referenced by DeInstallIntEHook(), and InstallIntEHook().

◆ PCR_SEL

ULONG PCR_SEL = PCR_SELECTOR
static

Definition at line 49 of file pgflt.c.

◆ tempPageFault

char tempPageFault[1024]

Definition at line 43 of file pgflt.c.