mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
PLUGINS: Simplify ELF plugin providers & DLObject subclasses
* Remove DLObject virtual methods allocSegment and freeSegment. As long as all DLObject implementations use memalign + free to allocate/release segments, there is no point in wrapping those. This enables further simplifications. * Add TemplatedELFPlugin template class. Use this instead of explicit ELFPlugin subclasses. * Rename DLObject::discard_symtab to discardSymtab svn-id: r54082
This commit is contained in:
parent
102e7ee88c
commit
7ace85e636
@ -32,43 +32,15 @@
|
||||
#include "backends/plugins/elf/arm-loader.h"
|
||||
|
||||
class DSDLObject : public ARMDLObject {
|
||||
public:
|
||||
DSDLObject() :
|
||||
ARMDLObject() {
|
||||
}
|
||||
|
||||
virtual ~DSDLObject() {
|
||||
unload();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void *allocSegment(size_t boundary, size_t size) const {
|
||||
return memalign(boundary, size);
|
||||
}
|
||||
|
||||
virtual void freeSegment(void *segment) const {
|
||||
free(segment);
|
||||
}
|
||||
|
||||
virtual void flushDataCache(void *ptr, uint32 len) const {
|
||||
DC_FlushRange(ptr, len);
|
||||
IC_InvalidateRange(ptr, len);
|
||||
}
|
||||
};
|
||||
|
||||
class DSPlugin : public ELFPlugin {
|
||||
public:
|
||||
DSPlugin(const Common::String &filename) :
|
||||
ELFPlugin(filename) {
|
||||
}
|
||||
|
||||
virtual DLObject *makeDLObject() {
|
||||
return new DSDLObject();
|
||||
}
|
||||
};
|
||||
|
||||
Plugin *DSPluginProvider::createPlugin(const Common::FSNode &node) const {
|
||||
return new DSPlugin(node.getPath());
|
||||
return new TemplatedELFPlugin<DSDLObject>(node.getPath());
|
||||
}
|
||||
|
||||
#endif // defined(DYNAMIC_MODULES) && defined(__DS__)
|
||||
|
@ -36,11 +36,6 @@ class ARMDLObject : public DLObject {
|
||||
protected:
|
||||
virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment);
|
||||
virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr);
|
||||
|
||||
public:
|
||||
ARMDLObject() :
|
||||
DLObject() {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ARM_TARGET) */
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "common/fs.h"
|
||||
#include "common/ptr.h"
|
||||
|
||||
#include <malloc.h> // for memalign()
|
||||
|
||||
DLObject::DLObject() :
|
||||
_file(0),
|
||||
_segment(0),
|
||||
@ -49,10 +51,13 @@ DLObject::DLObject() :
|
||||
}
|
||||
|
||||
DLObject::~DLObject() {
|
||||
discardSymtab();
|
||||
free(_segment);
|
||||
_segment = 0;
|
||||
}
|
||||
|
||||
// Expel the symbol table from memory
|
||||
void DLObject::discard_symtab() {
|
||||
void DLObject::discardSymtab() {
|
||||
free(_symtab);
|
||||
_symtab = 0;
|
||||
|
||||
@ -64,9 +69,9 @@ void DLObject::discard_symtab() {
|
||||
|
||||
// Unload all objects from memory
|
||||
void DLObject::unload() {
|
||||
discard_symtab();
|
||||
discardSymtab();
|
||||
|
||||
freeSegment(_segment);
|
||||
free(_segment);
|
||||
|
||||
_segment = 0;
|
||||
_segmentSize = 0;
|
||||
@ -160,7 +165,7 @@ bool DLObject::readProgramHeaders(Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half
|
||||
}
|
||||
|
||||
bool DLObject::loadSegment(Elf32_Phdr *phdr) {
|
||||
_segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz);
|
||||
_segment = (byte *)memalign(phdr->p_align, phdr->p_memsz);
|
||||
|
||||
if (!_segment) {
|
||||
warning("elfloader: Out of memory.");
|
||||
|
@ -84,8 +84,6 @@ protected:
|
||||
virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0;
|
||||
|
||||
// platform specific
|
||||
virtual void *allocSegment(size_t boundary, size_t size) const = 0;
|
||||
virtual void freeSegment(void *segment) const = 0;
|
||||
virtual void flushDataCache(void *ptr, uint32 len) const = 0;
|
||||
|
||||
public:
|
||||
@ -95,7 +93,7 @@ public:
|
||||
bool open(const char *path);
|
||||
bool close();
|
||||
void *symbol(const char *name);
|
||||
void discard_symtab();
|
||||
void discardSymtab();
|
||||
};
|
||||
|
||||
#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) */
|
||||
|
@ -137,7 +137,7 @@ bool ELFPlugin::loadPlugin() {
|
||||
}
|
||||
#endif
|
||||
|
||||
_dlHandle->discard_symtab();
|
||||
_dlHandle->discardSymtab();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -71,6 +71,19 @@ public:
|
||||
void unloadPlugin();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class TemplatedELFPlugin : public ELFPlugin {
|
||||
public:
|
||||
TemplatedELFPlugin(const Common::String &filename) :
|
||||
ELFPlugin(filename) {
|
||||
}
|
||||
|
||||
virtual DLObject *makeDLObject() {
|
||||
return new T();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ELFPluginProvider : public FilePluginProvider {
|
||||
protected:
|
||||
virtual Plugin *createPlugin(const Common::FSNode &node) const = 0;
|
||||
|
@ -281,7 +281,7 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) {
|
||||
// We need to take account of non-allocated segment for shorts
|
||||
if (phdr->p_flags & PF_X) { // This is a relocated segment
|
||||
// Attempt to allocate memory for segment
|
||||
_segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz);
|
||||
_segment = (byte *)memalign(phdr->p_align, phdr->p_memsz);
|
||||
|
||||
if (!_segment) {
|
||||
warning("elfloader: Out of memory.");
|
||||
@ -328,7 +328,10 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) {
|
||||
// Unload all objects from memory
|
||||
void MIPSDLObject::unload() {
|
||||
DLObject::unload();
|
||||
|
||||
freeShortsSegment();
|
||||
}
|
||||
|
||||
void MIPSDLObject::freeShortsSegment() {
|
||||
if (_shortsSegment) {
|
||||
ShortsMan.deleteSegment(_shortsSegment);
|
||||
_shortsSegment = 0;
|
||||
|
@ -45,12 +45,17 @@ protected:
|
||||
virtual bool loadSegment(Elf32_Phdr *phdr);
|
||||
virtual void unload();
|
||||
|
||||
void freeShortsSegment();
|
||||
|
||||
public:
|
||||
MIPSDLObject() :
|
||||
DLObject() {
|
||||
_shortsSegment = NULL;
|
||||
_gpVal = 0;
|
||||
}
|
||||
~MIPSDLObject() {
|
||||
freeShortsSegment();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) */
|
||||
|
@ -36,11 +36,6 @@ class PPCDLObject : public DLObject {
|
||||
protected:
|
||||
virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment);
|
||||
virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr);
|
||||
|
||||
public:
|
||||
PPCDLObject() :
|
||||
DLObject() {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(PPC_TARGET) */
|
||||
|
@ -29,23 +29,7 @@
|
||||
#include "backends/plugins/elf/mips-loader.h"
|
||||
|
||||
class PS2DLObject : public MIPSDLObject {
|
||||
public:
|
||||
PS2DLObject() :
|
||||
MIPSDLObject() {
|
||||
}
|
||||
|
||||
virtual ~PS2DLObject() {
|
||||
unload();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void *allocSegment(size_t boundary, size_t size) const {
|
||||
return memalign(boundary, size);
|
||||
}
|
||||
|
||||
virtual void freeSegment(void *segment) const {
|
||||
free(segment);
|
||||
}
|
||||
|
||||
virtual void flushDataCache(void *, uint32) const {
|
||||
FlushCache(0);
|
||||
@ -53,19 +37,8 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class PS2Plugin : public ELFPlugin {
|
||||
public:
|
||||
PS2Plugin(const Common::String &filename) :
|
||||
ELFPlugin(filename) {
|
||||
}
|
||||
|
||||
virtual DLObject *makeDLObject() {
|
||||
return new PS2DLObject();
|
||||
}
|
||||
};
|
||||
|
||||
Plugin *PS2PluginProvider::createPlugin(const Common::FSNode &node) const {
|
||||
return new PS2Plugin(node.getPath());
|
||||
return new TemplatedELFPlugin<PS2DLObject>(node.getPath());
|
||||
}
|
||||
|
||||
#endif // defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__)
|
||||
|
@ -32,43 +32,15 @@
|
||||
#include "backends/plugins/elf/mips-loader.h"
|
||||
|
||||
class PSPDLObject : public MIPSDLObject {
|
||||
public:
|
||||
PSPDLObject() :
|
||||
MIPSDLObject() {
|
||||
}
|
||||
|
||||
virtual ~PSPDLObject() {
|
||||
unload();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void *allocSegment(size_t boundary, size_t size) const {
|
||||
return memalign(boundary, size);
|
||||
}
|
||||
|
||||
virtual void freeSegment(void *segment) const {
|
||||
free(segment);
|
||||
}
|
||||
|
||||
virtual void flushDataCache(void *ptr, uint32 len) const {
|
||||
sceKernelDcacheWritebackRange(ptr, len);
|
||||
sceKernelIcacheInvalidateRange(ptr, len);
|
||||
}
|
||||
};
|
||||
|
||||
class PSPPlugin : public ELFPlugin {
|
||||
public:
|
||||
PSPPlugin(const Common::String &filename) :
|
||||
ELFPlugin(filename) {
|
||||
}
|
||||
|
||||
virtual DLObject *makeDLObject() {
|
||||
return new PSPDLObject();
|
||||
}
|
||||
};
|
||||
|
||||
Plugin *PSPPluginProvider::createPlugin(const Common::FSNode &node) const {
|
||||
return new PSPPlugin(node.getPath());
|
||||
return new TemplatedELFPlugin<PSPDLObject>(node.getPath());
|
||||
}
|
||||
|
||||
#endif // defined(DYNAMIC_MODULES) && defined(__PSP__)
|
||||
|
@ -32,43 +32,15 @@
|
||||
#include "backends/plugins/elf/ppc-loader.h"
|
||||
|
||||
class WiiDLObject : public PPCDLObject {
|
||||
public:
|
||||
WiiDLObject() :
|
||||
PPCDLObject() {
|
||||
}
|
||||
|
||||
virtual ~WiiDLObject() {
|
||||
unload();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void *allocSegment(size_t boundary, size_t size) const {
|
||||
return memalign(boundary, size);
|
||||
}
|
||||
|
||||
virtual void freeSegment(void *segment) const {
|
||||
free(segment);
|
||||
}
|
||||
|
||||
virtual void flushDataCache(void *ptr, uint32 len) const {
|
||||
DCFlushRange(ptr, len);
|
||||
ICInvalidateRange(ptr, len);
|
||||
}
|
||||
};
|
||||
|
||||
class WiiPlugin : public ELFPlugin {
|
||||
public:
|
||||
WiiPlugin(const Common::String &filename) :
|
||||
ELFPlugin(filename) {
|
||||
}
|
||||
|
||||
virtual DLObject *makeDLObject() {
|
||||
return new WiiDLObject();
|
||||
}
|
||||
};
|
||||
|
||||
Plugin *WiiPluginProvider::createPlugin(const Common::FSNode &node) const {
|
||||
return new WiiPlugin(node.getPath());
|
||||
return new TemplatedELFPlugin<WiiDLObject>(node.getPath());
|
||||
}
|
||||
|
||||
#endif // defined(DYNAMIC_MODULES) && defined(__WII__)
|
||||
|
Loading…
Reference in New Issue
Block a user