3 #include <mono/metadata/assembly.h>
4 #include <mono/metadata/mono-config.h>
5 #include <mono/utils/mono-mmap.h>
14 # ifndef BUILDVER_INCLUDED
15 # include "buildver-boehm.h"
20 * If the MONO_ENV_OPTIONS environment variable is set, it uses this as a
21 * source of command line arguments that are passed to Mono before the
22 * command line arguments specified in the command line.
25 mono_main_with_options (int argc, char *argv [])
27 mono_parse_env_options (&argc, &argv);
29 return mono_main (argc, argv);
32 #define STREAM_INT(x) GUINT32_TO_LE((*(uint32_t*)x))
33 #define STREAM_LONG(x) GUINT64_TO_LE((*(uint64_t*)x))
36 * Loads a chunk of data from the file pointed to by the
37 * @fd starting at the file offset @offset for @size bytes
38 * and returns an allocated version of that string, or NULL
42 load_from_region (int fd, uint64_t offset, uint64_t size)
49 loc = lseek (fd, offset, SEEK_SET);
50 } while (loc == -1 && errno == EINTR);
53 buffer = g_malloc (size + 1);
58 status = read (fd, buffer, size);
59 } while (status == -1 && errno == EINTR);
68 probe_embedded (const char *program, int *ref_argc, char **ref_argv [])
70 MonoBundledAssembly last = { NULL, 0, 0 };
71 char sigbuffer [16+sizeof (uint64_t)];
72 gboolean status = FALSE;
73 uint64_t directory_location;
74 off_t sigstart, baseline = 0;
75 uint64_t directory_size;
78 unsigned char *mapaddress = NULL;
79 void *maphandle = NULL;
81 char *entry_point = NULL;
85 int fd = open (program, O_RDONLY);
88 if ((sigstart = lseek (fd, -24, SEEK_END)) == -1)
90 if (read (fd, sigbuffer, sizeof (sigbuffer)) == -1)
92 if (memcmp (sigbuffer+sizeof(uint64_t), "xmonkeysloveplay", 16) != 0)
94 directory_location = GUINT64_FROM_LE ((*(uint64_t *) &sigbuffer [0]));
95 if (lseek (fd, directory_location, SEEK_SET) == -1)
97 directory_size = sigstart-directory_location;
98 directory = g_malloc (directory_size);
99 if (directory == NULL)
101 if (read (fd, directory, directory_size) == -1)
104 items = STREAM_INT (directory);
107 assemblies = g_array_new (0, 0, sizeof (MonoBundledAssembly*));
108 for (i = 0; i < items; i++){
110 int strsize = STREAM_INT (p);
111 uint64_t offset, item_size;
114 offset = STREAM_LONG(p);
116 item_size = STREAM_INT (p);
119 if (mapaddress == NULL){
120 mapaddress = mono_file_map (directory_location-offset, MONO_MMAP_READ | MONO_MMAP_PRIVATE, fd, offset, &maphandle);
121 if (mapaddress == NULL){
122 perror ("Error mapping file");
127 if (strncmp (kind, "assembly:", strlen ("assembly:")) == 0){
128 char *aname = kind + strlen ("assembly:");
129 MonoBundledAssembly mba = { aname, mapaddress + offset - baseline, item_size }, *ptr;
130 ptr = g_new (MonoBundledAssembly, 1);
131 memcpy (ptr, &mba, sizeof (MonoBundledAssembly));
132 g_array_append_val (assemblies, ptr);
133 if (entry_point == NULL)
135 } else if (strncmp (kind, "config:", strlen ("config:")) == 0){
136 char *config = kind + strlen ("config:");
137 char *aname = g_strdup (config);
138 aname [strlen(aname)-strlen(".config")] = 0;
139 mono_register_config_for_assembly (aname, load_from_region (fd, offset, item_size));
140 } else if (strncmp (kind, "systemconfig:", strlen ("systemconfig:")) == 0){
141 mono_config_parse_memory (load_from_region (fd, offset, item_size));
142 } else if (strncmp (kind, "options:", strlen ("options:")) == 0){
143 mono_parse_options_from (load_from_region (fd, offset, item_size), ref_argc, ref_argv);
144 } else if (strncmp (kind, "config_dir:", strlen ("config_dir:")) == 0){
145 mono_set_dirs (getenv ("MONO_PATH"), load_from_region (fd, offset, item_size));
146 } else if (strncmp (kind, "machineconfig:", strlen ("machineconfig:")) == 0) {
147 mono_register_machine_config (load_from_region (fd, offset, item_size));
148 } else if (strncmp (kind, "env:", strlen ("env:")) == 0){
149 char *data = load_from_region (fd, offset, item_size);
150 uint8_t count = *data++;
151 char *value = data + count + 1;
152 g_setenv (data, value, FALSE);
154 fprintf (stderr, "Unknown stream on embedded package: %s\n", kind);
158 g_array_append_val (assemblies, last);
160 mono_register_bundled_assemblies ((const MonoBundledAssembly **) assemblies->data);
161 new_argv = g_new (char *, (*ref_argc)+1);
162 for (j = 0; j < *ref_argc; j++)
163 new_argv [j] = (*ref_argv)[j];
164 new_argv [j] = entry_point;
165 *ref_argv = new_argv;
180 #include <shellapi.h>
185 TCHAR szFileName[MAX_PATH];
192 argvw = CommandLineToArgvW (GetCommandLine (), &argc);
193 argv = g_new0 (gchar*, argc + 1);
194 for (i = 0; i < argc; i++)
195 argv [i] = g_utf16_to_utf8 (argvw [i], -1, NULL, NULL, NULL);
200 if ((count = GetModuleFileName (NULL, szFileName, MAX_PATH)) != 0){
201 char *entry = g_utf16_to_utf8 (szFileName, count, NULL, NULL, NULL);
202 probe_embedded (entry, &argc, &argv);
205 return mono_main_with_options (argc, argv);
211 main (int argc, char* argv[])
213 mono_build_date = build_date;
215 probe_embedded (argv [0], &argc, &argv);
216 return mono_main_with_options (argc, argv);