This was due to the few base __scanf() functions, used by strto*() and
co. to share their framework with scanf() specifiers, being in the main
scanf() file. Not sure why it ended up pulling the entire file even with
LTO, but now that it's separate there's no issue anymore.
Pulling in the entirety of scanf() is mostly expensive because it
contains specifiers(), including strtod(), which itself computes on
floating point numbers, leading to many libm functions being linked in,
some of them with their internal data tables.
In the end you'd call atoi() and get a 24-kB size increase.
Which is not ✨great✨ :)
A standard libc would normally use the kernel's syscall interface to
connect with the lower level, and this interface would usually imitate
POSIX or a similar style. With the statically-linked unikernel design,
the syscalls would be functions, but the interface wouldn't change much.
However, there are some fundamental differences. For instance, in gint
there aren't separate kernel/userspace memory allocators, there's just a
unified allocator in the kernel. This makes malloc() conceptually a
direct syscall, which pushes the kernel/libc boundary at an unusual
location.
Having a clearly-marked HAL makes it easier to identify where the
boundary is. Code from <time.h> currently has an ad-hoc interface which
should be replaced with clock_gettime(2) in the future.
The HAL offers default implementations but these aren't used by gint
yet, because it's more practical to have undefined references than to
end up with the stubs in an executable. These are provided for future
completeness.
This change does not lift the requirement to recursively link gint with
the libc and the libc with gint.
Also set -Wa,--dsp also on C files because the fxSDK sets it globally
and LTO complains if -Wa/-Xassembler options are not uniform across all
compilation units.
Previously FXSDK_COMPILER_INSTALL would be stored as the install prefix.
However, this prefix is subject to unannounced changes when the compiler
version is upgraded without reconfiguring the fxlibc, which happens in
the GiteaPC workflow.
This commit avoids the use of CMAKE_INSTALL_PREFIX when using gint with
no specified prefix, and instead uses another cached variable which
leaves the prefix to be dynamically resolved based on the uncached
variable FXSDK_COMPILER_INSTALL, like most repositories do (eg. gint).
We need the cached indicator because we frequently reconfigure and
CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT is not persistent.
@update
> CMakeLists.txt
| remove the generation of the shared version of the fxlibc (deprecated, unused)
> include/errno
| add some error macros needed in vhex
> src/string/strerror
| add EINTR support
| add EAGAIN support
| add ENOMEDIUM support
| add EMEDIUMTYPE support
@fix
> include/target/vhex
| add missing headers
@update
> malloc : do not use syscall, involve kmalloc
> realloc : do not use syscall, involve krealloc
> free : do not use syscall, involve kfree
@fix
> _Exit : remove syscall
This version of signal (which does not rely on a notion of userland
processes and is thus excluded from Vhex) follows C99 semantics but does
not generate any signals by default.
Basically, the signal function sets up function pointers and the signal
function calls them. Termination signals call exit() while other signals
call _Exit(), which is a quicker program termination similar to abort().
C99 allows programs to long jump out of signal handlers (!) which is
unbelievably scary because it would bypass stack switching code in Vhex
as well as normal interrupt handler termination in gint.
This is implemented for gint only currently; on Vhex, _Exit() is likely
just going to be a syscall. For CASIOWIN, this is slightly more
difficult, as there is no native exit syscall.