syscall_emul: fix warn_once behavior
authorSteve Reinhardt <steve.reinhardt@amd.com>
Tue, 5 May 2015 16:25:59 +0000 (09:25 -0700)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Tue, 5 May 2015 16:25:59 +0000 (09:25 -0700)
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.

src/arch/arm/linux/process.cc
src/arch/x86/linux/process.cc
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh

index 269e92baed5b4096f0a87e6e13d06d3d762ae8ae..223db7afd11b1132fa56b22963f3a7d4277859d8 100644 (file)
@@ -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),
index 9a2bb96b5931dc293f13d41663e32711ca5b29a0..ed17d73889665ca0539c51dd78fb0bde93b81c07 100644 (file)
@@ -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),
index 8f3d08cd7ddb9ba52de1ee730a05c1e3b8ae3c5f..b1d3edde48cf8548749daafd0f9aeaa4b30cf081 100644 (file)
@@ -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;
 }
index 8c1a21a65b5f69bc379fc8d7f949d86c7a07682a..05f87fd7d956c4a2aaec60d31e8017dd02f91da1 100644 (file)
@@ -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,