From e35b491c464f8961f5f3fff56478f12716f5a424 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 4 Oct 2019 01:21:24 -0700 Subject: [PATCH] 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 Reviewed-by: Gabe Black Tested-by: kokoro Maintainer: Gabe Black --- src/arch/alpha/linux/process.cc | 2 +- src/arch/arm/freebsd/process.cc | 2 +- src/arch/arm/linux/process.cc | 2 +- src/arch/mips/linux/process.cc | 2 +- src/arch/power/linux/process.cc | 2 +- src/arch/riscv/linux/process.cc | 2 +- src/arch/sparc/linux/process.cc | 2 +- src/arch/sparc/solaris/process.cc | 2 +- src/arch/x86/linux/process.cc | 2 +- src/base/loader/object_file.cc | 31 ---------------------------- src/base/loader/object_file.hh | 34 ------------------------------- src/sim/process.cc | 33 +++++++++++++++++++++++++++++- src/sim/process.hh | 32 +++++++++++++++++++++++++++++ 13 files changed, 73 insertions(+), 75 deletions(-) diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index f129b263f..322a5b9fe 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -48,7 +48,7 @@ using namespace AlphaISA; 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 69424c989..399da3a42 100644 --- a/src/arch/arm/freebsd/process.cc +++ b/src/arch/arm/freebsd/process.cc @@ -56,7 +56,7 @@ using namespace ArmISA; 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 426f66a55..ca8e00c71 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -65,7 +65,7 @@ using namespace ArmISA; 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 596f2dda0..1d2709aa1 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -51,7 +51,7 @@ using namespace MipsISA; 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 97032d989..f39de53f8 100644 --- a/src/arch/power/linux/process.cc +++ b/src/arch/power/linux/process.cc @@ -51,7 +51,7 @@ using namespace PowerISA; 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 6708e026f..4a16f77f7 100644 --- a/src/arch/riscv/linux/process.cc +++ b/src/arch/riscv/linux/process.cc @@ -55,7 +55,7 @@ using namespace RiscvISA; 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 2fd983808..5fb3b0348 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -48,7 +48,7 @@ using namespace SparcISA; 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 fb38c77ee..18f2316a2 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -46,7 +46,7 @@ using namespace SparcISA; 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 8f669bfa5..dfb1c42f8 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -58,7 +58,7 @@ using namespace X86ISA; 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 b7e05428c..10c927125 100644 --- a/src/base/loader/object_file.cc +++ b/src/base/loader/object_file.cc @@ -42,37 +42,6 @@ using namespace std; ObjectFile::ObjectFile(ImageFileDataPtr ifd) : ImageFile(ifd) {} -namespace -{ - -typedef std::vector 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 ObjectFileFormatList; diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index da35db148..0c279c933 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 @@ class ObjectFile : public ImageFile 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 a01cfea91..db013aee0 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 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 @@ ProcessParams::create() 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 8e353071c..a28d58e9a 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -183,6 +183,38 @@ class Process : public SimObject 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; -- 2.30.2