extern u32 x86_init_ptbl_l2[1024];
+struct X86ExTable {
+ ulong faultaddr, handler;
+};
+
+extern X86ExTable extable_start, extable_end;
+
struct X86InitStack {
u8 stack[4096 - ::Threads::thread_size];
::Threads::Thread thread;
void show_regs(Regs *regs)
{
+ u32 esp = regs->cs & 3 ? regs->user_esp :
+ (u32)regs + (u32)sizeof(regs);
+
printf("eax: 0x%08x ecx: 0x%08x edx: 0x%08x ebx: 0x%08x\n"
"esp: 0x%08x ebp: 0x%08x esi: 0x%08x edi: 0x%08x\n"
"eflags: 0x%08x ds: %04x es: %04x ss: %04x\n",
- regs->eax, regs->ecx, regs->edx, regs->ebx,
- regs->cs & 3 ? regs->user_esp : (u32)regs + (u32)sizeof(regs),
+ regs->eax, regs->ecx, regs->edx, regs->ebx, esp,
regs->ebp, regs->esi, regs->edi, regs->eflags,
regs->ds, regs->es, regs->cs & 3 ? regs->user_ss : regs->ds);
-
+
printf("Stack trace: ");
u32 *frame = (u32 *)regs->ebp;
for (int i = 2; i < 32; i++) {
- u32 stackptr = frame[1];
- frame = (u32 *)frame[0];
-
if ((u32)frame < 0x80000000UL)
break;
+ u32 stackptr = frame[1];
+ frame = (u32 *)frame[0];
+
if (!(i % 7))
printf("\n");
printf("0x%08x ", stackptr);
}
+
+ printf("\nStack dump: ");
+
+ for (int i = 2; i < 32; i++) {
+ if (!(i % 7))
+ printf("\n");
+
+ printf("0x%08x ", ((u32 *)esp)[i-2]);
+ }
+
}
struct TimerInt : public IRQ::Interrupt {
};
TimerInt timer_int;
+
+ bool check_extable(Regs *regs, int cause)
+ {
+ X86ExTable *ext;
+ assert((regs->cs & 3) == 0);
+
+ for (ext = &extable_start; ext < &extable_end; ext++) {
+ if (ext->faultaddr == regs->eip) {
+ regs->eip = ext->handler;
+ regs->edx = cause;
+ return true;
+ }
+ }
+
+ return false;
+ }
}
using IRQ::i8259;
Priv::tss.ss0 = 8;
asm volatile("ltr %w0" : : "r" (0x18) : "memory");
- init_thread->addr_space = new Mem::ProcAddrSpace(x86_init_ptbl_l2);
- init_thread->active_addr_space = init_thread->addr_space;
+ init_thread->aspace = new Mem::ProcAddrSpace(x86_init_ptbl_l2);
+ init_thread->active_aspace = init_thread->aspace;
}
void timer_init()
IRQ::InterruptSlot *timer = i8259.get_slot(0);
i8259.request_int(timer, &Priv::timer_int);
}
-
- void ArchThread::init(void *entry, void *arg)
- {
- void **stack = reinterpret_cast<void **>(this);
-
- *--stack = arg;
- *--stack = entry;
-
- esp = stack;
- ebp = 0;
- jump_to_init = 1;
- }
}
using Arch::Priv::show_regs;
extern "C" void x86_do_page_fault(Regs *regs, u32 fault_addr, u32 error_code)
{
Mem::AddrSpace *as;
+ int cause;
if (in_fault)
for(;;);
goto bad_fault;
// Don't allow fault-ins using a borrowed addr-space.
- as = curthread->addr_space;
+ as = curthread->aspace;
if (!as || curthread == Arch::init_thread)
goto bad_fault;
ll_ints_on();
// FIXME: no-exec
- if (as->handle_fault(fault_addr, error_code & 2,
- false /* error_code & 16 */, error_code & 4))
+ cause = as->handle_fault(fault_addr, error_code & 2,
+ false /* error_code & 16 */,
+ error_code & 4);
+
+ if (cause < 0)
+ return;
+
+ if (!(error_code & 4) && check_extable(regs, cause))
return;
// FIXME: throw exception to user
namespace Arch {
namespace Priv {
struct OrbRegs {
+ u32 ds, es;
+
union {
System::RunTime::ParamInfoBlock *pib;
ulong exptr;
extern "C" void x86_invoke_method(Arch::Priv::OrbRegs *regs)
{
assert(regs->cs & 3);
- ORB::invoke_method(regs->pib, regs->user_esp);
+ printf("x86_invoke_method %p\n", regs->pib);
+
+ try {
+ ORB::invoke_method(regs->pib, regs->user_esp);
+ }
+
+ catch (SystemException &se) {
+ // Copy exception to user
+ // If an exception is thrown during dispatch, it must be
+ // with the caller's address space, and user_esp must be
+ // the caller's.
+
+ printf("sys exception\n");
+
+ typedef System::Exceptions::NativeCodeExceptionOriginInfo OriginInfo;
+ OriginInfo *oi = OriginInfo::downcast(se.origin);
+
+ if (oi)
+ printf("PC %llx\n", oi->pc);
+ }
+
+ catch (...) {
+ printf("other exception\n");
+ }
}
extern "C" void x86_return_from_method(Arch::Priv::OrbRegs *regs)