/** * printf helper function that converts unsigned integer to string */ static char* libc_printf_uint_to_string (uintmax_t value, /**< integer value */ char *buffer_p, /**< buffer for output string */ size_t buffer_size, /**< buffer size */ const char *alphabet, /**< alphabet used for digits */ uint32_t radix) /**< radix */ { char *str_buffer_end = buffer_p + buffer_size; char *str_p = str_buffer_end; *--str_p = '\0'; LIBC_ASSERT (radix >= 2); if ((radix & (radix - 1)) != 0) { /* * Radix is not power of 2. Only 32-bit numbers are supported in this mode. */ LIBC_ASSERT ((value >> 32) == 0); uint32_t value_lo = (uint32_t) value; while (value_lo != 0) { LIBC_ASSERT (str_p != buffer_p); *--str_p = alphabet[ value_lo % radix ]; value_lo /= radix; } }
/** * Setup new memory limits */ void jrt_set_mem_limits (size_t data_size, /**< limit for data + bss + brk heap */ size_t stack_size) /**< limit for stack */ { struct { unsigned long long rlim_cur; unsigned long long rlim_max; } data_limit = { data_size, data_size }; struct { unsigned long long rlim_cur; unsigned long long rlim_max; } stack_limit = { stack_size, stack_size }; long int ret; #ifdef __TARGET_HOST_x64 ret = syscall_2 (__NR_setrlimit, RLIMIT_DATA, (intptr_t) &data_limit); LIBC_ASSERT (ret == 0); ret = syscall_2 (__NR_setrlimit, RLIMIT_STACK, (intptr_t) &stack_limit); LIBC_ASSERT (ret == 0); #elif defined (__TARGET_HOST_ARMv7) ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_DATA, (intptr_t) &data_limit); LIBC_ASSERT (ret == 0); ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_STACK, (intptr_t) &stack_limit); LIBC_ASSERT (ret == 0); #elif defined (__TARGET_HOST_x86) # error "__TARGET_HOST_x86 case is not implemented" #else /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */ # error "!__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86" #endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */ } /* jrt_set_mem_limits */
/** * fopen * * @return FILE pointer - upon successful completion, * NULL - otherwise */ FILE * fopen (const char *path, /**< file path */ const char *mode) /**< file open mode */ { bool may_read = false; bool may_write = false; bool truncate = false; bool create_if_not_exist = false; bool position_at_end = false; LIBC_ASSERT (path != NULL && mode != NULL); LIBC_ASSERT (mode[1] == '+' || mode[1] == '\0'); switch (mode[0]) { case 'r': { may_read = true; may_write = (mode[1] == '+'); break; } case 'w': { may_write = true; truncate = true; create_if_not_exist = true; may_read = (mode[1] == '+'); break; } case 'a': { may_write = true; position_at_end = true; create_if_not_exist = true; if (mode[1] == '+') { /* Not supported */ LIBC_UNREACHABLE (); } break; } default: { LIBC_UNREACHABLE (); } } int flags = 0; int access = S_IRUSR | S_IWUSR; if (may_read && !may_write) { flags = O_RDONLY; } else if (!may_read && may_write) { flags = O_WRONLY; } else { LIBC_ASSERT (may_read && may_write); flags = O_RDWR; } if (truncate) { flags |= O_TRUNC; } if (create_if_not_exist) { flags |= O_CREAT; } if (position_at_end) { flags |= O_APPEND; } long int ret = syscall_3 (__NR_open, (long int) path, flags, access); return (void *) (uintptr_t) (ret); } /* fopen */