Simplified new plugin loader (only read plugin once).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8360 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2006-01-17 20:39:44 +00:00
parent 2f56ee9d0f
commit a40d355ee7

View file

@ -368,13 +368,10 @@ 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);
int fd, rc; int fd, rc;
#ifndef SIMULATOR
struct plugin_header header;
ssize_t readsize;
#else
struct plugin_header *hdr; struct plugin_header *hdr;
#ifndef SIMULATOR
ssize_t readsize;
#endif #endif
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
int xm, ym; int xm, ym;
@ -387,14 +384,12 @@ int plugin_load(const char* plugin, void* parameter)
plugin_loaded = false; plugin_loaded = false;
} }
#ifdef HAVE_LCD_BITMAP
lcd_clear_display(); lcd_clear_display();
#ifdef HAVE_LCD_BITMAP
xm = lcd_getxmargin(); xm = lcd_getxmargin();
ym = lcd_getymargin(); ym = lcd_getymargin();
lcd_setmargins(0,0); lcd_setmargins(0,0);
lcd_update(); lcd_update();
#else
lcd_clear_display();
#endif #endif
#ifdef SIMULATOR #ifdef SIMULATOR
hdr = sim_plugin_load((char *)plugin, &fd); hdr = sim_plugin_load((char *)plugin, &fd);
@ -416,59 +411,44 @@ 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;
} }
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)); /* zero out plugin buffer to ensure a properly zeroed bss area */
close(fd); memset(pluginbuf, 0, PLUGIN_BUFFER_SIZE);
/* Close for now. Less code than doing it in all error checks.
* Would need to seek back anyway. */
if (readsize != sizeof(header)) { readsize = read(fd, pluginbuf, PLUGIN_BUFFER_SIZE);
close(fd);
if (readsize <= (signed)sizeof(struct plugin_header)) {
gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin); gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin);
return -1; return -1;
} }
if (header.magic != PLUGIN_MAGIC hdr = (struct plugin_header *)pluginbuf;
|| header.target_id != TARGET_ID
|| header.load_addr != pluginbuf if (hdr->magic != PLUGIN_MAGIC
|| header.end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) { || hdr->target_id != TARGET_ID
|| hdr->load_addr != pluginbuf
|| hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) {
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL)); gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
return -1; return -1;
} }
if (header.api_version > PLUGIN_API_VERSION if (hdr->api_version > PLUGIN_API_VERSION
|| header.api_version < PLUGIN_MIN_API_VERSION) { || hdr->api_version < PLUGIN_MIN_API_VERSION) {
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 */ plugin_size = hdr->end_addr - pluginbuf;
memset(pluginbuf, 0, header.end_addr - pluginbuf);
fd = open(plugin, O_RDONLY);
if (fd < 0) {
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin);
return fd;
}
readsize = read(fd, pluginbuf, PLUGIN_BUFFER_SIZE);
close(fd);
if (readsize < 0) {
/* read error */
gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin);
return -1;
}
plugin_size = header.end_addr - header.load_addr;
plugin_start = header.entry_point;
#endif #endif
plugin_loaded = true; plugin_loaded = true;
invalidate_icache(); invalidate_icache();
rc = plugin_start((struct plugin_api*) &rockbox_api, parameter); rc = hdr->entry_point((struct plugin_api*) &rockbox_api, parameter);
/* explicitly casting the pointer here to avoid touching every plugin. */ /* explicitly casting the pointer here to avoid touching every plugin. */
button_clear_queue(); button_clear_queue();