pthread.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <pthread.h>
23 
24 #include <errno.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <stdint.h>
28 
29 #define MAX_THREAD_SPECIFIC_DATA 512
30 
31 extern "C" uint64_t thread_context_cpuid(void);
32 extern "C" uint64_t thread_context_tlsptr(void);
33 
34 #define UNHANDLED() \
35  { \
36  const char *str_text = "\033[1;33mWARNING\033[0m: unsupported pthread function called = "; \
37  const char *str_func = __PRETTY_FUNCTION__; \
38  const char *str_endl = "\n"; \
39  write(0, str_text, strlen(str_text)); \
40  write(0, str_func, strlen(str_func)); \
41  write(0, str_endl, strlen(str_endl)); \
42  }
43 
44 #define ARG_UNSUPPORTED(a) \
45  { \
46  const char *str_text = "\033[1;33mWARNING\033[0m: " a " not supported for function called = "; \
47  const char *str_func = __PRETTY_FUNCTION__; \
48  const char *str_endl = "\n"; \
49  write(0, str_text, strlen(str_text)); \
50  write(0, str_func, strlen(str_func)); \
51  write(0, str_endl, strlen(str_endl)); \
52  }
53 
54 #ifndef LOOKUP_TLS_DATA
56 #endif
57 
58 extern "C" int
59 pthread_cond_broadcast(pthread_cond_t *cond)
60 {
61  if (!cond)
62  return -EINVAL;
63 
64  __sync_lock_release(cond);
65 
66  return 0;
67 }
68 
69 extern "C" int
70 pthread_cond_destroy(pthread_cond_t *)
71 {
72  UNHANDLED();
73  return -ENOSYS;
74 }
75 
76 extern "C" int
77 pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
78 {
79  if (attr)
80  ARG_UNSUPPORTED("attr");
81 
82  if (!cond)
83  return -EINVAL;
84 
85  *cond = 0;
86  return 0;
87 }
88 
89 extern "C" int
90 pthread_cond_signal(pthread_cond_t *)
91 {
92  UNHANDLED();
93  return -ENOSYS;
94 }
95 
96 extern "C" int
97 pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *)
98 {
99  UNHANDLED();
100  return -ENOSYS;
101 }
102 
103 extern "C" int
104 pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
105 {
106  if (!cond || !mutex)
107  return -EINVAL;
108 
109  *cond = 1;
110 
111  pthread_mutex_unlock(mutex);
112  while (__sync_lock_test_and_set(cond, 1)) { while (*cond); };
113  pthread_mutex_lock(mutex);
114 
115  return 0;
116 }
117 
118 extern "C" int
119 pthread_detach(pthread_t)
120 {
121  UNHANDLED();
122  return -ENOSYS;
123 }
124 
125 extern "C" int
126 pthread_equal(pthread_t, pthread_t)
127 {
128  UNHANDLED();
129  return -ENOSYS;
130 }
131 
132 extern "C" void *
133 pthread_getspecific(pthread_key_t key)
134 {
135  if (key > MAX_THREAD_SPECIFIC_DATA)
136  return nullptr;
137 
138 #ifdef LOOKUP_TLS_DATA
139  auto threadSpecificData = reinterpret_cast<void **>(thread_context_tlsptr());
140 #endif
141 
142  return threadSpecificData[key];
143 }
144 
145 extern "C" int
146 pthread_join(pthread_t, void **)
147 {
148  UNHANDLED();
149  return -ENOSYS;
150 }
151 
152 extern "C" int
153 pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
154 {
155  static int64_t g_keys = 0;
156 
157  if (destructor)
158  ARG_UNSUPPORTED("destructor");
159 
160  if (!key)
161  return -EINVAL;
162 
163  *key = __sync_fetch_and_add(&g_keys, 1);
164 
165  return 0;
166 }
167 
168 extern "C" int
169 pthread_key_delete(pthread_key_t)
170 {
171  UNHANDLED();
172  return -ENOSYS;
173 }
174 
175 extern "C" int
176 pthread_mutex_destroy(pthread_mutex_t *)
177 {
178  UNHANDLED();
179  return -ENOSYS;
180 }
181 
182 extern "C" int
183 pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
184 {
185  if (attr)
186  ARG_UNSUPPORTED("attr");
187 
188  if (!mutex)
189  return -EINVAL;
190 
191  *mutex = 0;
192  return 0;
193 }
194 
195 extern "C" int
196 pthread_mutex_lock(pthread_mutex_t *mutex)
197 {
198  if (!mutex)
199  return -EINVAL;
200 
201  while (__sync_lock_test_and_set(mutex, 1)) { while (*mutex); };
202 
203  return 0;
204 }
205 
206 extern "C" int
207 pthread_mutex_trylock(pthread_mutex_t *)
208 {
209  UNHANDLED();
210  return -ENOSYS;
211 }
212 
213 extern "C" int
214 pthread_mutex_unlock(pthread_mutex_t *mutex)
215 {
216  if (!mutex)
217  return -EINVAL;
218 
219  __sync_lock_release(mutex);
220 
221  return 0;
222 }
223 
224 extern "C" int
225 pthread_mutexattr_destroy(pthread_mutexattr_t *)
226 {
227  UNHANDLED();
228  return -ENOSYS;
229 }
230 
231 extern "C" int
232 pthread_mutexattr_init(pthread_mutexattr_t *)
233 {
234  UNHANDLED();
235  return -ENOSYS;
236 }
237 
238 extern "C" int
239 pthread_mutexattr_settype(pthread_mutexattr_t *, int)
240 {
241  UNHANDLED();
242  return -ENOSYS;
243 }
244 
245 extern "C" int
246 pthread_once(pthread_once_t *once, void (*init)(void))
247 {
248  if (!once || !init)
249  return -EINVAL;
250 
251  if (__sync_fetch_and_add(once, 1) == 0)
252  (*init)();
253 
254  return 0;
255 }
256 
257 extern "C" pthread_t
259 {
260  UNHANDLED();
261  return 1;
262 }
263 
264 extern "C" int
265 pthread_setspecific(pthread_key_t key, const void *data)
266 {
267  if (key > MAX_THREAD_SPECIFIC_DATA)
268  return -EINVAL;
269 
270 #ifdef LOOKUP_TLS_DATA
271  auto threadSpecificData = reinterpret_cast<void **>(thread_context_tlsptr());
272 #endif
273 
274  threadSpecificData[key] = const_cast<void *>(data);
275  return 0;
276 }
int pthread_equal(pthread_t, pthread_t)
Definition: pthread.cpp:126
int pthread_cond_destroy(pthread_cond_t *)
Definition: pthread.cpp:70
void * pthread_getspecific(pthread_key_t key)
Definition: pthread.cpp:133
int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: pthread.cpp:59
int pthread_cond_signal(pthread_cond_t *)
Definition: pthread.cpp:90
uint64_t thread_context_cpuid(void)
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: pthread.cpp:183
int pthread_mutexattr_init(pthread_mutexattr_t *)
Definition: pthread.cpp:232
int pthread_mutex_trylock(pthread_mutex_t *)
Definition: pthread.cpp:207
int64_t unsigned long void * data
pthread_t pthread_self(void)
Definition: pthread.cpp:258
int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: pthread.cpp:214
int pthread_mutex_destroy(pthread_mutex_t *)
Definition: pthread.cpp:176
int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *)
Definition: pthread.cpp:97
#define MAX_THREAD_SPECIFIC_DATA
Definition: pthread.cpp:29
int pthread_detach(pthread_t)
Definition: pthread.cpp:119
int pthread_mutexattr_settype(pthread_mutexattr_t *, int)
Definition: pthread.cpp:239
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: pthread.cpp:104
int pthread_once(pthread_once_t *once, void(*init)(void))
Definition: pthread.cpp:246
int pthread_key_create(pthread_key_t *key, void(*destructor)(void *))
Definition: pthread.cpp:153
int pthread_key_delete(pthread_key_t)
Definition: pthread.cpp:169
int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: pthread.cpp:196
int pthread_setspecific(pthread_key_t key, const void *data)
Definition: pthread.cpp:265
#define ARG_UNSUPPORTED(a)
Definition: pthread.cpp:44
int pthread_mutexattr_destroy(pthread_mutexattr_t *)
Definition: pthread.cpp:225
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: pthread.cpp:77
uint64_t thread_context_tlsptr(void)
void * threadSpecificData[MAX_THREAD_SPECIFIC_DATA]
Definition: pthread.cpp:55
int pthread_join(pthread_t, void **)
Definition: pthread.cpp:146
#define UNHANDLED()
Definition: pthread.cpp:34