16
16
#include <coreclrhost.h>
17
17
#include <dirent.h>
18
18
19
+ #include <corehost/host_runtime_contract.h>
20
+
19
21
/********* exported symbols *********/
20
22
21
23
/* JNI exports */
@@ -34,11 +36,15 @@ Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz);
34
36
35
37
/********* implementation *********/
36
38
37
- static const char * g_bundle_path = NULL ;
39
+ static char * g_bundle_path = NULL ;
38
40
static const char * g_executable_path = NULL ;
39
41
static unsigned int g_coreclr_domainId = 0 ;
40
42
static void * g_coreclr_handle = NULL ;
41
43
44
+ #define MAX_MAPPED_COUNT 50 // Arbitrarily 'large enough' number
45
+ static void * g_mapped_files [MAX_MAPPED_COUNT ];
46
+ static size_t g_mapped_file_sizes [MAX_MAPPED_COUNT ];
47
+ static unsigned int g_mapped_files_count = 0 ;
42
48
43
49
#define LOG_INFO (fmt , ...) __android_log_print(ANDROID_LOG_DEBUG, "DOTNET", fmt, ##__VA_ARGS__)
44
50
#define LOG_ERROR (fmt , ...) __android_log_print(ANDROID_LOG_ERROR, "DOTNET", fmt, ##__VA_ARGS__)
@@ -70,7 +76,7 @@ strncpy_str (JNIEnv *env, char *buff, jstring str, int nbuff)
70
76
71
77
/*
72
78
* Get the list of trusted assemblies from a specified @dir_path.
73
- * The path is searched for .dll files which when found are concatenated
79
+ * The path is searched for .dll files which when found are concatenated
74
80
* to the output string @tpas separated by ':'.
75
81
* The output string should be freed by the caller.
76
82
* The return value is the length of the output string.
@@ -147,6 +153,56 @@ bundle_executable_path (const char* executable, const char* bundle_path, const c
147
153
return executable_path_len ;
148
154
}
149
155
156
+ static bool
157
+ external_assembly_probe (const char * name , void * * data , int64_t * size )
158
+ {
159
+ if (g_mapped_files_count >= MAX_MAPPED_COUNT )
160
+ {
161
+ LOG_ERROR ("Too many mapped files, cannot map %s" , name );
162
+ return false;
163
+ }
164
+
165
+ // Get just the file name
166
+ const char * pos = strrchr (name , '/' );
167
+ if (pos != NULL )
168
+ name = pos + 1 ;
169
+
170
+ // Look in the bundle path where the files were extracted
171
+ char full_path [1024 ];
172
+ size_t path_len = strlen (g_bundle_path ) + strlen (name ) + 1 ; // +1 for '/'
173
+ size_t res = snprintf (full_path , path_len + 1 , "%s/%s" , g_bundle_path , name );
174
+ if (res < 0 || res != path_len )
175
+ return false;
176
+
177
+ int fd = open (full_path , O_RDONLY );
178
+ if (fd == -1 )
179
+ return false;
180
+
181
+ struct stat buf ;
182
+ if (fstat (fd , & buf ) == -1 )
183
+ {
184
+ close (fd );
185
+ return false;
186
+ }
187
+
188
+ int64_t size_local = buf .st_size ;
189
+ void * mapped = mmap (NULL , size_local , PROT_READ , MAP_PRIVATE , fd , 0 );
190
+ if (mapped == MAP_FAILED )
191
+ {
192
+ close (fd );
193
+ return false;
194
+ }
195
+
196
+ LOG_INFO ("Mapped %s -> %s" , name , full_path );
197
+ g_mapped_files [g_mapped_files_count ] = mapped ;
198
+ g_mapped_file_sizes [g_mapped_files_count ] = size_local ;
199
+ g_mapped_files_count ++ ;
200
+ close (fd );
201
+ * data = mapped ;
202
+ * size = size_local ;
203
+ return true;
204
+ }
205
+
150
206
static void
151
207
free_resources ()
152
208
{
@@ -166,9 +222,13 @@ free_resources ()
166
222
coreclr_shutdown (g_coreclr_handle , g_coreclr_domainId );
167
223
g_coreclr_handle = NULL ;
168
224
}
225
+ for (int i = 0 ; i < g_mapped_files_count ; ++ i )
226
+ {
227
+ munmap (g_mapped_files [i ], g_mapped_file_sizes [i ]);
228
+ }
169
229
}
170
230
171
- static int
231
+ static int
172
232
mono_droid_execute_assembly (const char * executable_path , void * coreclr_handle , unsigned int coreclr_domainId , int managed_argc , const char * * managed_argv )
173
233
{
174
234
unsigned int rv ;
@@ -178,6 +238,8 @@ mono_droid_execute_assembly (const char* executable_path, void* coreclr_handle,
178
238
return rv ;
179
239
}
180
240
241
+ #define PROPERTY_COUNT 3
242
+
181
243
static int
182
244
mono_droid_runtime_init (const char * executable )
183
245
{
@@ -198,34 +260,38 @@ mono_droid_runtime_init (const char* executable)
198
260
199
261
chdir (g_bundle_path );
200
262
201
- // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
263
+ struct host_runtime_contract host_contract = {
264
+ sizeof (struct host_runtime_contract ),
265
+ NULL , // context
266
+ NULL , // get_runtime_property
267
+ NULL , // bundle_proble
268
+ NULL , // pinvoke_override
269
+ & external_assembly_probe };
202
270
203
- const char * appctx_keys [3 ];
271
+ const char * appctx_keys [PROPERTY_COUNT ];
204
272
appctx_keys [0 ] = "RUNTIME_IDENTIFIER" ;
205
273
appctx_keys [1 ] = "APP_CONTEXT_BASE_DIRECTORY" ;
206
- appctx_keys [2 ] = "TRUSTED_PLATFORM_ASSEMBLIES " ;
274
+ appctx_keys [2 ] = "HOST_RUNTIME_CONTRACT " ;
207
275
208
- const char * appctx_values [3 ];
276
+ const char * appctx_values [PROPERTY_COUNT ];
209
277
appctx_values [0 ] = ANDROID_RUNTIME_IDENTIFIER ;
210
278
appctx_values [1 ] = g_bundle_path ;
211
- size_t tpas_len = get_tpas_from_path (g_bundle_path , & appctx_values [2 ]);
212
- if (tpas_len < 1 )
213
- {
214
- LOG_ERROR ("Failed to get trusted assemblies from path: %s" , g_bundle_path );
215
- return -1 ;
216
- }
279
+
280
+ char contract_str [19 ]; // 0x + 16 hex digits + '\0'
281
+ snprintf (contract_str , 19 , "0x%zx" , (size_t )(& host_contract ));
282
+ appctx_values [2 ] = contract_str ;
217
283
218
284
LOG_INFO ("Calling coreclr_initialize" );
219
285
int rv = coreclr_initialize (
220
286
g_executable_path ,
221
287
executable ,
222
- 3 ,
288
+ PROPERTY_COUNT ,
223
289
appctx_keys ,
224
290
appctx_values ,
225
291
& g_coreclr_handle ,
226
292
& g_coreclr_domainId
227
293
);
228
- LOG_INFO ("coreclr_initialize returned %d " , rv );
294
+ LOG_INFO ("coreclr_initialize returned 0x%x " , rv );
229
295
return rv ;
230
296
}
231
297
@@ -237,7 +303,7 @@ Java_net_dot_MonoRunner_setEnv (JNIEnv* env, jobject thiz, jstring j_key, jstrin
237
303
238
304
const char * key = (* env )-> GetStringUTFChars (env , j_key , 0 );
239
305
const char * val = (* env )-> GetStringUTFChars (env , j_value , 0 );
240
-
306
+
241
307
LOG_INFO ("Setting env: %s=%s" , key , val );
242
308
setenv (key , val , true);
243
309
(* env )-> ReleaseStringUTFChars (env , j_key , key );
270
336
Java_net_dot_MonoRunner_execEntryPoint (JNIEnv * env , jobject thiz , jstring j_entryPointLibName , jobjectArray j_args )
271
337
{
272
338
LOG_INFO ("Java_net_dot_MonoRunner_execEntryPoint (CoreCLR):" );
273
-
339
+
274
340
if ((g_bundle_path == NULL ) || (g_executable_path == NULL ))
275
341
{
276
342
LOG_ERROR ("Bundle path or executable path not set" );
0 commit comments