Model & version check for simulator plugins.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8356 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2006-01-16 23:20:58 +00:00
parent 137501b9ac
commit a79027743a
4 changed files with 47 additions and 39 deletions

View file

@ -369,15 +369,15 @@ static const struct plugin_api rockbox_api = {
int plugin_load(const char* plugin, void* parameter) int plugin_load(const char* plugin, void* parameter)
{ {
enum plugin_status (*plugin_start)(struct plugin_api* api, void* param); enum plugin_status (*plugin_start)(struct plugin_api* api, void* param);
int rc; int fd, rc;
#ifndef SIMULATOR #ifndef SIMULATOR
struct plugin_header header; struct plugin_header header;
ssize_t readsize; ssize_t readsize;
#else
struct plugin_header *hdr;
#endif #endif
int fd;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
int xm,ym; int xm, ym;
#endif #endif
if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */ if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */
@ -397,16 +397,32 @@ int plugin_load(const char* plugin, void* parameter)
lcd_clear_display(); lcd_clear_display();
#endif #endif
#ifdef SIMULATOR #ifdef SIMULATOR
plugin_start = sim_plugin_load((char *)plugin, &fd); hdr = sim_plugin_load((char *)plugin, &fd);
if(!plugin_start) if (!fd) {
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin);
return -1; return -1;
}
if (hdr == NULL
|| hdr->magic != PLUGIN_MAGIC
|| hdr->target_id != TARGET_ID
|| hdr->entry_point == NULL) {
sim_plugin_close(fd);
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
return -1;
}
if (hdr->api_version > PLUGIN_API_VERSION
|| hdr->api_version < PLUGIN_MIN_API_VERSION) {
sim_plugin_close(fd);
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION));
return -1;
}
plugin_start = hdr->entry_point;
#else #else
fd = open(plugin, O_RDONLY); fd = open(plugin, O_RDONLY);
if (fd < 0) { if (fd < 0) {
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin); gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin);
return fd; return fd;
} }
readsize = read(fd, &header, sizeof(header)); readsize = read(fd, &header, sizeof(header));
close(fd); close(fd);
/* Close for now. Less code than doing it in all error checks. /* Close for now. Less code than doing it in all error checks.
@ -428,7 +444,6 @@ int plugin_load(const char* plugin, void* parameter)
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION)); gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION));
return -1; return -1;
} }
/* zero out plugin buffer to ensure a properly zeroed bss area */ /* zero out plugin buffer to ensure a properly zeroed bss area */
memset(pluginbuf, 0, header.end_addr - pluginbuf); memset(pluginbuf, 0, header.end_addr - pluginbuf);
@ -445,8 +460,8 @@ int plugin_load(const char* plugin, void* parameter)
gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin); gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin);
return -1; return -1;
} }
plugin_start = header.entry_point;
plugin_size = header.end_addr - header.load_addr; plugin_size = header.end_addr - header.load_addr;
plugin_start = header.entry_point;
#endif #endif
plugin_loaded = true; plugin_loaded = true;
@ -463,11 +478,15 @@ int plugin_load(const char* plugin, void* parameter)
#else /* LCD_DEPTH == 1 */ #else /* LCD_DEPTH == 1 */
lcd_set_drawmode(DRMODE_SOLID); lcd_set_drawmode(DRMODE_SOLID);
#endif /* LCD_DEPTH */ #endif /* LCD_DEPTH */
/* restore margins */
lcd_setmargins(xm,ym);
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */
if (pfn_tsr_exit == NULL) if (pfn_tsr_exit == NULL)
plugin_loaded = false; plugin_loaded = false;
sim_plugin_close(fd);
switch (rc) { switch (rc) {
case PLUGIN_OK: case PLUGIN_OK:
break; break;
@ -480,13 +499,6 @@ int plugin_load(const char* plugin, void* parameter)
break; break;
} }
sim_plugin_close(fd);
#ifdef HAVE_LCD_BITMAP
/* restore margins */
lcd_setmargins(xm,ym);
#endif
return PLUGIN_OK; return PLUGIN_OK;
} }

View file

@ -427,7 +427,6 @@ struct plugin_api {
}; };
#ifndef SIMULATOR
/* plugin header */ /* plugin header */
struct plugin_header { struct plugin_header {
unsigned long magic; unsigned long magic;
@ -438,6 +437,7 @@ struct plugin_header {
enum plugin_status(*entry_point)(struct plugin_api*, void*); enum plugin_status(*entry_point)(struct plugin_api*, void*);
}; };
#ifdef PLUGIN #ifdef PLUGIN
#ifndef SIMULATOR
extern unsigned char plugin_start_addr[]; extern unsigned char plugin_start_addr[];
extern unsigned char plugin_end_addr[]; extern unsigned char plugin_end_addr[];
#define PLUGIN_HEADER \ #define PLUGIN_HEADER \
@ -445,9 +445,12 @@ extern unsigned char plugin_end_addr[];
__attribute__ ((section (".header")))= { \ __attribute__ ((section (".header")))= { \
PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \
plugin_start_addr, plugin_end_addr, plugin_start }; plugin_start_addr, plugin_end_addr, plugin_start };
#endif
#else /* SIMULATOR */ #else /* SIMULATOR */
#define PLUGIN_HEADER #define PLUGIN_HEADER \
const struct plugin_header __header = { \
PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \
NULL, NULL, plugin_start };
#endif
#endif #endif
int plugin_load(const char* plugin, void* parameter); int plugin_load(const char* plugin, void* parameter);
@ -456,7 +459,6 @@ void* plugin_get_audio_buffer(int *buffer_size);
void plugin_tsr(void (*exit_callback)(void)); void plugin_tsr(void (*exit_callback)(void));
/* defined by the plugin */ /* defined by the plugin */
enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter);
__attribute__ ((section (".entry")));
#endif #endif

View file

@ -377,16 +377,15 @@ void sim_codec_close(int pd)
void *sim_plugin_load(char *plugin, int *fd) void *sim_plugin_load(char *plugin, int *fd)
{ {
void* pd; void *pd, *hdr;
char path[256]; char path[256];
int (*plugin_start)(void * api, void* param);
#ifdef WIN32 #ifdef WIN32
char buf[256]; char buf[256];
#endif #endif
snprintf(path, sizeof path, "archos%s", plugin); snprintf(path, sizeof path, "archos%s", plugin);
*fd = -1; *fd = 0;
pd = dlopen(path, RTLD_NOW); pd = dlopen(path, RTLD_NOW);
if (!pd) { if (!pd) {
@ -402,16 +401,12 @@ void *sim_plugin_load(char *plugin, int *fd)
return NULL; return NULL;
} }
plugin_start = dlsym(pd, "plugin_start"); hdr = dlsym(pd, "__header");
if (!plugin_start) { if (!hdr)
plugin_start = dlsym(pd, "_plugin_start"); hdr = dlsym(pd, "___header");
if (!plugin_start) {
dlclose(pd);
return NULL;
}
}
*fd = (int)pd; /* success */ *fd = (int)pd; /* success */
return plugin_start; return hdr; /* maybe NULL if symbol not present */
} }
void sim_plugin_close(int pd) void sim_plugin_close(int pd)

View file

@ -1,3 +1,2 @@
EXPORTS EXPORTS
plugin_start __header