Merge pull request #884 from akoeplinger/fix-ipv6-teredo
[mono.git] / mono / mini / mini-llvm.h
1 /*
2  * Handle the differences between the llvm backend beeing embedded
3  * or loaded at runtime.
4  */
5 #ifdef MONO_LLVM_LOADED
6
7 int mono_llvm_load (const char* bpath) MONO_INTERNAL;
8
9 #ifdef MONO_LLVM_IN_MINI
10
11 #ifdef __MACH__
12 #include <mach-o/dyld.h>
13 #endif
14
15 typedef void (*MonoLLVMVoidFunc)(void);
16 typedef void (*MonoLLVMCFGFunc)(MonoCompile *cfg);
17 typedef void (*MonoLLVMEmitCallFunc)(MonoCompile *cfg, MonoCallInst *call);
18 typedef void (*MonoLLVMCreateAotFunc)(const char *got_symbol);
19 typedef void (*MonoLLVMEmitAotFunc)(const char *filename, int got_size);
20
21 static MonoLLVMVoidFunc mono_llvm_init_fptr;
22 static MonoLLVMVoidFunc mono_llvm_cleanup_fptr;
23 static MonoLLVMCFGFunc mono_llvm_emit_method_fptr;
24 static MonoLLVMEmitCallFunc mono_llvm_emit_call_fptr;
25 static MonoLLVMCreateAotFunc mono_llvm_create_aot_module_fptr;
26 static MonoLLVMEmitAotFunc mono_llvm_emit_aot_module_fptr;
27 static MonoLLVMCFGFunc mono_llvm_check_method_supported_fptr;
28
29 void
30 mono_llvm_init (void)
31 {
32         mono_llvm_init_fptr ();
33 }
34
35 void
36 mono_llvm_cleanup (void)
37 {
38         mono_llvm_cleanup_fptr ();
39 }
40
41 void
42 mono_llvm_emit_method (MonoCompile *cfg)
43 {
44         mono_llvm_emit_method_fptr (cfg);
45 }
46
47 void
48 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
49 {
50         mono_llvm_emit_call_fptr (cfg, call);
51 }
52
53 void
54 mono_llvm_create_aot_module (const char *got_symbol)
55 {
56         g_assert (mono_llvm_create_aot_module_fptr);
57         mono_llvm_create_aot_module_fptr (got_symbol);
58 }
59
60 void
61 mono_llvm_emit_aot_module (const char *filename, int got_size)
62 {
63         g_assert (mono_llvm_emit_aot_module_fptr);
64         mono_llvm_emit_aot_module_fptr (filename, got_size);
65 }
66
67 void
68 mono_llvm_check_method_supported (MonoCompile *cfg)
69 {
70         mono_llvm_check_method_supported_fptr (cfg);
71 }
72
73 static MonoDl*
74 try_llvm_load (char *dir, char **err)
75 {
76         gpointer iter;
77         MonoDl *llvm_lib;
78         char *path;
79         iter = NULL;
80         *err = NULL;
81         while ((path = mono_dl_build_path (dir, "mono-llvm", &iter))) {
82                 g_free (*err);
83                 llvm_lib = mono_dl_open (path, MONO_DL_LAZY, err);
84                 g_free (path);
85                 if (llvm_lib)
86                         return llvm_lib;
87         }
88         return NULL;
89 }
90
91 int
92 mono_llvm_load (const char* bpath)
93 {
94         MonoDl *llvm_lib = NULL;
95         char *err;
96         char buf [4096];
97         int binl;
98         binl = readlink ("/proc/self/exe", buf, sizeof (buf)-1);
99 #ifdef __MACH__
100         if (binl == -1) {
101                 uint32_t bsize = sizeof (buf);
102                 if (_NSGetExecutablePath (buf, &bsize) == 0) {
103                         binl = strlen (buf);
104                 }
105         }
106 #endif
107         if (binl != -1) {
108                 char *base;
109                 char *resolvedname, *name;
110                 buf [binl] = 0;
111                 resolvedname = mono_path_resolve_symlinks (buf);
112                 base = g_path_get_dirname (resolvedname);
113                 name = g_strdup_printf ("%s/.libs", base);
114                 err = NULL;
115                 llvm_lib = try_llvm_load (name, &err);
116                 g_free (name);
117                 if (!llvm_lib) {
118                         char *newbase = g_path_get_dirname (base);
119                         name = g_strdup_printf ("%s/lib", newbase);
120                         err = NULL;
121                         llvm_lib = try_llvm_load (name, &err);
122                         g_free (name);
123                 }
124 #ifdef __MACH__
125                 if (!llvm_lib) {
126                         char *newbase = g_path_get_dirname (base);
127                         name = g_strdup_printf ("%s/Libraries", newbase);
128                         err = NULL;
129                         llvm_lib = try_llvm_load (name, &err);
130                         g_free (name);
131                 }
132 #endif
133                 g_free (base);
134                 g_free (resolvedname);
135         }
136         if (!llvm_lib) {
137                 llvm_lib = try_llvm_load (NULL, &err);
138                 if (!llvm_lib) {
139                         g_warning ("llvm load failed: %s\n", err);
140                         g_free (err);
141                         return FALSE;
142                 }
143         }
144         err = mono_dl_symbol (llvm_lib, "mono_llvm_init", (void**)&mono_llvm_init_fptr);
145         if (err) goto symbol_error;
146         err = mono_dl_symbol (llvm_lib, "mono_llvm_cleanup", (void**)&mono_llvm_cleanup_fptr);
147         if (err) goto symbol_error;
148         err = mono_dl_symbol (llvm_lib, "mono_llvm_emit_method", (void**)&mono_llvm_emit_method_fptr);
149         if (err) goto symbol_error;
150         err = mono_dl_symbol (llvm_lib, "mono_llvm_emit_call", (void**)&mono_llvm_emit_call_fptr);
151         if (err) goto symbol_error;
152         err = mono_dl_symbol (llvm_lib, "mono_llvm_create_aot_module", (void**)&mono_llvm_create_aot_module_fptr);
153         if (err) goto symbol_error;
154         err = mono_dl_symbol (llvm_lib, "mono_llvm_emit_aot_module", (void**)&mono_llvm_emit_aot_module_fptr);
155         if (err) goto symbol_error;
156         err = mono_dl_symbol (llvm_lib, "mono_llvm_check_method_supported", (void**)&mono_llvm_check_method_supported_fptr);
157         if (err) goto symbol_error;
158         return TRUE;
159 symbol_error:
160         g_warning ("llvm symbol load failed: %s\n", err);
161         g_free (err);
162         return FALSE;
163 }
164
165 #endif
166
167 #else
168 #define mono_llvm_load(bpath) TRUE
169 #endif /* MONO_LLVM_LOADED */
170