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__) 36 const std::nothrow_t std::nothrow = std::nothrow_t{ }; 37 # elif __GNUC__ >= 3 38 const std::nothrow_t std::nothrow = {}; 39 # else 40 const 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 52 const mynothrow_t mynothrow = {}; 53 54 #if __GNUC__ == 2 55 56 extern "C" void 57 __pure_virtual() 58 { 59 panic("pure virtual function call\n"); 60 } 61 62 #elif __GNUC__ >= 3 63 64 extern "C" void 65 __cxa_pure_virtual() 66 { 67 panic("pure virtual function call\n"); 68 } 69 70 71 extern "C" int 72 __cxa_atexit(void (*hook)(void*), void* data, void* dsoHandle) 73 { 74 return 0; 75 } 76 77 78 extern "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)) 87 void * 88 operator 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 97 void * 98 operator new[](size_t size) 99 { 100 return malloc(size); 101 } 102 103 104 void * 105 operator new(size_t size, const std::nothrow_t &) _NOEXCEPT 106 { 107 return malloc(size); 108 } 109 110 111 void * 112 operator new[](size_t size, const std::nothrow_t &) _NOEXCEPT 113 { 114 return malloc(size); 115 } 116 117 118 void * 119 operator new(size_t size, const mynothrow_t &) _NOEXCEPT 120 { 121 return malloc(size); 122 } 123 124 125 void * 126 operator new[](size_t size, const mynothrow_t &) _NOEXCEPT 127 { 128 return malloc(size); 129 } 130 131 132 void 133 operator delete(void *ptr) _NOEXCEPT 134 { 135 free(ptr); 136 } 137 138 139 void 140 operator delete[](void *ptr) _NOEXCEPT 141 { 142 free(ptr); 143 } 144 145 146 void 147 operator delete(void *ptr, std::nothrow_t const &) _NOEXCEPT 148 { 149 free(ptr); 150 } 151 152 153 #if __cplusplus >= 201402L 154 155 void 156 operator delete(void* ptr, std::size_t) _NOEXCEPT 157 { 158 free(ptr); 159 } 160 161 162 void 163 operator delete[](void* ptr, std::size_t) _NOEXCEPT 164 { 165 free(ptr); 166 } 167 168 #endif 169 170 171 #ifndef _BOOT_MODE 172 173 FILE *stderr = NULL; 174 175 extern "C" 176 int 177 fprintf(FILE *f, const char *format, ...) 178 { 179 // TODO: Introduce a vdprintf()... 180 dprintf("fprintf(`%s',...)\n", format); 181 return 0; 182 } 183 184 extern "C" 185 size_t 186 fwrite(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 192 extern "C" 193 int 194 fputs(const char *string, FILE *stream) 195 { 196 dprintf("%s", string); 197 return 0; 198 } 199 200 extern "C" 201 int 202 fputc(int c, FILE *stream) 203 { 204 dprintf("%c", c); 205 return 0; 206 } 207 208 #ifndef _LOADER_MODE 209 extern "C" 210 int 211 printf(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 219 extern "C" 220 int 221 puts(const char *string) 222 { 223 return fputs(string, NULL); 224 } 225 226 #endif // #ifndef _BOOT_MODE 227 228 #if __GNUC__ >= 4 229 230 extern "C" 231 void 232 _Unwind_DeleteException() 233 { 234 panic("_Unwind_DeleteException"); 235 } 236 237 extern "C" 238 void 239 _Unwind_Find_FDE() 240 { 241 panic("_Unwind_Find_FDE"); 242 } 243 244 245 extern "C" 246 void 247 _Unwind_GetDataRelBase() 248 { 249 panic("_Unwind_GetDataRelBase"); 250 } 251 252 extern "C" 253 void 254 _Unwind_GetGR() 255 { 256 panic("_Unwind_GetGR"); 257 } 258 259 extern "C" 260 void 261 _Unwind_GetIP() 262 { 263 panic("_Unwind_GetIP"); 264 } 265 266 extern "C" 267 void 268 _Unwind_GetIPInfo() 269 { 270 panic("_Unwind_GetIPInfo"); 271 } 272 273 extern "C" 274 void 275 _Unwind_GetLanguageSpecificData() 276 { 277 panic("_Unwind_GetLanguageSpecificData"); 278 } 279 280 extern "C" 281 void 282 _Unwind_GetRegionStart() 283 { 284 panic("_Unwind_GetRegionStart"); 285 } 286 287 extern "C" 288 void 289 _Unwind_GetTextRelBase() 290 { 291 panic("_Unwind_GetTextRelBase"); 292 } 293 294 extern "C" 295 void 296 _Unwind_RaiseException() 297 { 298 panic("_Unwind_RaiseException"); 299 } 300 301 extern "C" 302 void 303 _Unwind_Resume() 304 { 305 panic("_Unwind_Resume"); 306 } 307 308 extern "C" 309 void 310 _Unwind_Resume_or_Rethrow() 311 { 312 panic("_Unwind_Resume_or_Rethrow"); 313 } 314 315 extern "C" 316 void 317 _Unwind_SetGR() 318 { 319 panic("_Unwind_SetGR"); 320 } 321 322 extern "C" 323 void 324 _Unwind_SetIP() 325 { 326 panic("_Unwind_SetIP"); 327 } 328 329 extern "C" 330 void 331 __deregister_frame_info() 332 { 333 panic("__deregister_frame_info"); 334 } 335 336 extern "C" 337 void 338 __register_frame_info() 339 { 340 panic("__register_frame_info"); 341 } 342 343 /* ARM */ 344 extern "C" void 345 __aeabi_unwind_cpp_pr0(void) 346 { 347 panic("__aeabi_unwind_cpp_pr0"); 348 } 349 350 extern "C" void 351 __aeabi_unwind_cpp_pr1(void) 352 { 353 panic("__aeabi_unwind_cpp_pr1"); 354 } 355 356 extern "C" void 357 __aeabi_unwind_cpp_pr2(void) 358 { 359 panic("__aeabi_unwind_cpp_pr2"); 360 } 361 362 extern "C" void 363 _Unwind_Complete(void) 364 { 365 panic("_Unwind_Complete"); 366 } 367 368 extern "C" void 369 _Unwind_VRS_Set(void) 370 { 371 panic("_Unwind_VRS_Set"); 372 } 373 374 extern "C" void 375 _Unwind_VRS_Get(void) 376 { 377 panic("_Unwind_VRS_Get"); 378 } 379 380 extern "C" void 381 __gnu_unwind_frame(void) 382 { 383 panic("__gnu_unwind_frame"); 384 } 385 386 #endif // __GNUC__ >= 4 387 388 extern "C" 389 void 390 abort() 391 { 392 while (true) 393 panic("abort() called!"); 394 } 395 396 397 #ifndef _BOOT_MODE 398 399 extern "C" 400 void 401 debugger(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 411 extern "C" 412 void 413 exit(int status) 414 { 415 while (true) 416 panic("exit() called with status code = %d!", status); 417 } 418 419