diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -58,6 +58,7 @@ # Usage # add_libc_unittest( # +# [REDIRECTED] # SUITE # SRCS # HDRS @@ -71,7 +72,7 @@ cmake_parse_arguments( "LIBC_UNITTEST" - "" # No optional arguments + "REDIRECTED" # Optional arguments "SUITE" # Single value arguments "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments ${ARGN} @@ -144,6 +145,22 @@ ${fq_deps_list} ) + if(LIBC_UNITTEST_REDIRECTED) + find_library( + libc_redirectors + llvmlibc_redirectors + PATHS ${LIBC_BUILD_DIR}/lib + ) + target_link_libraries( + ${fq_target_name} + PRIVATE + ${libc_redirectors} + ) + add_dependencies( + ${fq_target_name} + llvmlibc_redirectors + ) + endif() target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest libc_test_utils) add_custom_command( diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -31,6 +31,7 @@ libc.src.stdlib.abs libc.src.stdlib.labs libc.src.stdlib.llabs + libc.src.stdlib.malloc # string.h entrypoints libc.src.string.bzero diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -213,6 +213,9 @@ } def StdlibAPI : PublicAPI<"stdlib.h"> { + let TypeDeclarations = [ + SizeT, + ]; } def TimeAPI : PublicAPI<"time.h"> { diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -46,6 +46,7 @@ libc.src.stdlib.abs libc.src.stdlib.labs libc.src.stdlib.llabs + libc.src.stdlib.malloc # string.h entrypoints libc.src.string.bzero diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt --- a/libc/lib/CMakeLists.txt +++ b/libc/lib/CMakeLists.txt @@ -9,3 +9,9 @@ DEPENDS ${TARGET_LIBM_ENTRYPOINTS} ) + +add_redirector_library( + llvmlibc_redirectors + DEPENDS + malloc_redirector +) diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -426,13 +426,16 @@ HeaderSpec StdLib = HeaderSpec< "stdlib.h", [], // Macros - [], // Types + [ // Types + SizeTType, + ], [], // Enumerations [ FunctionSpec<"abort", RetValSpec, [ArgSpec]>, FunctionSpec<"abs", RetValSpec, [ArgSpec]>, FunctionSpec<"labs", RetValSpec, [ArgSpec]>, FunctionSpec<"llabs", RetValSpec, [ArgSpec]>, + FunctionSpec<"malloc", RetValSpec, [ArgSpec]>, FunctionSpec<"_Exit", RetValSpec, [ArgSpec]>, ] >; diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -56,3 +56,18 @@ DEPENDS .abs_utils ) + +add_entrypoint_object( + malloc + REDIRECTED + SRCS + malloc.cpp + HDRS + malloc.h +) + +add_redirector_object( + malloc_redirector + SRC + malloc_redirector.cpp +) diff --git a/libc/src/stdlib/malloc.h b/libc/src/stdlib/malloc.h new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/malloc.h @@ -0,0 +1,20 @@ +//===-- Implementation header for malloc ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDLIB_MALLOC_H +#define LLVM_LIBC_SRC_STDLIB_MALLOC_H + +#include // size_t + +namespace __llvm_libc { + +void *malloc(size_t size); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STDLIB_MALLOC_H diff --git a/libc/src/stdlib/malloc.cpp b/libc/src/stdlib/malloc.cpp new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/malloc.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of malloc ------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// TODO: Add implementation of malloc and remove malloc redirector. + +#include "src/stdlib/malloc.h" +#include "src/__support/common.h" +#include // size_t + +namespace __llvm_libc { + +void *__malloc_redirector(size_t size); + +LLVM_LIBC_FUNCTION(void *, malloc, (size_t size)) { + return __malloc_redirector(size); +} + +} // namespace __llvm_libc diff --git a/libc/src/stdlib/malloc_redirector.cpp b/libc/src/stdlib/malloc_redirector.cpp new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/malloc_redirector.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of malloc redirector -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// TODO: Remove the malloc redirector once LLVM-libc has the implementation +// for malloc. + +#include // malloc +#include // size_t + +namespace __llvm_libc { + +void *__malloc_redirector(size_t size) { return ::malloc(size); } + +} // namespace __llvm_libc diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -54,3 +54,15 @@ DEPENDS libc.src.stdlib.llabs ) + +add_libc_unittest( + malloc_test + REDIRECTED + SUITE + libc_stdlib_unittests + SRCS + malloc_test.cpp + DEPENDS + libc.src.stdlib.malloc + libc.src.stdlib.free +) diff --git a/libc/test/src/stdlib/malloc_test.cpp b/libc/test/src/stdlib/malloc_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/stdlib/malloc_test.cpp @@ -0,0 +1,24 @@ +//===-- Unittests for malloc ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/free.h" +#include "src/stdlib/malloc.h" +#include "utils/UnitTest/Test.h" + +TEST(LlvmLibcMallocTest, MallocInt) { + int *pi = static_cast(__llvm_libc::malloc(sizeof(int))); + *pi = 1; + EXPECT_EQ(*pi, 1); + __llvm_libc::free(pi); +} + +// Making sure the result returned from malloc(0) could be freed. +TEST(LlvmLibcMallocTest, MallocZero) { + void *p = __llvm_libc::malloc(0); + __llvm_libc::free(p); +}