| 227 | } |
| 228 | |
| 229 | void CPU::prepareException(int code, int error) { |
| 230 | const KProcessPtr& process = this->thread->process; |
| 231 | |
| 232 | // blocking signals, signalfd can't handle these |
| 233 | if (code==EXCEPTION_GP && (process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_IGN && process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_DFL)) { |
| 234 | process->sigActions[K_SIGSEGV].sigInfo[0] = K_SIGSEGV; |
| 235 | process->sigActions[K_SIGSEGV].sigInfo[1] = error; |
| 236 | process->sigActions[K_SIGSEGV].sigInfo[2] = 0; |
| 237 | process->sigActions[K_SIGSEGV].sigInfo[3] = 0; // address |
| 238 | process->sigActions[K_SIGSEGV].sigInfo[4] = 13; // trap #, TRAP_x86_PROTFLT |
| 239 | this->thread->runSignal(K_SIGSEGV, 13, error); |
| 240 | } else if (code==EXCEPTION_DIVIDE && error == 0 && (process->sigActions[K_SIGFPE].handlerAndSigAction!=K_SIG_IGN && process->sigActions[K_SIGFPE].handlerAndSigAction!=K_SIG_DFL)) { |
| 241 | process->sigActions[K_SIGFPE].sigInfo[0] = K_SIGFPE; |
| 242 | process->sigActions[K_SIGFPE].sigInfo[1] = error; |
| 243 | process->sigActions[K_SIGFPE].sigInfo[2] = K_FPE_INTDIV; |
| 244 | process->sigActions[K_SIGFPE].sigInfo[3] = this->eip.u32; // address |
| 245 | process->sigActions[K_SIGFPE].sigInfo[4] = 0; // trap #, TRAP_x86_DIVIDE |
| 246 | this->thread->runSignal(K_SIGFPE, 0, error); |
| 247 | } else if (code==EXCEPTION_DIVIDE && error == 1 && (process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_IGN && process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_DFL)) { |
| 248 | process->sigActions[K_SIGSEGV].sigInfo[0] = K_SIGFPE; |
| 249 | process->sigActions[K_SIGSEGV].sigInfo[1] = 0; |
| 250 | process->sigActions[K_SIGSEGV].sigInfo[2] = K_FPE_INTOVF; |
| 251 | process->sigActions[K_SIGSEGV].sigInfo[3] = this->eip.u32; // address |
| 252 | process->sigActions[K_SIGSEGV].sigInfo[4] = 4; // trap #, TRAP_x86_OFLOW |
| 253 | this->thread->runSignal(K_SIGSEGV, 4, error); |
| 254 | } else if (code==EXCEPTION_NP && (process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_IGN && process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_DFL)) { |
| 255 | process->sigActions[K_SIGSEGV].sigInfo[0] = K_SIGSEGV; |
| 256 | process->sigActions[K_SIGSEGV].sigInfo[1] = 0; |
| 257 | process->sigActions[K_SIGSEGV].sigInfo[2] = 0; |
| 258 | process->sigActions[K_SIGSEGV].sigInfo[3] = this->eip.u32; // address |
| 259 | process->sigActions[K_SIGSEGV].sigInfo[4] = 11; // trap #, TRAP_x86_SEGNPFLT |
| 260 | this->thread->runSignal(K_SIGSEGV, 11, error); |
| 261 | } else if (code==EXCEPTION_SS && (process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_IGN && process->sigActions[K_SIGSEGV].handlerAndSigAction!=K_SIG_DFL)) { |
| 262 | process->sigActions[K_SIGSEGV].sigInfo[0] = K_SIGSEGV; |
| 263 | process->sigActions[K_SIGSEGV].sigInfo[1] = 0; |
| 264 | process->sigActions[K_SIGSEGV].sigInfo[2] = 0; |
| 265 | process->sigActions[K_SIGSEGV].sigInfo[3] = this->eip.u32; // address |
| 266 | process->sigActions[K_SIGSEGV].sigInfo[4] = 12; // trap #, TRAP_x86_SEGNPFLT |
| 267 | this->thread->runSignal(K_SIGSEGV, 12, error); |
| 268 | } else { |
| 269 | CPU* cpu = this; |
| 270 | this->walkStack(this->eip.u32, EBP, 2); |
| 271 | kpanic_fmt("unhandled exception: code=%d error=%d", code, error); |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | class TTYBufferAccess : public BufferAccess { |
| 276 | public: |
no test coverage detected