util: Add a unit test for the "inst" call type in the m5 util.
authorGabe Black <gabeblack@google.com>
Thu, 9 Apr 2020 09:33:56 +0000 (02:33 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 25 Aug 2020 19:45:26 +0000 (19:45 +0000)
This test does two things. First, it makes sure that the "inst" call
type detects that it's being requested in the command line arguments
correctly.

Second, it detects whether it's running in gem5 or not, really just
detecting an environment variable which tells it whether it is. If it
is, then it attempts to run the "sum" op which it expects to succeed and
give the right answer.

If not, it expects to get a SIGILL signal from the OS when it tries to
execute the otherwise illegal instruction. It sets up a signal handler
to catch it, and in that handler saves off information about what
happened. It then uses siglongjmp to return to sanity (before the
signal) and to examine what happened to see if the right instruction was
attempted.

It looks like, depending on the architecture, Linux will either set
si_code to ILL_ILLOPC (illegal opcode) or ILL_ILLOPN (illegal operand).
The later doesn't seem right since the entire instruction is illegal,
not just some operand, but it is what it is and we need to handle
either.

The test then calls a small function, abi_verify, which takes the
siginfo_t and does any abi specific verification. That includes
extracting fields from the instruction if the instruction trigger the
signal, or checking for architecture specific constants, etc.

Also, to centralize setting the macro which lets a call type know that
it's the default, the call types are now also responsible for setting up
their own tweaks to the environment.

Change-Id: I8710e39e20bd9c03b1375a2dccefb27bd6fe0c10
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27689
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
14 files changed:
util/m5/SConstruct
util/m5/src/SConscript
util/m5/src/abi/aarch64/SConsopts
util/m5/src/abi/aarch64/verify_inst.cc [new file with mode: 0644]
util/m5/src/abi/arm/SConsopts
util/m5/src/abi/arm/verify_inst.cc [new file with mode: 0644]
util/m5/src/abi/sparc/SConsopts
util/m5/src/abi/sparc/verify_inst.cc [new file with mode: 0644]
util/m5/src/abi/thumb/SConsopts
util/m5/src/abi/thumb/verify_inst.cc [new file with mode: 0644]
util/m5/src/abi/x86/SConsopts
util/m5/src/abi/x86/verify_inst.cc [new file with mode: 0644]
util/m5/src/call_type/inst.test.cc
util/m5/src/call_type/verify_inst.hh [new file with mode: 0644]

index 3bcba876747d4e5169d970a2ab389fcf486844bf..bbae8d9bbf968c5ca201cb413f44d0eef44768c4 100644 (file)
@@ -95,13 +95,24 @@ class CallType(object):
         self.name = name
         self.impl_file = None
         self.enabled = False
+        self.verifier = None
         self.default = False
 
-    def impl(self, impl, default=False):
+    def impl(self, impl, verifier=None, default=False):
         self.impl_file = impl
         self.enabled = True
+        self.verifier = verifier
         self.default = default
 
+    # Being the default can be disabled for testing purposes, so we can tell if
+    # a call type was selected because it was chosen, or because nobody else
+    # was.
+    def setup_env(self, env, allow_default=True):
+        env = env.Clone()
+        is_default = 'true' if self.default and allow_default else 'false'
+        env.Append(CXXFLAGS=[ '-DCALL_TYPE_IS_DEFAULT=%s' % is_default ])
+        return env
+
 call_types = {
     # Magic instruction.
     'inst': CallType('inst'),
index 19fce1a323cff15796dd5caedc4379b56dec17d8..c5e51911b0fb243efa184c5c044300fa4ea9a6e5 100644 (file)
@@ -67,9 +67,7 @@ commands = env.SConscript('command/SConscript', exports={ "env": static_env })
 #
 ct_support = []
 for ct in call_types:
-    ct_env = static_env.Clone()
-    is_default = 'true' if ct.default else 'false'
-    ct_env.Append(CXXFLAGS=[ '-DCALL_TYPE_IS_DEFAULT=%s' % is_default ])
+    ct_env = ct.setup_env(static_env)
     ct_support.extend(ct_env.StaticObject('call_type/%s.cc' % ct.name))
 m5_bin = static_env.Program('out/m5', ct_support +
         [ args, call_type, command, commands, m5, m5_mmap, libm5, usage ])
@@ -87,11 +85,12 @@ call_type_shared = shared_env.SharedObject(call_type)
 args_shared = shared_env.SharedObject(args)
 m5_mmap_shared = shared_env.SharedObject(m5_mmap)
 for ct in call_types:
-    ct_env = shared_env.Clone()
-    ct_env.Append(CXXFLAGS=[ '-DCALL_TYPE_IS_DEFAULT=false' ])
-    ct_env.GTest('call_type/%s' % ct.name, 'call_type/%s.test.cc' % ct.name,
-                 'call_type/%s.cc' % ct.name, call_type_shared, args_shared,
-                 m5_mmap_shared, m5ops[ct.name])
+    ct_env = ct.setup_env(shared_env, allow_default=False)
+    srcs = [ 'call_type/%s.test.cc' % ct.name, 'call_type/%s.cc' % ct.name,
+             call_type_shared, args_shared, m5_mmap_shared, m5ops[ct.name] ]
+    if ct.verifier:
+        srcs.append('abi/${ABI}/%s' % ct.verifier)
+    ct_env.GTest('call_type/%s' % ct.name, *srcs)
 
 if env['HAVE_JAVA']:
     #
index 938a866ec41f9386d9257b4dbe59acc4e4746f55..47ada020902b71029e40e6ac71df092745792bad 100644 (file)
@@ -28,6 +28,6 @@ Import('*')
 env['ABI'] = 'aarch64'
 get_abi_opt('CROSS_COMPILE', 'aarch64-linux-gnu-')
 
-env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
+env['CALL_TYPE']['inst'].impl('m5op.S', 'verify_inst.cc', default=True)
 env['CALL_TYPE']['addr'].impl('m5op_addr.S')
 env['CALL_TYPE']['semi'].impl('m5op_semi.S')
diff --git a/util/m5/src/abi/aarch64/verify_inst.cc b/util/m5/src/abi/aarch64/verify_inst.cc
new file mode 100644 (file)
index 0000000..7370e9e
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include "call_type/verify_inst.hh"
+
+void
+abi_verify_inst(const siginfo_t &info, int func)
+{
+    EXPECT_EQ(func, *(uint8_t *)((uintptr_t)info.si_addr + 2));
+}
index 1a24ef023d4c487a84a859b30db5a37a5cb3297d..c94584d79d8eb36b1fe4441ecca4526fd51e76a1 100644 (file)
@@ -29,4 +29,4 @@ env['ABI'] = 'arm'
 get_abi_opt('CROSS_COMPILE', 'arm-linux-gnueabihf-')
 env.Append(CXXFLAGS='-march=armv7-a')
 
-env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
+env['CALL_TYPE']['inst'].impl('m5op.S', 'verify_inst.cc', default=True)
diff --git a/util/m5/src/abi/arm/verify_inst.cc b/util/m5/src/abi/arm/verify_inst.cc
new file mode 100644 (file)
index 0000000..7370e9e
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include "call_type/verify_inst.hh"
+
+void
+abi_verify_inst(const siginfo_t &info, int func)
+{
+    EXPECT_EQ(func, *(uint8_t *)((uintptr_t)info.si_addr + 2));
+}
index 18374c42f9d3b110e45f2ffaa89886df1be97ddf..5f35848ad743904c80b37dcd219832662177a4e6 100644 (file)
@@ -29,4 +29,4 @@ env['ABI'] = 'sparc'
 get_abi_opt('CROSS_COMPILE', 'sparc64-linux-gnu-')
 env.Append(CXXFLAGS='-m64')
 
-env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
+env['CALL_TYPE']['inst'].impl('m5op.S', 'verify_inst.cc', default=True)
diff --git a/util/m5/src/abi/sparc/verify_inst.cc b/util/m5/src/abi/sparc/verify_inst.cc
new file mode 100644 (file)
index 0000000..9fcf0fc
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include "call_type/verify_inst.hh"
+
+void
+abi_verify_inst(const siginfo_t &info, int func)
+{
+    EXPECT_EQ(func, (*(uint64_t *)info.si_addr >> 7) & 0xff);
+}
index b78cc068acad0c2f10516b01d0a7398ae9fcd2e9..f2441cf44c3877becd3ef9eef008dee268333577 100644 (file)
@@ -29,4 +29,4 @@ env['ABI'] = 'thumb'
 get_abi_opt('CROSS_COMPILE', 'arm-linux-gnueabihf-')
 env.Append(CXXFLAGS=[ '-mthumb', '-march=armv7' ])
 
-env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
+env['CALL_TYPE']['inst'].impl('m5op.S', 'verify_inst.cc', default=True)
diff --git a/util/m5/src/abi/thumb/verify_inst.cc b/util/m5/src/abi/thumb/verify_inst.cc
new file mode 100644 (file)
index 0000000..c3d6cda
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include "call_type/verify_inst.hh"
+
+void
+abi_verify_inst(const siginfo_t &info, int func)
+{
+    EXPECT_EQ(func, *(uint8_t *)info.si_addr);
+}
index 95c57d45134264245b829c74be6100c8b2c817d5..5c41ea7d2997a357caa326e30f48bf82ec97423b 100644 (file)
@@ -30,5 +30,5 @@ get_abi_opt('CROSS_COMPILE', '')
 env.Append(CXXFLAGS='-DM5OP_ADDR=0xFFFF0000')
 env.Append(CCFLAGS='-DM5OP_ADDR=0xFFFF0000')
 
-env['CALL_TYPE']['inst'].impl('m5op.S')
+env['CALL_TYPE']['inst'].impl('m5op.S', 'verify_inst.cc')
 env['CALL_TYPE']['addr'].impl('m5op_addr.S', default=True)
diff --git a/util/m5/src/abi/x86/verify_inst.cc b/util/m5/src/abi/x86/verify_inst.cc
new file mode 100644 (file)
index 0000000..8809ec1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include "call_type/verify_inst.hh"
+
+void
+abi_verify_inst(const siginfo_t &info, int func)
+{
+    EXPECT_EQ(func, *(uint16_t *)((uintptr_t)info.si_addr + 2));
+}
index e4a8520090968b8a00ae0de70c6663cc3c0abf9d..be87b0ba3798adc34475db7744de4904bd458106 100644 (file)
 
 #include <gtest/gtest.h>
 
+#include <csetjmp>
+#include <csignal>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+#include <gem5/asm/generic/m5ops.h>
+
+#include "args.hh"
 #include "call_type.hh"
+#include "call_type/verify_inst.hh"
+#include "dispatch_table.hh"
+
+class DefaultCallType : public CallType
+{
+  private:
+    DispatchTable dt;
+
+  public:
+    DefaultCallType() : CallType("default") {}
+
+    bool init_called = false;
+    void init() override { init_called = true; }
+
+    bool isDefault() const override { return true; }
+    void printDesc(std::ostream &os) const override {}
+    const DispatchTable &getDispatch() const override { return dt; }
+};
+
+DefaultCallType defaultCallType;
+
+TEST(InstCallType, Detect)
+{
+    CallType *ct;
+
+    // Inst should not be selected if there are no arguments.
+    Args empty({});
+    defaultCallType.init_called = false;
+    ct = CallType::detect(empty);
+    EXPECT_EQ(ct, &defaultCallType);
+    EXPECT_TRUE(defaultCallType.init_called);
+
+    // Inst should not be selected if --inst isn't the first argument.
+    Args one_arg({"one"});
+    defaultCallType.init_called = false;
+    ct = CallType::detect(one_arg);
+    EXPECT_EQ(ct, &defaultCallType);
+    EXPECT_TRUE(defaultCallType.init_called);
+
+    // Inst should be selected if --inst is the first argument.
+    Args selected({"--inst"});
+    defaultCallType.init_called = false;
+    ct = CallType::detect(selected);
+    EXPECT_NE(ct, &defaultCallType);
+    EXPECT_NE(ct, nullptr);
+    EXPECT_FALSE(defaultCallType.init_called);
+
+    Args extra({"--inst", "foo"});
+    defaultCallType.init_called = false;
+    ct = CallType::detect(extra);
+    EXPECT_NE(ct, &defaultCallType);
+    EXPECT_NE(ct, nullptr);
+    EXPECT_FALSE(defaultCallType.init_called);
+
+    // Inst should not be selected if --inst isn't first.
+    Args not_first({"foo", "--inst"});
+    defaultCallType.init_called = false;
+    ct = CallType::detect(not_first);
+    EXPECT_EQ(ct, &defaultCallType);
+    EXPECT_TRUE(defaultCallType.init_called);
+}
+
+sigjmp_buf interceptEnv;
+siginfo_t interceptSiginfo;
+
+void
+sigill_handler(int sig, siginfo_t *info, void *ucontext)
+{
+    std::memcpy(&interceptSiginfo, info, sizeof(interceptSiginfo));
+    siglongjmp(interceptEnv, 1);
+}
 
 TEST(InstCallType, Sum)
 {
+    // Get the inst call type, which is in an anonymous namespace.
+    Args args({"--inst"});
+    CallType *inst_call_type = CallType::detect(args);
+    EXPECT_NE(inst_call_type, nullptr);
+
+    // Get the dispatch table associated with it.
+    const auto &dt = inst_call_type->getDispatch();
+
+    // Determine if we're running within gem5 by checking whether a flag is
+    // set in the environment.
+    bool in_gem5 = (std::getenv("RUNNING_IN_GEM5") != nullptr);
+    if (in_gem5)
+        std::cout << "In gem5, m5 ops should work." << std::endl;
+    else
+        std::cout << "Not in gem5, m5 ops won't work." << std::endl;
+
+    // If it is, then we should be able to run the "sum" command.
+    if (in_gem5) {
+        EXPECT_EQ((*dt.m5_sum)(2, 2, 0, 0, 0, 0), 4);
+        return;
+    }
+
+    // If not, then we'll need to try to catch the fall out from trying to run
+    // an m5 op and verify that what we were trying looks correct.
+
+    struct sigaction sigill_action;
+    std::memset(&sigill_action, 0, sizeof(sigill_action));
+    sigill_action.sa_sigaction = &sigill_handler;
+    sigill_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
+
+    struct sigaction old_sigill_action;
+
+    sigaction(SIGILL, &sigill_action, &old_sigill_action);
+
+    if (!sigsetjmp(interceptEnv, 1)) {
+        (*dt.m5_sum)(2, 2, 0, 0, 0, 0);
+        sigaction(SIGILL, &old_sigill_action, nullptr);
+        ADD_FAILURE() << "Didn't die when attempting to run \"sum\".";
+        return;
+    }
+
+    // Back from siglongjump.
+    auto &info = interceptSiginfo;
+
+    EXPECT_EQ(info.si_signo, SIGILL);
+    EXPECT_TRUE(info.si_code == ILL_ILLOPC || info.si_code == ILL_ILLOPN);
+
+    // Do abi specific verification.
+    abi_verify_inst(info, M5OP_SUM);
 }
diff --git a/util/m5/src/call_type/verify_inst.hh b/util/m5/src/call_type/verify_inst.hh
new file mode 100644 (file)
index 0000000..2b471fe
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <csignal>
+
+#ifndef __VERIFY_INST_HH__
+#define __VERIFY_INST_HH__
+
+void abi_verify_inst(const siginfo_t &info, int func);
+
+#endif // __VERIFY_INST_HH__