1 /*
2  * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
3  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
4  */
5 
6 #include "bx_p.h"
7 #include <bx/debug.h>
8 #include <bx/file.h>
9 #include <bx/math.h>
10 #include <bx/sort.h>
11 #include <bx/timer.h>
12 
13 #if BX_CRT_NONE
14 
15 #include "crt0.h"
16 
17 #define NOT_IMPLEMENTED() \
18 	{ bx::debugPrintf("crtnone: %s not implemented\n", BX_FUNCTION); abort(); }
19 
memcpy(void * _dst,const void * _src,size_t _numBytes)20 extern "C" void* memcpy(void* _dst, const void* _src, size_t _numBytes)
21 {
22 	bx::memCopy(_dst, _src, _numBytes);
23 	return _dst;
24 }
25 
memmove(void * _dst,const void * _src,size_t _numBytes)26 extern "C" void* memmove(void* _dst, const void* _src, size_t _numBytes)
27 {
28 	bx::memMove(_dst, _src, _numBytes);
29 	return _dst;
30 }
31 
memset(void * _dst,int _ch,size_t _numBytes)32 extern "C" void* memset(void* _dst, int _ch, size_t _numBytes)
33 {
34 	bx::memSet(_dst, uint8_t(_ch), _numBytes);
35 	return _dst;
36 }
37 
38 #if !BX_PLATFORM_NONE
39 
40 typedef int64_t off64_t;
41 typedef int32_t pid_t;
42 
memcmp(const void * _lhs,const void * _rhs,size_t _numBytes)43 extern "C" int32_t memcmp(const void* _lhs, const void* _rhs, size_t _numBytes)
44 {
45 	return bx::memCmp(_lhs, _rhs, _numBytes);
46 }
47 
strlen(const char * _str)48 extern "C" size_t strlen(const char* _str)
49 {
50 	return bx::strLen(_str);
51 }
52 
strnlen(const char * _str,size_t _max)53 extern "C" size_t strnlen(const char* _str, size_t _max)
54 {
55 	return bx::strLen(_str, _max);
56 }
57 
strcpy(char * _dst,const char * _src)58 extern "C" void* strcpy(char* _dst, const char* _src)
59 {
60 	bx::strCopy(_dst, INT32_MAX, _src, INT32_MAX);
61 	return _dst;
62 }
63 
strncpy(char * _dst,const char * _src,size_t _num)64 extern "C" void* strncpy(char* _dst, const char* _src, size_t _num)
65 {
66 	bx::strCopy(_dst, INT32_MAX, _src, _num);
67 	return _dst;
68 }
69 
strcat(char * _dst,const char * _src)70 extern "C" char* strcat(char* _dst, const char* _src)
71 {
72 	bx::strCat(_dst, INT32_MAX, _src, INT32_MAX);
73 	return _dst;
74 }
75 
strchr(const char * _str,int _ch)76 extern "C" const char* strchr(const char* _str, int _ch)
77 {
78 	return bx::strFind(_str, _ch).getPtr();
79 }
80 
strcmp(const char * _lhs,const char * _rhs)81 extern "C" int32_t strcmp(const char* _lhs, const char* _rhs)
82 {
83 	return bx::strCmp(_lhs, _rhs);
84 }
85 
strncmp(const char * _lhs,const char * _rhs,size_t _max)86 extern "C" int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max)
87 {
88 	return bx::strCmp(_lhs, _rhs, _max);
89 }
90 
strcasecmp(const char * _lhs,const char * _rhs)91 extern "C" int32_t strcasecmp(const char* _lhs, const char* _rhs)
92 {
93 	return bx::strCmpI(_lhs, _rhs);
94 }
95 
strstr(const char * _str,const char * _find)96 extern "C" const char* strstr(const char* _str, const char* _find)
97 {
98 	return bx::strFind(_str, _find).getPtr();
99 }
100 
qsort(void * _base,size_t _num,size_t _size,bx::ComparisonFn _fn)101 extern "C" void qsort(void* _base, size_t _num, size_t _size, bx::ComparisonFn _fn)
102 {
103 	BX_CHECK(_num <= UINT32_MAX && _size <= UINT32_MAX, "");
104 	return bx::quickSort(_base, _num, _size, _fn);
105 }
106 
isprint(int _ch)107 extern "C" int isprint(int _ch)
108 {
109 	return bx::isPrint(_ch);
110 }
111 
toupper(int _ch)112 extern "C" int toupper(int _ch)
113 {
114 	return bx::toUpper(_ch);
115 }
116 
mbstowcs(wchar_t * _dst,const char * _src,size_t _max)117 extern "C" size_t mbstowcs(wchar_t* _dst, const char* _src, size_t _max)
118 {
119 	BX_UNUSED(_dst, _src, _max);
120 	return 0;
121 }
122 
strdup(const char * _src)123 extern "C" char* strdup(const char* _src)
124 {
125 	uint32_t size = bx::strLen(_src)+1;
126 	char* dup = (char*)malloc(size);
127 	bx::strCopy(dup, size, _src);
128 	return dup;
129 }
130 
strtol(const char * _str,char ** _end,int _base)131 extern "C" long int strtol(const char* _str, char** _end, int _base)
132 {
133 	BX_UNUSED(_str, _end, _base);
134 	NOT_IMPLEMENTED();
135 	return -1;
136 }
137 
abs(int _value)138 extern "C" int abs(int _value)
139 {
140 	return _value >= 0 ? _value : -_value;
141 }
142 
fabsf(float _x)143 extern "C" float fabsf(float _x)
144 {
145 	return bx::abs(_x);
146 }
147 
fabs(double _x)148 extern "C" double fabs(double _x)
149 {
150 	return bx::abs(_x);
151 }
152 
ldexp(double _x,int _exp)153 extern "C" double ldexp(double _x, int _exp)
154 {
155 	return bx::ldexp(float(_x), _exp);
156 }
157 
expf(float _x)158 extern "C" float expf(float _x)
159 {
160 	return bx::exp(_x);
161 }
162 
logf(float _x)163 extern "C" float logf(float _x)
164 {
165 	return bx::log(_x);
166 }
167 
log10f(float _x)168 extern "C" float log10f(float _x)
169 {
170 	BX_UNUSED(_x);
171 	return 0.0f;
172 }
173 
powf(float _x,float _y)174 extern "C" float powf(float _x, float _y)
175 {
176 	return bx::pow(_x, _y);
177 }
178 
pow(double _x,float _y)179 extern "C" double pow(double _x, float _y)
180 {
181 	return bx::pow(_x, _y);
182 }
183 
sinf(float _x)184 extern "C" float sinf(float _x)
185 {
186 	return bx::sin(_x);
187 }
188 
cosf(float _x)189 extern "C" float cosf(float _x)
190 {
191 	return bx::cos(_x);
192 }
193 
tanf(float _x)194 extern "C" float tanf(float _x)
195 {
196 	return bx::tan(_x);
197 }
198 
atan2f(float _y,float _x)199 extern "C" float atan2f(float _y, float _x)
200 {
201 	return bx::atan2(_y, _x);
202 }
203 
sqrtf(float _x)204 extern "C" float sqrtf(float _x)
205 {
206 	return bx::sqrt(_x);
207 }
208 
sqrt(double _x)209 extern "C" double sqrt(double _x)
210 {
211 	return bx::sqrt(_x);
212 }
213 
ceilf(float _x)214 extern "C" float ceilf(float _x)
215 {
216 	return bx::ceil(_x);
217 }
218 
ceil(double _x)219 extern "C" double ceil(double _x)
220 {
221 	return bx::ceil(_x);
222 }
223 
floorf(float _x)224 extern "C" float floorf(float _x)
225 {
226 	return bx::floor(_x);
227 }
228 
floor(double _x)229 extern "C" double floor(double _x)
230 {
231 	return bx::floor(_x);
232 }
233 
acosf(float _x)234 extern "C" float acosf(float _x)
235 {
236 	return bx::acos(_x);
237 }
238 
fmodf(float _numer,float _denom)239 extern "C" float fmodf(float _numer, float _denom)
240 {
241 	return bx::mod(_numer, _denom);
242 }
243 
atoi(const char * _str)244 extern "C" int atoi(const char* _str)
245 {
246 	int32_t result = 0;
247 	bx::fromString(&result, _str);
248 	return result;
249 }
250 
atof(const char * _str)251 extern "C" double atof(const char* _str)
252 {
253 	double result = 0.0;
254 	bx::fromString(&result, _str);
255 	return result;
256 }
257 
opendir(const char * _dirname)258 extern "C" struct DIR* opendir(const char* _dirname)
259 {
260 	BX_UNUSED(_dirname);
261 //	NOT_IMPLEMENTED();
262 	return NULL;
263 }
264 
readdir(struct DIR * _dirp)265 extern "C" struct dirent* readdir(struct DIR* _dirp)
266 {
267 	BX_UNUSED(_dirp);
268 	NOT_IMPLEMENTED();
269 	return NULL;
270 }
271 
closedir(struct DIR * _dirp)272 extern "C" int closedir(struct DIR* _dirp)
273 {
274 	BX_UNUSED(_dirp);
275 	NOT_IMPLEMENTED();
276 	return 0;
277 }
278 
vsnprintf(char * _out,size_t _max,const char * _format,va_list _argList)279 extern "C" int vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList)
280 {
281 	return bx::vsnprintf(_out, _max, _format, _argList);
282 }
283 
sprintf(char * _out,const char * _format,...)284 extern "C" int sprintf(char* _out, const char* _format, ...)
285 {
286 	va_list argList;
287 	va_start(argList, _format);
288 	int32_t len = bx::vsnprintf(_out, INT32_MAX, _format, argList);
289 	va_end(argList);
290 	return len;
291 }
292 
snprintf(char * _out,size_t _max,const char * _format,...)293 extern "C" int snprintf(char* _out, size_t _max, const char* _format, ...)
294 {
295 	va_list argList;
296 	va_start(argList, _format);
297 	int32_t len = bx::vsnprintf(_out, _max, _format, argList);
298 	va_end(argList);
299 	return len;
300 }
301 
printf(const char * _format,...)302 extern "C" int printf(const char* _format, ...)
303 {
304 	va_list argList;
305 	va_start(argList, _format);
306 	bx::WriterI* writer = bx::getStdOut();
307 	bx::Error err;
308 	int32_t len = bx::write(writer, &err, _format, argList);
309 	va_end(argList);
310 	return len;
311 }
312 
313 struct FILE
314 {
315 };
316 
fprintf(FILE * _stream,const char * _format,...)317 extern "C" int fprintf(FILE* _stream, const char* _format, ...)
318 {
319 	BX_UNUSED(_stream, _format);
320 	return -1;
321 }
322 
vfprintf(FILE * _stream,const char * _format,va_list _argList)323 extern "C" int vfprintf(FILE* _stream, const char* _format, va_list _argList)
324 {
325 	BX_UNUSED(_stream, _format, _argList);
326 	return -1;
327 }
328 
sscanf(const char * _str,const char * _format,...)329 extern "C" int sscanf(const char* _str, const char* _format, ...)
330 {
331 	BX_UNUSED(_str, _format);
332 	return -1;
333 }
334 
fscanf(FILE * _stream,const char * _format,...)335 extern "C" int fscanf(FILE* _stream, const char* _format, ...)
336 {
337 	BX_UNUSED(_stream, _format);
338 	return -1;
339 }
340 
341 FILE * stdout;
342 
fopen(const char * _filename,const char * _mode)343 extern "C" FILE* fopen(const char* _filename, const char* _mode)
344 {
345 	BX_UNUSED(_filename, _mode);
346 	bx::debugPrintf("fopen(\"%s\", \"%s\");\n", _filename, _mode);
347 //	NOT_IMPLEMENTED();
348 	return NULL;
349 }
350 
fclose(FILE * _stream)351 extern "C" int fclose(FILE* _stream)
352 {
353 	BX_UNUSED(_stream);
354 	bx::debugPrintf("fclose(%p);\n", _stream);
355 //	NOT_IMPLEMENTED();
356 	return 0;
357 }
358 
fread(void * _ptr,size_t _size,size_t _count,FILE * _stream)359 extern "C" size_t fread(void* _ptr, size_t _size, size_t _count, FILE* _stream)
360 {
361 	BX_UNUSED(_ptr, _size, _count, _stream);
362 	NOT_IMPLEMENTED();
363 	return -1;
364 }
365 
fwrite(const void * _ptr,size_t _size,size_t _count,FILE * _stream)366 extern "C" size_t fwrite(const void* _ptr, size_t _size, size_t _count, FILE* _stream)
367 {
368 	BX_UNUSED(_ptr, _size, _count, _stream);
369 	NOT_IMPLEMENTED();
370 	return -1;
371 }
372 
fseek(FILE * _stream,long int _offset,int _origin)373 extern "C" int fseek(FILE* _stream, long int _offset, int _origin)
374 {
375 	BX_UNUSED(_stream, _offset, _origin);
376 	NOT_IMPLEMENTED();
377 	return -1;
378 }
379 
fseeko64(FILE * _stream,off64_t _offset,int _whence)380 extern "C" int fseeko64(FILE* _stream, off64_t _offset, int _whence)
381 {
382 	BX_UNUSED(_stream, _offset, _whence);
383 	NOT_IMPLEMENTED();
384 	return -1;
385 }
386 
ftell(FILE * _stream)387 extern "C" long int ftell(FILE* _stream)
388 {
389 	BX_UNUSED(_stream);
390 	NOT_IMPLEMENTED();
391 	return -1;
392 }
393 
ftello64(FILE * _stream)394 extern "C" off64_t ftello64(FILE* _stream)
395 {
396 	BX_UNUSED(_stream);
397 	NOT_IMPLEMENTED();
398 	return -1;
399 }
400 
feof(FILE * _stream)401 extern "C" int feof(FILE* _stream)
402 {
403 	BX_UNUSED(_stream);
404 	NOT_IMPLEMENTED();
405 	return -1;
406 }
407 
ferror(FILE * _stream)408 extern "C" int ferror(FILE* _stream)
409 {
410 	BX_UNUSED(_stream);
411 	NOT_IMPLEMENTED();
412 	return -1;
413 }
414 
popen(const char * _command,const char * _type)415 extern "C" FILE* popen(const char* _command, const char* _type)
416 {
417 	BX_UNUSED(_command, _type);
418 	NOT_IMPLEMENTED();
419 	return NULL;
420 }
421 
pclose(FILE * _stream)422 extern "C" int pclose(FILE* _stream)
423 {
424 	BX_UNUSED(_stream);
425 	NOT_IMPLEMENTED();
426 	return -1;
427 }
428 
execvp(const char * _file,char * const _argv[])429 extern "C" int execvp(const char* _file, char* const _argv[])
430 {
431 	BX_UNUSED(_file, _argv);
432 	NOT_IMPLEMENTED();
433 	return -1;
434 }
435 
436 typedef int32_t clockid_t;
437 
toTimespecNs(timespec & _ts,int64_t _nsecs)438 inline void toTimespecNs(timespec& _ts, int64_t _nsecs)
439 {
440 	_ts.tv_sec  = _nsecs/INT64_C(1000000000);
441 	_ts.tv_nsec = _nsecs%INT64_C(1000000000);
442 }
443 
clock_gettime(clockid_t _clock,struct timespec * _ts)444 extern "C" int clock_gettime(clockid_t _clock, struct timespec* _ts)
445 {
446 	BX_UNUSED(_clock);
447 	int64_t now = crt0::getHPCounter();
448 	toTimespecNs(*_ts, now);
449 	return 0;
450 }
451 
syscall(long _num,...)452 extern "C" long syscall(long _num, ...)
453 {
454 	va_list argList;
455 	va_start(argList, _num);
456 
457 	long result = -1;
458 
459 	switch (_num)
460 	{
461 	case 39:
462 		result = crt0::processGetId();
463 		break;
464 
465 	case 228:
466 		{
467 			clockid_t arg0 = va_arg(argList, clockid_t);
468 			timespec* arg1 = va_arg(argList, timespec*);
469 			result = clock_gettime(arg0, arg1);
470 		}
471 		break;
472 
473 	default:
474 		bx::debugPrintf("? syscall %d\n", _num);
475 		break;
476 	}
477 
478 	va_end(argList);
479 
480 	return result;
481 }
482 
sysconf(int name)483 extern "C" long sysconf(int name)
484 {
485 	BX_UNUSED(name);
486 	NOT_IMPLEMENTED();
487 	return -1;
488 }
489 
fork(void)490 extern "C" pid_t fork(void)
491 {
492 	NOT_IMPLEMENTED();
493 	return -1;
494 }
495 
sched_yield(void)496 extern "C" int sched_yield(void)
497 {
498 	NOT_IMPLEMENTED();
499 	return -1;
500 }
501 
prctl(int _option,unsigned long _arg2,unsigned long _arg3,unsigned long _arg4,unsigned long _arg5)502 extern "C" int prctl(int _option, unsigned long _arg2, unsigned long _arg3, unsigned long _arg4, unsigned long _arg5)
503 {
504 	BX_UNUSED(_option, _arg2, _arg3, _arg4, _arg5);
505 	NOT_IMPLEMENTED();
506 	return -1;
507 }
508 
chdir(const char * _path)509 extern "C" int chdir(const char* _path)
510 {
511 	BX_UNUSED(_path);
512 	bx::debugPrintf("chdir(%s) not implemented!\n", _path);
513 	return -1;
514 }
515 
getcwd(char * _buf,size_t _size)516 extern "C" char* getcwd(char* _buf, size_t _size)
517 {
518 	BX_UNUSED(_buf, _size);
519 	NOT_IMPLEMENTED();
520 	return NULL;
521 }
522 
getenv(const char * _name)523 extern "C" char* getenv(const char* _name)
524 {
525 	return const_cast<char*>(crt0::getEnv(_name) );
526 }
527 
setenv(const char * _name,const char * _value,int _overwrite)528 extern "C" int setenv(const char* _name, const char* _value, int _overwrite)
529 {
530 	BX_UNUSED(_name, _value, _overwrite);
531 	bx::debugPrintf("setenv(%s, %s, %d) not implemented!\n", _name, _value, _overwrite);
532 	return -1;
533 }
534 
unsetenv(const char * _name)535 extern "C" int unsetenv(const char* _name)
536 {
537 	BX_UNUSED(_name);
538 	bx::debugPrintf("unsetenv(%s) not implemented!\n", _name);
539 	return -1;
540 }
541 
542 #if 0
543 struct timeval
544 {
545 	time_t tv_sec;
546 	suseconds_t tv_usec;
547 };
548 
549 struct timespec
550 {
551 	time_t tv_sec;
552 	long tv_nsec;
553 };
554 #endif //
555 
gettimeofday(struct timeval * _tv,struct timezone * _tz)556 extern "C" int gettimeofday(struct timeval* _tv, struct timezone* _tz)
557 {
558 	BX_UNUSED(_tz);
559 
560 	timespec ts;
561 
562 	if (NULL == _tv)
563 	{
564 		return 0;
565 	}
566 
567 	clock_gettime(0 /*CLOCK_REALTIME*/, &ts);
568 	_tv->tv_sec = ts.tv_sec;
569 	_tv->tv_usec = (int)ts.tv_nsec / 1000;
570 	return 0;
571 }
572 
573 typedef int64_t time_t;
574 
time(time_t * _arg)575 extern "C" time_t time(time_t* _arg)
576 {
577 	timespec ts;
578 	clock_gettime(0 /*CLOCK_REALTIME*/, &ts);
579 	time_t result = ts.tv_sec;
580 
581 	if (NULL != _arg)
582 	{
583 		*_arg = result;
584 	}
585 
586 	return result;
587 }
588 
realloc(void * _ptr,size_t _size)589 extern "C" void* realloc(void* _ptr, size_t _size)
590 {
591 	return crt0::realloc(_ptr, _size);
592 }
593 
malloc(size_t _size)594 extern "C" void* malloc(size_t _size)
595 {
596 	return crt0::realloc(NULL, _size);
597 }
598 
free(void * _ptr)599 extern "C" void free(void* _ptr)
600 {
601 	crt0::realloc(_ptr, 0);
602 }
603 
604 #endif // BX_PLATFORM_*
605 
abort(void)606 extern "C" void abort(void)
607 {
608 	bx::debugPrintf("crtnone: abort called!\n");
609 	crt0::exit(bx::kExitFailure);
610 }
611 
__assert_fail(const char * _assertion,const char * _file,uint32_t _line,const char * _function)612 extern "C" void __assert_fail(const char* _assertion, const char* _file, uint32_t _line, const char* _function)
613 {
614 	BX_UNUSED(_assertion, _file, _line, _function);
615 	abort();
616 }
617 
618 void* __dso_handle = (void*)&__dso_handle;
619 
operator delete(void *)620 void operator delete(void*)
621 {
622 }
623 
__cxa_pure_virtual(void)624 extern "C" void __cxa_pure_virtual(void)
625 {
626 }
627 
__cxa_atexit(void (* _dtorFn)(void *),void * _arg,void * _dsoHandle)628 extern "C" int __cxa_atexit(void (*_dtorFn)(void*), void* _arg, void* _dsoHandle)
629 {
630 	BX_UNUSED(_dtorFn, _arg, _dsoHandle);
631 	return 0;
632 }
633 
__gxx_personality_v0(void)634 extern "C" void __gxx_personality_v0(void)
635 {
636 }
637 
_Unwind_Resume(void *)638 extern "C" void _Unwind_Resume(void*)
639 {
640 }
641 
__gcc_personality_v0(int _version,...)642 extern "C" int __gcc_personality_v0(int _version, ...)
643 {
644 	BX_UNUSED(_version);
645 	return 0;
646 }
647 
648 namespace __cxxabiv1
649 {
650 	class __class_type_info
651 	{
652 	public:
653 		virtual ~__class_type_info();
654 
655 		const char* m_name;
656 	};
657 
~__class_type_info()658 	__class_type_info::~__class_type_info()
659 	{
660 	}
661 
662 	class __si_class_type_info : public __class_type_info
663 	{
664 	public:
665 		virtual ~__si_class_type_info();
666 	};
667 
~__si_class_type_info()668 	__si_class_type_info::~__si_class_type_info()
669 	{
670 	}
671 
672 	class __vmi_class_type_info : public __class_type_info
673 	{
674 	public:
675 		virtual ~__vmi_class_type_info();
676 	};
677 
~__vmi_class_type_info()678 	__vmi_class_type_info::~__vmi_class_type_info()
679 	{
680 	}
681 
682 	__extension__ typedef int __guard __attribute__( (mode(__DI__) ) );
683 
__cxa_guard_acquire(__guard * _g)684 	extern "C" int __cxa_guard_acquire(__guard* _g)
685 	{
686 		return !*(char*)(_g);
687 	}
688 
__cxa_guard_release(__guard * _g)689 	extern "C" void __cxa_guard_release(__guard* _g)
690 	{
691 		*(char*)_g = 1;
692 	}
693 
__cxa_guard_abort(__guard * _g)694 	extern "C" void __cxa_guard_abort(__guard* _g)
695 	{
696 		BX_UNUSED(_g);
697 	}
698 
699 } // namespace __cxxabiv1
700 
701 #endif // BX_CRT_NONE
702