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