[libc] add malloc funcs as external entrypoints
authorMichael Jones <michaelrj@google.com>
Tue, 19 Oct 2021 23:06:52 +0000 (16:06 -0700)
committerMichael Jones <michaelrj@google.com>
Wed, 27 Oct 2021 17:21:01 +0000 (10:21 -0700)
malloc, calloc, realloc, and free are all functions that other libc
functions depend on, but are pulled from external sources, instead of
having an internal implementation. This patch adds a way to include
functions like that as entrypoints in the list of external entrypoints,
and includes the malloc functions using this new path.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D112104

libc/cmake/modules/LLVMLibCLibraryRules.cmake
libc/cmake/modules/LLVMLibCObjectRules.cmake
libc/config/linux/x86_64/entrypoints.txt
libc/lib/CMakeLists.txt
libc/spec/stdc.td
libc/src/stdlib/CMakeLists.txt

index a5dc8043651a8f61e63cf16705fcbc3a5c9c77c3..14a2bc5f0406de97b51d9fc0ba5c46f9b88e09ae 100644 (file)
@@ -36,16 +36,23 @@ function(collect_object_file_deps target result)
     set(${result} ${all_deps} PARENT_SCOPE)
     return()
   endif()
+
+  if(${target_type} STREQUAL ${ENTRYPOINT_EXT_TARGET_TYPE})
+    # It is not possible to recursively extract deps of external dependencies.
+    # So, we just accumulate the direct dep and return.
+    get_target_property(deps ${target} "DEPS")
+    set(${result} ${deps} PARENT_SCOPE)
+    return()
+  endif()
 endfunction(collect_object_file_deps)
 
 # A rule to build a library from a collection of entrypoint objects.
 # Usage:
 #     add_entrypoint_library(
 #       DEPENDS <list of add_entrypoint_object targets>
-#       EXT_DEPS <list of external object targets, no type checking is done>
 #     )
 #
-# NOTE: If one wants an entrypoint to be availabe in a library, then they will
+# NOTE: If one wants an entrypoint to be available in a library, then they will
 # have to list the entrypoint target explicitly in the DEPENDS list. Implicit
 # entrypoint dependencies will not be added to the library.
 function(add_entrypoint_library target_name)
@@ -53,7 +60,7 @@ function(add_entrypoint_library target_name)
     "ENTRYPOINT_LIBRARY"
     "" # No optional arguments
     "" # No single value arguments
-    "DEPENDS;EXT_DEPS" # Multi-value arguments
+    "DEPENDS" # Multi-value arguments
     ${ARGN}
   )
   if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
@@ -65,9 +72,9 @@ function(add_entrypoint_library target_name)
   set(all_deps "")
   foreach(dep IN LISTS fq_deps_list)
     get_target_property(dep_type ${dep} "TARGET_TYPE")
-    if(NOT (${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}))
+    if(NOT ((${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}) OR (${dep_type} STREQUAL ${ENTRYPOINT_EXT_TARGET_TYPE})))
       message(FATAL_ERROR "Dependency '${dep}' of 'add_entrypoint_collection' is "
-                          "not an 'add_entrypoint_object' target.")
+                          "not an 'add_entrypoint_object' or 'add_entrypoint_external' target.")
     endif()
     collect_object_file_deps(${dep} recursive_deps)
     list(APPEND all_deps ${recursive_deps})
@@ -78,10 +85,6 @@ function(add_entrypoint_library target_name)
     list(APPEND objects $<TARGET_OBJECTS:${dep}>)
   endforeach(dep)
 
