Commit d2349b0

kravantokh <kravantokh@noreply.codeberg.org>
2026-08-30 13:48:14
Make LTO work.
1 parent a56b467
testing/tests/000_entry_exit.c
@@ -1,6 +1,6 @@
 #define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	terminate(0);
 }
testing/tests/002_safemath.c
@@ -3,7 +3,7 @@
 
 #define N 12
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 
 	union {
 		u64 u64;
testing/tests/003_round.c
@@ -3,7 +3,7 @@
 
 #define N 13
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	u64 result = N - 1;
 
 	/* Basic functionality test */
testing/tests/012_mem_basic.c
@@ -3,7 +3,7 @@
 
 #define PAGECOUNT 2
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	Page *mem = 0;
 
 	assert(S_OK(
testing/tests/013_arena_basic.c
@@ -3,7 +3,7 @@
 
 Arena a = {0};
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	assert( S_OK(
 		Arena_create( &a, KiB(5) )
 	));
testing/tests/014_heap.c
@@ -1,7 +1,7 @@
 #define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 
 	Heap h = {0};
 
testing/tests/015_array_basic.c
@@ -1,7 +1,7 @@
 #define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	Heap h = {0};
 
 	assert(S_OK( Heap_create( &h, KiB(8) ) ));
testing/tests/016_strings_and_slices.c
@@ -1,7 +1,7 @@
 #define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	STRING( hackunana, "hackunana" );
 	STRING( hack, "hack" );
 	STRING( hack2, "hack" );
testing/tests/020_file_basic.c
@@ -26,7 +26,7 @@ void reset_state(void) {
 	written_amount = 0;
 }
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 	test_existing_open_missing_create();
 	reset_state();
 	test_existing_truncate_missing_create();
testing/tests/021_fileview.c
@@ -1,7 +1,7 @@
 #define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
-void entry(void) {
+void PRESERVE_WITH_LTO entry(void) {
 
 	FileView fv = {0};
 	STRING( filename, "test.txt" );
testing/test.sh
@@ -32,6 +32,7 @@ build () {
 		o1) flags+=(-O1) ;;
 		o2) flags+=(-O2) ;;
 		o3) flags+=(-O3) ;;
+		lto) flags+=(-O2 -flto) ;;
 		*)   echo "Invalid optimization flag passed to build()." >&2
 		exit 1 ;;
 	esac
@@ -67,10 +68,12 @@ for SRC in ./testing/tests/*.c; do
 	build $SRC gcc dbg o0 & pids+=($!)
 	build $SRC gcc dbg o2 & pids+=($!)
 	build $SRC gcc rel o2 & pids+=($!)
+	build $SRC gcc rel lto & pids+=($!)
 
 	build $SRC clang dbg o0 & pids+=($!)
 	build $SRC clang dbg o2 & pids+=($!)
 	build $SRC clang rel o2 & pids+=($!)
+	build $SRC clang rel lto & pids+=($!)
 
 	# tcc doesn't do optimization, so it just ignores it
 	build $SRC tcc dbg o2 & pids+=($!)
notlibc.c
@@ -9,7 +9,8 @@
 /* Compiler-specific debugging/checking system implementations */
 #if (COMPILER == COMPILER_GCC || COMPILER == COMPILER_CLANG) && defined(NOTLIBC_IMPLEMENT) 
 	/* This is so that GCC can detect stack smashing via canaries and crash the program when it happens. */
-	void __stack_chk_fail(void) {
+
+	void PRESERVE_WITH_LTO __stack_chk_fail(void) {
 		assert(0);
 	}
 #endif
@@ -904,7 +905,7 @@ Status StrAsm_fmtd_s64( StrAsm *sa, s64 value) {
 #if OS == OS_LINUX
 /*============================= Entrypoint ===================================*/
 #if ARCH == ARCH_X86_64
-	u8* _linux_startup_sp = 0;
+	u8* PRESERVE_WITH_LTO _linux_startup_sp = 0;
 
 	__asm__ (
 		".section .text\n"
@@ -980,7 +981,7 @@ Status _linux_get_args_and_env( Heap *h, StrSlcs **args, StrSlcs **env ) {
 #ifndef NOTLIBC_NOMAIN
 	Heap _linux_heap = {0};
 
-	void entry(void) {
+	void PRESERVE_WITH_LTO entry(void) {
 		StrSlcs *args = 0;
 		StrSlcs *env = 0;
 
notlibc.h
@@ -131,6 +131,11 @@
 	-DCOMPILER_NAME=name to override the automatic detection.
 #endif
 
+#if COMPILER == COMPILER_GCC
+	#define PRESERVE_WITH_LTO __attribute__((used))
+#else
+	#define PRESERVE_WITH_LTO
+#endif
 
 /*                          Struct and union macros                           */
 #define STRUCT( name, ...) \
@@ -1578,7 +1583,7 @@ static inline Status File_open_validate_flags( usize flags, Status err_source )
 /*============================= Entrypoint ===================================*/
 
 extern u8* _linux_startup_sp;
-void entry(void);
+extern void entry(void);
 
 #ifndef NOTLIBC_NOMAIN
 	extern Heap _linux_heap;