Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign syscallbuf to always unwind on interruption #3322

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ set(BASIC_TESTS
daemon
desched_blocking_poll
desched_sigkill
desched_sigreturn
detach_state
detach_threads
detach_sigkill
Expand Down
7 changes: 4 additions & 3 deletions src/DiversionSession.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ static void process_syscall_arch(Task* t, int syscallno) {
if (syscallno == t->session().syscall_number_for_rrcall_rdtsc()) {
uint64_t rdtsc_value = static_cast<DiversionSession*>(&t->session())->next_rdtsc_value();
LOG(debug) << "Faking rrcall_rdtsc syscall with value " << rdtsc_value;
remote_ptr<uint64_t> out_param(t->regs().arg1());
t->write_mem(out_param, rdtsc_value);
finish_emulated_syscall_with_ret(t, 0);
Registers r = t->regs();
r.set_dx(rdtsc_value >> 32);
t->set_regs(r);
finish_emulated_syscall_with_ret(t, (uint32_t)rdtsc_value);
return;
}

Expand Down
302 changes: 160 additions & 142 deletions src/Monkeypatcher.cc

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions src/Monkeypatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,24 +125,34 @@ class Monkeypatcher {
};
std::vector<ExtendedJumpPage> extended_jump_pages;

bool is_jump_stub_instruction(remote_code_ptr p, bool include_safearea);
// Return the breakpoint instruction (i.e. the last branch back to caller)
// if we are on the exit path in the jump stub
remote_code_ptr get_jump_stub_exit_breakpoint(remote_code_ptr ip, RecordTask *t);

struct patched_syscall {
// Pointer to hook inside the syscall_hooks array, which gets initialized
// once and is fixed afterwars.
const syscall_patch_hook *hook;
remote_ptr<uint8_t> patch_addr;
remote_ptr<uint8_t> stub_addr;
size_t size;
uint16_t safe_prefix = 0;
uint16_t safe_suffix = 0;
};

patched_syscall *find_jump_stub(remote_code_ptr ip, bool include_safearea);
bool is_jump_stub_instruction(remote_code_ptr p, bool include_safearea) {
return (bool)find_jump_stub(p, include_safearea);
}

patched_syscall *find_syscall_patch(remote_code_ptr patch_location);

// Return the breakpoint instruction (i.e. the last branch back to caller)
// if we are on the exit path in the jump stub
remote_code_ptr get_jump_stub_exit_breakpoint(remote_code_ptr ip, RecordTask *t);
/**
* Addresses/lengths of syscallbuf stubs.
*/
std::map<remote_ptr<uint8_t>, patched_syscall> syscallbuf_stubs;
std::vector<patched_syscall> syscall_stub_list;
std::map<remote_ptr<uint8_t>, int> syscallbuf_stubs_by_extended_patch;
std::map<remote_ptr<uint8_t>, int> syscallbuf_stubs_by_patch_addr;

private:
/**
Expand Down
Loading