diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/export/load_code.h | 20 | ||||
-rw-r--r-- | firmware/load_code.c | 104 | ||||
-rw-r--r-- | firmware/target/hosted/lc-unix.c | 34 |
4 files changed, 32 insertions, 128 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index c2bd45996c..eb49e3e581 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -7,7 +7,6 @@ backlight.c | |||
7 | buflib.c | 7 | buflib.c |
8 | core_alloc.c | 8 | core_alloc.c |
9 | general.c | 9 | general.c |
10 | load_code.c | ||
11 | powermgmt.c | 10 | powermgmt.c |
12 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) | 11 | #if (CONFIG_PLATFORM & PLATFORM_HOSTED) |
13 | 12 | ||
@@ -32,6 +31,7 @@ logf.c | |||
32 | #endif /* ROCKBOX_HAS_LOGF */ | 31 | #endif /* ROCKBOX_HAS_LOGF */ |
33 | kernel.c | 32 | kernel.c |
34 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | 33 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) |
34 | load_code.c | ||
35 | #ifdef RB_PROFILE | 35 | #ifdef RB_PROFILE |
36 | profile.c | 36 | profile.c |
37 | #endif /* RB_PROFILE */ | 37 | #endif /* RB_PROFILE */ |
diff --git a/firmware/export/load_code.h b/firmware/export/load_code.h index 6f8505aba7..cca577044e 100644 --- a/firmware/export/load_code.h +++ b/firmware/export/load_code.h | |||
@@ -25,10 +25,11 @@ | |||
25 | 25 | ||
26 | #include "config.h" | 26 | #include "config.h" |
27 | 27 | ||
28 | extern void *lc_open(const char *filename, unsigned char *buf, size_t buf_size); | ||
29 | |||
28 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | 30 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) |
29 | #include "system.h" | 31 | #include "system.h" |
30 | 32 | ||
31 | extern void *lc_open(const char *filename, unsigned char *buf, size_t buf_size); | ||
32 | /* header is always at the beginning of the blob, and handle actually points | 33 | /* header is always at the beginning of the blob, and handle actually points |
33 | * to the start of the blob (the header is there) */ | 34 | * to the start of the blob (the header is there) */ |
34 | static inline void *lc_open_from_mem(void* addr, size_t blob_size) | 35 | static inline void *lc_open_from_mem(void* addr, size_t blob_size) |
@@ -44,23 +45,10 @@ static inline void lc_close(void *handle) { (void)handle; } | |||
44 | 45 | ||
45 | #elif (CONFIG_PLATFORM & PLATFORM_HOSTED) | 46 | #elif (CONFIG_PLATFORM & PLATFORM_HOSTED) |
46 | 47 | ||
47 | /* don't call these directly for loading code | 48 | extern void *lc_open_from_mem(void* addr, size_t blob_size); |
48 | * they're to be wrapped by platform specific functions */ | ||
49 | #ifdef WIN32 | ||
50 | /* windows' LoadLibrary can only handle ucs2, no utf-8 */ | ||
51 | #define _lc_open_char wchar_t | ||
52 | #else | ||
53 | #define _lc_open_char char | ||
54 | #endif | ||
55 | extern void *_lc_open(const _lc_open_char *filename, unsigned char *buf, size_t buf_size); | ||
56 | extern void *_lc_get_header(void *handle); | ||
57 | extern void _lc_close(void *handle); | ||
58 | |||
59 | extern void *lc_open(const char *filename, unsigned char *buf, size_t buf_size); | ||
60 | extern void *lc_open_from_mem(void *addr, size_t blob_size); | ||
61 | extern void *lc_get_header(void *handle); | 49 | extern void *lc_get_header(void *handle); |
62 | extern void lc_close(void *handle); | 50 | extern void lc_close(void *handle); |
63 | extern const char* lc_last_error(void); | 51 | |
64 | #endif | 52 | #endif |
65 | 53 | ||
66 | /* this struct needs to be the first part of other headers | 54 | /* this struct needs to be the first part of other headers |
diff --git a/firmware/load_code.c b/firmware/load_code.c index a76aca380d..d22d6bb3b2 100644 --- a/firmware/load_code.c +++ b/firmware/load_code.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "debug.h" | 25 | #include "debug.h" |
26 | #include "load_code.h" | 26 | #include "load_code.h" |
27 | 27 | ||
28 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | ||
29 | |||
30 | /* load binary blob from disk to memory, returning a handle */ | 28 | /* load binary blob from disk to memory, returning a handle */ |
31 | void * lc_open(const char *filename, unsigned char *buf, size_t buf_size) | 29 | void * lc_open(const char *filename, unsigned char *buf, size_t buf_size) |
32 | { | 30 | { |
@@ -97,105 +95,3 @@ error_fd: | |||
97 | error: | 95 | error: |
98 | return NULL; | 96 | return NULL; |
99 | } | 97 | } |
100 | |||
101 | #elif (CONFIG_PLATFORM & PLATFORM_HOSTED) | ||
102 | /* libdl wrappers */ | ||
103 | |||
104 | |||
105 | #ifdef WIN32 | ||
106 | /* win32 */ | ||
107 | #include <windows.h> | ||
108 | #define dlopen(_x_, _y_) LoadLibraryW(_x_) | ||
109 | #define dlsym(_x_, _y_) (void *)GetProcAddress(_x_, _y_) | ||
110 | #define dlclose(_x_) FreeLibrary(_x_) | ||
111 | static inline char *_dlerror(void) | ||
112 | { | ||
113 | static char err_buf[64]; | ||
114 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, | ||
115 | err_buf, sizeof(err_buf), NULL); | ||
116 | return err_buf; | ||
117 | } | ||
118 | #define dlerror _dlerror | ||
119 | #else | ||
120 | /* unix */ | ||
121 | #include <dlfcn.h> | ||
122 | #endif | ||
123 | #include <stdio.h> | ||
124 | #include "rbpaths.h" | ||
125 | #include "general.h" | ||
126 | |||
127 | void * _lc_open(const _lc_open_char *filename, unsigned char *buf, size_t buf_size) | ||
128 | { | ||
129 | (void)buf; | ||
130 | (void)buf_size; | ||
131 | return dlopen(filename, RTLD_NOW); | ||
132 | } | ||
133 | |||
134 | void *lc_open_from_mem(void *addr, size_t blob_size) | ||
135 | { | ||
136 | #ifndef SIMULATOR | ||
137 | (void)addr; | ||
138 | (void)blob_size; | ||
139 | /* we don't support loading code from memory on application builds, | ||
140 | * it doesn't make sense (since it means writing the blob to disk again and | ||
141 | * then falling back to load from disk) and requires the ability to write | ||
142 | * to an executable directory */ | ||
143 | return NULL; | ||
144 | #else | ||
145 | /* support it in the sim for the sake of simulating */ | ||
146 | int fd, i; | ||
147 | char temp_filename[MAX_PATH]; | ||
148 | |||
149 | /* We have to create the dynamic link library file from ram so we | ||
150 | can simulate the codec loading. With voice and crossfade, | ||
151 | multiple codecs may be loaded at the same time, so we need | ||
152 | to find an unused filename */ | ||
153 | for (i = 0; i < 10; i++) | ||
154 | { | ||
155 | snprintf(temp_filename, sizeof(temp_filename), | ||
156 | ROCKBOX_DIR "/libtemp_binary_%d.dll", i); | ||
157 | fd = open(temp_filename, O_WRONLY|O_CREAT|O_TRUNC, 0700); | ||
158 | if (fd >= 0) | ||
159 | break; /* Created a file ok */ | ||
160 | } | ||
161 | |||
162 | if (fd < 0) | ||
163 | { | ||
164 | DEBUGF("open failed\n"); | ||
165 | return NULL; | ||
166 | } | ||
167 | |||
168 | if (write(fd, addr, blob_size) < (ssize_t)blob_size) | ||
169 | { | ||
170 | DEBUGF("Write failed\n"); | ||
171 | close(fd); | ||
172 | remove(temp_filename); | ||
173 | return NULL; | ||
174 | } | ||
175 | |||
176 | close(fd); | ||
177 | return lc_open(temp_filename, NULL, 0); | ||
178 | #endif | ||
179 | } | ||
180 | |||
181 | |||
182 | void *_lc_get_header(void *handle) | ||
183 | { | ||
184 | char *ret = dlsym(handle, "__header"); | ||
185 | if (ret == NULL) | ||
186 | ret = dlsym(handle, "___header"); | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | void _lc_close(void *handle) | ||
192 | { | ||
193 | if (handle) | ||
194 | dlclose(handle); | ||
195 | } | ||
196 | |||
197 | const char *lc_last_error(void) | ||
198 | { | ||
199 | return dlerror(); | ||
200 | } | ||
201 | #endif | ||
diff --git a/firmware/target/hosted/lc-unix.c b/firmware/target/hosted/lc-unix.c index 8a265de066..6e5f15ec99 100644 --- a/firmware/target/hosted/lc-unix.c +++ b/firmware/target/hosted/lc-unix.c | |||
@@ -20,24 +20,44 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include <string.h> /* size_t */ | 22 | #include <string.h> /* size_t */ |
23 | #include <dlfcn.h> | ||
24 | #include "debug.h" | ||
23 | #include "load_code.h" | 25 | #include "load_code.h" |
24 | 26 | ||
25 | /* unix specific because WIN32 wants UCS instead of UTF-8, so filenames | ||
26 | * need to be converted */ | ||
27 | |||
28 | /* plain wrappers , nothing to do */ | ||
29 | void *lc_open(const char *filename, unsigned char *buf, size_t buf_size) | 27 | void *lc_open(const char *filename, unsigned char *buf, size_t buf_size) |
30 | { | 28 | { |
31 | return _lc_open(filename, buf, buf_size); | 29 | (void)buf; |
30 | (void)buf_size; | ||
31 | void *handle = dlopen(filename, RTLD_NOW); | ||
32 | if (handle == NULL) | ||
33 | { | ||
34 | DEBUGF("failed to load %s\n", filename); | ||
35 | DEBUGF("lc_open(%s): %s\n", filename, dlerror()); | ||
36 | } | ||
37 | return handle; | ||
32 | } | 38 | } |
33 | 39 | ||
34 | void *lc_get_header(void *handle) | 40 | void *lc_get_header(void *handle) |
35 | { | 41 | { |
36 | return _lc_get_header(handle); | 42 | char *ret = dlsym(handle, "__header"); |
43 | if (ret == NULL) | ||
44 | ret = dlsym(handle, "___header"); | ||
45 | |||
46 | return ret; | ||
37 | } | 47 | } |
38 | 48 | ||
39 | void lc_close(void *handle) | 49 | void lc_close(void *handle) |
40 | { | 50 | { |
41 | _lc_close(handle); | 51 | dlclose(handle); |
42 | } | 52 | } |
43 | 53 | ||
54 | void *lc_open_from_mem(void *addr, size_t blob_size) | ||
55 | { | ||
56 | (void)addr; | ||
57 | (void)blob_size; | ||
58 | /* we don't support loading code from memory on application builds, | ||
59 | * it doesn't make sense (since it means writing the blob to disk again and | ||
60 | * then falling back to load from disk) and requires the ability to write | ||
61 | * to an executable directory */ | ||
62 | return NULL; | ||
63 | } | ||