Another example is the divide by 0 exception, which allows the system to recover from an anomalous operation.
There are three types of exceptions: traps, aborts and faults. Traps are exceptions whose execution continues after the instruction that generated the trap once it is processed, as an example we have the int 3 for debugging.
Faults are exception that can be corrected, and then the instruction that generated the fault can be re-executed. As an example we have page fault commented above.
Finally aborts are severe exceptions such as hardware problems. Usually the final cause of the exception is not known, that is, a problem is detected but it is unknown where it originated.
The routines called by the CPU when a certain exception occurs are called Exception Service Routines. Exception Service Routines are similar to Interrupt Service Routines with the difference that they are generated by the CPU, so they are stored in the same memory structure called IDT (Interrupt Descriptor Table).
In protected mode, Intel platform has up to 256 interrupt entries, each one is represented by an 8 bytes structure in the IDT, which means the size of the whole IDT is 2KB. The processor knows the base address of the IDT through the IDTR register.
The IDT can have several types of entries being the following:
- Interrupt Gate
- Task Gate
- Trap Gate
So now, all we have to do to find the Service Routine for the divide by 0 exception (vector 0) is get the first 8 bytes of the memory pointed to by the IDTR register:
kd> dd idtr L 2
8003f400 0008e19c 80538e00
Rearranging it to fit to previous image we have:
8053 8e00
0008 e19c
So the routine address is 0x8053e19c, and the segment selector is 8. We can also check this entry is an interrupt gate looking the sixth byte: 0x8e. This means it is a 32-bits (D=1) interrupt gate with 0 priviledge (DPL=00).
Finally we check the address we got:
kd> ln 0x8053e19c
(8053e19c) nt!KiTrap00 | (8053e268) nt!Dr_kit1_a
Exact matches:
nt!KiTrap00
Or equivalently:
kd> !idt 0
Dumping IDT:
00: 8053e19c nt!KiTrap00
We can also check the segment selector:
It shows segment selector 8 is for kernel code, as we expected.
As a further example we can find the Service Rotine for Page Fault (Vector14):
kd> dd idtr+8*e L2
8003f470 00080450 80548e00
kd> ln 80540450
(80540450) nt!KiTrap0E | (805406d4) nt!Dr_kitf_a
Exact matches:
nt!KiTrap0E = <no type information>
Before I finish this post there is something else I think is worth mentioning, if you want to find a ISR in the IDT, just add 32 to the interrupt number you want to find, that is, if you want to find interrupt 0 ISR, just get the 32sd entry in the IDT.
This post is mainly aimed to myself ;), but if someone finds any bug or something is not clear enough, please send a comment so I can fix it. Thanks!!
No hay comentarios:
Publicar un comentario