Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,19 @@ function(_get_common_compile_options output_var flags)
list(APPEND compile_options "-idirafter${LIBC_KERNEL_HEADERS}")
endif()
endif()
if(LIBC_TARGET_OS_IS_DARWIN)
execute_process(
COMMAND xcrun --sdk macosx --show-sdk-path
OUTPUT_VARIABLE MACOSX_SDK_PATH
RESULT_VARIABLE MACOSX_SDK_PATH_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(MACOSX_SDK_PATH_RESULT EQUAL 0)
list(APPEND compile_options "-I" "${MACOSX_SDK_PATH}/usr/include")
else()
message(WARNING "Could not find macOS SDK path. `xcrun --sdk macosx --show-sdk-path` failed.")
endif()
endif()
endif()

if(LIBC_COMPILER_HAS_FIXED_POINT)
Expand Down
1 change: 1 addition & 0 deletions libc/config/darwin/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.setjmp.setjmp
libc.src.setjmp.siglongjmp
libc.src.setjmp.sigsetjmp
libc.src.stdlib._Exit
)
endif()

Expand Down
5 changes: 5 additions & 0 deletions libc/include/llvm-libc-macros/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
add_header(
time_macros
HDR
time-macros.h
)
14 changes: 14 additions & 0 deletions libc/include/llvm-libc-macros/darwin/time-macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//===-- Definition of macros from time.h ---------------------------------===//
//
// 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_MACROS_LINUX_TIME_MACROS_H
#define LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H

#include <_time.h>

#endif // LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
2 changes: 2 additions & 0 deletions libc/include/llvm-libc-macros/time-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "linux/time-macros.h"
#elif defined(__ELF__)
#include "baremetal/time-macros.h"
#elif defined(__APPLE__)
#include "darwin/time-macros.h"
#else
#define CLOCKS_PER_SEC 1000000
#endif
Expand Down
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/clockid_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_CLOCKID_T_H
#define LLVM_LIBC_TYPES_CLOCKID_T_H

#if defined(__APPLE__)
// Darwin provides its own defintion for clockid_t . Use that to prevent
// redeclaration errors and correctness.
#include <_time.h>
#else
typedef int clockid_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_CLOCKID_T_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/struct_timespec.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@
#ifndef LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
#define LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H

#if defined(__APPLE__)
// Darwin provides its own definition for struct timespec. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_timespec.h>
#else
#include "time_t.h"

struct timespec {
time_t tv_sec; /* Seconds. */
/* TODO: BIG_ENDIAN may require padding. */
long tv_nsec; /* Nanoseconds. */
};
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/struct_timeval.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
#include "suseconds_t.h"
#include "time_t.h"

#if defined(__APPLE__)
// Darwin provides its own definition for struct timeval. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_timeval.h>
#else
struct timeval {
time_t tv_sec; // Seconds
suseconds_t tv_usec; // Micro seconds
};
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_STRUCT_TIMEVAL_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/suseconds_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
// types...] and suseconds_t are no greater than the width of type long.

// The kernel expects 64 bit suseconds_t at least on x86_64.
#if defined(__APPLE__)
// Darwin provides its own definition for suseconds_t. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_suseconds_t.h>
#else
typedef long suseconds_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_SUSECONDS_T_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/time_t_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_TIME_T_32_H
#define LLVM_LIBC_TYPES_TIME_T_32_H

#if defined(__APPLE__)
// Darwin provides its own definition for time_t. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_time_t.h>
#else
typedef __INT32_TYPE__ time_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_TIME_T_32_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/time_t_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_TIME_T_64_H
#define LLVM_LIBC_TYPES_TIME_T_64_H

#if defined(__APPLE__)
// Darwin provides its own definition for time_t. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_time_t.h>
#else
typedef __INT64_TYPE__ time_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_TIME_T_64_H
7 changes: 6 additions & 1 deletion libc/include/sys/syscall.h.def
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
#ifndef LLVM_LIBC_SYS_SYSCALL_H
#define LLVM_LIBC_SYS_SYSCALL_H

//TODO: Handle non-linux syscalls
#if defined(__APPLE__)

#include <sys/syscall.h>

#elif defined(__linux__)

#include <asm/unistd.h>

Expand Down Expand Up @@ -2361,5 +2365,6 @@
#define SYS_writev __NR_writev
#endif

#endif // __linux__

#endif // LLVM_LIBC_SYS_SYSCALL_H
7 changes: 5 additions & 2 deletions libc/src/__support/OSUtil/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ endif()

add_subdirectory(${LIBC_TARGET_ARCHITECTURE})

