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 256 // 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__)
@@ -68,66 +74,6 @@ strncpy_str (JNIEnv *env, char *buff, jstring str, int nbuff)
68
74
(* env )-> ReleaseStringUTFChars (env , str , copy_buff );
69
75
}
70
76
71
- /*
72
- * Get the list of trusted assemblies from a specified @dir_path.
73
- * The path is searched for .dll files which when found are concatenated
74
- * to the output string @tpas separated by ':'.
75
- * The output string should be freed by the caller.
76
- * The return value is the length of the output string.
77
- */
78
- static size_t
79
- get_tpas_from_path (const char * dir_path , const char * * tpas )
80
- {
81
- DIR * dir = opendir (dir_path );
82
- if (dir == NULL )
83
- {
84
- LOG_ERROR ("Failed to open directory at: %s" , dir_path );
85
- return -1 ;
86
- }
87
-
88
- struct dirent * dir_entry ;
89
- size_t dir_path_len = strlen (dir_path );
90
- char * concat_dll_paths = NULL ;
91
- size_t concat_dll_paths_len = 0 ;
92
-
93
- while ((dir_entry = readdir (dir )))
94
- {
95
- if (dir_entry -> d_type == DT_REG )
96
- {
97
- size_t file_name_len = strlen (dir_entry -> d_name );
98
- // filter out .dll files
99
- if (file_name_len > 4 && strcmp (dir_entry -> d_name + file_name_len - 4 , ".dll" ) == 0 )
100
- {
101
- size_t curr_dll_path = dir_path_len + file_name_len + 2 ; // +2 for '/' and ':'
102
- concat_dll_paths_len += curr_dll_path ;
103
- concat_dll_paths = realloc (concat_dll_paths , concat_dll_paths_len );
104
- if (concat_dll_paths == NULL )
105
- {
106
- LOG_ERROR ("realloc failed while resolving: %s" , dir_entry -> d_name );
107
- closedir (dir );
108
- return -1 ;
109
- }
110
- concat_dll_paths [concat_dll_paths_len - curr_dll_path ] = '\0' ; // adjust previous string end
111
- size_t ret = sprintf (concat_dll_paths , "%s%s/%s:" , concat_dll_paths , dir_path , dir_entry -> d_name ); // concat the current dll path
112
- if (ret != concat_dll_paths_len )
113
- {
114
- LOG_ERROR ("sprintf failed while resolving: %s" , dir_entry -> d_name );
115
- closedir (dir );
116
- return -1 ;
117
- }
118
- }
119
- }
120
- }
121
- closedir (dir );
122
-
123
- if (concat_dll_paths != NULL && concat_dll_paths_len > 0 ) {
124
- concat_dll_paths [concat_dll_paths_len - 1 ] = '\0' ; // remove the trailing ':'
125
- }
126
-
127
- * tpas = concat_dll_paths ;
128
- return concat_dll_paths_len ;
129
- }
130
-
131
77
static int
132
78
bundle_executable_path (const char * executable , const char * bundle_path , const char * * executable_path )
133
79
{
@@ -147,6 +93,56 @@ bundle_executable_path (const char* executable, const char* bundle_path, const c
147
93
return executable_path_len ;
148
94
}
149
95
96
+ static bool
97
+ external_assembly_probe (const char * name , void * * data , int64_t * size )
98
+ {
99
+ if (g_mapped_files_count >= MAX_MAPPED_COUNT )
100
+ {
101
+ LOG_ERROR ("Too many mapped files, cannot map %s" , name );
102
+ return false;
103
+ }
104
+
105
+ // Get just the file name
106
+ const char * pos = strrchr (name , '/' );
107
+ if (pos != NULL )
108
+ name = pos + 1 ;
109
+
110
+ // Look in the bundle path where the files were extracted
111
+ char full_path [1024 ];
112
+ size_t path_len = strlen (g_bundle_path ) + strlen (name ) + 1 ; // +1 for '/'
113
+ size_t res = snprintf (full_path , path_len + 1 , "%s/%s" , g_bundle_path , name );
114
+ if (res < 0 || res != path_len )
115
+ return false;
116
+
117
+ int fd = open (full_path , O_RDONLY );
118
+ if (fd == -1 )
119
+ return false;
120
+
121
+ struct stat buf ;
122
+ if (fstat (fd , & buf ) == -1 )
123
+ {
124
+ close (fd );
125
+ return false;
126
+ }
127
+
128
+ int64_t size_local = buf .st_size ;
129
+ void * mapped = mmap (NULL , size_local , PROT_READ , MAP_PRIVATE , fd , 0 );
130
+ if (mapped == MAP_FAILED )
131
+ {
132
+ close (fd );
133
+ return false;
134
+ }
135
+
136
+ LOG_INFO ("Mapped %s -> %s" , name , full_path );
137
+ g_mapped_files [g_mapped_files_count ] = mapped ;
138
+ g_mapped_file_sizes [g_mapped_files_count ] = size_local ;
139
+ g_mapped_files_count ++ ;
140
+ close (fd );
141
+ * data = mapped ;
142
+ * size = size_local ;
143
+ return true;
144
+ }
145
+
150
146
static void
151
147
free_resources ()
152
148
{
@@ -166,9 +162,13 @@ free_resources ()
166
162
coreclr_shutdown (g_coreclr_handle , g_coreclr_domainId );
167
163
g_coreclr_handle = NULL ;
168
164
}
165
+ for (int i = 0 ; i < g_mapped_files_count ; ++ i )
166
+ {
167
+ munmap (g_mapped_files [i ], g_mapped_file_sizes [i ]);
168
+ }
169
169
}
170
170
171
- static int
171
+ static int
172
172
mono_droid_execute_assembly (const char * executable_path , void * coreclr_handle , unsigned int coreclr_domainId , int managed_argc , const char * * managed_argv )
173
173
{
174
174
unsigned int rv ;
@@ -178,6 +178,8 @@ mono_droid_execute_assembly (const char* executable_path, void* coreclr_handle,
178
178
return rv ;
179
179
}
180
180
181
+ #define PROPERTY_COUNT 3
182
+
181
183
static int
182
184
mono_droid_runtime_init (const char * executable )
183
185
{
@@ -198,34 +200,38 @@ mono_droid_runtime_init (const char* executable)
198
200
199
201
chdir (g_bundle_path );
200
202
201
- // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
203
+ struct host_runtime_contract host_contract = {
204
+ sizeof (struct host_runtime_contract ),
205
+ NULL , // context
206
+ NULL , // get_runtime_property
207
+ NULL , // bundle_proble
208
+ NULL , // pinvoke_override
209
+ & external_assembly_probe };
202
210
203
- const char * appctx_keys [3 ];
211
+ const char * appctx_keys [PROPERTY_COUNT ];
204
212
appctx_keys [0 ] = "RUNTIME_IDENTIFIER" ;
205
213
appctx_keys [1 ] = "APP_CONTEXT_BASE_DIRECTORY" ;
206
- appctx_keys [2 ] = "TRUSTED_PLATFORM_ASSEMBLIES " ;
214
+ appctx_keys [2 ] = "HOST_RUNTIME_CONTRACT " ;
207
215
208
- const char * appctx_values [3 ];
216
+ const char * appctx_values [PROPERTY_COUNT ];
209
217
appctx_values [0 ] = ANDROID_RUNTIME_IDENTIFIER ;
210
218
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
- }
219
+
220
+ char contract_str [19 ]; // 0x + 16 hex digits + '\0'
221
+ snprintf (contract_str , 19 , "0x%zx" , (size_t )(& host_contract ));
222
+ appctx_values [2 ] = contract_str ;
217
223
218
224
LOG_INFO ("Calling coreclr_initialize" );
219
225
int rv = coreclr_initialize (
220
226
g_executable_path ,
221
227
executable ,
222
- 3 ,
228
+ PROPERTY_COUNT ,
223
229
appctx_keys ,
224
230
appctx_values ,
225
231
& g_coreclr_handle ,
226
232
& g_coreclr_domainId
227
233
);
228
- LOG_INFO ("coreclr_initialize returned %d " , rv );
234
+ LOG_INFO ("coreclr_initialize returned 0x%x " , rv );
229
235
return rv ;
230
236
}
231
237
@@ -237,7 +243,7 @@ Java_net_dot_MonoRunner_setEnv (JNIEnv* env, jobject thiz, jstring j_key, jstrin
237
243
238
244
const char * key = (* env )-> GetStringUTFChars (env , j_key , 0 );
239
245
const char * val = (* env )-> GetStringUTFChars (env , j_value , 0 );
240
-
246
+
241
247
LOG_INFO ("Setting env: %s=%s" , key , val );
242
248
setenv (key , val , true);
243
249
(* env )-> ReleaseStringUTFChars (env , j_key , key );
270
276
Java_net_dot_MonoRunner_execEntryPoint (JNIEnv * env , jobject thiz , jstring j_entryPointLibName , jobjectArray j_args )
271
277
{
272
278
LOG_INFO ("Java_net_dot_MonoRunner_execEntryPoint (CoreCLR):" );
273
-
279
+
274
280
if ((g_bundle_path == NULL ) || (g_executable_path == NULL ))
275
281
{
276
282
LOG_ERROR ("Bundle path or executable path not set" );
0 commit comments