From ea2182fedd9da23801d5535ea8180d340a820944 Mon Sep 17 00:00:00 2001 From: Maksim Panchenko Date: Tue, 5 Jul 2022 19:55:26 -0700 Subject: [PATCH] [BOLT] Add runtime functions required by freestanding environment Compiler can generate calls to some functions implicitly, even under constraints of freestanding environment. Make sure these functions are available in our runtime objects. Fixes test failures on some systems after https://reviews.llvm.org/D128960. Reviewed By: yota9 Differential Revision: https://reviews.llvm.org/D129168 --- bolt/runtime/common.h | 58 +++++++++++++++++++++++++++++++---------- bolt/runtime/hugify.cpp | 4 +-- bolt/runtime/instr.cpp | 6 ++--- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/bolt/runtime/common.h b/bolt/runtime/common.h index b1e39e5f3e95..3920b1479e2e 100644 --- a/bolt/runtime/common.h +++ b/bolt/runtime/common.h @@ -76,6 +76,49 @@ typedef int int32_t; "pop %%rbx\n" \ "pop %%rax\n" +// Functions that are required by freestanding environment. Compiler may +// generate calls to these implicitly. +extern "C" { +void *memcpy(void *Dest, const void *Src, size_t Len) { + uint8_t *d = static_cast(Dest); + const uint8_t *s = static_cast(Src); + while (Len--) + *d++ = *s++; + return Dest; +} + +void *memmove(void *Dest, const void *Src, size_t Len) { + uint8_t *d = static_cast(Dest); + const uint8_t *s = static_cast(Src); + if (d < s) { + while (Len--) + *d++ = *s++; + } else { + s += Len - 1; + d += Len - 1; + while (Len--) + *d-- = *s--; + } + + return Dest; +} + +void memset(char *Buf, char C, uint32_t Size) { + for (int I = 0; I < Size; ++I) + *Buf++ = C; +} + +int memcmp(const void *s1, const void *s2, size_t n) { + const uint8_t *c1 = static_cast(s1); + const uint8_t *c2 = static_cast(s2); + for (; n--; c1++, c2++) { + if (*c1 != *c2) + return *c1 < *c2 ? -1 : 1; + } + return 0; +} +} // extern "C" + // Anonymous namespace covering everything but our library entry point namespace { @@ -187,7 +230,7 @@ uint64_t __exit(uint64_t code) { } // Helper functions for writing strings to the .fdata file. We intentionally -// avoid using libc names (lowercase memset) to make it clear it is our impl. +// avoid using libc names to make it clear it is our impl. /// Write number Num using Base to the buffer in OutBuf, returns a pointer to /// the end of the string. @@ -231,19 +274,6 @@ int strnCmp(const char *Str1, const char *Str2, size_t Num) { return *(unsigned char *)Str1 - *(unsigned char *)Str2; } -void memSet(char *Buf, char C, uint32_t Size) { - for (int I = 0; I < Size; ++I) - *Buf++ = C; -} - -void *memCpy(void *Dest, const void *Src, size_t Len) { - char *d = static_cast(Dest); - const char *s = static_cast(Src); - while (Len--) - *d++ = *s++; - return Dest; -} - uint32_t strLen(const char *Str) { uint32_t Size = 0; while (*Str++) diff --git a/bolt/runtime/hugify.cpp b/bolt/runtime/hugify.cpp index 056aa65e0eab..69e1a7e0694a 100644 --- a/bolt/runtime/hugify.cpp +++ b/bolt/runtime/hugify.cpp @@ -59,7 +59,7 @@ static void hugify_for_old_kernel(uint8_t *from, uint8_t *to) { #endif // Copy the hot code to a temproary location. - memCpy(mem, from, size); + memcpy(mem, from, size); // Maps out the existing hot code. if (__mmap(reinterpret_cast(from), size, @@ -77,7 +77,7 @@ static void hugify_for_old_kernel(uint8_t *from, uint8_t *to) { } // Copy the hot code back. - memCpy(from, mem, size); + memcpy(from, mem, size); // Change permission back to read-only, ignore failure __mprotect(from, size, PROT_READ | PROT_EXEC); diff --git a/bolt/runtime/instr.cpp b/bolt/runtime/instr.cpp index d111599e3b7c..8dd84ffcb4e8 100644 --- a/bolt/runtime/instr.cpp +++ b/bolt/runtime/instr.cpp @@ -224,7 +224,7 @@ BumpPtrAllocator GlobalAlloc; void *operator new(size_t Sz, BumpPtrAllocator &A) { return A.allocate(Sz); } void *operator new(size_t Sz, BumpPtrAllocator &A, char C) { auto *Ptr = reinterpret_cast(A.allocate(Sz)); - memSet(Ptr, C, Sz); + memset(Ptr, C, Sz); return Ptr; } void *operator new[](size_t Sz, BumpPtrAllocator &A) { @@ -232,7 +232,7 @@ void *operator new[](size_t Sz, BumpPtrAllocator &A) { } void *operator new[](size_t Sz, BumpPtrAllocator &A, char C) { auto *Ptr = reinterpret_cast(A.allocate(Sz)); - memSet(Ptr, C, Sz); + memset(Ptr, C, Sz); return Ptr; } // Only called during exception unwinding (useless). We must manually dealloc. @@ -1438,7 +1438,7 @@ int openProfile() { /// Where 0xdeadbeef is this function address and PROCESSNAME your binary file /// name. extern "C" void __bolt_instr_clear_counters() { - memSet(reinterpret_cast(__bolt_instr_locations), 0, + memset(reinterpret_cast(__bolt_instr_locations), 0, __bolt_num_counters * 8); for (int I = 0; I < __bolt_instr_num_ind_calls; ++I) GlobalIndCallCounters[I].resetCounters();