diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake index 9fc10375a1d379..e3dfe1a1529691 100644 --- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake +++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake @@ -71,6 +71,10 @@ function(_get_compile_options_from_config output_var) list(APPEND config_options "-DLIBC_QSORT_IMPL=${LIBC_CONF_QSORT_IMPL}") endif() + if(LIBC_TYPES_TIME_T_IS_32_BIT AND LLVM_LIBC_FULL_BUILD) + list(APPEND config_options "-DLIBC_TYPES_TIME_T_IS_32_BIT") + endif() + set(${output_var} ${config_options} PARENT_SCOPE) endfunction(_get_compile_options_from_config) diff --git a/libc/cmake/modules/LLVMLibCFlagRules.cmake b/libc/cmake/modules/LLVMLibCFlagRules.cmake index 3629a7f111a7c5..69f31ace80dd3d 100644 --- a/libc/cmake/modules/LLVMLibCFlagRules.cmake +++ b/libc/cmake/modules/LLVMLibCFlagRules.cmake @@ -286,3 +286,16 @@ if(NOT((LIBC_TARGET_ARCHITECTURE_IS_X86 AND (LIBC_CPU_FEATURES MATCHES "SSE4_2") LIBC_TARGET_ARCHITECTURE_IS_AARCH64 OR LIBC_TARGET_OS_IS_GPU)) set(SKIP_FLAG_EXPANSION_ROUND_OPT TRUE) endif() + +# Choose whether time_t is 32- or 64-bit, based on target architecture +# and config options. This will be used to set a #define during the +# library build, and also to select the right version of time_t.h for +# the output headers. +if(LIBC_TARGET_ARCHITECTURE_IS_ARM AND NOT (LIBC_CONF_TIME_64BIT)) + # Set time_t to 32 bit for compatibility with glibc, unless + # configuration says otherwise + set(LIBC_TYPES_TIME_T_IS_32_BIT TRUE) +else() + # Other platforms default to 64-bit time_t + set(LIBC_TYPES_TIME_T_IS_32_BIT FALSE) +endif() diff --git a/libc/cmake/modules/LLVMLibCHeaderRules.cmake b/libc/cmake/modules/LLVMLibCHeaderRules.cmake index 3049f4db7301f6..c2c675bda26d31 100644 --- a/libc/cmake/modules/LLVMLibCHeaderRules.cmake +++ b/libc/cmake/modules/LLVMLibCHeaderRules.cmake @@ -9,8 +9,8 @@ function(add_header target_name) cmake_parse_arguments( "ADD_HEADER" - "" # No optional arguments - "HDR" # Single value arguments + "" # No optional arguments + "HDR;DEST_HDR" # Single value arguments "DEPENDS" ${ARGN} ) @@ -18,7 +18,12 @@ function(add_header target_name) message(FATAL_ERROR "'add_header' rules requires the HDR argument specifying a headef file.") endif() - set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR}) + if(ADD_HEADER_DEST_HDR) + set(dest_leaf_filename ${ADD_HEADER_DEST_HDR}) + else() + set(dest_leaf_filename ${ADD_HEADER_HDR}) + endif() + set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${dest_leaf_filename}) file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path}) set(dest_file ${LIBC_INCLUDE_DIR}/${relative_path}) set(src_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR}) diff --git a/libc/config/config.json b/libc/config/config.json index 538fea53cc704a..2e72c0a3fd1d69 100644 --- a/libc/config/config.json +++ b/libc/config/config.json @@ -88,5 +88,11 @@ "value": true, "doc": "Make setjmp save the value of x18, and longjmp restore it. The AArch64 ABI delegates this register to platform ABIs, which can choose whether to make it caller-saved." } + }, + "time": { + "LIBC_CONF_TIME_64BIT": { + "value": false, + "doc": "Force the size of time_t to 64 bits, even on platforms where compatibility considerations would otherwise make it 32-bit." + } } } diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst index 950de0eee4c05d..54ca5d55d7b243 100644 --- a/libc/docs/configure.rst +++ b/libc/docs/configure.rst @@ -52,3 +52,5 @@ to learn about the defaults for your platform and target. * **"string" options** - ``LIBC_CONF_MEMSET_X86_USE_SOFTWARE_PREFETCHING``: Inserts prefetch for write instructions (PREFETCHW) for memset on x86 to recover performance when hardware prefetcher is disabled. - ``LIBC_CONF_STRING_UNSAFE_WIDE_READ``: Read more than a byte at a time to perform byte-string operations like strlen. +* **"time" options** + - ``LIBC_CONF_TIME_64BIT``: Force the size of time_t to 64 bits, even on platforms where compatibility considerations would otherwise make it 32-bit. diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 9e77ab226ce6c2..0fa86e0152f9ba 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -59,7 +59,11 @@ add_header(pthread_rwlockattr_t HDR pthread_rwlockattr_t.h) add_header(pthread_spinlock_t HDR pthread_spinlock_t.h DEPENDS .pid_t) add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type) add_header(rlim_t HDR rlim_t.h) -add_header(time_t HDR time_t.h) +if(LIBC_TYPES_TIME_T_IS_32_BIT) + add_header(time_t HDR time_t_32.h DEST_HDR time_t.h) +else() + add_header(time_t HDR time_t_64.h DEST_HDR time_t.h) +endif() add_header(stack_t HDR stack_t.h DEPENDS .size_t) add_header(suseconds_t HDR suseconds_t.h) add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t) diff --git a/libc/include/llvm-libc-types/time_t.h b/libc/include/llvm-libc-types/time_t.h index 59953b343ba963..76920dc07ec69c 100644 --- a/libc/include/llvm-libc-types/time_t.h +++ b/libc/include/llvm-libc-types/time_t.h @@ -1,4 +1,4 @@ -//===-- Definition of the type time_t -------------------------------------===// +//===-- Definition of the type time_t, for use during the libc build ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,10 +9,10 @@ #ifndef LLVM_LIBC_TYPES_TIME_T_H #define LLVM_LIBC_TYPES_TIME_T_H -#if (defined(__arm__) || defined(_M_ARM)) -typedef __INTPTR_TYPE__ time_t; +#ifdef LIBC_TYPES_TIME_T_IS_32_BIT +#include "time_t_32.h" #else -typedef __INT64_TYPE__ time_t; +#include "time_t_64.h" #endif #endif // LLVM_LIBC_TYPES_TIME_T_H diff --git a/libc/include/llvm-libc-types/time_t_32.h b/libc/include/llvm-libc-types/time_t_32.h new file mode 100644 index 00000000000000..2c415f6fa9dcab --- /dev/null +++ b/libc/include/llvm-libc-types/time_t_32.h @@ -0,0 +1,14 @@ +//===-- Definition of the type time_t -------------------------------------===// +// +// 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_TYPES_TIME_T_32_H +#define LLVM_LIBC_TYPES_TIME_T_32_H + +typedef __INT32_TYPE__ time_t; + +#endif // LLVM_LIBC_TYPES_TIME_T_32_H diff --git a/libc/include/llvm-libc-types/time_t_64.h b/libc/include/llvm-libc-types/time_t_64.h new file mode 100644 index 00000000000000..8f7fd3233646e6 --- /dev/null +++ b/libc/include/llvm-libc-types/time_t_64.h @@ -0,0 +1,14 @@ +//===-- Definition of the type time_t -------------------------------------===// +// +// 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_TYPES_TIME_T_64_H +#define LLVM_LIBC_TYPES_TIME_T_64_H + +typedef __INT64_TYPE__ time_t; + +#endif // LLVM_LIBC_TYPES_TIME_T_64_H