syscall_emul: fix warn_once behavior
The current ignoreWarnOnceFunc doesn't really work as expected, since it will only generate one warning total, for whichever "warn-once" syscall is invoked first. This patch fixes that behavior by keeping a "warned" flag in the SyscallDesc object, allowing suitably flagged syscalls to warn exactly once per syscall.
This commit is contained in:
parent
40e180ecbe
commit
c65fa3dceb
|
@ -245,7 +245,7 @@ static SyscallDesc syscallDescs32[] = {
|
|||
/* 123 */ SyscallDesc("unused#123", unimplementedFunc),
|
||||
/* 124 */ SyscallDesc("adjtimex", unimplementedFunc),
|
||||
/* 125 */ SyscallDesc("mprotect", ignoreFunc),
|
||||
/* 126 */ SyscallDesc("sigprocmask", ignoreWarnOnceFunc),
|
||||
/* 126 */ SyscallDesc("sigprocmask", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 127 */ SyscallDesc("unused#127", unimplementedFunc),
|
||||
/* 128 */ SyscallDesc("init_module", unimplementedFunc),
|
||||
/* 129 */ SyscallDesc("delete_module", unimplementedFunc),
|
||||
|
@ -281,7 +281,7 @@ static SyscallDesc syscallDescs32[] = {
|
|||
/* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
|
||||
/* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
|
||||
/* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
|
||||
/* 162 */ SyscallDesc("nanosleep", ignoreWarnOnceFunc),
|
||||
/* 162 */ SyscallDesc("nanosleep", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 163 */ SyscallDesc("mremap", mremapFunc<ArmLinux32>), // ARM-specific
|
||||
/* 164 */ SyscallDesc("setresuid", unimplementedFunc),
|
||||
/* 165 */ SyscallDesc("getresuid", unimplementedFunc),
|
||||
|
@ -293,8 +293,8 @@ static SyscallDesc syscallDescs32[] = {
|
|||
/* 171 */ SyscallDesc("getresgid", unimplementedFunc),
|
||||
/* 172 */ SyscallDesc("prctl", unimplementedFunc),
|
||||
/* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
|
||||
/* 174 */ SyscallDesc("rt_sigaction", ignoreWarnOnceFunc),
|
||||
/* 175 */ SyscallDesc("rt_sigprocmask", ignoreWarnOnceFunc),
|
||||
/* 174 */ SyscallDesc("rt_sigaction", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 175 */ SyscallDesc("rt_sigprocmask", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc),
|
||||
/* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
||||
/* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
|
||||
|
@ -359,7 +359,7 @@ static SyscallDesc syscallDescs32[] = {
|
|||
/* 237 */ SyscallDesc("fremovexattr", unimplementedFunc),
|
||||
/* 238 */ SyscallDesc("tkill", unimplementedFunc),
|
||||
/* 239 */ SyscallDesc("sendfile64", unimplementedFunc),
|
||||
/* 240 */ SyscallDesc("futex", ignoreWarnOnceFunc),
|
||||
/* 240 */ SyscallDesc("futex", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
|
||||
/* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
|
||||
/* 243 */ SyscallDesc("io_setup", unimplementedFunc),
|
||||
|
@ -589,7 +589,7 @@ static SyscallDesc syscallDescs64[] = {
|
|||
/* 98 */ SyscallDesc("futex", unimplementedFunc),
|
||||
/* 99 */ SyscallDesc("set_robust_list", unimplementedFunc),
|
||||
/* 100 */ SyscallDesc("get_robust_list", unimplementedFunc),
|
||||
/* 101 */ SyscallDesc("nanosleep", ignoreWarnOnceFunc),
|
||||
/* 101 */ SyscallDesc("nanosleep", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 102 */ SyscallDesc("getitimer", unimplementedFunc),
|
||||
/* 103 */ SyscallDesc("setitimer", unimplementedFunc),
|
||||
/* 104 */ SyscallDesc("kexec_load", unimplementedFunc),
|
||||
|
@ -623,7 +623,7 @@ static SyscallDesc syscallDescs64[] = {
|
|||
/* 132 */ SyscallDesc("sigaltstack", unimplementedFunc),
|
||||
/* 133 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
|
||||
/* 134 */ SyscallDesc("rt_sigaction", ignoreFunc),
|
||||
/* 135 */ SyscallDesc("rt_sigprocmask", ignoreWarnOnceFunc),
|
||||
/* 135 */ SyscallDesc("rt_sigprocmask", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 136 */ SyscallDesc("rt_sigpending", unimplementedFunc),
|
||||
/* 137 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
||||
/* 138 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
|
||||
|
|
|
@ -231,8 +231,8 @@ static SyscallDesc syscallDescs64[] = {
|
|||
/* 10 */ SyscallDesc("mprotect", ignoreFunc),
|
||||
/* 11 */ SyscallDesc("munmap", munmapFunc),
|
||||
/* 12 */ SyscallDesc("brk", brkFunc),
|
||||
/* 13 */ SyscallDesc("rt_sigaction", ignoreFunc),
|
||||
/* 14 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
|
||||
/* 13 */ SyscallDesc("rt_sigaction", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 14 */ SyscallDesc("rt_sigprocmask", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
|
||||
/* 16 */ SyscallDesc("ioctl", ioctlFunc<X86Linux64>),
|
||||
/* 17 */ SyscallDesc("pread64", unimplementedFunc),
|
||||
|
@ -253,7 +253,7 @@ static SyscallDesc syscallDescs64[] = {
|
|||
/* 32 */ SyscallDesc("dup", dupFunc),
|
||||
/* 33 */ SyscallDesc("dup2", unimplementedFunc),
|
||||
/* 34 */ SyscallDesc("pause", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("nanosleep", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("nanosleep", ignoreFunc, SyscallDesc::WarnOnce),
|
||||
/* 36 */ SyscallDesc("getitimer", unimplementedFunc),
|
||||
/* 37 */ SyscallDesc("alarm", unimplementedFunc),
|
||||
/* 38 */ SyscallDesc("setitimer", unimplementedFunc),
|
||||
|
|
|
@ -99,20 +99,18 @@ ignoreFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
warn("ignoring syscall %s(%d, ...)", desc->name,
|
||||
process->getSyscallArg(tc, index));
|
||||
const char *extra_text = "";
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (desc->warnOnce()) {
|
||||
if (desc->warned)
|
||||
return 0;
|
||||
|
||||
desc->warned = true;
|
||||
extra_text = "\n (further warnings will be suppressed)";
|
||||
}
|
||||
|
||||
SyscallReturn
|
||||
ignoreWarnOnceFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
int index = 0;
|
||||
warn_once("ignoring syscall %s(%d, ...)", desc->name,
|
||||
process->getSyscallArg(tc, index));
|
||||
warn("ignoring syscall %s(%d, ...)%s", desc->name,
|
||||
process->getSyscallArg(tc, index), extra_text);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ class SyscallDesc {
|
|||
const char *name; //!< Syscall name (e.g., "open").
|
||||
FuncPtr funcPtr; //!< Pointer to emulation function.
|
||||
int flags; //!< Flags (see Flags enum).
|
||||
bool warned; //!< Have we warned about unimplemented syscall?
|
||||
|
||||
/// Flag values for controlling syscall behavior.
|
||||
enum Flags {
|
||||
|
@ -104,17 +105,21 @@ class SyscallDesc {
|
|||
/// Used for syscalls with non-standard return conventions
|
||||
/// that explicitly set the ThreadContext regs (e.g.,
|
||||
/// sigreturn).
|
||||
SuppressReturnValue = 1
|
||||
SuppressReturnValue = 1,
|
||||
WarnOnce = 2
|
||||
};
|
||||
|
||||
/// Constructor.
|
||||
SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0)
|
||||
: name(_name), funcPtr(_funcPtr), flags(_flags)
|
||||
: name(_name), funcPtr(_funcPtr), flags(_flags), warned(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// Emulate the syscall. Public interface for calling through funcPtr.
|
||||
void doSyscall(int callnum, LiveProcess *proc, ThreadContext *tc);
|
||||
|
||||
/// Is the WarnOnce flag set?
|
||||
bool warnOnce() const { return (flags & WarnOnce); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -137,8 +142,6 @@ SyscallReturn unimplementedFunc(SyscallDesc *desc, int num,
|
|||
/// trace flag is enabled. Return success to the target program.
|
||||
SyscallReturn ignoreFunc(SyscallDesc *desc, int num,
|
||||
LiveProcess *p, ThreadContext *tc);
|
||||
SyscallReturn ignoreWarnOnceFunc(SyscallDesc *desc, int num,
|
||||
LiveProcess *p, ThreadContext *tc);
|
||||
|
||||
/// Target exit() handler: terminate current context.
|
||||
SyscallReturn exitFunc(SyscallDesc *desc, int num,
|
||||
|
|
Loading…
Reference in a new issue