Well, this is a similar problem I had for when I was doing gamedev for loading image files. I had a base image class with function with virtual functions for checking for a valid file, loading, and unloading. Then I had an image loading class, that was just a list of loaders... I could call AddLoader, and it would add whatever was passed it's way...
ImageLoad.Add(new BitmapLoader_C);
ImageLoad.Add(new TGALoader_C);
Then to load an image, I just call ImageLoad.Load("Test.bmp");. It would automatically call BitmapLoader_C and TGALoder_C to check if they support the file format. I could dynamically add file formats just by adding the new class (Which must be inherited from the base Loader_C class and have the correct overloaded functions). So, depending on what you needed, I would have a base class for EXE files...
Code: Select all
class BaseModule_C
{
public:
virtual char IsValid(char *Data, int Size) = 0; //Check if it's valid
virtual int FindSymbol(char *Data, char *Symbol, int Size) = 0; //Find a symbol in the file
virtual void Relocate(char *Data, int Size, int Address) = 0; //Relocate to this address
};
class ModuleLoader_C
{
public:
//Any type of list you prefer
List_C<BaseModule_C*> ModuleList;
public:
AddLoader(BaseModule_C *ptrLoader); //Add this one to our list...
BaseModule_C* FindLoader(char *Data, int Size); //return the module that can load it
};
You can then create an EXE loader, Coff loader, a.out, elf by inheriting the base class, then writing a bit of code to detect the magic value's and checking for a valid header. You would find the loader, then you can perform whatever you need on the module.
Code: Select all
ModuleLoader_C ModuleLoader;
int main(int argc, char *argv[])
{
BaseModule_C *ptrLoader;
int SymbolStart;
ModuleLoader.AddLoader(new EXELoader_C);
ModuleLoader.AddLoader(new CoffLoader_C);
ModuleLoader.AddLoader(new ELFLoader_C);
//Get the loader that can read this :)
ptrLoader = ModuleLoader.FindLoader(FileData,FileSize);
//Relocate the file
ptrLoader->Relocate(FileData,FileSize,LoadAddress);
//find a symbol
SymbolStart = ptrLoader->FindSymbol(FileData,"Start",FileSize);
return 1;
}
You can abstract it however far you'd like, but that is the general idea... you can dynamically add module loaders by inheriting from the base class, even after it's running without issue.