Compare commits
2 Commits
de6fe7f7c2
...
f9003d7a58
Author | SHA1 | Date | |
---|---|---|---|
f9003d7a58 | |||
89786d8be2 |
@ -18,6 +18,16 @@ struct FPData
|
|||||||
void save();
|
void save();
|
||||||
void restore();
|
void restore();
|
||||||
|
|
||||||
|
void* data()
|
||||||
|
{
|
||||||
|
return (void*)m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize size() const
|
||||||
|
{
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char m_data[512] alignas(16);
|
char m_data[512] alignas(16);
|
||||||
bool m_already_saved;
|
bool m_already_saved;
|
||||||
|
@ -111,8 +111,11 @@ bool Thread::deliver_signal(int signo, Registers* current_regs)
|
|||||||
|
|
||||||
regs.rsp -= 128; // Skip the red zone
|
regs.rsp -= 128; // Skip the red zone
|
||||||
|
|
||||||
|
fp_data.save();
|
||||||
|
|
||||||
if (push_mem_on_stack((u8*)current_regs, sizeof(*current_regs)).has_error()) return false;
|
if (push_mem_on_stack((u8*)current_regs, sizeof(*current_regs)).has_error()) return false;
|
||||||
if (push_mem_on_stack((u8*)&signal_mask, sizeof(signal_mask)).has_error()) return false;
|
if (push_mem_on_stack((u8*)&signal_mask, sizeof(signal_mask)).has_error()) return false;
|
||||||
|
if (push_mem_on_stack((u8*)fp_data.data(), fp_data.size()).has_error()) return false;
|
||||||
|
|
||||||
u64 rsp = regs.rsp;
|
u64 rsp = regs.rsp;
|
||||||
|
|
||||||
@ -147,16 +150,20 @@ void Thread::sigreturn(Registers* current_regs)
|
|||||||
{
|
{
|
||||||
memcpy(®s, current_regs, sizeof(regs));
|
memcpy(®s, current_regs, sizeof(regs));
|
||||||
|
|
||||||
|
u64 rflags = current_regs->rflags;
|
||||||
|
|
||||||
u64 rsp;
|
u64 rsp;
|
||||||
pop_mem_from_stack((u8*)&rsp, sizeof(rsp));
|
pop_mem_from_stack((u8*)&rsp, sizeof(rsp));
|
||||||
regs.rsp = rsp;
|
regs.rsp = rsp;
|
||||||
|
pop_mem_from_stack((u8*)fp_data.data(), fp_data.size());
|
||||||
pop_mem_from_stack((u8*)&signal_mask, sizeof(signal_mask));
|
pop_mem_from_stack((u8*)&signal_mask, sizeof(signal_mask));
|
||||||
pop_mem_from_stack((u8*)current_regs, sizeof(*current_regs));
|
pop_mem_from_stack((u8*)current_regs, sizeof(*current_regs));
|
||||||
memcpy(®s, current_regs, sizeof(regs));
|
memcpy(®s, current_regs, sizeof(regs));
|
||||||
regs.cs = 0x18 | 3;
|
regs.cs = 0x18 | 3;
|
||||||
regs.ss = 0x20 | 3;
|
regs.ss = 0x20 | 3;
|
||||||
// FIXME: Using this, a program can craft a special RFLAGS that gives them a higher IOPL or other stuff. Find out
|
regs.rflags = (rflags & ~0xdff) | (regs.rflags & 0xdff);
|
||||||
// exactly what bits to block from modifying.
|
|
||||||
|
fp_data.restore();
|
||||||
|
|
||||||
kinfoln("sigreturn: restored program state, sp=%p, ip=%p", (void*)regs.rsp, (void*)regs.rip);
|
kinfoln("sigreturn: restored program state, sp=%p, ip=%p", (void*)regs.rsp, (void*)regs.rip);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user