2022-08-15 04:20:27 -05:00
|
|
|
/***************************************************************************
|
|
|
|
*
|
|
|
|
* Copyright 2015-2019 BES.
|
|
|
|
* All rights reserved. All unpublished rights reserved.
|
|
|
|
*
|
|
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
|
|
* permission of BES.
|
|
|
|
*
|
|
|
|
* Use of this work is governed by a license granted by BES.
|
|
|
|
* This work contains confidential and proprietary information of
|
|
|
|
* BES. which is protected by copyright, trade secret,
|
|
|
|
* trademark and other intellectual property rights.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
#if (defined(__GNUC__) && !defined(__ARMCC_VERSION))
|
|
|
|
|
|
|
|
#if !defined(NOSTD) && !defined(MBED)
|
|
|
|
#define LIBC_HOOKS
|
|
|
|
#endif
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
#ifdef LIBC_HOOKS
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
#include "hal_trace.h"
|
2023-02-01 14:52:54 -06:00
|
|
|
#include <errno.h>
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
#ifndef FILEHANDLE
|
|
|
|
typedef int FILEHANDLE;
|
|
|
|
#endif
|
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
#define WEAK __attribute__((weak))
|
|
|
|
#define PACKED __attribute__((packed))
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/syslimits.h>
|
2023-02-01 14:52:54 -06:00
|
|
|
#include <sys/unistd.h>
|
|
|
|
#define PREFIX(x) x
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer,
|
2023-02-01 14:52:54 -06:00
|
|
|
unsigned int length, int mode) {
|
|
|
|
int n = 0; // n is the number of bytes written
|
|
|
|
if (fh < 3) {
|
|
|
|
hal_trace_output(buffer, length);
|
|
|
|
n = length;
|
|
|
|
}
|
|
|
|
return n;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer,
|
2023-02-01 14:52:54 -06:00
|
|
|
unsigned int length, int mode) {
|
|
|
|
int n = 0; // n is the number of bytes read
|
|
|
|
if (fh < 3) {
|
|
|
|
// only read a character at a time from stdin
|
|
|
|
// TODO: Read from trace uart input
|
|
|
|
n = 1;
|
|
|
|
}
|
|
|
|
return n;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
|
|
/* prevents the exception handling name demangling code getting pulled in */
|
|
|
|
namespace __gnu_cxx {
|
2023-02-01 14:52:54 -06:00
|
|
|
void __verbose_terminate_handler() { ASSERT(0, "Exception"); }
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
extern "C" WEAK void __cxa_pure_virtual(void);
|
2023-02-01 14:52:54 -06:00
|
|
|
extern "C" WEAK void __cxa_pure_virtual(void) { _exit(1); }
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Provide implementation of _sbrk (low-level dynamic memory allocation
|
|
|
|
// routine) for GCC_ARM which compares new heap pointer with MSP instead of
|
|
|
|
// SP. This make it compatible with RTX RTOS thread stacks.
|
|
|
|
#if defined(__GNUC__) && defined(__arm__)
|
|
|
|
// Linker defined symbol used by _sbrk to indicate where heap should start.
|
|
|
|
extern "C" int __end__;
|
2023-02-01 14:52:54 -06:00
|
|
|
extern "C" uint32_t __HeapLimit;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
// Turn off the errno macro and use actual global variable instead.
|
|
|
|
#undef errno
|
|
|
|
extern "C" int errno;
|
|
|
|
|
|
|
|
// For ARM7 only
|
2023-02-01 14:52:54 -06:00
|
|
|
register unsigned char *stack_ptr __asm("sp");
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
// Dynamic memory allocation related syscall.
|
2023-02-01 14:52:54 -06:00
|
|
|
extern "C" caddr_t _sbrk(int incr) {
|
|
|
|
static unsigned char *heap = (unsigned char *)&__end__;
|
|
|
|
unsigned char *prev_heap = heap;
|
|
|
|
unsigned char *new_heap = heap + incr;
|
2022-08-15 04:20:27 -05:00
|
|
|
|
|
|
|
#if defined(TARGET_ARM7)
|
2023-02-01 14:52:54 -06:00
|
|
|
if (new_heap >= stack_ptr) {
|
2022-08-15 04:20:27 -05:00
|
|
|
#elif defined(TARGET_CORTEX_A)
|
2023-02-01 14:52:54 -06:00
|
|
|
if (new_heap >=
|
|
|
|
(unsigned char *)&__HeapLimit) { /* __HeapLimit is end of heap section */
|
2022-08-15 04:20:27 -05:00
|
|
|
#else
|
2023-02-01 14:52:54 -06:00
|
|
|
if (new_heap >=
|
|
|
|
(unsigned char *)&__HeapLimit) { /* __HeapLimit is end of heap section */
|
2022-08-15 04:20:27 -05:00
|
|
|
#endif
|
2023-02-01 14:52:54 -06:00
|
|
|
ASSERT(false, "_sbrk:Heap overflowed: start=%p end=%p cur=%p incr=%d",
|
|
|
|
(unsigned char *)&__end__, (unsigned char *)&__HeapLimit, heap,
|
|
|
|
incr);
|
|
|
|
errno = ENOMEM;
|
|
|
|
return (caddr_t)-1;
|
|
|
|
}
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
TRACE(2, "_sbrk: incr %d cur=%p\n", incr, heap);
|
2022-08-15 04:20:27 -05:00
|
|
|
|
2023-02-01 14:52:54 -06:00
|
|
|
heap = new_heap;
|
|
|
|
return (caddr_t)prev_heap;
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__GNUC__) && defined(__arm__)
|
2023-02-01 14:52:54 -06:00
|
|
|
extern "C" void _exit(int return_code) {
|
2022-08-15 04:20:27 -05:00
|
|
|
#else
|
|
|
|
namespace std {
|
2023-02-01 14:52:54 -06:00
|
|
|
extern "C" void exit(int return_code) {
|
2022-08-15 04:20:27 -05:00
|
|
|
#endif
|
2023-02-01 14:52:54 -06:00
|
|
|
if (return_code) {
|
|
|
|
ASSERT(false, "system die: %d", return_code);
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
volatile int i = 0;
|
|
|
|
i++;
|
|
|
|
} while (1);
|
2022-08-15 04:20:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !(defined(__GNUC__) && defined(__arm__)) && !defined(TOOLCHAIN_GCC_CW)
|
2023-02-01 14:52:54 -06:00
|
|
|
} // namespace std
|
2022-08-15 04:20:27 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /*LIBC_HOOKS*/
|
|
|
|
|
|
|
|
#endif // __GNUC__ && !__ARMCC_VERSION
|