add_header_library(
add_object_library(
darwin_util
SRCS
exit.cpp
HDRS
io.h
syscall.h
DEPENDS
.${LIBC_TARGET_ARCHITECTURE}.darwin_util
.${LIBC_TARGET_ARCHITECTURE}.darwin_${LIBC_TARGET_ARCHITECTURE}_util
libc.src.__support.common
libc.src.__support.CPP.string_view
libc.include.sys_syscall
)
2 changes: 1 addition & 1 deletion libc/src/__support/OSUtil/darwin/aarch64/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
add_header_library(
darwin_util
darwin_aarch64_util
HDRS
syscall.h
DEPENDS
Expand Down
24 changes: 24 additions & 0 deletions libc/src/__support/OSUtil/darwin/exit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===------------ MacOS implementation of an exit function ------*- 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
//
//===----------------------------------------------------------------------===//

#include "src/__support/OSUtil/darwin/syscall.h" // syscall_impl
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "sys/syscall.h" // For syscall numbers.

namespace LIBC_NAMESPACE_DECL {
namespace internal {

[[noreturn]] void exit(int status) {
for (;;) {
LIBC_NAMESPACE::syscall_impl<long>(SYS_exit, status);
}
}

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
12 changes: 12 additions & 0 deletions libc/src/__support/time/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_object_library(
clock_gettime
SRCS
clock_gettime.cpp
HDRS
../clock_gettime.h
DEPENDS
libc.src.__support.common
libc.src.__support.error_or
libc.hdr.types.struct_timeval
libc.hdr.types.struct_timespec
)
44 changes: 44 additions & 0 deletions libc/src/__support/time/darwin/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- Darwin implementation of internal clock_gettime -------------------===//
//
// 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/__support/time/clock_gettime.h"
#include "hdr/errno_macros.h" // For EINVAL
#include "hdr/time_macros.h"
#include "hdr/types/struct_timespec.h"
#include "hdr/types/struct_timeval.h"
#include "src/__support/OSUtil/syscall.h" // For syscall_impl
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include <sys/syscall.h> // For SYS_gettimeofday
#include <sys/time.h> // For struct timezone

namespace LIBC_NAMESPACE_DECL {
namespace internal {

ErrorOr<int> clock_gettime(clockid_t clockid, struct timespec *ts) {
if (clockid != CLOCK_REALTIME) {
return Error(EINVAL);
}
struct timeval tv;
// The second argument to gettimeofday is a timezone pointer
// The third argument is mach_absolute_time
// Both of these, we don't need here, so they are 0
long ret = LIBC_NAMESPACE::syscall_impl<long>(
SYS_gettimeofday, reinterpret_cast<long>(&tv), 0, 0);
if (ret != 0) {
// The syscall returns -1 on error and sets errno.
return Error(EINVAL);
}

ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec * 1000;
return 0;
}

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
10 changes: 10 additions & 0 deletions libc/src/time/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_entrypoint_object(
clock_gettime
SRCS
clock_gettime.cpp
HDRS
# The public header is part of the parent directory's library.
DEPENDS
libc.src.__support.time.clock_gettime
libc.src.errno.errno
)
29 changes: 29 additions & 0 deletions libc/src/time/darwin/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===---------- Darwin implementation of the POSIX clock_gettime function
//--===//
//
// 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/time/clock_gettime.h"

#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/time/clock_gettime.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, clock_gettime,
(clockid_t clockid, struct timespec *ts)) {
auto result = internal::clock_gettime(clockid, ts);
if (!result.has_value()) {
libc_errno = result.error();
return -1;
}
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
2 changes: 1 addition & 1 deletion libc/test/UnitTest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ add_unittest_framework_library(
)

set(libc_death_test_srcs LibcDeathTestExecutors.cpp)
if(${LIBC_TARGET_OS} STREQUAL "linux")
if(${LIBC_TARGET_OS} STREQUAL "linux" OR ${LIBC_TARGET_OS} STREQUAL "darwin")
list(APPEND libc_death_test_srcs ExecuteFunctionUnix.cpp)
endif()

Expand Down
4 changes: 1 addition & 3 deletions libc/test/UnitTest/ExecuteFunctionUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ ProcessStatus invoke_in_subprocess(FunctionCaller *func, int timeout_ms) {
}
::close(pipe_fds[1]);

struct pollfd poll_fd {
pipe_fds[0], 0, 0
};
struct pollfd poll_fd{pipe_fds[0], POLLIN, 0};
// No events requested so this call will only return after the timeout or if
// the pipes peer was closed, signaling the process exited.
if (::poll(&poll_fd, 1, timeout_ms) == -1) {
Expand Down
8 changes: 8 additions & 0 deletions libc/test/src/__support/time/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_libc_test(
clock_gettime
SUITE libc-support-time-tests
SRCS clock_gettime.cpp
DEPENDS
libc.src.__support.CPP.expected
libc.src.__support.time.darwin.clock_gettime
)
20 changes: 20 additions & 0 deletions libc/test/src/__support/time/darwin/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- unit tests for darwin's time utilities --------------------------===//
//
// 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/__support/time/clock_gettime.h"
#include "src/__support/CPP/expected.h"
#include "test/UnitTest/Test.h"

template <class T, class E>
using expected = LIBC_NAMESPACE::cpp::expected<T, E>;

TEST(LlvmLibcSupportDarwinClockGetTime, BasicGetTime) {
struct timespec ts;
auto result = LIBC_NAMESPACE::internal::clock_gettime(CLOCK_REALTIME, &ts);
ASSERT_TRUE(result.has_value());
}
13 changes: 13 additions & 0 deletions libc/test/src/stdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,19 @@ if(LLVM_LIBC_FULL_BUILD)
libc-stdlib-tests
SRCS
_Exit_test.cpp
DEPENDS
libc.src.__support.OSUtil.osutil
libc.src.stdlib._Exit
)

add_libc_test(
exit_test
# The EXPECT_EXITS test is only availible for unit tests.
UNIT_TEST_ONLY
SUITE
libc-stdlib-tests
SRCS
exit_test.cpp
DEPENDS
libc.src.stdlib._Exit
libc.src.stdlib.exit
Expand Down
4 changes: 0 additions & 4 deletions libc/test/src/stdlib/_Exit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
//===----------------------------------------------------------------------===//

#include "src/stdlib/_Exit.h"
#include "src/stdlib/exit.h"
#include "test/UnitTest/Test.h"

TEST(LlvmLibcStdlib, _Exit) {
EXPECT_EXITS([] { LIBC_NAMESPACE::_Exit(1); }, 1);
EXPECT_EXITS([] { LIBC_NAMESPACE::_Exit(65); }, 65);

EXPECT_EXITS([] { LIBC_NAMESPACE::exit(1); }, 1);
EXPECT_EXITS([] { LIBC_NAMESPACE::exit(65); }, 65);
}
Loading
Loading