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:
Max Horn 2010-11-05 01:20:34 +00:00
parent 102e7ee88c
commit 7ace85e636
12 changed files with 38 additions and 135 deletions

View File

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

View File

@ -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) */

View File

@ -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.");

View File

@ -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) */

View File

@ -137,7 +137,7 @@ bool ELFPlugin::loadPlugin() {
}
#endif
_dlHandle->discard_symtab();
_dlHandle->discardSymtab();
return ret;
}

View File

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

View File

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

View File

@ -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) */

View File

@ -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) */

View File

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

View File

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

View File

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