summaryrefslogtreecommitdiff
path: root/apps/plugin.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-01-15 18:20:18 +0000
committerJens Arnold <amiconn@rockbox.org>2006-01-15 18:20:18 +0000
commita36b1d4083e5cf34df1b217516be28471e7d0dc7 (patch)
tree629bb610d0ffcc451d3b0383f62daaed7d602603 /apps/plugin.c
parentc7c9069ed4bda959e649520342017d826123931e (diff)
New plugin loader. Solves the crashes introduced with the .bss changes while keeping the small binary size. The model & api version check is now part of the plugin loader. Codecs are not yet adapted, but the old method still works for them. Simulator plugins are not (yet) version-checked. API version numbering restarted, as this is an all-new system. Uses the target ID from configure, so don't change that too often.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8349 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugin.c')
-rw-r--r--apps/plugin.c135
1 files changed, 64 insertions, 71 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 9a20827e26..0997b0a901 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -78,13 +78,8 @@ static bool plugin_loaded = false;
static int plugin_size = 0;
static void (*pfn_tsr_exit)(void) = NULL; /* TSR exit callback */
-static int plugin_test(int api_version, int model, int memsize);
-
static const struct plugin_api rockbox_api = {
- PLUGIN_API_VERSION,
- plugin_test,
-
/* lcd */
lcd_set_contrast,
lcd_clear_display,
@@ -135,6 +130,7 @@ static const struct plugin_api rockbox_api = {
checkbox,
font_get,
font_getstringsize,
+ font_get_width,
#endif
backlight_on,
backlight_off,
@@ -243,9 +239,18 @@ static const struct plugin_api rockbox_api = {
strcat,
memcmp,
strcasestr,
+ /* unicode stuff */
+ utf8decode,
+ iso_decode,
+ utf16LEdecode,
+ utf16BEdecode,
+ utf8encode,
+ utf8length,
/* sound */
sound_set,
+ sound_min,
+ sound_max,
#ifndef SIMULATOR
mp3_play_data,
mp3_play_pause,
@@ -307,6 +312,21 @@ static const struct plugin_api rockbox_api = {
&rundb_fd,
&rundb_initialized,
+ /* menu */
+ menu_init,
+ menu_exit,
+ menu_show,
+ menu_run,
+ menu_cursor,
+ menu_description,
+ menu_delete,
+ menu_count,
+ menu_moveup,
+ menu_movedown,
+ menu_draw,
+ menu_insert,
+ menu_set_cursor,
+
/* misc */
srand,
rand,
@@ -337,39 +357,13 @@ static const struct plugin_api rockbox_api = {
#endif
#ifdef HAVE_LCD_BITMAP
read_bmp_file,
+ screen_dump_set_hook,
#endif
show_logo,
/* new stuff at the end, sort into place next time
the API gets incompatible */
- menu_init,
- menu_exit,
- menu_show,
- menu_run,
- menu_cursor,
- menu_description,
- menu_delete,
- menu_count,
- menu_moveup,
- menu_movedown,
- menu_draw,
- menu_insert,
- menu_set_cursor,
-
-#ifdef HAVE_LCD_BITMAP
- screen_dump_set_hook,
- font_get_width,
-#endif
- utf8decode,
- iso_decode,
- utf16LEdecode,
- utf16BEdecode,
- utf8encode,
- utf8length,
-
- sound_min,
- sound_max,
};
int plugin_load(const char* plugin, void* parameter)
@@ -377,7 +371,8 @@ int plugin_load(const char* plugin, void* parameter)
enum plugin_status (*plugin_start)(struct plugin_api* api, void* param);
int rc;
#ifndef SIMULATOR
- char buf[64];
+ struct plugin_header header;
+ ssize_t readsize;
#endif
int fd;
@@ -408,28 +403,50 @@ int plugin_load(const char* plugin, void* parameter)
#else
fd = open(plugin, O_RDONLY);
if (fd < 0) {
- snprintf(buf, sizeof buf, str(LANG_PLUGIN_CANT_OPEN), plugin);
- gui_syncsplash(HZ*2, true, buf);
+ gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin);
return fd;
}
-
+
+ readsize = read(fd, &header, sizeof(header));
+ close(fd);
+ /* Close for now. Less code than doing it in all error checks.
+ * Would need to seek back anyway. */
+
+ if (readsize != sizeof(header)) {
+ gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin);
+ return -1;
+ }
+ if (header.magic != PLUGIN_MAGIC
+ || header.target_id != TARGET_ID
+ || header.load_addr != pluginbuf
+ || header.end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) {
+ gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
+ return -1;
+ }
+ if (header.api_version > PLUGIN_API_VERSION
+ || header.api_version < PLUGIN_MIN_API_VERSION) {
+ 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, PLUGIN_BUFFER_SIZE);
+ memset(pluginbuf, 0, header.end_addr - pluginbuf);
- plugin_start = (void*)&pluginbuf;
- plugin_size = read(fd, plugin_start, PLUGIN_BUFFER_SIZE);
+ 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 (plugin_size < 0) {
+
+ if (readsize < 0) {
/* read error */
- snprintf(buf, sizeof buf, str(LANG_READ_FAILED), plugin);
- gui_syncsplash(HZ*2, true, buf);
- return -1;
- }
- if (plugin_size == 0) {
- /* loaded a 0-byte plugin, implying it's not for this model */
- gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
+ 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;
#endif
plugin_loaded = true;
@@ -458,14 +475,6 @@ int plugin_load(const char* plugin, void* parameter)
case PLUGIN_USB_CONNECTED:
return PLUGIN_USB_CONNECTED;
- case PLUGIN_WRONG_API_VERSION:
- gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION));
- break;
-
- case PLUGIN_WRONG_MODEL:
- gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
- break;
-
default:
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_ERROR));
break;
@@ -521,19 +530,3 @@ void plugin_tsr(void (*exit_callback)(void))
{
pfn_tsr_exit = exit_callback; /* remember the callback for later */
}
-
-
-static int plugin_test(int api_version, int model, int memsize)
-{
- if (api_version < PLUGIN_MIN_API_VERSION ||
- api_version > PLUGIN_API_VERSION)
- return PLUGIN_WRONG_API_VERSION;
-
- if (model != MODEL)
- return PLUGIN_WRONG_MODEL;
-
- if (memsize != MEM)
- return PLUGIN_WRONG_MODEL;
-
- return PLUGIN_OK;
-}