-  foreach(dep IN LISTS ENTRYPOINT_LIBRARY_EXT_DEPS)
-    list(APPEND objects $<TARGET_OBJECTS:${dep}>)
-  endforeach(dep)
-
   add_library(
     ${target_name}
     STATIC
index 55761ee238fbb22ac541f6aa8c249260d8b4ba22..69ec2160f1c0dd38ed149fbb8b53d0a0a4ded53d 100644 (file)
@@ -258,6 +258,36 @@ function(add_entrypoint_object target_name)
 
 endfunction(add_entrypoint_object)
 
+set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT")
+
+# A rule for external entrypoint targets.
+# Usage:
+#     add_entrypoint_external(
+#       <target_name>
+#       DEPENDS <list of dependencies>
+#     )
+function(add_entrypoint_external target_name)
+  cmake_parse_arguments(
+    "ADD_ENTRYPOINT_EXT"
+    "" # No optional arguments
+    "" # No single value arguments
+    "DEPENDS"  # Multi value arguments
+    ${ARGN}
+  )
+  get_fq_target_name(${target_name} fq_target_name)
+  set(entrypoint_name ${target_name})
+
+  add_custom_target(${fq_target_name})
+  set_target_properties(
+    ${fq_target_name}
+    PROPERTIES
+      "ENTRYPOINT_NAME" ${entrypoint_name}
+      "TARGET_TYPE" ${ENTRYPOINT_EXT_TARGET_TYPE}
+      "DEPS" "${ADD_ENTRYPOINT_EXT_DEPENDS}"
+  )
+
+endfunction(add_entrypoint_external)
+
 # Rule build a redirector object file.
 function(add_redirector_object target_name)
   cmake_parse_arguments(
index 9ea7928faef2c0d557496dd435f673a5965851a0..951e76fb831580d1486350264a9fd3c631fa7913 100644 (file)
@@ -228,6 +228,19 @@ if(LLVM_LIBC_FULL_BUILD)
   )
 endif()
 
+if(LLVM_LIBC_INCLUDE_SCUDO)
+  list(APPEND TARGET_LIBC_ENTRYPOINTS
+
+    # stdlib.h external entrypoints
+    libc.src.stdlib.malloc
+    libc.src.stdlib.calloc
+    libc.src.stdlib.realloc
+    libc.src.stdlib.free
+
+
+  )
+endif()
+
 set(TARGET_LLVMLIBC_ENTRYPOINTS
   ${TARGET_LIBC_ENTRYPOINTS}
   ${TARGET_LIBM_ENTRYPOINTS}
index 67fe75ea43472f5f8e896bd1f04d9adad32b8ca3..c5d48e8480f77b6927ba2af283c44c04ea781e05 100644 (file)
@@ -1,27 +1,7 @@
-set(SCUDO_DEPS "")
-
-if(LLVM_LIBC_INCLUDE_SCUDO)
-  include(../../compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake)
-  if(NOT (LIBC_TARGET_ARCHITECTURE IN_LIST ALL_SCUDO_STANDALONE_SUPPORTED_ARCH))
-    message(FATAL_ERROR "Architecture ${LIBC_TARGET_ARCHITECTURE} is not supported by SCUDO. 
-Either disable LLVM_LIBC_INCLUDE_SCUDO or change your target architecture.")
-  endif()
-  list(APPEND SCUDO_DEPS RTScudoStandalone.${LIBC_TARGET_ARCHITECTURE} RTScudoStandaloneCWrappers.${LIBC_TARGET_ARCHITECTURE})
-  if((LIBC_TARGET_ARCHITECTURE IN_LIST ALL_GWP_ASAN_SUPPORTED_ARCH) AND COMPILER_RT_BUILD_GWP_ASAN)
-    list(APPEND SCUDO_DEPS RTGwpAsan.${LIBC_TARGET_ARCHITECTURE} 
-                            RTGwpAsanBacktraceLibc.${LIBC_TARGET_ARCHITECTURE} 
-                            RTGwpAsanSegvHandler.${LIBC_TARGET_ARCHITECTURE})
-  elseif(COMPILER_RT_BUILD_GWP_ASAN)
-    message(WARNING "Architecture ${LIBC_TARGET_ARCHITECTURE} is not supported by GWP-ASan. Skipping.")
-  endif()
-endif()
-
 add_entrypoint_library(
   llvmlibc
   DEPENDS
   ${TARGET_LLVMLIBC_ENTRYPOINTS}
-  EXT_DEPS
-  ${SCUDO_DEPS}
 )
 
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
index 4643154fdd8c09fa9973d6e8079cb67594f6d9b7..f55f269ad3f96af2ebdaebe3214b2a669032409a 100644 (file)
@@ -513,6 +513,11 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
           FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
 
+          FunctionSpec<"malloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>]>,
+          FunctionSpec<"calloc", RetValSpec<VoidPtr>, [ArgSpec<SizeTType>, ArgSpec<SizeTType>]>,
+          FunctionSpec<"realloc", RetValSpec<VoidPtr>, [ArgSpec<VoidPtr>, ArgSpec<SizeTType>]>,
+          FunctionSpec<"free", RetValSpec<VoidType>, [ArgSpec<VoidPtr>]>,
+
           FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
       ]
   >;
index ab49c2ac6be45300f4ee2cb9c3b3bc98f303b1fe..3700d9a2409528ef500bfcabe662952cc146966b 100644 (file)
@@ -181,6 +181,48 @@ add_entrypoint_object(
     libc.include.stdlib
 )
 
+if(LLVM_LIBC_INCLUDE_SCUDO)
+  set(SCUDO_DEPS "")
+
+  include(${LIBC_SOURCE_DIR}/../compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake)
+  if(NOT (LIBC_TARGET_ARCHITECTURE IN_LIST ALL_SCUDO_STANDALONE_SUPPORTED_ARCH))
+    message(FATAL_ERROR "Architecture ${LIBC_TARGET_ARCHITECTURE} is not supported by SCUDO. 
+      Either disable LLVM_LIBC_INCLUDE_SCUDO or change your target architecture.")
+  endif()
+  list(APPEND SCUDO_DEPS RTScudoStandalone.${LIBC_TARGET_ARCHITECTURE} 
+       RTScudoStandaloneCWrappers.${LIBC_TARGET_ARCHITECTURE})
+  if((LIBC_TARGET_ARCHITECTURE IN_LIST ALL_GWP_ASAN_SUPPORTED_ARCH) 
+      AND COMPILER_RT_BUILD_GWP_ASAN)
+    list(APPEND SCUDO_DEPS RTGwpAsan.${LIBC_TARGET_ARCHITECTURE} 
+                            RTGwpAsanBacktraceLibc.${LIBC_TARGET_ARCHITECTURE} 
+                            RTGwpAsanSegvHandler.${LIBC_TARGET_ARCHITECTURE})
+  elseif(COMPILER_RT_BUILD_GWP_ASAN)
+    message(WARNING "Architecture ${LIBC_TARGET_ARCHITECTURE} is not supported by GWP-ASan. Skipping.")
+  endif()
+
+  add_entrypoint_external(
+    malloc
+    DEPENDS
+      ${SCUDO_DEPS}
+  )
+  add_entrypoint_external(
+    calloc
+    DEPENDS
+      ${SCUDO_DEPS}
+  )
+  add_entrypoint_external(
+    realloc
+    DEPENDS
+      ${SCUDO_DEPS}
+  )
+  add_entrypoint_external(
+    free
+    DEPENDS
+      ${SCUDO_DEPS}
+  )
+
+endif()
+
 if(NOT LLVM_LIBC_FULL_BUILD)
   return()
 endif()