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>
This commit is contained in:
Gabe Black
2019-10-04 01:21:24 -07:00
parent 245422102c
commit e35b491c46
13 changed files with 73 additions and 75 deletions

View File

@@ -48,7 +48,7 @@ using namespace AlphaISA;
namespace
{
class AlphaLinuxObjectFileLoader : public ObjectFile::Loader
class AlphaLinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -56,7 +56,7 @@ using namespace ArmISA;
namespace
{
class ArmFreebsdObjectFileLoader : public ObjectFile::Loader
class ArmFreebsdObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -65,7 +65,7 @@ using namespace ArmISA;
namespace
{
class ArmLinuxObjectFileLoader : public ObjectFile::Loader
class ArmLinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -51,7 +51,7 @@ using namespace MipsISA;
namespace
{
class MipsLinuxObjectFileLoader : public ObjectFile::Loader
class MipsLinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -51,7 +51,7 @@ using namespace PowerISA;
namespace
{
class PowerLinuxObjectFileLoader : public ObjectFile::Loader
class PowerLinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -55,7 +55,7 @@ using namespace RiscvISA;
namespace
{
class RiscvLinuxObjectFileLoader : public ObjectFile::Loader
class RiscvLinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -48,7 +48,7 @@ using namespace SparcISA;
namespace
{
class SparcLinuxObjectFileLoader : public ObjectFile::Loader
class SparcLinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -46,7 +46,7 @@ using namespace SparcISA;
namespace
{
class SparcSolarisObjectFileLoader : public ObjectFile::Loader
class SparcSolarisObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -58,7 +58,7 @@ using namespace X86ISA;
namespace
{
class X86LinuxObjectFileLoader : public ObjectFile::Loader
class X86LinuxObjectFileLoader : public Process::Loader
{
public:
Process *

View File

@@ -42,37 +42,6 @@ using namespace std;
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;

View File

@@ -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

View File

@@ -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 @@ 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;

View File

@@ -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;