diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs.c | 101 | ||||
-rw-r--r-- | apps/plugin.c | 102 | ||||
-rw-r--r-- | apps/plugins/plugin_crt0.c | 6 |
3 files changed, 135 insertions, 74 deletions
diff --git a/apps/codecs.c b/apps/codecs.c index b072c65f40..9e77dd9099 100644 --- a/apps/codecs.c +++ b/apps/codecs.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <ctype.h> | 28 | #include <ctype.h> |
29 | #include <stdarg.h> | 29 | #include <stdarg.h> |
30 | #include "string-extra.h" | 30 | #include "string-extra.h" |
31 | #include "load_code.h" | ||
32 | #include "debug.h" | 31 | #include "debug.h" |
33 | #include "button.h" | 32 | #include "button.h" |
34 | #include "dir.h" | 33 | #include "dir.h" |
@@ -75,13 +74,26 @@ size_t codec_size; | |||
75 | 74 | ||
76 | extern void* plugin_get_audio_buffer(size_t *buffer_size); | 75 | extern void* plugin_get_audio_buffer(size_t *buffer_size); |
77 | 76 | ||
78 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) && defined(HAVE_RECORDING) | ||
79 | #undef open | 77 | #undef open |
80 | static int open(const char* pathname, int flags, ...) | 78 | static int open(const char* pathname, int flags, ...) |
81 | { | 79 | { |
80 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) | ||
81 | int fd; | ||
82 | if (flags & O_CREAT) | ||
83 | { | ||
84 | va_list ap; | ||
85 | va_start(ap, flags); | ||
86 | fd = sim_open(pathname, flags, va_arg(ap, unsigned int)); | ||
87 | va_end(ap); | ||
88 | } | ||
89 | else | ||
90 | fd = sim_open(pathname, flags); | ||
91 | |||
92 | return fd; | ||
93 | #else | ||
82 | return file_open(pathname, flags); | 94 | return file_open(pathname, flags); |
83 | } | ||
84 | #endif | 95 | #endif |
96 | } | ||
85 | struct codec_api ci = { | 97 | struct codec_api ci = { |
86 | 98 | ||
87 | 0, /* filesize */ | 99 | 0, /* filesize */ |
@@ -185,46 +197,62 @@ void codec_get_full_path(char *path, const char *codec_root_fn) | |||
185 | CODECS_DIR, codec_root_fn); | 197 | CODECS_DIR, codec_root_fn); |
186 | } | 198 | } |
187 | 199 | ||
188 | static int codec_load_ram(void *handle, struct codec_api *api) | 200 | static int codec_load_ram(int size, struct codec_api *api) |
189 | { | 201 | { |
190 | struct codec_header *hdr = lc_get_header(handle); | 202 | struct codec_header *hdr; |
191 | int status; | 203 | int status; |
192 | 204 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | |
193 | if (hdr == NULL | 205 | hdr = (struct codec_header *)codecbuf; |
206 | |||
207 | if (size <= (signed)sizeof(struct codec_header) | ||
194 | || (hdr->magic != CODEC_MAGIC | 208 | || (hdr->magic != CODEC_MAGIC |
195 | #ifdef HAVE_RECORDING | 209 | #ifdef HAVE_RECORDING |
196 | && hdr->magic != CODEC_ENC_MAGIC | 210 | && hdr->magic != CODEC_ENC_MAGIC |
197 | #endif | 211 | #endif |
198 | ) | 212 | ) |
199 | || hdr->target_id != TARGET_ID | 213 | || hdr->target_id != TARGET_ID |
200 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | ||
201 | || hdr->load_addr != codecbuf | 214 | || hdr->load_addr != codecbuf |
202 | || hdr->end_addr > codecbuf + CODEC_SIZE | 215 | || hdr->end_addr > codecbuf + CODEC_SIZE) |
203 | #endif | ||
204 | ) | ||
205 | { | 216 | { |
206 | logf("codec header error"); | 217 | logf("codec header error"); |
207 | lc_close(handle); | ||
208 | return CODEC_ERROR; | 218 | return CODEC_ERROR; |
209 | } | 219 | } |
210 | 220 | ||
221 | codec_size = hdr->end_addr - codecbuf; | ||
222 | |||
223 | #elif (CONFIG_PLATFORM & PLATFORM_HOSTED) | ||
224 | void *pd; | ||
225 | |||
226 | hdr = sim_codec_load_ram(codecbuf, size, &pd); | ||
227 | |||
228 | if (pd == NULL) | ||
229 | return CODEC_ERROR; | ||
230 | |||
231 | if (hdr == NULL | ||
232 | || (hdr->magic != CODEC_MAGIC | ||
233 | #ifdef HAVE_RECORDING | ||
234 | && hdr->magic != CODEC_ENC_MAGIC | ||
235 | #endif | ||
236 | ) | ||
237 | || hdr->target_id != TARGET_ID) { | ||
238 | sim_codec_close(pd); | ||
239 | return CODEC_ERROR; | ||
240 | } | ||
241 | |||
242 | codec_size = codecbuf - codecbuf; | ||
243 | |||
244 | #endif /* CONFIG_PLATFORM */ | ||
211 | if (hdr->api_version > CODEC_API_VERSION | 245 | if (hdr->api_version > CODEC_API_VERSION |
212 | || hdr->api_version < CODEC_MIN_API_VERSION) { | 246 | || hdr->api_version < CODEC_MIN_API_VERSION) { |
213 | logf("codec api version error"); | 247 | sim_codec_close(pd); |
214 | lc_close(handle); | ||
215 | return CODEC_ERROR; | 248 | return CODEC_ERROR; |
216 | } | 249 | } |
217 | 250 | ||
218 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | ||
219 | codec_size = hdr->end_addr - codecbuf; | ||
220 | #else | ||
221 | codec_size = 0; | ||
222 | #endif | ||
223 | |||
224 | *(hdr->api) = api; | 251 | *(hdr->api) = api; |
252 | cpucache_invalidate(); | ||
225 | status = hdr->entry_point(); | 253 | status = hdr->entry_point(); |
226 | 254 | ||
227 | lc_close(handle); | 255 | sim_codec_close(pd); |
228 | 256 | ||
229 | return status; | 257 | return status; |
230 | } | 258 | } |
@@ -232,37 +260,36 @@ static int codec_load_ram(void *handle, struct codec_api *api) | |||
232 | int codec_load_buf(unsigned int hid, struct codec_api *api) | 260 | int codec_load_buf(unsigned int hid, struct codec_api *api) |
233 | { | 261 | { |
234 | int rc; | 262 | int rc; |
235 | void *handle; | ||
236 | rc = bufread(hid, CODEC_SIZE, codecbuf); | 263 | rc = bufread(hid, CODEC_SIZE, codecbuf); |
237 | if (rc < 0) { | 264 | if (rc < 0) { |
238 | logf("error loading codec"); | 265 | logf("error loading codec"); |
239 | return CODEC_ERROR; | 266 | return CODEC_ERROR; |
240 | } | 267 | } |
241 | handle = lc_open_from_mem(codecbuf, rc); | ||
242 | if (handle == NULL) | ||
243 | { | ||
244 | logf("error loading codec"); | ||
245 | return CODEC_ERROR; | ||
246 | } | ||
247 | |||
248 | api->discard_codec(); | 268 | api->discard_codec(); |
249 | return codec_load_ram(handle, api); | 269 | return codec_load_ram(rc, api); |
250 | } | 270 | } |
251 | 271 | ||
252 | int codec_load_file(const char *plugin, struct codec_api *api) | 272 | int codec_load_file(const char *plugin, struct codec_api *api) |
253 | { | 273 | { |
254 | char path[MAX_PATH]; | 274 | char path[MAX_PATH]; |
255 | void *handle; | 275 | int fd; |
276 | int rc; | ||
256 | 277 | ||
257 | codec_get_full_path(path, plugin); | 278 | codec_get_full_path(path, plugin); |
258 | 279 | ||
259 | handle = lc_open(path, codecbuf, CODEC_SIZE); | 280 | fd = open(path, O_RDONLY); |
260 | 281 | if (fd < 0) { | |
261 | if (handle == NULL) { | 282 | logf("Codec load error:%d", fd); |
262 | logf("Codec load error"); | ||
263 | splashf(HZ*2, "Couldn't load codec: %s", path); | 283 | splashf(HZ*2, "Couldn't load codec: %s", path); |
284 | return fd; | ||
285 | } | ||
286 | |||
287 | rc = read(fd, &codecbuf[0], CODEC_SIZE); | ||
288 | close(fd); | ||
289 | if (rc <= 0) { | ||
290 | logf("Codec read error"); | ||
264 | return CODEC_ERROR; | 291 | return CODEC_ERROR; |
265 | } | 292 | } |
266 | 293 | ||
267 | return codec_load_ram(handle, api); | 294 | return codec_load_ram((size_t)rc, api); |
268 | } | 295 | } |
diff --git a/apps/plugin.c b/apps/plugin.c index 53a05bf527..cc540cd988 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include "errno.h" | 42 | #include "errno.h" |
43 | #include "diacritic.h" | 43 | #include "diacritic.h" |
44 | #include "filefuncs.h" | 44 | #include "filefuncs.h" |
45 | #include "load_code.h" | ||
46 | 45 | ||
47 | #if CONFIG_CHARGING | 46 | #if CONFIG_CHARGING |
48 | #include "power.h" | 47 | #include "power.h" |
@@ -76,19 +75,21 @@ static unsigned int open_files; | |||
76 | 75 | ||
77 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) | 76 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) |
78 | static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE]; | 77 | static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE]; |
78 | void *sim_plugin_load(char *plugin, void **pd); | ||
79 | void sim_plugin_close(void *pd); | ||
79 | void sim_lcd_ex_init(unsigned long (*getpixel)(int, int)); | 80 | void sim_lcd_ex_init(unsigned long (*getpixel)(int, int)); |
80 | void sim_lcd_ex_update_rect(int x, int y, int width, int height); | 81 | void sim_lcd_ex_update_rect(int x, int y, int width, int height); |
81 | #else | 82 | #else |
83 | #define sim_plugin_close(x) | ||
82 | extern unsigned char pluginbuf[]; | 84 | extern unsigned char pluginbuf[]; |
83 | #include "bitswap.h" | 85 | #include "bitswap.h" |
84 | #endif | 86 | #endif |
85 | 87 | ||
86 | /* for actual plugins only, not for codecs */ | 88 | /* for actual plugins only, not for codecs */ |
89 | static bool plugin_loaded = false; | ||
87 | static int plugin_size = 0; | 90 | static int plugin_size = 0; |
88 | static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */ | 91 | static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */ |
89 | static char current_plugin[MAX_PATH]; | 92 | static char current_plugin[MAX_PATH]; |
90 | /* NULL if no plugin is loaded, otherwise the handle that lc_open() returned */ | ||
91 | static void *current_plugin_handle; | ||
92 | 93 | ||
93 | char *plugin_get_current_filename(void); | 94 | char *plugin_get_current_filename(void); |
94 | 95 | ||
@@ -727,60 +728,98 @@ int plugin_load(const char* plugin, const void* parameter) | |||
727 | { | 728 | { |
728 | int rc, i; | 729 | int rc, i; |
729 | struct plugin_header *hdr; | 730 | struct plugin_header *hdr; |
731 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) | ||
732 | void *pd; | ||
733 | #else /* PLATFOR_NATIVE */ | ||
734 | int fd; | ||
735 | ssize_t readsize; | ||
736 | #if NUM_CORES > 1 | ||
737 | unsigned my_core; | ||
738 | #endif | ||
739 | #endif /* CONFIG_PLATFORM */ | ||
730 | 740 | ||
731 | #if LCD_DEPTH > 1 | 741 | #if LCD_DEPTH > 1 |
732 | fb_data* old_backdrop; | 742 | fb_data* old_backdrop; |
733 | #endif | 743 | #endif |
734 | 744 | ||
735 | if (current_plugin_handle && pfn_tsr_exit) | 745 | if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */ |
736 | { /* if we have a resident old plugin and a callback */ | 746 | { |
737 | if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false ) | 747 | if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false ) |
738 | { | 748 | { |
739 | /* not allowing another plugin to load */ | 749 | /* not allowing another plugin to load */ |
740 | return PLUGIN_OK; | 750 | return PLUGIN_OK; |
741 | } | 751 | } |
742 | lc_close(current_plugin_handle); | 752 | pfn_tsr_exit = NULL; |
743 | current_plugin_handle = pfn_tsr_exit = NULL; | 753 | plugin_loaded = false; |
744 | } | 754 | } |
745 | 755 | ||
746 | splash(0, ID2P(LANG_WAIT)); | 756 | splash(0, ID2P(LANG_WAIT)); |
747 | strcpy(current_plugin, plugin); | 757 | strcpy(current_plugin, plugin); |
748 | 758 | ||
749 | current_plugin_handle = lc_open(plugin, pluginbuf, PLUGIN_BUFFER_SIZE); | 759 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) |
750 | if (current_plugin_handle == NULL) { | 760 | hdr = sim_plugin_load((char *)plugin, &pd); |
761 | if (pd == NULL) { | ||
751 | splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin); | 762 | splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin); |
752 | return -1; | 763 | return -1; |
753 | } | 764 | } |
765 | if (hdr == NULL | ||
766 | || hdr->magic != PLUGIN_MAGIC | ||
767 | || hdr->target_id != TARGET_ID) { | ||
768 | sim_plugin_close(pd); | ||
769 | splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL)); | ||
770 | return -1; | ||
771 | } | ||
772 | if (hdr->api_version > PLUGIN_API_VERSION | ||
773 | || hdr->api_version < PLUGIN_MIN_API_VERSION) { | ||
774 | sim_plugin_close(pd); | ||
775 | splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION)); | ||
776 | return -1; | ||
777 | } | ||
778 | #else | ||
779 | fd = open(plugin, O_RDONLY); | ||
780 | if (fd < 0) { | ||
781 | splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin); | ||
782 | return fd; | ||
783 | } | ||
784 | #if NUM_CORES > 1 | ||
785 | /* Make sure COP cache is flushed and invalidated before loading */ | ||
786 | my_core = switch_core(CURRENT_CORE ^ 1); | ||
787 | cpucache_invalidate(); | ||
788 | switch_core(my_core); | ||
789 | #endif | ||
754 | 790 | ||
755 | hdr = lc_get_header(current_plugin_handle); | 791 | readsize = read(fd, pluginbuf, PLUGIN_BUFFER_SIZE); |
792 | close(fd); | ||
756 | 793 | ||
757 | if (hdr == NULL | 794 | if (readsize < 0) { |
795 | splashf(HZ*2, str(LANG_READ_FAILED), plugin); | ||
796 | return -1; | ||
797 | } | ||
798 | hdr = (struct plugin_header *)pluginbuf; | ||
799 | |||
800 | if ((unsigned)readsize <= sizeof(struct plugin_header) | ||
758 | || hdr->magic != PLUGIN_MAGIC | 801 | || hdr->magic != PLUGIN_MAGIC |
759 | || hdr->target_id != TARGET_ID | 802 | || hdr->target_id != TARGET_ID |
760 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | ||
761 | || hdr->load_addr != pluginbuf | 803 | || hdr->load_addr != pluginbuf |
762 | || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE | 804 | || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) { |
763 | #endif | ||
764 | ) | ||
765 | { | ||
766 | lc_close(current_plugin_handle); | ||
767 | splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL)); | 805 | splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL)); |
768 | return -1; | 806 | return -1; |
769 | } | 807 | } |
770 | if (hdr->api_version > PLUGIN_API_VERSION | 808 | if (hdr->api_version > PLUGIN_API_VERSION |
771 | || hdr->api_version < PLUGIN_MIN_API_VERSION) | 809 | || hdr->api_version < PLUGIN_MIN_API_VERSION) { |
772 | { | ||
773 | lc_close(current_plugin_handle); | ||
774 | splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION)); | 810 | splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION)); |
775 | return -1; | 811 | return -1; |
776 | } | 812 | } |
777 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | ||
778 | plugin_size = hdr->end_addr - pluginbuf; | 813 | plugin_size = hdr->end_addr - pluginbuf; |
779 | #else | 814 | |
780 | plugin_size = 0; | 815 | /* zero out bss area only, above guards end of pluginbuf */ |
816 | if (plugin_size > readsize) | ||
817 | memset(pluginbuf + readsize, 0, plugin_size - readsize); | ||
781 | #endif | 818 | #endif |
782 | 819 | ||
783 | *(hdr->api) = &rockbox_api; | 820 | *(hdr->api) = &rockbox_api; |
821 | plugin_loaded = true; | ||
822 | |||
784 | 823 | ||
785 | #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1 | 824 | #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1 |
786 | old_backdrop = lcd_get_backdrop(); | 825 | old_backdrop = lcd_get_backdrop(); |
@@ -795,6 +834,8 @@ int plugin_load(const char* plugin, const void* parameter) | |||
795 | 834 | ||
796 | FOR_NB_SCREENS(i) | 835 | FOR_NB_SCREENS(i) |
797 | viewportmanager_theme_enable(i, false, NULL); | 836 | viewportmanager_theme_enable(i, false, NULL); |
837 | |||
838 | cpucache_invalidate(); | ||
798 | 839 | ||
799 | #ifdef HAVE_TOUCHSCREEN | 840 | #ifdef HAVE_TOUCHSCREEN |
800 | touchscreen_set_mode(TOUCHSCREEN_BUTTON); | 841 | touchscreen_set_mode(TOUCHSCREEN_BUTTON); |
@@ -806,12 +847,6 @@ int plugin_load(const char* plugin, const void* parameter) | |||
806 | 847 | ||
807 | rc = hdr->entry_point(parameter); | 848 | rc = hdr->entry_point(parameter); |
808 | 849 | ||
809 | if (!pfn_tsr_exit) | ||
810 | { /* close handle if plugin is no tsr one */ | ||
811 | lc_close(current_plugin_handle); | ||
812 | current_plugin_handle = NULL; | ||
813 | } | ||
814 | |||
815 | /* Go back to the global setting in case the plugin changed it */ | 850 | /* Go back to the global setting in case the plugin changed it */ |
816 | #ifdef HAVE_TOUCHSCREEN | 851 | #ifdef HAVE_TOUCHSCREEN |
817 | touchscreen_set_mode(global_settings.touch_mode); | 852 | touchscreen_set_mode(global_settings.touch_mode); |
@@ -852,8 +887,11 @@ int plugin_load(const char* plugin, const void* parameter) | |||
852 | FOR_NB_SCREENS(i) | 887 | FOR_NB_SCREENS(i) |
853 | viewportmanager_theme_undo(i, false); | 888 | viewportmanager_theme_undo(i, false); |
854 | 889 | ||
890 | if (pfn_tsr_exit == NULL) | ||
891 | plugin_loaded = false; | ||
892 | |||
855 | #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE | 893 | #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE |
856 | if(open_files != 0 && !current_plugin_handle) | 894 | if(open_files != 0 && !plugin_loaded) |
857 | { | 895 | { |
858 | int fd; | 896 | int fd; |
859 | logf("Plugin '%s' leaks file handles", plugin); | 897 | logf("Plugin '%s' leaks file handles", plugin); |
@@ -871,6 +909,8 @@ int plugin_load(const char* plugin, const void* parameter) | |||
871 | } | 909 | } |
872 | #endif | 910 | #endif |
873 | 911 | ||
912 | sim_plugin_close(pd); | ||
913 | |||
874 | if (rc == PLUGIN_ERROR) | 914 | if (rc == PLUGIN_ERROR) |
875 | splash(HZ*2, str(LANG_PLUGIN_ERROR)); | 915 | splash(HZ*2, str(LANG_PLUGIN_ERROR)); |
876 | 916 | ||
@@ -883,7 +923,7 @@ void* plugin_get_buffer(size_t *buffer_size) | |||
883 | { | 923 | { |
884 | int buffer_pos; | 924 | int buffer_pos; |
885 | 925 | ||
886 | if (current_plugin_handle) | 926 | if (plugin_loaded) |
887 | { | 927 | { |
888 | if (plugin_size >= PLUGIN_BUFFER_SIZE) | 928 | if (plugin_size >= PLUGIN_BUFFER_SIZE) |
889 | return NULL; | 929 | return NULL; |
diff --git a/apps/plugins/plugin_crt0.c b/apps/plugins/plugin_crt0.c index e34124c5a2..536eccaffa 100644 --- a/apps/plugins/plugin_crt0.c +++ b/apps/plugins/plugin_crt0.c | |||
@@ -32,8 +32,6 @@ PLUGIN_HEADER | |||
32 | #define EXIT_MAGIC 0x0CDEBABE | 32 | #define EXIT_MAGIC 0x0CDEBABE |
33 | 33 | ||
34 | extern enum plugin_status plugin_start(const void*); | 34 | extern enum plugin_status plugin_start(const void*); |
35 | extern unsigned char plugin_bss_start[]; | ||
36 | extern unsigned char plugin_end_addr[]; | ||
37 | 35 | ||
38 | static jmp_buf __exit_env; | 36 | static jmp_buf __exit_env; |
39 | /* only 1 atexit handler for now, chain in the exit handler if you need more */ | 37 | /* only 1 atexit handler for now, chain in the exit handler if you need more */ |
@@ -63,10 +61,6 @@ enum plugin_status plugin__start(const void *param) | |||
63 | int exit_ret; | 61 | int exit_ret; |
64 | enum plugin_status ret; | 62 | enum plugin_status ret; |
65 | 63 | ||
66 | /* zero out the bss section */ | ||
67 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | ||
68 | rb->memset(plugin_bss_start, 0, plugin_end_addr - plugin_bss_start); | ||
69 | #endif | ||
70 | /* we come back here if exit() was called or the plugin returned normally */ | 64 | /* we come back here if exit() was called or the plugin returned normally */ |
71 | exit_ret = setjmp(__exit_env); | 65 | exit_ret = setjmp(__exit_env); |
72 | if (exit_ret == 0) | 66 | if (exit_ret == 0) |