Some compilers apparently optimize code in fastlz/ to call memset(), so
the uncompressing boot loader, fastlz/lzloader.cc, needs to implement
this function. The current implementation called the "builtin" memset,
which, if you look at the compilation result, actually calls memset()
and results in endless recursion and a hanging boot... This started
happening on Fedora 32 with Gcc 10, for example.
So let's implement memset() using the base_memset() we already have in
libc/string/memset.c.
Fixes #1084.
fastlz/lzloader.cc | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/fastlz/lzloader.cc b/fastlz/lzloader.cc
index f65fb2be..7eae2191 100644
--- a/fastlz/lzloader.cc
+++ b/fastlz/lzloader.cc
@@ -21,11 +21,16 @@ extern char _binary_loader_stripped_elf_lz_start;
extern char _binary_loader_stripped_elf_lz_end;
extern char _binary_loader_stripped_elf_lz_size;
-// std libraries used by fastlz.
-extern "C" void *memset(void *s, int c, size_t n)
-{
- return __builtin_memset(s, c, n);
-}
+// The code in fastlz.cc does not call memset(), but some version of gcc
+// implement some assignments by calling memset(), so we need to implement
+// a memset() function. This is not performance-critical so let's stick to
+// the basic implementation we have in libc/string/memset.c. To avoid
+// compiling this source file a second time (the loader needs different
+// compile parameters), we #include it here instead.
+extern "C" void *memset(void *s, int c, size_t n);
+#define memset_base memset
+#include "libc/string/memset.c"
+#undef memset_base
extern "C" void uncompress_loader()
{
--
2.26.2