Skip to content

Commit

Permalink
[libc] add malloc funcs as external entrypoints
Browse files Browse the repository at this point in the history
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
  • Loading branch information
michaelrj-google committed Oct 27, 2021
1 parent 6c9f207 commit 7dcdbab
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 29 deletions.
21 changes: 12 additions & 9 deletions libc/cmake/modules/LLVMLibCLibraryRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,31 @@ 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)
cmake_parse_arguments(
"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)
Expand All @@ -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})
Expand All @@ -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
Expand Down
30 changes: 30 additions & 0 deletions libc/cmake/modules/LLVMLibCObjectRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
13 changes: 13 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
20 changes: 0 additions & 20 deletions libc/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
5 changes: 5 additions & 0 deletions libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>]>,
]
>;
Expand Down
42 changes: 42 additions & 0 deletions libc/src/stdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 7dcdbab

Please sign in to comment.