sim: Eliminate m5MainCommands and simplify calling m5.main.

m5MainCommands had been a way to override the python code which would
get the python side of gem5 started, used by some "unit" tests which
were really tests of all of gem5 but focus on a particular area. Those
tests have either been converted into real unit tests or eliminated,
and so that mechanism is no longer needed.

This change eliminates that mechanism, and also uses pybind11 to
significantly simplify the code that calls m5.main().

Change-Id: I553ae17074cd5389708f1b7313630a13a6946d76
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49412
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/sim/init.cc b/src/sim/init.cc
index ce72b04..abbb8c2 100644
--- a/src/sim/init.cc
+++ b/src/sim/init.cc
@@ -225,16 +225,6 @@
 }
 
 /*
- * Make the commands array weak so that they can be overridden (used
- * by unit tests to specify a different python main function.
- */
-GEM5_WEAK const char *m5MainCommands[] = {
-    "import m5",
-    "m5.main()",
-    0 // sentinel is required
-};
-
-/*
  * Start up the M5 simulator.  This mostly vectors into the python
  * main function.
  */
@@ -263,27 +253,14 @@
 
     PySys_SetArgv(argc, argv);
 
-    // We have to set things up in the special __main__ module
-    PyObject *module = PyImport_AddModule(PyCC("__main__"));
-    if (module == NULL)
-        panic("Could not import __main__");
-    PyObject *dict = PyModule_GetDict(module);
+    try {
+        py::module_::import("m5").attr("main")();
+    } catch (py::error_already_set &e) {
+        if (e.matches(PyExc_SystemExit))
+            return e.value().attr("code").cast<int>();
 
-    // import the main m5 module
-    PyObject *result;
-    const char **command = m5MainCommands;
-
-    // evaluate each command in the m5MainCommands array (basically a
-    // bunch of python statements.
-    while (*command) {
-        result = PyRun_String(*command, Py_file_input, dict, dict);
-        if (!result) {
-            PyErr_Print();
-            return 1;
-        }
-        Py_DECREF(result);
-
-        command++;
+        std::cerr << e.what();
+        return 1;
     }
 
 #if HAVE_PROTOBUF