1/*
2 * Copyright 2003-2007, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Axel D��rfler, axeld@pinc-software.de.
7 *		Ingo Weinhold, bonefish@users.sf.net.
8 */
9
10//!	C++ in the kernel
11
12
13#include "util/kernel_cpp.h"
14
15#ifdef _BOOT_MODE
16#	include <boot/platform.h>
17#else
18#	include <KernelExport.h>
19#	include <stdio.h>
20#endif
21
22#ifdef _LOADER_MODE
23#	define panic printf
24#	define dprintf printf
25#	define kernel_debugger printf
26#endif
27
28
29// Always define the symbols needed when not linking against libgcc.a --
30// we simply override them.
31
32// ... it doesn't seem to work with this symbol at least.
33#ifndef USING_LIBGCC
34#	if __GNUC__ >= 6 || defined(__clang__)
35const std::nothrow_t std::nothrow = std::nothrow_t{ };
36#	elif __GNUC__ >= 3
37const std::nothrow_t std::nothrow = {};
38#	else
39const nothrow_t std::nothrow = {};
40#	endif
41#endif
42
43#if __cplusplus >= 201402L
44#define _THROW(x)
45#define _NOEXCEPT noexcept
46#else
47#define _THROW(x) throw (x)
48#define _NOEXCEPT throw ()
49#endif
50
51const mynothrow_t mynothrow = {};
52
53#if __GNUC__ == 2
54
55extern "C" void
56__pure_virtual()
57{
58	panic("pure virtual function call\n");
59}
60
61#elif __GNUC__ >= 3
62
63extern "C" void
64__cxa_pure_virtual()
65{
66	panic("pure virtual function call\n");
67}
68
69
70extern "C" int
71__cxa_atexit(void (*hook)(void*), void* data, void* dsoHandle)
72{
73	return 0;
74}
75
76
77extern "C" void
78__cxa_finalize(void* dsoHandle)
79{
80}
81
82#endif
83
84// full C++ support in the kernel
85#if (defined(_KERNEL_MODE) || defined(_LOADER_MODE))
86void *
87operator new(size_t size) _THROW(std::bad_alloc)
88{
89	// we don't actually throw any exceptions, but we have to
90	// keep the prototype as specified in <new>, or else GCC 3
91	// won't like us
92	return malloc(size);
93}
94
95
96void *
97operator new[](size_t size)
98{
99	return malloc(size);
100}
101
102
103void *
104operator new(size_t size, const std::nothrow_t &) _NOEXCEPT
105{
106	return malloc(size);
107}
108
109
110void *
111operator new[](size_t size, const std::nothrow_t &) _NOEXCEPT
112{
113	return malloc(size);
114}
115
116
117void *
118operator new(size_t size, const mynothrow_t &) _NOEXCEPT
119{
120	return malloc(size);
121}
122
123
124void *
125operator new[](size_t size, const mynothrow_t &) _NOEXCEPT
126{
127	return malloc(size);
128}
129
130
131void
132operator delete(void *ptr) _NOEXCEPT
133{
134	free(ptr);
135}
136
137
138void
139operator delete[](void *ptr) _NOEXCEPT
140{
141	free(ptr);
142}
143
144
145#if __cplusplus >= 201402L
146
147void
148operator delete(void* ptr, std::size_t) _NOEXCEPT
149{
150	free(ptr);
151}
152
153
154void
155operator delete[](void* ptr, std::size_t) _NOEXCEPT
156{
157	free(ptr);
158}
159
160#endif
161
162
163#ifndef _BOOT_MODE
164
165FILE *stderr = NULL;
166
167extern "C"
168int
169fprintf(FILE *f, const char *format, ...)
170{
171	// TODO: Introduce a vdprintf()...
172	dprintf("fprintf(`%s',...)\n", format);
173	return 0;
174}
175
176extern "C"
177size_t
178fwrite(const void *buffer, size_t size, size_t numItems, FILE *stream)
179{
180	dprintf("%.*s", int(size * numItems), (char*)buffer);
181	return 0;
182}
183
184extern "C"
185int
186fputs(const char *string, FILE *stream)
187{
188	dprintf("%s", string);
189	return 0;
190}
191
192extern "C"
193int
194fputc(int c, FILE *stream)
195{
196	dprintf("%c", c);
197	return 0;
198}
199
200#ifndef _LOADER_MODE
201extern "C"
202int
203printf(const char *format, ...)
204{
205	// TODO: Introduce a vdprintf()...
206	dprintf("printf(`%s',...)\n", format);
207	return 0;
208}
209#endif // #ifndef _LOADER_MODE
210
211extern "C"
212int
213puts(const char *string)
214{
215	return fputs(string, NULL);
216}
217
218#endif	// #ifndef _BOOT_MODE
219
220#if __GNUC__ >= 4
221
222extern "C"
223void
224_Unwind_DeleteException()
225{
226	panic("_Unwind_DeleteException");
227}
228
229extern "C"
230void
231_Unwind_Find_FDE()
232{
233	panic("_Unwind_Find_FDE");
234}
235
236
237extern "C"
238void
239_Unwind_GetDataRelBase()
240{
241	panic("_Unwind_GetDataRelBase");
242}
243
244extern "C"
245void
246_Unwind_GetGR()
247{
248	panic("_Unwind_GetGR");
249}
250
251extern "C"
252void
253_Unwind_GetIP()
254{
255	panic("_Unwind_GetIP");
256}
257
258extern "C"
259void
260_Unwind_GetIPInfo()
261{
262	panic("_Unwind_GetIPInfo");
263}
264
265extern "C"
266void
267_Unwind_GetLanguageSpecificData()
268{
269	panic("_Unwind_GetLanguageSpecificData");
270}
271
272extern "C"
273void
274_Unwind_GetRegionStart()
275{
276	panic("_Unwind_GetRegionStart");
277}
278
279extern "C"
280void
281_Unwind_GetTextRelBase()
282{
283	panic("_Unwind_GetTextRelBase");
284}
285
286extern "C"
287void
288_Unwind_RaiseException()
289{
290	panic("_Unwind_RaiseException");
291}
292
293extern "C"
294void
295_Unwind_Resume()
296{
297	panic("_Unwind_Resume");
298}
299
300extern "C"
301void
302_Unwind_Resume_or_Rethrow()
303{
304	panic("_Unwind_Resume_or_Rethrow");
305}
306
307extern "C"
308void
309_Unwind_SetGR()
310{
311	panic("_Unwind_SetGR");
312}
313
314extern "C"
315void
316_Unwind_SetIP()
317{
318	panic("_Unwind_SetIP");
319}
320
321extern "C"
322void
323__deregister_frame_info()
324{
325	panic("__deregister_frame_info");
326}
327
328extern "C"
329void
330__register_frame_info()
331{
332	panic("__register_frame_info");
333}
334
335/* ARM */
336extern "C" void
337__aeabi_unwind_cpp_pr0(void)
338{
339	panic("__aeabi_unwind_cpp_pr0");
340}
341
342extern "C" void
343__aeabi_unwind_cpp_pr1(void)
344{
345	panic("__aeabi_unwind_cpp_pr1");
346}
347
348extern "C" void
349__aeabi_unwind_cpp_pr2(void)
350{
351	panic("__aeabi_unwind_cpp_pr2");
352}
353
354extern "C" void
355_Unwind_Complete(void)
356{
357	panic("_Unwind_Complete");
358}
359
360extern "C" void
361_Unwind_VRS_Set(void)
362{
363	panic("_Unwind_VRS_Set");
364}
365
366extern "C" void
367_Unwind_VRS_Get(void)
368{
369	panic("_Unwind_VRS_Get");
370}
371
372extern "C" void
373__gnu_unwind_frame(void)
374{
375	panic("__gnu_unwind_frame");
376}
377
378#endif	// __GNUC__ >= 4
379
380extern "C"
381void
382abort()
383{
384	panic("abort() called!");
385}
386
387
388#ifndef _BOOT_MODE
389
390extern "C"
391void
392debugger(const char *message)
393{
394	kernel_debugger(message);
395}
396
397#endif	// #ifndef _BOOT_MODE
398
399#endif	// #if (defined(_KERNEL_MODE) || defined(_LOADER_MODE))
400
401
402extern "C"
403void
404exit(int status)
405{
406	while (true)
407		panic("exit() called with status code = %d!", status);
408}
409
410