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