blob: 68462c8059d9aa6384a8de418497c0fc3f72f4c8 [file] [log] [blame]
Jim Cownie33f7b242014-04-09 15:40:23 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.txt for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#include "offload_util.h"
12#include <errno.h>
13#include "liboffload_error_codes.h"
14
15#ifdef TARGET_WINNT
16void *thread_getspecific(pthread_key_t key)
17{
18 if (key == 0) {
19 return NULL;
20 }
21 else {
22 return TlsGetValue(key);
23 }
24}
25
26int thread_setspecific(pthread_key_t key, const void *value)
27{
28 return (TlsSetValue(key, (LPVOID)value)) ? 0 : GetLastError();
29}
30#endif // TARGET_WINNT
31
32bool __offload_parse_size_string(const char *str, uint64_t &new_size)
33{
34 uint64_t val;
35 char *suffix;
36
37 errno = 0;
38#ifdef TARGET_WINNT
39 val = strtoul(str, &suffix, 10);
40#else // TARGET_WINNT
41 val = strtoull(str, &suffix, 10);
42#endif // TARGET_WINNT
43 if (errno != 0 || suffix == str) {
44 return false;
45 }
46
47 if (suffix[0] == '\0') {
48 // default is Kilobytes
49 new_size = val * 1024;
50 return true;
51 }
52 else if (suffix[1] == '\0') {
53 // Optional suffixes: B (bytes), K (Kilobytes), M (Megabytes),
54 // G (Gigabytes), or T (Terabytes) specify the units.
55 switch (suffix[0]) {
56 case 'b':
57 case 'B':
58 new_size = val;
59 break;
60
61 case 'k':
62 case 'K':
63 new_size = val * 1024;
64 break;
65
66 case 'm':
67 case 'M':
68 new_size = val * 1024 * 1024;
69 break;
70
71 case 'g':
72 case 'G':
73 new_size = val * 1024 * 1024 * 1024;
74 break;
75
76 case 't':
77 case 'T':
78 new_size = val * 1024 * 1024 * 1024 * 1024;
79 break;
80
81 default:
82 return false;
83 }
84 return true;
85 }
86
87 return false;
88}
89
90bool __offload_parse_int_string(const char *str, int64_t &value)
91{
92 int64_t val;
93 char *suffix;
94
95 errno = 0;
96#ifdef TARGET_WINNT
97 val = strtol(str, &suffix, 0);
98#else
99 val = strtoll(str, &suffix, 0);
100#endif
101 if (errno == 0 && suffix != str && *suffix == '\0') {
102 value = val;
103 return true;
104 }
105 return false;
106}
107
108#ifdef TARGET_WINNT
109extern void* DL_open(const char *path)
110{
111 void *handle;
112 int error_mode;
113
114 /*
115 * do not display message box with error if it the call below fails to
116 * load dynamic library.
117 */
118 error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
119
120 /* load dynamic library */
121 handle = (void*) LoadLibrary(path);
122
123 /* restore error mode */
124 SetErrorMode(error_mode);
125
126 return handle;
127}
128
129extern int DL_addr(const void *addr, Dl_info *dl_info)
130{
131 MEMORY_BASIC_INFORMATION mem_info;
132 char mod_name[MAX_PATH];
133 HMODULE mod_handle;
134
135 /* Fill MEMORY_BASIC_INFORMATION struct */
136 if (!VirtualQuery(addr, &mem_info, sizeof(mem_info))) {
137 return 0;
138 }
139 mod_handle = (HMODULE)mem_info.AllocationBase;
140
141 /* ANSI file name for module */
142 if (!GetModuleFileNameA(mod_handle, (char*) mod_name, sizeof(mod_name))) {
143 return 0;
144 }
145 strcpy(dl_info->dli_fname, mod_name);
146 dl_info->dli_fbase = mem_info.BaseAddress;
147 dl_info->dli_saddr = addr;
148 strcpy(dl_info->dli_sname, mod_name);
149 return 1;
150}
151
152// Run once
153static BOOL CALLBACK __offload_run_once_wrapper(
154 PINIT_ONCE initOnce,
155 PVOID parameter,
156 PVOID *context
157)
158{
159 void (*init_routine)(void) = (void(*)(void)) parameter;
160 init_routine();
161 return true;
162}
163
164void __offload_run_once(OffloadOnceControl *ctrl, void (*func)(void))
165{
166 InitOnceExecuteOnce(ctrl, __offload_run_once_wrapper, (void*) func, 0);
167}
168#endif // TARGET_WINNT
169
170/* ARGSUSED */ // version is not used on windows
171void* DL_sym(void *handle, const char *name, const char *version)
172{
173#ifdef TARGET_WINNT
174 return GetProcAddress((HMODULE) handle, name);
175#else // TARGET_WINNT
176 if (version == 0) {
177 return dlsym(handle, name);
178 }
179 else {
180 return dlvsym(handle, name, version);
181 }
182#endif // TARGET_WINNT
183}
184
185int64_t get_el_value(
186 char *base,
187 int64_t offset,
188 int64_t size)
189{
190 int64_t val = 0;
191 switch (size) {
192 case 1:
193 val = static_cast<int64_t>(*((char *)(base + offset)));
194 break;
195 case 2:
196 val = static_cast<int64_t>(*((short *)(base + offset)));
197 break;
198 case 4:
199 val = static_cast<int64_t>(*((int *)(base + offset)));
200 break;
201 default:
202 val = *((int64_t *)(base + offset));
203 break;
204 }
205 return val;
206}