diff --git a/apps/plugin.c b/apps/plugin.c index 0997b0a901..a2cb0dedcb 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -369,15 +369,15 @@ static const struct plugin_api rockbox_api = { int plugin_load(const char* plugin, void* parameter) { enum plugin_status (*plugin_start)(struct plugin_api* api, void* param); - int rc; + int fd, rc; #ifndef SIMULATOR struct plugin_header header; ssize_t readsize; +#else + struct plugin_header *hdr; #endif - int fd; - #ifdef HAVE_LCD_BITMAP - int xm,ym; + int xm, ym; #endif if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */ @@ -397,18 +397,34 @@ int plugin_load(const char* plugin, void* parameter) lcd_clear_display(); #endif #ifdef SIMULATOR - plugin_start = sim_plugin_load((char *)plugin, &fd); - if(!plugin_start) + hdr = sim_plugin_load((char *)plugin, &fd); + if (!fd) { + gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin); 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 fd = open(plugin, O_RDONLY); if (fd < 0) { gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin); return fd; } - readsize = read(fd, &header, sizeof(header)); - close(fd); + close(fd); /* Close for now. Less code than doing it in all error checks. * Would need to seek back anyway. */ @@ -428,7 +444,6 @@ int plugin_load(const char* plugin, void* parameter) gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION)); return -1; } - /* zero out plugin buffer to ensure a properly zeroed bss area */ 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); return -1; } - plugin_start = header.entry_point; plugin_size = header.end_addr - header.load_addr; + plugin_start = header.entry_point; #endif plugin_loaded = true; @@ -463,11 +478,15 @@ int plugin_load(const char* plugin, void* parameter) #else /* LCD_DEPTH == 1 */ lcd_set_drawmode(DRMODE_SOLID); #endif /* LCD_DEPTH */ + /* restore margins */ + lcd_setmargins(xm,ym); #endif /* HAVE_LCD_BITMAP */ if (pfn_tsr_exit == NULL) plugin_loaded = false; + sim_plugin_close(fd); + switch (rc) { case PLUGIN_OK: break; @@ -480,13 +499,6 @@ int plugin_load(const char* plugin, void* parameter) break; } - sim_plugin_close(fd); - -#ifdef HAVE_LCD_BITMAP - /* restore margins */ - lcd_setmargins(xm,ym); -#endif - return PLUGIN_OK; } diff --git a/apps/plugin.h b/apps/plugin.h index bf8f34ab9e..69a2a79ba8 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -427,7 +427,6 @@ struct plugin_api { }; -#ifndef SIMULATOR /* plugin header */ struct plugin_header { unsigned long magic; @@ -438,6 +437,7 @@ struct plugin_header { enum plugin_status(*entry_point)(struct plugin_api*, void*); }; #ifdef PLUGIN +#ifndef SIMULATOR extern unsigned char plugin_start_addr[]; extern unsigned char plugin_end_addr[]; #define PLUGIN_HEADER \ @@ -445,9 +445,12 @@ extern unsigned char plugin_end_addr[]; __attribute__ ((section (".header")))= { \ PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ plugin_start_addr, plugin_end_addr, plugin_start }; -#endif #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 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)); /* defined by the plugin */ -enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) - __attribute__ ((section (".entry"))); +enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter); #endif diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index a5353af5e5..1871b29395 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -303,7 +303,7 @@ int sim_fsync(int fd) #include #endif -void *sim_codec_load_ram(char* codecptr, int size, +void *sim_codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap, int *pd_fd) { void *pd; @@ -372,22 +372,21 @@ void *sim_codec_load_ram(char* codecptr, int size, void sim_codec_close(int pd) { - dlclose((void *)pd); + dlclose((void *)pd); } void *sim_plugin_load(char *plugin, int *fd) { - void* pd; + void *pd, *hdr; char path[256]; - int (*plugin_start)(void * api, void* param); #ifdef WIN32 char buf[256]; #endif snprintf(path, sizeof path, "archos%s", plugin); - - *fd = -1; + *fd = 0; + pd = dlopen(path, RTLD_NOW); if (!pd) { DEBUGF("failed to load %s\n", plugin); @@ -402,16 +401,12 @@ void *sim_plugin_load(char *plugin, int *fd) return NULL; } - plugin_start = dlsym(pd, "plugin_start"); - if (!plugin_start) { - plugin_start = dlsym(pd, "_plugin_start"); - if (!plugin_start) { - dlclose(pd); - return NULL; - } - } + hdr = dlsym(pd, "__header"); + if (!hdr) + hdr = dlsym(pd, "___header"); + *fd = (int)pd; /* success */ - return plugin_start; + return hdr; /* maybe NULL if symbol not present */ } void sim_plugin_close(int pd) diff --git a/uisimulator/win32/plugin.def b/uisimulator/win32/plugin.def index 403b2d1ff4..e37ce20d8f 100755 --- a/uisimulator/win32/plugin.def +++ b/uisimulator/win32/plugin.def @@ -1,3 +1,2 @@ EXPORTS - plugin_start - + __header