libc: Description: C11 compliant C library. Includes threading TLS support for optimal performance, BSD extensions, and some Plan 9 functions. Large set of runtime entry points allowing linker to produce minimal binaries. Entry points do not call exit() by default unless atexit() is used, otherwise calls _exit(). Similar with standard stream usage. TLS, standard streams, exit() termination behaviour not enforced, depends on what is used and final binary is still C compliant. <grp.h> and <pwd.h>, not contained in C library to allow for different login semantics (headers also not provided). <pthread.h> is provided by separate library, allowing the use of different POSIX threads implementation. <threads.h> provided as static inline C functions to allow for inlining and optimizations. malloc(), calloc(), realloc(), etc provided in separate library to allow the use of different implementations for different uses. libc.a - All entry points and static code. libc.so - No entry points. - Dynamic code, still need to find a way to include all non-TLS, TLS, standard stream, versions of functions. Architecture is selected from the common names: amd64, x86-64, i386, etc. Makefile config.mk macro ARCH = amd64 OS is selected using __OS__ notation defined by POSIX C. Makefile config.mk macro: OS = __linux__ GOALS: - Produce clean binaries (minimal required amount of symbols and sections in final binary). - TLS by default. Also would like to include non-TLS threading as a build option. - Easily portable following the build template. - C11 <stdatomic.h> atomics for minimally lockless threading. - Posix threads <pthread.h> is backed by minimal C11 <threads.h> implementation. - Supports C11 _Thread_local for TLS. NOTE: Ensure libc.a is the last library searched in the linker directory path. - The linker needs to select the right entry point in libc.a depending on what symbols are undefined. If an object file or library along the build path uses thread local storage the linker needs to choose the entry point that initializes the main thread TLS. Entry and exit points all defined in libc.a (static library). Linker picks entry point. Entry and exit points can't be moved to a shared library without added complexity in the build system. All binaries will have copies of the entry code although this is negligible. Streams are lazily initilized with per stream locks. Need to think of a way to build without locks if not using TLS. libc.a: Contains static routines. 12 entry points: _start entry point defined as weak so the user can redefine it if they want to implement their own entry and exit code. Note: Entry code is OS and machine specific. All entry points call into C entry point main(). Entry points also contain the exit routines. Entry points 4 - 11 call exit(), but differ in what variables they initialize and if they clean up standard streams or not. The linker should pick the correct entry point depending on what is referenced in the C main() entry point and executable. entry0.o: - Calls _exit(). entry1.o: - Initializes *argv0 then calls _exit(). entry2.o: - Initializes *argv0 and **environ then calls _exit(). entry3.o: - Initializes **environ then calls _exit(). entry4.o: - Calls exit(). entry5.o: - On exit cleans up standard streams. entry6.o: - Initializes *argv0 and calls exit(). entry7.o: - Initializes *argv0 and on termination cleans up standard streams. entry8.o: - Initializes **environ and on termination calls exit(). entry9.o: - Initializes **environ and on termination cleans up standard streams. entry10.o: - Initializes *argv0 and **environ, on termination calls exit(). entry11.o: - Initializes *argv0 and **environ, on termination cleans up standard streams. libc.so: Contains dynamic versions of routines and no entry or exit code. At link time the executable entry and exit points will be built using libc.a. Don't use trampolines and lazy initialization/clean-up because the trampolines are an unnecessary attack vector. - stdio_u.h (u = unlocked) - Unlocked versions of stream functions. - Potentially unnecessary because of POSIX api (file descriptors). - stdio.h: - Include way for file streams to share buffers and offsets for reading and writing. - Include BSD extensions. - err.h (must be included with C library) - BSD error and warning printing. - Be careful when referencing stderr, use indirection on locks and buffer. - That way FILE stderr is not included in symbol table. - Include argv0 as the program name (directory removed). - Allow caller to initialize via ARGBEGIN? or initialize in crt.s?