feat: ajout de wrappers pour SYSENTER et pour toutes les exceptions. Génération automatique des API par métadonnées dans le source.
This commit is contained in:
parent
3c3f0bb88e
commit
0af99c069b
|
@ -2,7 +2,7 @@
|
||||||
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
||||||
/* */
|
/* */
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
__attribute__ ((noreturn)) void exception_handler(regs *dump);
|
||||||
__attribute__((interrupt)) void interruption(exception_stack_noerror *caller);
|
__attribute__((interrupt)) void interruption(exception_stack_noerror *caller);
|
||||||
void exception0();
|
void exception0();
|
||||||
void exception1();
|
void exception1();
|
||||||
|
|
|
@ -48,15 +48,10 @@
|
||||||
/* fréquence pour timer dans un PC ou AT */
|
/* fréquence pour timer dans un PC ou AT */
|
||||||
# define HZ 100 /* Fréquence d'horloge (ajutste logiciellement sur IBM-PC) */
|
# define HZ 100 /* Fréquence d'horloge (ajutste logiciellement sur IBM-PC) */
|
||||||
|
|
||||||
# define getESP(mem) ({ \
|
# define setESP(mem) ({ \
|
||||||
asm volatile ("movl %%esp,%[tomem];":: [tomem] "m" (mem)); \
|
asm volatile ("movl %[frommem],%%esp;":[frommem] "=m" (mem):); \
|
||||||
})
|
})
|
||||||
|
|
||||||
# define getEBP(mem) ({ \
|
|
||||||
asm volatile ("movl %%ebp,%[tomem];":: [tomem] "m" (mem)); \
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
# define savecpu(dump,caller,oldesp) ({\
|
# define savecpu(dump,caller,oldesp) ({\
|
||||||
getEBP(oldesp);\
|
getEBP(oldesp);\
|
||||||
dumpcpu();\
|
dumpcpu();\
|
||||||
|
@ -168,24 +163,18 @@
|
||||||
pushl %%eax":::);\
|
pushl %%eax":::);\
|
||||||
})
|
})
|
||||||
|
|
||||||
# define restcpu() ({\
|
# define restcpu_kernel() ({\
|
||||||
asm("\
|
asm("\
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
popl %%edx \n \
|
popl %%edx \n \
|
||||||
mov $0xC0000080, %%ecx \n \
|
mov $0xC0000080, %%ecx \n \
|
||||||
wrmsr\n \
|
wrmsr\n \
|
||||||
popl %%eax\n \
|
popl %%eax\n \
|
||||||
mov %%eax,%%dr7 \n \
|
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
mov %%eax,%%dr6 \n \
|
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
mov %%eax,%%dr3 \n \
|
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
mov %%eax,%%dr2 \n \
|
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
mov %%eax,%%dr1 \n \
|
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
mov %%eax,%%dr0 \n \
|
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
mov %%eax,%%cr3 \n \
|
mov %%eax,%%cr3 \n \
|
||||||
|
@ -196,15 +185,26 @@
|
||||||
popl %%esi\n \
|
popl %%esi\n \
|
||||||
popl %%edx\n \
|
popl %%edx\n \
|
||||||
popl %%ecx\n \
|
popl %%ecx\n \
|
||||||
|
mov 36(%%esp),%%eax\n \
|
||||||
|
mov 32(%%esp),%%ebx\n \
|
||||||
|
mov %%ebx,-4(%%eax)\n \
|
||||||
|
mov 28(%%esp),%%ebx\n \
|
||||||
|
mov %%ebx,-8(%%eax)\n \
|
||||||
|
mov 24(%%esp),%%ebx\n \
|
||||||
|
mov %%ebx,-12(%%eax)\n \
|
||||||
popl %%ebx\n \
|
popl %%ebx\n \
|
||||||
popl %%eax\n \
|
popl %%eax\n \
|
||||||
popl %%gs\n \
|
popl %%gs\n \
|
||||||
popl %%fs\n \
|
popl %%fs\n \
|
||||||
popl %%es\n \
|
popl %%es\n \
|
||||||
popl %%ds\n \"::);\
|
popl %%ds\n \
|
||||||
|
add $12,%%esp\n \
|
||||||
|
popl %%esp\n \
|
||||||
|
sub $12,%%esp\n \
|
||||||
|
iret ":::);\
|
||||||
})
|
})
|
||||||
|
|
||||||
# define restdebugcpu() ({\
|
# define restcpu_user() ({\
|
||||||
asm("\
|
asm("\
|
||||||
popl %%eax \n \
|
popl %%eax \n \
|
||||||
popl %%edx \n \
|
popl %%edx \n \
|
||||||
|
@ -234,6 +234,7 @@
|
||||||
popl %%ds":::);\
|
popl %%ds":::);\
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
lors d'un iret en mode user:
|
lors d'un iret en mode user:
|
||||||
pushl %%ss\n \
|
pushl %%ss\n \
|
||||||
|
|
|
@ -47,4 +47,5 @@
|
||||||
|
|
||||||
/* Vers 6 arguments maximum */
|
/* Vers 6 arguments maximum */
|
||||||
void initsyscall(void);
|
void initsyscall(void);
|
||||||
__attribute__ ((noreturn)) void sysenter_handler(void);
|
__attribute__ ((noreturn)) void sysenter_handler(regs *dump);
|
||||||
|
|
||||||
|
|
284
lib/handlers.c
284
lib/handlers.c
|
@ -22,21 +22,72 @@ __attribute__((interrupt)) void interruption(exception_stack_noerror *caller)
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Les expections */
|
/* Les expections */
|
||||||
|
|
||||||
void exception0()
|
static u8 ex14_errors1[] =
|
||||||
{
|
"Supervisory process tried to read a non-present page entry";
|
||||||
regs *dump;
|
static u8 ex14_errors2[] =
|
||||||
exception_stack_noerror *caller;
|
"Supervisory process tried to read a page and caused a protection fault";
|
||||||
u32 *oldesp;
|
static u8 ex14_errors3[] =
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
"Supervisory process tried to write to a non-present page entry";
|
||||||
cpuerror("#DE Divide error", dump, false);
|
static u8 ex14_errors4[] =
|
||||||
}
|
"Supervisory process tried to write a page and caused a protection fault";
|
||||||
|
static u8 ex14_errors5[] =
|
||||||
|
"User process tried to read a non-present page entry";
|
||||||
|
static u8 ex14_errors6[] =
|
||||||
|
"User process tried to read a page and caused a protection fault";
|
||||||
|
static u8 ex14_errors7[] =
|
||||||
|
"User process tried to write to a non-present page entry";
|
||||||
|
static u8 ex14_errors8[] =
|
||||||
|
"User process tried to write a page and caused a protection fault";
|
||||||
|
static u8 *ex14_errors[] =
|
||||||
|
{ &ex14_errors1, &ex14_errors2, &ex14_errors3, &ex14_errors4,
|
||||||
|
&ex14_errors5, &ex14_errors6, &ex14_errors7, &ex14_errors8
|
||||||
|
};
|
||||||
|
|
||||||
void exception1()
|
__attribute__ ((noreturn)) void exception_handler(regs *dump)
|
||||||
{
|
{
|
||||||
regs *dump;
|
u32 exception=dump->eip;
|
||||||
exception_stack_noerror *caller;
|
exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1);
|
||||||
u32 *oldesp;
|
bool noerror,user;
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE)
|
||||||
|
{
|
||||||
|
noerror=true;
|
||||||
|
dump->eip = caller->eip;
|
||||||
|
dump->cs = caller->cs;
|
||||||
|
dump->eflags = caller->eflags;
|
||||||
|
if (dump->cs==SEL_KERNEL_CODE)
|
||||||
|
{
|
||||||
|
dump->esp = (u32) caller + sizeof(exception_stack_noerror);
|
||||||
|
user=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dump->esp = (u32) ((exception_stack_noerror_user*) caller)->esp;
|
||||||
|
dump->ss = (u32) ((exception_stack_noerror_user*) caller)->ss;
|
||||||
|
user=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
noerror=false;
|
||||||
|
dump->eip = ((exception_stack*)caller)->eip;
|
||||||
|
dump->cs = ((exception_stack*)caller)->cs;
|
||||||
|
if (dump->cs==SEL_KERNEL_CODE)
|
||||||
|
{
|
||||||
|
dump->esp = (u32) caller + sizeof(exception_stack);
|
||||||
|
user=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dump->esp = (u32) ((exception_stack_user*) caller)->esp;
|
||||||
|
dump->ss = (u32) ((exception_stack_user*) caller)->ss;
|
||||||
|
user=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (exception)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
cpuerror("#DE Divide error", dump, false);
|
||||||
|
case 1:
|
||||||
changevc(6);
|
changevc(6);
|
||||||
clearscreen();
|
clearscreen();
|
||||||
show_lightcpu(dump);
|
show_lightcpu(dump);
|
||||||
|
@ -59,158 +110,33 @@ void exception1()
|
||||||
initselectors(getinitretry());
|
initselectors(getinitretry());
|
||||||
}
|
}
|
||||||
changevc(0);
|
changevc(0);
|
||||||
restdebugcpu();
|
goto endofexception;
|
||||||
iret();
|
case 2:
|
||||||
}
|
|
||||||
|
|
||||||
void exception2()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("NMI Non-maskable hardware interrupt", dump, false);
|
cpuerror("NMI Non-maskable hardware interrupt", dump, false);
|
||||||
}
|
case 3:
|
||||||
|
|
||||||
void exception3()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#BP INT3 instruction", dump, true);
|
cpuerror("#BP INT3 instruction", dump, true);
|
||||||
iret();
|
iret();
|
||||||
}
|
case 4:
|
||||||
|
|
||||||
void exception4()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#OF INTO instruction detected overflow", dump, false);
|
cpuerror("#OF INTO instruction detected overflow", dump, false);
|
||||||
}
|
case 5:
|
||||||
|
|
||||||
void exception5()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#BR BOUND instruction detected overrange", dump, false);
|
cpuerror("#BR BOUND instruction detected overrange", dump, false);
|
||||||
}
|
case 6:
|
||||||
|
|
||||||
void exception6()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#UD Invalid instruction opcode", dump, false);
|
cpuerror("#UD Invalid instruction opcode", dump, false);
|
||||||
}
|
case 7:
|
||||||
|
|
||||||
void exception7()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#NM No coprocessor", dump, false);
|
cpuerror("#NM No coprocessor", dump, false);
|
||||||
}
|
case 8:
|
||||||
|
|
||||||
void exception8()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#DF Double fault", dump, false);
|
cpuerror("#DF Double fault", dump, false);
|
||||||
}
|
case 9:
|
||||||
|
|
||||||
void exception9()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("Coprocessor segment overrun", dump, false);
|
cpuerror("Coprocessor segment overrun", dump, false);
|
||||||
}
|
case 10:
|
||||||
|
|
||||||
void exception10()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#TS Invalid task state segment (TSS)", dump, false);
|
cpuerror("#TS Invalid task state segment (TSS)", dump, false);
|
||||||
}
|
case 11:
|
||||||
|
|
||||||
void exception11()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#NP Segment not present", dump, false);
|
cpuerror("#NP Segment not present", dump, false);
|
||||||
}
|
case 12:
|
||||||
|
|
||||||
void exception12()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#SS Stack fault", dump, false);
|
cpuerror("#SS Stack fault", dump, false);
|
||||||
}
|
case 13:
|
||||||
|
|
||||||
void exception13()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu(dump, caller, oldesp);
|
|
||||||
cpuerror("#GP General protection fault (GPF)", dump, false);
|
cpuerror("#GP General protection fault (GPF)", dump, false);
|
||||||
}
|
case 14:
|
||||||
|
|
||||||
static u8 ex14_errors1[] =
|
|
||||||
"Supervisory process tried to read a non-present page entry";
|
|
||||||
static u8 ex14_errors2[] =
|
|
||||||
"Supervisory process tried to read a page and caused a protection fault";
|
|
||||||
static u8 ex14_errors3[] =
|
|
||||||
"Supervisory process tried to write to a non-present page entry";
|
|
||||||
static u8 ex14_errors4[] =
|
|
||||||
"Supervisory process tried to write a page and caused a protection fault";
|
|
||||||
static u8 ex14_errors5[] =
|
|
||||||
"User process tried to read a non-present page entry";
|
|
||||||
static u8 ex14_errors6[] =
|
|
||||||
"User process tried to read a page and caused a protection fault";
|
|
||||||
static u8 ex14_errors7[] =
|
|
||||||
"User process tried to write to a non-present page entry";
|
|
||||||
static u8 ex14_errors8[] =
|
|
||||||
"User process tried to write a page and caused a protection fault";
|
|
||||||
static u8 *ex14_errors[] =
|
|
||||||
{ &ex14_errors1, &ex14_errors2, &ex14_errors3, &ex14_errors4,
|
|
||||||
&ex14_errors5, &ex14_errors6, &ex14_errors7, &ex14_errors8
|
|
||||||
};
|
|
||||||
|
|
||||||
void exception14()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
getEBP(oldesp);
|
|
||||||
dumpcpu();
|
|
||||||
getESP(dump);
|
|
||||||
dump->ebp = *oldesp;
|
|
||||||
dump->eip = caller->eip;
|
|
||||||
dump->cs = caller->cs;
|
|
||||||
if (caller->cs == SEL_KERNEL_CODE)
|
|
||||||
dump->esp = (u32) oldesp + sizeof(exception_stack);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dump->esp = (u32) ((exception_stack_user *) caller)->esp;
|
|
||||||
dump->ss = (u32) ((exception_stack_user *) caller)->ss;
|
|
||||||
}
|
|
||||||
if (dump->cr2 >= USER_CODE && dump->cr2 < USER_STACK)
|
if (dump->cr2 >= USER_CODE && dump->cr2 < USER_STACK)
|
||||||
{
|
{
|
||||||
virtual_range_new(getcurrentprocess()->pdd,
|
virtual_range_new(getcurrentprocess()->pdd,
|
||||||
|
@ -220,48 +146,32 @@ void exception14()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Page fault - %s at adress %Y cs:eip - %Y:%Y\r\n",
|
printf("Page fault - %s at adress %Y cs:eip - %Y:%Y\r\n",
|
||||||
ex14_errors[caller->error_code & 0xF], dump->cr2,
|
ex14_errors[((exception_stack*) caller)->error_code & 0xF], dump->cr2,
|
||||||
dump->cs, dump->eip);
|
dump->cs, dump->eip);
|
||||||
cpuerror("#PGF Page fault", dump, false);
|
cpuerror("#PGF Page fault", dump, false);
|
||||||
}
|
}
|
||||||
restdebugcpu();
|
goto endofexception;
|
||||||
iret();
|
case 15:
|
||||||
}
|
|
||||||
|
|
||||||
void exception15()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("(reserved)", dump, false);
|
cpuerror("(reserved)", dump, false);
|
||||||
}
|
case 16:
|
||||||
|
|
||||||
void exception16()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#MF Coprocessor error", dump, false);
|
cpuerror("#MF Coprocessor error", dump, false);
|
||||||
}
|
case 17:
|
||||||
|
|
||||||
void exception17()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#AC Alignment check", dump, false);
|
cpuerror("#AC Alignment check", dump, false);
|
||||||
}
|
case 18:
|
||||||
|
|
||||||
void exception18()
|
|
||||||
{
|
|
||||||
regs *dump;
|
|
||||||
exception_stack_noerror *caller;
|
|
||||||
u32 *oldesp;
|
|
||||||
savecpu_noerror(dump, caller, oldesp);
|
|
||||||
cpuerror("#MC Machine check", dump, false);
|
cpuerror("#MC Machine check", dump, false);
|
||||||
|
}
|
||||||
|
endofexception:
|
||||||
|
if (dump->cs==SEL_KERNEL_CODE)
|
||||||
|
{
|
||||||
|
setESP(dump);
|
||||||
|
restcpu_kernel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setESP(dump);
|
||||||
|
restcpu_user();
|
||||||
|
iret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.macro exception num
|
||||||
|
.global wrapper_exception\num
|
||||||
|
wrapper_exception\num:
|
||||||
|
pushl %ss
|
||||||
|
pushl %esp
|
||||||
|
pushf
|
||||||
|
pushl %cs
|
||||||
|
pushl $\num
|
||||||
|
jmp dumpcpu
|
||||||
|
.endm
|
||||||
|
|
||||||
|
exception 0
|
||||||
|
exception 1
|
||||||
|
exception 2
|
||||||
|
exception 3
|
||||||
|
exception 4
|
||||||
|
exception 5
|
||||||
|
exception 6
|
||||||
|
exception 7
|
||||||
|
exception 8
|
||||||
|
exception 9
|
||||||
|
exception 10
|
||||||
|
exception 11
|
||||||
|
exception 12
|
||||||
|
exception 13
|
||||||
|
exception 14
|
||||||
|
exception 15
|
||||||
|
exception 16
|
||||||
|
exception 17
|
||||||
|
exception 18
|
||||||
|
|
||||||
|
.global wrapper_sysenter
|
||||||
|
wrapper_sysenter:
|
||||||
|
pushl %ss
|
||||||
|
pushl %esp
|
||||||
|
pushf
|
||||||
|
pushl %cs
|
||||||
|
pushl $0x00
|
||||||
|
pushl %ds
|
||||||
|
pushl %es
|
||||||
|
pushl %fs
|
||||||
|
pushl %gs
|
||||||
|
pushl %eax
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
pushl %edx
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
pushl %ebp
|
||||||
|
mov %cr0, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %cr2, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %cr3, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %cr4, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr0, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr1, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr2, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr3, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr6, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr7, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov $0xC0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
pushl %edx
|
||||||
|
pushl %eax
|
||||||
|
pushl %esp
|
||||||
|
call sysenter_handler
|
||||||
|
|
||||||
|
dumpcpu:
|
||||||
|
pushl %ds
|
||||||
|
pushl %es
|
||||||
|
pushl %fs
|
||||||
|
pushl %gs
|
||||||
|
pushl %eax
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
pushl %edx
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
pushl %ebp
|
||||||
|
mov %cr0, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %cr2, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %cr3, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %cr4, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr0, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr1, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr2, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr3, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr6, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov %dr7, %eax
|
||||||
|
pushl %eax
|
||||||
|
mov $0xC0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
pushl %edx
|
||||||
|
pushl %eax
|
||||||
|
pushl %esp
|
||||||
|
call exception_handler
|
|
@ -22,6 +22,25 @@ static idtdes idt[IDT_SIZE];
|
||||||
|
|
||||||
static u32 retry_address;
|
static u32 retry_address;
|
||||||
|
|
||||||
|
extern wrapper_exception0;
|
||||||
|
extern wrapper_exception1;
|
||||||
|
extern wrapper_exception2;
|
||||||
|
extern wrapper_exception3;
|
||||||
|
extern wrapper_exception4;
|
||||||
|
extern wrapper_exception5;
|
||||||
|
extern wrapper_exception6;
|
||||||
|
extern wrapper_exception7;
|
||||||
|
extern wrapper_exception8;
|
||||||
|
extern wrapper_exception9;
|
||||||
|
extern wrapper_exception10;
|
||||||
|
extern wrapper_exception11;
|
||||||
|
extern wrapper_exception12;
|
||||||
|
extern wrapper_exception13;
|
||||||
|
extern wrapper_exception14;
|
||||||
|
extern wrapper_exception15;
|
||||||
|
extern wrapper_exception16;
|
||||||
|
extern wrapper_exception17;
|
||||||
|
extern wrapper_exception18;
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Initialise la reprise après erreur */
|
/* Initialise la reprise après erreur */
|
||||||
|
|
||||||
|
@ -149,43 +168,43 @@ void putidt(u32 offset, u16 select, u16 type, u16 index)
|
||||||
void initidt(void)
|
void initidt(void)
|
||||||
{
|
{
|
||||||
u16 i;
|
u16 i;
|
||||||
putidt((u32) exception0, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception0, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 0);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 0);
|
||||||
putidt((u32) exception1, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception1, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 1);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 1);
|
||||||
putidt((u32) exception2, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception2, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 2);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 2);
|
||||||
putidt((u32) exception3, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception3, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 3);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 3);
|
||||||
putidt((u32) exception4, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception4, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 4);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 4);
|
||||||
putidt((u32) exception5, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception5, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 5);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 5);
|
||||||
putidt((u32) exception6, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception6, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 6);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 6);
|
||||||
putidt((u32) exception7, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception7, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 7);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 7);
|
||||||
putidt((u32) exception8, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception8, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 8);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 8);
|
||||||
putidt((u32) exception9, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception9, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 9);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 9);
|
||||||
putidt((u32) exception10, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception10, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 10);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 10);
|
||||||
putidt((u32) exception11, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception11, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 11);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 11);
|
||||||
putidt((u32) exception12, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception12, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 12);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 12);
|
||||||
putidt((u32) exception13, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception13, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 13);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 13);
|
||||||
putidt((u32) exception14, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception14, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 14);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 14);
|
||||||
putidt((u32) exception15, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception15, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 15);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 15);
|
||||||
putidt((u32) exception16, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception16, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 16);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 16);
|
||||||
putidt((u32) exception17, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception17, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 17);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 17);
|
||||||
putidt((u32) exception18, SEL_KERNEL_CODE,
|
putidt((u32) &wrapper_exception18, SEL_KERNEL_CODE,
|
||||||
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 18);
|
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 18);
|
||||||
for (i = 19; i < 32; i++)
|
for (i = 19; i < 32; i++)
|
||||||
{
|
{
|
||||||
|
|
10
lib/makefile
10
lib/makefile
|
@ -1,7 +1,10 @@
|
||||||
CC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -m32 -F elf_i386 -fno-pie -no-pie -I ../include -c
|
CC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -m32 -F elf_i386 -fno-pie -no-pie -I ../include -c
|
||||||
|
ASM=gcc -nostdinc -ffreestanding -fno-builtin -m32 -c -fno-pie -no-pie
|
||||||
LINK=ld -m elf_i386 -r -o
|
LINK=ld -m elf_i386 -r -o
|
||||||
SRCS= $(wildcard *.c)
|
SRCS= $(wildcard *.c)
|
||||||
OBJS= $(SRCS:.c=.o)
|
OBJS= $(SRCS:.c=.o)
|
||||||
|
SRCASM= $(wildcard *.S)
|
||||||
|
OBJASM= $(SRCASM:.S=.o)
|
||||||
CONVERT=dos2unix
|
CONVERT=dos2unix
|
||||||
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
|
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
|
||||||
REMOVE=rm -f
|
REMOVE=rm -f
|
||||||
|
@ -12,8 +15,11 @@ all: libs.o
|
||||||
|
|
||||||
togit: clean indent
|
togit: clean indent
|
||||||
|
|
||||||
libs.o:$(OBJS)
|
libs.o:$(OBJS) $(OBJASM)
|
||||||
$(LINK) libs.o $(OBJS)
|
$(LINK) libs.o $(OBJS) $(OBJASM)
|
||||||
|
|
||||||
|
.o: .S
|
||||||
|
$(ASM) $^
|
||||||
|
|
||||||
handlers.o:handlers.c
|
handlers.o:handlers.c
|
||||||
$(CC) -mgeneral-regs-only $^
|
$(CC) -mgeneral-regs-only $^
|
||||||
|
|
|
@ -235,7 +235,10 @@ void task_switch(u32 pid, bool fromkernelmode)
|
||||||
setTSS(0x0, 0x0);
|
setTSS(0x0, 0x0);
|
||||||
current->dump.eflags = (current->dump.eflags | 0x200) & 0xFFFFBFFF;
|
current->dump.eflags = (current->dump.eflags | 0x200) & 0xFFFFBFFF;
|
||||||
createdump(current->dump);
|
createdump(current->dump);
|
||||||
restdebugcpu();
|
if (current->dump.cs==SEL_KERNEL_CODE)
|
||||||
|
restcpu_kernel();
|
||||||
|
else
|
||||||
|
restcpu_user();
|
||||||
iret();
|
iret();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
* %esi Arg2
|
* %esi Arg2
|
||||||
* %edi Arg3*/
|
* %edi Arg3*/
|
||||||
|
|
||||||
|
extern wrapper_sysenter;
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Initialise les appels système par SYSENTER/SYSEXIT */
|
/* Initialise les appels système par SYSENTER/SYSEXIT */
|
||||||
|
|
||||||
|
@ -24,7 +26,8 @@ void initsyscall(void)
|
||||||
{
|
{
|
||||||
wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
|
wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
|
||||||
wrmsr(0x175, 0x60000, 0x0);
|
wrmsr(0x175, 0x60000, 0x0);
|
||||||
wrmsr(0x176, &sysenter_handler, 0x0);
|
wrmsr(0x176, &wrapper_sysenter, 0x0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
@ -54,15 +57,8 @@ u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump)
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Entrée pour les appels système SYSENTER */
|
/* Entrée pour les appels système SYSENTER */
|
||||||
|
__attribute__ ((noreturn)) void sysenter_handler(regs *dump)
|
||||||
__attribute__ ((noreturn)) void sysenter_handler(void)
|
|
||||||
{
|
{
|
||||||
cli();
|
|
||||||
regs *dump;
|
|
||||||
dumpcpu();
|
|
||||||
getESP(dump);
|
|
||||||
dump->cs=SEL_USER_CODE;
|
|
||||||
dump->eip=dump->edx;
|
|
||||||
sti();
|
sti();
|
||||||
switch (dump->eax)
|
switch (dump->eax)
|
||||||
{
|
{
|
||||||
|
@ -86,7 +82,10 @@ __attribute__ ((noreturn)) void sysenter_handler(void)
|
||||||
printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip);
|
printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
restdebugcpu();
|
//dump->eflags &= ~(1 << 6);
|
||||||
|
dump->eflags |= (1 << 6);
|
||||||
|
setESP(dump);
|
||||||
|
restcpu_user();
|
||||||
sysexit();
|
sysexit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
makefile
5
makefile
|
@ -9,6 +9,11 @@ bits64: ARCH=bits64
|
||||||
bits64: lib/libs.o system/system.sys
|
bits64: lib/libs.o system/system.sys
|
||||||
sync
|
sync
|
||||||
|
|
||||||
|
syscall: clean remakeapi all
|
||||||
|
|
||||||
|
remakeapi:
|
||||||
|
python makesyscall.py
|
||||||
|
|
||||||
programs: programs/test lib/TEST/test.c
|
programs: programs/test lib/TEST/test.c
|
||||||
|
|
||||||
lib/TEST/test.c:
|
lib/TEST/test.c:
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
//u32 result = testapi(0x1234,0x88888888,0x2505);
|
u32 result = testapi(0x1234,0x88888888,0x2505);
|
||||||
print("ceci est un test d'appel");
|
print("ceci est un test d'appel");
|
||||||
waitkey();
|
waitkey();
|
||||||
//exit(result);
|
exit(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
* %esi Arg2
|
* %esi Arg2
|
||||||
* %edi Arg3*/
|
* %edi Arg3*/
|
||||||
|
|
||||||
|
extern wrapper_sysenter;
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Initialise les appels système par SYSENTER/SYSEXIT */
|
/* Initialise les appels système par SYSENTER/SYSEXIT */
|
||||||
|
|
||||||
|
@ -24,7 +26,7 @@ void initsyscall(void)
|
||||||
{
|
{
|
||||||
wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
|
wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
|
||||||
wrmsr(0x175, 0x60000, 0x0);
|
wrmsr(0x175, 0x60000, 0x0);
|
||||||
wrmsr(0x176, &sysenter_handler, 0x0);
|
wrmsr(0x176, &wrapper_sysenter, 0x0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,15 +57,8 @@ u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump)
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* Entrée pour les appels système SYSENTER */
|
/* Entrée pour les appels système SYSENTER */
|
||||||
|
__attribute__ ((noreturn)) void sysenter_handler(regs *dump)
|
||||||
__attribute__ ((noreturn)) void sysenter_handler(void)
|
|
||||||
{
|
{
|
||||||
cli();
|
|
||||||
regs *dump;
|
|
||||||
dumpcpu();
|
|
||||||
getESP(dump);
|
|
||||||
dump->cs=SEL_USER_CODE;
|
|
||||||
dump->eip=dump->edx;
|
|
||||||
sti();
|
sti();
|
||||||
switch (dump->eax)
|
switch (dump->eax)
|
||||||
{
|
{
|
||||||
|
@ -72,7 +67,10 @@ __attribute__ ((noreturn)) void sysenter_handler(void)
|
||||||
printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip);
|
printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
restdebugcpu();
|
//dump->eflags &= ~(1 << 6);
|
||||||
|
dump->eflags |= (1 << 6);
|
||||||
|
setESP(dump);
|
||||||
|
restcpu_user();
|
||||||
sysexit();
|
sysexit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue