x86: Revise SET_INTERRUPT_HANDLER to avoid using inline assembly feature that does not work with LLVM Clang

The SET_INTERRUPT_HANDLER macro in interrupt.h used an inline assembly
feature to cause GCC to generate a unique number for a trampoline
label.  Clang compiled the code using that feature without generating
any compile-time errors, but it always generated the number 0,
resulting in all interrupt trampolines having the same label names.
This patch replaces the usage of that feature with local labels, which
are supported by both GCC and Clang.  See
https://sourceware.org/binutils/docs/as/Symbol-Names.html for an
explanation of local labels.
This commit is contained in:
Michael LeMay 2015-07-29 07:21:55 -07:00 committed by Jesus Sanchez-Palencia
parent f9072c166b
commit 128d9f3566

View File

@ -67,22 +67,17 @@ struct interrupt_context {
* interrupt. * interrupt.
* *
* [1] http://wiki.osdev.org/Interrupt_Service_Routines * [1] http://wiki.osdev.org/Interrupt_Service_Routines
*
* XXX: If you are debugging at assembly level, make sure you don't be misled
* by the "trampolineXX" symbol name. The suffix number is NOT related to the
* interrupt number at all. The suffix number is a unique random number to
* guarantee there is no symbol name clashing.
*/ */
#define SET_INTERRUPT_HANDLER(num, has_error_code, handler) \ #define SET_INTERRUPT_HANDLER(num, has_error_code, handler) \
do { \ do { \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"push $trampoline%=\n\t" \ "push $1f\n\t" \
"push %0\n\t" \ "push %0\n\t" \
"call %P1\n\t" \ "call %P1\n\t" \
"add $8, %%esp\n\t" \ "add $8, %%esp\n\t" \
"jmp skip_trampoline%=\n\t" \ "jmp 2f\n\t" \
".align 4\n\t" \ ".align 4\n\t" \
"trampoline%=:\n\t" \ "1:\n\t" \
" pushal\n\t" \ " pushal\n\t" \
" call %P2\n\t" \ " call %P2\n\t" \
" popal\n\t" \ " popal\n\t" \
@ -90,7 +85,7 @@ struct interrupt_context {
" add $4, %%esp\n\t" \ " add $4, %%esp\n\t" \
" .endif\n\t" \ " .endif\n\t" \
" iret\n\t" \ " iret\n\t" \
"skip_trampoline%=:\n\t" \ "2:\n\t" \
:: "g" (num), "i" (idt_set_intr_gate_desc), "i" (handler) \ :: "g" (num), "i" (idt_set_intr_gate_desc), "i" (handler) \
: "eax", "ecx", "edx" \ : "eax", "ecx", "edx" \
); \ ); \