I'm getting a simple error because I read a document (https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#x86-Function-Attributes) and wanted to do things properly. In this document is stated that:
An interrupt handler must be declared with a mandatory pointer argument:
struct interrupt_frame; __attribute__ ((interrupt)) void f (struct interrupt_frame *frame) { }
and you must define struct interrupt_frame as described in the processor’s manual.
Exception handlers differ from interrupt handlers because the system pushes an error code on the stack. An exception handler declaration is similar to that for an interrupt handler, but with a different mandatory function signature. The compiler arranges to pop the error code off the stack before the IRET instruction.
#ifdef __x86_64__ typedef unsigned long long int uword_t; #else typedef unsigned int uword_t; #endif struct interrupt_frame; __attribute__ ((interrupt)) void f (struct interrupt_frame *frame, uword_t error_code) { ... }
Exception handlers should only be used for exceptions that push an error code; you should use an interrupt handler in other cases. The system will crash if the wrong kind of handler is used.
Exceptions that push an error code should thus have a 64 bits long as the second argument. Others should have only the user defined interrupt_frame struct. I thus attempted to do that with the following code:
struct InterruptFrame{
UINT64 rsp;
};
//Divide by zero error
__attribute__((interrupt)) void IDT::isr0(InterruptFrame* frame) {
asm volatile("hlt");
}
//Page fault
__attribute__((interrupt)) void IDT::isr14(InterruptFrame* frame, unsigned long long int errorCode) {
asm volatile("hlt");
}
Those are just examples because I have more separate ISRs. When I compile with
g++ -static -ffreestanding -nostdlib -mgeneral-regs-only -mno-red-zone -c -m64 Kernel/Source/IDT.cpp -oKernel/Object/IDT.o
I get an error stating
error: interrupt service routine should have ‘unsigned long int’ as the second argument
even though I did exactly as mentioned in documentation. I get the error for each ISR even for the page fault handler which currently has an unsigned long long int as a second argument. I didn't find much searching on the web for the error so I thought of asking here.
What is wrong? Also, what members should the InterruptFrame struct contain for x86-64?