https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66960
Goswin von Brederlow <goswin-v-b at web dot de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |goswin-v-b at web dot de --- Comment #11 from Goswin von Brederlow <goswin-v-b at web dot de> --- I think the design is fundamentally lacking in the following points: 1. interrupt handler must be declared with a mandatory pointer argument: struct interrupt_frame; __attribute__ ((interrupt)) void f (struct interrupt_frame *frame) { ... } and user must properly define the structure the pointer pointing to. First how does one define the struct interrupt_frame properly? What is in there? Is that just the data the CPU pushes to the stack? If so then gcc should define the structure somewhere so code can be written cpu independent. Since the frame pointer is passed as argument I assume the function prolog will save the first argument register (on amd64) to stack. Is that to be included in the struct interrupt_frame? Secondly how does one access the original register contents? Some kernel designs use a single kernel stack and switch tasks when returning to user space. That means that one has to copy all the user registers into the thread structure and reload a new set of user registers from the new thread on exit from the interrupt handler. The above interface would not allow this. 2. exception handler: The exception handler is very similar to the interrupt handler with a different mandatory function signature: typedef unsigned int uword_t __attribute__ ((mode (__word__))); struct interrupt_frame; __attribute__ ((interrupt)) void f (struct interrupt_frame *frame, uword_t error_code) { ... } and compiler pops the error code off stack before the 'IRET' instruction. In a kernel there will always be some exception that simply prints a register dump and stack backtrace. So again how do you access the original register contents? Secondly why pass error_code as argument if is already on the stack and could be accessed through the frame pointer? The argument register (amd64) would have to be saved on the stack too causing an extra push/pop. But if it is passed as argument then why not pop it before the call to keep the stack frame the same as for interrupts (assuming the saved registers are not included in the frame)? If it is not poped or saved registers are included in the frame then the exception stack frame differs from the interrupt frame (extra error_code and extra register). They should not use the same structure, that's just confusing. 'no_caller_saved_registers' attribute Use this attribute to indicate that the specified function has no caller-saved registers. That is, all registers are callee-saved. Does that include the argument registers (if the function takes arguments)? Wouldn't it be more flexible to define a list of registers that the function will clobber?