arch,base,sim: Move Process loader hooks into the Process class.

This code was originally in the ObjectFile class, but not all object
files will become Processes. All Processes will ultimately come from
ObjectFiles though, so it makes more sense to put that class there.

Change-Id: Ie73e4cdecbb51ce53d24cf68911a6cfc0685d771
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21468
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc
index f129b26..322a5b9 100644
--- a/src/arch/alpha/linux/process.cc
+++ b/src/arch/alpha/linux/process.cc
@@ -48,7 +48,7 @@
 namespace
 {
 
-class AlphaLinuxObjectFileLoader : public ObjectFile::Loader
+class AlphaLinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/arm/freebsd/process.cc b/src/arch/arm/freebsd/process.cc
index 69424c9..399da3a 100644
--- a/src/arch/arm/freebsd/process.cc
+++ b/src/arch/arm/freebsd/process.cc
@@ -56,7 +56,7 @@
 namespace
 {
 
-class ArmFreebsdObjectFileLoader : public ObjectFile::Loader
+class ArmFreebsdObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index 426f66a..ca8e00c 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -65,7 +65,7 @@
 namespace
 {
 
-class ArmLinuxObjectFileLoader : public ObjectFile::Loader
+class ArmLinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
index 596f2dd..1d2709a 100644
--- a/src/arch/mips/linux/process.cc
+++ b/src/arch/mips/linux/process.cc
@@ -51,7 +51,7 @@
 namespace
 {
 
-class MipsLinuxObjectFileLoader : public ObjectFile::Loader
+class MipsLinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc
index 97032d9..f39de53 100644
--- a/src/arch/power/linux/process.cc
+++ b/src/arch/power/linux/process.cc
@@ -51,7 +51,7 @@
 namespace
 {
 
-class PowerLinuxObjectFileLoader : public ObjectFile::Loader
+class PowerLinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/riscv/linux/process.cc b/src/arch/riscv/linux/process.cc
index 6708e02..4a16f77 100644
--- a/src/arch/riscv/linux/process.cc
+++ b/src/arch/riscv/linux/process.cc
@@ -55,7 +55,7 @@
 namespace
 {
 
-class RiscvLinuxObjectFileLoader : public ObjectFile::Loader
+class RiscvLinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index 2fd9838..5fb3b03 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -48,7 +48,7 @@
 namespace
 {
 
-class SparcLinuxObjectFileLoader : public ObjectFile::Loader
+class SparcLinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc
index fb38c77..18f2316 100644
--- a/src/arch/sparc/solaris/process.cc
+++ b/src/arch/sparc/solaris/process.cc
@@ -46,7 +46,7 @@
 namespace
 {
 
-class SparcSolarisObjectFileLoader : public ObjectFile::Loader
+class SparcSolarisObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index 8f669bf..dfb1c42 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -58,7 +58,7 @@
 namespace
 {
 
-class X86LinuxObjectFileLoader : public ObjectFile::Loader
+class X86LinuxObjectFileLoader : public Process::Loader
 {
   public:
     Process *
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index b7e0542..10c9271 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -42,37 +42,6 @@
 
 ObjectFile::ObjectFile(ImageFileDataPtr ifd) : ImageFile(ifd) {}
 
-namespace
-{
-
-typedef std::vector<ObjectFile::Loader *> LoaderList;
-
-LoaderList &
-object_file_loaders()
-{
-    static LoaderList loaders;
-    return loaders;
-}
-
-} // anonymous namespace
-
-ObjectFile::Loader::Loader()
-{
-    object_file_loaders().emplace_back(this);
-}
-
-Process *
-ObjectFile::tryLoaders(ProcessParams *params, ObjectFile *obj_file)
-{
-    for (auto &loader: object_file_loaders()) {
-        Process *p = loader->load(params, obj_file);
-        if (p)
-            return p;
-    }
-
-    return nullptr;
-}
-
 namespace {
 
 typedef std::vector<ObjectFileFormat *> ObjectFileFormatList;
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index da35db1..0c279c9 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -40,8 +40,6 @@
 #include "base/logging.hh"
 #include "base/types.hh"
 
-class Process;
-class ProcessParams;
 class SymbolTable;
 
 class ObjectFile : public ImageFile
@@ -131,38 +129,6 @@
 
   public:
     Addr entryPoint() const { return entry; }
-
-    /**
-     * Each instance of a Loader subclass will have a chance to try to load
-     * an object file when tryLoaders is called. If they can't because they
-     * aren't compatible with it (wrong arch, wrong OS, etc), then they
-     * silently fail by returning nullptr so other loaders can try.
-     */
-    class Loader
-    {
-      public:
-        Loader();
-
-        /* Loader instances are singletons. */
-        Loader(const Loader &) = delete;
-        void operator=(const Loader &) = delete;
-
-        virtual ~Loader() {}
-
-        /**
-         * Each subclass needs to implement this method. If the loader is
-         * compatible with the passed in object file, it should return the
-         * created Process object corresponding to it. If not, it should fail
-         * silently and return nullptr. If there's a non-compatibliity related
-         * error like file IO errors, etc., those should fail non-silently
-         * with a panic or fail as normal.
-         */
-        virtual Process *load(ProcessParams *params, ObjectFile *obj_file) = 0;
-    };
-
-    // Try all the Loader instance's "load" methods one by one until one is
-    // successful. If none are, complain and fail.
-    static Process *tryLoaders(ProcessParams *params, ObjectFile *obj_file);
 };
 
 class ObjectFileFormat
diff --git a/src/sim/process.cc b/src/sim/process.cc
index a01cfea..db013ae 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -75,6 +75,37 @@
 using namespace std;
 using namespace TheISA;
 
+namespace
+{
+
+typedef std::vector<Process::Loader *> LoaderList;
+
+LoaderList &
+process_loaders()
+{
+    static LoaderList loaders;
+    return loaders;
+}
+
+} // anonymous namespace
+
+Process::Loader::Loader()
+{
+    process_loaders().emplace_back(this);
+}
+
+Process *
+Process::tryLoaders(ProcessParams *params, ObjectFile *obj_file)
+{
+    for (auto &loader: process_loaders()) {
+        Process *p = loader->load(params, obj_file);
+        if (p)
+            return p;
+    }
+
+    return nullptr;
+}
+
 static std::string
 normalize(std::string& directory)
 {
@@ -554,7 +585,7 @@
     ObjectFile *obj_file = createObjectFile(executable);
     fatal_if(!obj_file, "Cannot load object file %s.", executable);
 
-    Process *process = ObjectFile::tryLoaders(this, obj_file);
+    Process *process = Process::tryLoaders(this, obj_file);
     fatal_if(!process, "Unknown error creating process object.");
 
     return process;
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 8e35307..a28d58e 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -183,6 +183,38 @@
 
     SETranslatingPortProxy initVirtMem; // memory proxy for initial image load
 
+    /**
+     * Each instance of a Loader subclass will have a chance to try to load
+     * an object file when tryLoaders is called. If they can't because they
+     * aren't compatible with it (wrong arch, wrong OS, etc), then they
+     * silently fail by returning nullptr so other loaders can try.
+     */
+    class Loader
+    {
+      public:
+        Loader();
+
+        /* Loader instances are singletons. */
+        Loader(const Loader &) = delete;
+        void operator=(const Loader &) = delete;
+
+        virtual ~Loader() {}
+
+        /**
+         * Each subclass needs to implement this method. If the loader is
+         * compatible with the passed in object file, it should return the
+         * created Process object corresponding to it. If not, it should fail
+         * silently and return nullptr. If there's a non-compatibliity related
+         * error like file IO errors, etc., those should fail non-silently
+         * with a panic or fail as normal.
+         */
+        virtual Process *load(ProcessParams *params, ObjectFile *obj_file) = 0;
+    };
+
+    // Try all the Loader instance's "load" methods one by one until one is
+    // successful. If none are, complain and fail.
+    static Process *tryLoaders(ProcessParams *params, ObjectFile *obj_file);
+
     ObjectFile *objFile;
     MemoryImage image;
     MemoryImage interpImage;