summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs.c101
-rw-r--r--apps/plugin.c102
-rw-r--r--apps/plugins/plugin_crt0.c6
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/export/load_code.h55
-rw-r--r--firmware/load_code.c165
-rw-r--r--uisimulator/common/io.c113
7 files changed, 235 insertions, 308 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
76extern void* plugin_get_audio_buffer(size_t *buffer_size); 75extern 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
80static int open(const char* pathname, int flags, ...) 78static 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}
85struct codec_api ci = { 97struct 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
188static int codec_load_ram(void *handle, struct codec_api *api) 200static 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)
232int codec_load_buf(unsigned int hid, struct codec_api *api) 260int 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
252int codec_load_file(const char *plugin, struct codec_api *api) 272int 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)
78static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE]; 77static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
78void *sim_plugin_load(char *plugin, void **pd);
79void sim_plugin_close(void *pd);
79void sim_lcd_ex_init(unsigned long (*getpixel)(int, int)); 80void sim_lcd_ex_init(unsigned long (*getpixel)(int, int));
80void sim_lcd_ex_update_rect(int x, int y, int width, int height); 81void sim_lcd_ex_update_rect(int x, int y, int width, int height);
81#else 82#else
83#define sim_plugin_close(x)
82extern unsigned char pluginbuf[]; 84extern 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 */
89static bool plugin_loaded = false;
87static int plugin_size = 0; 90static int plugin_size = 0;
88static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */ 91static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */
89static char current_plugin[MAX_PATH]; 92static char current_plugin[MAX_PATH];
90/* NULL if no plugin is loaded, otherwise the handle that lc_open() returned */
91static void *current_plugin_handle;
92 93
93char *plugin_get_current_filename(void); 94char *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
34extern enum plugin_status plugin_start(const void*); 34extern enum plugin_status plugin_start(const void*);
35extern unsigned char plugin_bss_start[];
36extern unsigned char plugin_end_addr[];
37 35
38static jmp_buf __exit_env; 36static 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)
diff --git a/firmware/SOURCES b/firmware/SOURCES
index f83b78970e..e6157fa7d0 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -3,7 +3,6 @@ events.c
3backlight.c 3backlight.c
4buffer.c 4buffer.c
5general.c 5general.c
6load_code.c
7powermgmt.c 6powermgmt.c
8system.c 7system.c
9usb.c 8usb.c
diff --git a/firmware/export/load_code.h b/firmware/export/load_code.h
deleted file mode 100644
index f4fa8f9b46..0000000000
--- a/firmware/export/load_code.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 by Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#include "config.h"
24
25#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
26#include "system.h"
27
28extern void *lc_open(const char *filename, char *buf, size_t buf_size);
29/* header is always at the beginning of the blob, and handle actually points
30 * to the start of the blob */
31static inline char *lc_open_from_mem(void* addr, size_t blob_size)
32{
33 (void)blob_size;
34 cpucache_invalidate();
35 return addr;
36}
37static inline void *lc_get_header(void *handle) { return handle; }
38/* no need to do anything */
39static inline void lc_close(void *handle) { (void)handle; }
40
41#elif (CONFIG_PLATFORM & PLATFORM_HOSTED)
42
43/* don't call these directly for loading code
44 * they're to be wrapped by platform specific functions */
45extern void *_lc_open(const char *filename, char *buf, size_t buf_size);
46extern void *_lc_get_header(void *handle);
47extern void _lc_close(void *handle);
48
49extern void *lc_open(const char *filename, char *buf, size_t buf_size);
50/* not possiible on hosted platforms */
51extern void *lc_open_from_mem(void *addr, size_t blob_size);
52extern void *lc_get_header(void *handle);
53extern void lc_close(void *handle);
54extern const char* lc_last_error(void);
55#endif
diff --git a/firmware/load_code.c b/firmware/load_code.c
deleted file mode 100644
index 9e8e71f9af..0000000000
--- a/firmware/load_code.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 by Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "system.h"
24#include "file.h"
25#include "debug.h"
26#include "load_code.h"
27
28#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
29/* load binary blob from disk to memory, returning a handle */
30void * lc_open(const char *filename, char *buf, size_t buf_size)
31{
32 int fd = open(filename, O_RDONLY);
33 ssize_t read_size;
34
35 if (fd < 0)
36 {
37 DEBUGF("Could not open file");
38 return NULL;
39 }
40
41#if NUM_CORES > 1
42 /* Make sure COP cache is flushed and invalidated before loading */
43 {
44 int my_core = switch_core(CURRENT_CORE ^ 1);
45 cpucache_invalidate();
46 switch_core(my_core);
47 }
48#endif
49
50 read_size = read(fd, buf, buf_size);
51 close(fd);
52 cpucache_invalidate();
53
54 if (read_size < 0)
55 {
56 DEBUGF("Could not read from file");
57 return NULL;
58 }
59 return buf;
60}
61
62#elif (CONFIG_PLATFORM & PLATFORM_HOSTED)
63/* libdl wrappers */
64
65
66#ifdef WIN32
67/* win32 */
68#include <windows.h>
69#define dlopen(_x_, _y_) LoadLibraryW(_x_)
70#define dlsym(_x_, _y_) (void *)GetProcAddress(_x_, _y_)
71#define dlclose(_x_) FreeLibrary(_x_)
72static inline char *_dlerror(void)
73{
74 static char err_buf[64];
75 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
76 err_buf, sizeof(err_buf), NULL);
77 return err_buf;
78}
79#define dlerror _dlerror
80#else
81/* unix */
82#include <dlfcn.h>
83#define O_BINARY 0
84#endif
85#include <stdio.h>
86#include "rbpaths.h"
87#include "general.h"
88
89void * _lc_open(const char *filename, char *buf, size_t buf_size)
90{
91 (void)buf;
92 (void)buf_size;
93 void* dl_handle = dlopen(filename, RTLD_NOW);
94 return dl_handle;
95}
96
97void *lc_open_from_mem(void *addr, size_t blob_size)
98{
99 int fd, i;
100 char temp_filename[MAX_PATH];
101
102 /* We have to create the dynamic link library file from ram so we
103 can simulate the codec loading. With voice and crossfade,
104 multiple codecs may be loaded at the same time, so we need
105 to find an unused filename */
106 for (i = 0; i < 10; i++)
107 {
108#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
109 /* we need that path fixed, since get_user_file_path()
110 * gives us the folder on the sdcard where we cannot load libraries
111 * from (no exec permissions)
112 */
113 snprintf(temp_filename, sizeof(temp_filename),
114 "/data/data/org.rockbox/app_rockbox/libtemp_binary_%d.so", i);
115#else
116 char name[MAX_PATH];
117 const char *_name = get_user_file_path(ROCKBOX_DIR, NEED_WRITE, name, sizeof(name));
118 snprintf(temp_filename, sizeof(temp_filename),
119 "%slibtemp_binary_%d.dll", _name, i);
120#endif
121 fd = open(temp_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0766);
122 if (fd >= 0)
123 break; /* Created a file ok */
124 }
125
126 DEBUGF("Creating %s\n", temp_filename);
127 if (fd < 0)
128 {
129 DEBUGF("open failed\n");
130 return NULL;
131 }
132
133 if (write(fd, addr, blob_size) < (ssize_t)blob_size)
134 {
135 DEBUGF("Write failed\n");
136 close(fd);
137 remove(temp_filename);
138 return NULL;
139 }
140
141 close(fd);
142 return lc_open(temp_filename, NULL, 0);
143}
144
145
146void *_lc_get_header(void *handle)
147{
148 char *ret = dlsym(handle, "__header");
149 if (ret == NULL)
150 ret = dlsym(handle, "___header");
151
152 return ret;
153}
154
155void _lc_close(void *handle)
156{
157 if (handle)
158 dlclose(handle);
159}
160
161const char *lc_last_error(void)
162{
163 return dlerror();
164}
165#endif
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index c8d6a8a67d..4c0fa33be5 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -58,7 +58,6 @@
58#include "debug.h" 58#include "debug.h"
59#include "ata.h" /* for IF_MV2 et al. */ 59#include "ata.h" /* for IF_MV2 et al. */
60#include "rbpaths.h" 60#include "rbpaths.h"
61#include "load_code.h"
62 61
63/* keep this in sync with file.h! */ 62/* keep this in sync with file.h! */
64#undef MAX_PATH /* this avoids problems when building simulator */ 63#undef MAX_PATH /* this avoids problems when building simulator */
@@ -531,28 +530,116 @@ int sim_fsync(int fd)
531#include <dlfcn.h> 530#include <dlfcn.h>
532#endif 531#endif
533 532
534 533void *sim_codec_load_ram(char* codecptr, int size, void **pd)
535void *lc_open(const char *filename, char *buf, size_t buf_size)
536{ 534{
537 const char *sim_path = get_sim_pathname(filename); 535 void *hdr;
538 void *handle = _lc_open((const char*)UTF8_TO_OS(sim_path), buf, buf_size); 536 char path[MAX_PATH];
537 int fd;
538 int codec_count;
539#ifdef WIN32
540 char buf[MAX_PATH];
541#endif
539 542
540 if (handle == NULL) 543 *pd = NULL;
544
545 /* We have to create the dynamic link library file from ram so we
546 can simulate the codec loading. With voice and crossfade,
547 multiple codecs may be loaded at the same time, so we need
548 to find an unused filename */
549 for (codec_count = 0; codec_count < 10; codec_count++)
541 { 550 {
542 DEBUGF("failed to load %s\n", filename); 551#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
543 DEBUGF("lc_open(%s): %s\n", filename, lc_last_error()); 552 /* we need that path fixed, since get_user_file_path()
553 * gives us the folder on the sdcard where we cannot load libraries
554 * from (no exec permissions)
555 */
556 snprintf(path, sizeof(path),
557 "/data/data/org.rockbox/app_rockbox/libtemp_codec_%d.so",
558 codec_count);
559#else
560 char name[MAX_PATH];
561 const char *_name = get_user_file_path(ROCKBOX_DIR, 0, name, sizeof(name));
562 snprintf(path, sizeof(path), "%s/_temp_codec%d.dll", get_sim_pathname(_name), codec_count);
563#endif
564 fd = OPEN(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU);
565 if (fd >= 0)
566 break; /* Created a file ok */
567 }
568 if (fd < 0)
569 {
570 DEBUGF("failed to open for write: %s\n", path);
571 return NULL;
572 }
573
574 if (write(fd, codecptr, size) != size)
575 {
576 DEBUGF("write failed");
577 return NULL;
578 }
579 close(fd);
580
581 /* Now load the library. */
582 *pd = dlopen(path, RTLD_NOW);
583 if (*pd == NULL)
584 {
585 DEBUGF("failed to load %s\n", path);
586#ifdef WIN32
587 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
588 buf, sizeof buf, NULL);
589 DEBUGF("dlopen(%s): %s\n", path, buf);
590#else
591 DEBUGF("dlopen(%s): %s\n", path, dlerror());
592#endif
593 return NULL;
544 } 594 }
545 return handle; 595
596 hdr = dlsym(*pd, "__header");
597 if (!hdr)
598 hdr = dlsym(*pd, "___header");
599
600 return hdr; /* maybe NULL if symbol not present */
601}
602
603void sim_codec_close(void *pd)
604{
605 dlclose(pd);
546} 606}
547 607
548void *lc_get_header(void *handle) 608void *sim_plugin_load(char *plugin, void **pd)
549{ 609{
550 return _lc_get_header(handle); 610 void *hdr;
611 char path[MAX_PATH];
612#ifdef WIN32
613 char buf[MAX_PATH];
614#endif
615
616 snprintf(path, sizeof(path), "%s", get_sim_pathname(plugin));
617
618 *pd = NULL;
619
620 *pd = dlopen(path, RTLD_NOW);
621 if (*pd == NULL) {
622 DEBUGF("failed to load %s\n", plugin);
623#ifdef WIN32
624 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
625 buf, sizeof(buf), NULL);
626 DEBUGF("dlopen(%s): %s\n", path, buf);
627#else
628 DEBUGF("dlopen(%s): %s\n", path, dlerror());
629#endif
630 return NULL;
631 }
632
633 hdr = dlsym(*pd, "__header");
634 if (!hdr)
635 hdr = dlsym(*pd, "___header");
636
637 return hdr; /* maybe NULL if symbol not present */
551} 638}
552 639
553void lc_close(void *handle) 640void sim_plugin_close(void *pd)
554{ 641{
555 _lc_close(handle); 642 dlclose(pd);
556} 643}
557 644
558#ifdef WIN32 645#ifdef WIN32