diff options
author | Jens Arnold <amiconn@rockbox.org> | 2006-01-15 18:20:18 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2006-01-15 18:20:18 +0000 |
commit | a36b1d4083e5cf34df1b217516be28471e7d0dc7 (patch) | |
tree | 629bb610d0ffcc451d3b0383f62daaed7d602603 /apps/plugin.c | |
parent | c7c9069ed4bda959e649520342017d826123931e (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.c | 135 |
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; -} |