[libc-commits] [libc] [libc][freebsd] initialize freebsd support (PR #124459)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Sun Jan 26 04:24:30 PST 2025


https://github.com/SchrodingerZhu created https://github.com/llvm/llvm-project/pull/124459

None

>From d401a773d7a40b8dec0845a5b146c66acad5b019 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Sun, 26 Jan 2025 20:22:58 +0800
Subject: [PATCH] [libc][freebsd] initialize freebsd support

---
 .../cmake/modules/LLVMLibCArchitectures.cmake |   4 +
 libc/config/freebsd/x86_64/entrypoints.txt    | 296 ++++++++++++++++++
 libc/config/freebsd/x86_64/headers.txt        |   9 +
 .../__support/OSUtil/freebsd/CMakeLists.txt   |  16 +
 libc/src/__support/OSUtil/freebsd/exit.cpp    |  31 ++
 libc/src/__support/OSUtil/freebsd/io.h        |  27 ++
 libc/src/__support/OSUtil/freebsd/syscall.h   |  39 +++
 .../OSUtil/freebsd/x86_64/CMakeLists.txt      |   7 +
 .../__support/OSUtil/freebsd/x86_64/syscall.h |  99 ++++++
 libc/src/__support/OSUtil/io.h                |   2 +
 libc/src/__support/OSUtil/syscall.h           |   2 +
 libc/test/UnitTest/FPExceptMatcher.cpp        |   4 +
 12 files changed, 536 insertions(+)
 create mode 100644 libc/config/freebsd/x86_64/entrypoints.txt
 create mode 100644 libc/config/freebsd/x86_64/headers.txt
 create mode 100644 libc/src/__support/OSUtil/freebsd/CMakeLists.txt
 create mode 100644 libc/src/__support/OSUtil/freebsd/exit.cpp
 create mode 100644 libc/src/__support/OSUtil/freebsd/io.h
 create mode 100644 libc/src/__support/OSUtil/freebsd/syscall.h
 create mode 100644 libc/src/__support/OSUtil/freebsd/x86_64/CMakeLists.txt
 create mode 100644 libc/src/__support/OSUtil/freebsd/x86_64/syscall.h

diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index fbb1091ddabab4..f6cd54cbf45b63 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -185,6 +185,10 @@ elseif(LIBC_TARGET_OS STREQUAL "darwin")
   set(LIBC_TARGET_OS_IS_DARWIN TRUE)
 elseif(LIBC_TARGET_OS STREQUAL "windows")
   set(LIBC_TARGET_OS_IS_WINDOWS TRUE)
+elseif(LIBC_TARGET_OS STREQUAL "portbld"
+    OR LIBC_TARGET_OS MATCHES "^freebsd.*")
+  set(LIBC_TARGET_OS_IS_FREEBSD TRUE)
+  set(LIBC_TARGET_OS "freebsd")
 elseif(LIBC_TARGET_OS STREQUAL "gpu")
   set(LIBC_TARGET_OS_IS_GPU TRUE)
 else()
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
new file mode 100644
index 00000000000000..36dc08ce2cbc82
--- /dev/null
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -0,0 +1,296 @@
+set(TARGET_LIBC_ENTRYPOINTS
+    # ctype.h entrypoints
+    libc.src.ctype.isalnum
+    libc.src.ctype.isalpha
+    libc.src.ctype.isascii
+    libc.src.ctype.isblank
+    libc.src.ctype.iscntrl
+    libc.src.ctype.isdigit
+    libc.src.ctype.isgraph
+    libc.src.ctype.islower
+    libc.src.ctype.isprint
+    libc.src.ctype.ispunct
+    libc.src.ctype.isspace
+    libc.src.ctype.isupper
+    libc.src.ctype.isxdigit
+    libc.src.ctype.toascii
+    libc.src.ctype.tolower
+    libc.src.ctype.toupper
+
+    # string.h entrypoints
+    libc.src.string.memccpy
+    libc.src.string.memchr
+    libc.src.string.memcmp
+    libc.src.string.memcpy
+    libc.src.string.memmem
+    libc.src.string.memmove
+    libc.src.string.mempcpy
+    libc.src.string.memrchr
+    libc.src.string.memset
+    libc.src.string.stpcpy
+    libc.src.string.stpncpy
+    libc.src.string.strcasestr
+    libc.src.string.strcat
+    libc.src.string.strchr
+    libc.src.string.strchrnul
+    libc.src.string.strcmp
+    libc.src.string.strcpy
+    libc.src.string.strcspn
+    libc.src.string.strlcat
+    libc.src.string.strlcpy
+    libc.src.string.strlen
+    libc.src.string.strncat
+    libc.src.string.strncmp
+    libc.src.string.strncpy
+    libc.src.string.strnlen
+    libc.src.string.strpbrk
+    libc.src.string.strrchr
+    libc.src.string.strspn
+    libc.src.string.strstr
+    libc.src.string.strtok
+    libc.src.string.strtok_r
+
+    # string.h entrypoints that depend on malloc
+    libc.src.string.strdup
+    libc.src.string.strndup
+
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
+    # inttypes.h entrypoints
+    libc.src.inttypes.imaxabs
+    libc.src.inttypes.imaxdiv
+    libc.src.inttypes.strtoimax
+    libc.src.inttypes.strtoumax
+
+    # stdlib.h entrypoints
+    libc.src.stdlib.abs
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atof
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.bsearch
+    libc.src.stdlib.div
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
+    libc.src.stdlib.qsort
+    libc.src.stdlib.strtod
+    libc.src.stdlib.strtof
+    libc.src.stdlib.strtol
+    libc.src.stdlib.strtold
+    libc.src.stdlib.strtoll
+    libc.src.stdlib.strtoul
+    libc.src.stdlib.strtoull
+
+    # stdlib.h external entrypoints
+    libc.src.stdlib.malloc
+    libc.src.stdlib.calloc
+    libc.src.stdlib.realloc
+    libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.free
+
+    # errno.h entrypoints
+    libc.src.errno.errno
+)
+
+set(TARGET_LIBM_ENTRYPOINTS
+    # fenv.h entrypoints
+    libc.src.fenv.feclearexcept
+    libc.src.fenv.fedisableexcept
+    libc.src.fenv.feenableexcept
+    libc.src.fenv.fegetenv
+    libc.src.fenv.fegetexcept
+    libc.src.fenv.fegetexceptflag
+    libc.src.fenv.fegetround
+    libc.src.fenv.feholdexcept
+    libc.src.fenv.fesetenv
+    libc.src.fenv.fesetexcept
+    libc.src.fenv.fesetexceptflag
+    libc.src.fenv.fesetround
+    libc.src.fenv.feraiseexcept
+    libc.src.fenv.fetestexcept
+    libc.src.fenv.fetestexceptflag
+    libc.src.fenv.feupdateenv
+
+    # math.h entrypoints
+    libc.src.math.acosf
+    libc.src.math.acoshf
+    libc.src.math.asinf
+    libc.src.math.asinhf
+    libc.src.math.atan2
+    libc.src.math.atan2f
+    libc.src.math.atanf
+    libc.src.math.atanhf
+    libc.src.math.cbrt
+    libc.src.math.cbrtf
+    libc.src.math.copysign
+    libc.src.math.copysignf
+    libc.src.math.copysignl
+    libc.src.math.ceil
+    libc.src.math.ceilf
+    libc.src.math.ceill
+    libc.src.math.cos
+    libc.src.math.cosf
+    libc.src.math.coshf
+    libc.src.math.daddl
+    libc.src.math.ddivl
+    libc.src.math.dfmal
+    libc.src.math.dsubl
+    libc.src.math.erff
+    libc.src.math.exp
+    libc.src.math.expf
+    libc.src.math.exp10
+    libc.src.math.exp10f
+    libc.src.math.exp2
+    libc.src.math.exp2f
+    libc.src.math.expm1
+    libc.src.math.expm1f
+    libc.src.math.fabs
+    libc.src.math.fabsf
+    libc.src.math.fabsl
+    libc.src.math.fadd
+    libc.src.math.faddl
+    libc.src.math.fdim
+    libc.src.math.fdimf
+    libc.src.math.fdiml
+    libc.src.math.fdiv
+    libc.src.math.fdivl
+    libc.src.math.ffma
+    libc.src.math.ffmal
+    libc.src.math.floor
+    libc.src.math.floorf
+    libc.src.math.floorl
+    libc.src.math.fma
+    libc.src.math.fmaf
+    libc.src.math.fmin
+    libc.src.math.fminf
+    libc.src.math.fminl
+    libc.src.math.fmax
+    libc.src.math.fmaxf
+    libc.src.math.fmaxl
+    libc.src.math.fmaximum
+    libc.src.math.fmaximumf
+    libc.src.math.fmaximuml
+    libc.src.math.fmaximum_num
+    libc.src.math.fmaximum_numf
+    libc.src.math.fmaximum_numl
+    libc.src.math.fmaximum_mag
+    libc.src.math.fmaximum_magf
+    libc.src.math.fmaximum_magl
+    libc.src.math.fmaximum_mag_num
+    libc.src.math.fmaximum_mag_numf
+    libc.src.math.fmaximum_mag_numl
+    libc.src.math.fminimum
+    libc.src.math.fminimumf
+    libc.src.math.fminimuml
+    libc.src.math.fminimum_num
+    libc.src.math.fminimum_numf
+    libc.src.math.fminimum_numl
+    libc.src.math.fminimum_mag
+    libc.src.math.fminimum_magf
+    libc.src.math.fminimum_magl
+    libc.src.math.fminimum_mag_num
+    libc.src.math.fminimum_mag_numf
+    libc.src.math.fminimum_mag_numl
+    libc.src.math.fmul
+    libc.src.math.fmod
+    libc.src.math.fmodf
+    libc.src.math.fmodl
+    libc.src.math.frexp
+    libc.src.math.frexpf
+    libc.src.math.frexpl
+    libc.src.math.fsub
+    libc.src.math.fsubl
+    libc.src.math.hypot
+    libc.src.math.hypotf
+    libc.src.math.ilogb
+    libc.src.math.ilogbf
+    libc.src.math.ilogbl
+    libc.src.math.ldexp
+    libc.src.math.ldexpf
+    libc.src.math.ldexpl
+    libc.src.math.llrint
+    libc.src.math.llrintf
+    libc.src.math.llrintl
+    libc.src.math.llround
+    libc.src.math.llroundf
+    libc.src.math.llroundl
+    libc.src.math.log10
+    libc.src.math.log10f
+    libc.src.math.log1p
+    libc.src.math.log1pf
+    libc.src.math.log2
+    libc.src.math.log2f
+    libc.src.math.log
+    libc.src.math.logf
+    libc.src.math.logb
+    libc.src.math.logbf
+    libc.src.math.logbl
+    libc.src.math.lrint
+    libc.src.math.lrintf
+    libc.src.math.lrintl
+    libc.src.math.lround
+    libc.src.math.lroundf
+    libc.src.math.lroundl
+    libc.src.math.modf
+    libc.src.math.modff
+    libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
+    libc.src.math.nearbyint
+    libc.src.math.nearbyintf
+    libc.src.math.nearbyintl
+    libc.src.math.nextafter
+    libc.src.math.nextafterf
+    libc.src.math.nextafterl
+    libc.src.math.nexttoward
+    libc.src.math.nexttowardf
+    libc.src.math.nexttowardl
+    libc.src.math.pow
+    libc.src.math.powf
+    libc.src.math.remainderf
+    libc.src.math.remainder
+    libc.src.math.remainderl
+    libc.src.math.remquof
+    libc.src.math.remquo
+    libc.src.math.remquol
+    libc.src.math.rint
+    libc.src.math.rintf
+    libc.src.math.rintl
+    libc.src.math.round
+    libc.src.math.roundf
+    libc.src.math.roundl
+    libc.src.math.scalbln
+    libc.src.math.scalblnf
+    libc.src.math.scalblnl
+    libc.src.math.scalbn
+    libc.src.math.scalbnf
+    libc.src.math.scalbnl
+    libc.src.math.sin
+    libc.src.math.sincosf
+    libc.src.math.sincosf
+    libc.src.math.sinf
+    libc.src.math.sinhf
+    libc.src.math.sqrt
+    libc.src.math.sqrtf
+    libc.src.math.sqrtl
+    libc.src.math.tan
+    libc.src.math.tanf
+    libc.src.math.tanhf
+    libc.src.math.trunc
+    libc.src.math.truncf
+    libc.src.math.truncl
+)
+
+set(TARGET_LLVMLIBC_ENTRYPOINTS
+  ${TARGET_LIBC_ENTRYPOINTS}
+  ${TARGET_LIBM_ENTRYPOINTS}
+)
+
diff --git a/libc/config/freebsd/x86_64/headers.txt b/libc/config/freebsd/x86_64/headers.txt
new file mode 100644
index 00000000000000..bccc04f7697e56
--- /dev/null
+++ b/libc/config/freebsd/x86_64/headers.txt
@@ -0,0 +1,9 @@
+set(TARGET_PUBLIC_HEADERS
+    libc.include.ctype
+    libc.include.string
+    libc.include.inttypes
+    libc.include.stdlib
+    libc.include.errno
+    libc.include.fenv
+    libc.include.math
+)
diff --git a/libc/src/__support/OSUtil/freebsd/CMakeLists.txt b/libc/src/__support/OSUtil/freebsd/CMakeLists.txt
new file mode 100644
index 00000000000000..a55b6b588eec98
--- /dev/null
+++ b/libc/src/__support/OSUtil/freebsd/CMakeLists.txt
@@ -0,0 +1,16 @@
+if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+  return()
+endif()
+
+add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
+
+add_object_library(
+  freebsd_util
+  SRCS
+    exit.cpp
+  HDRS
+    io.h
+  DEPENDS
+    .${LIBC_TARGET_ARCHITECTURE}.freebsd_${LIBC_TARGET_ARCHITECTURE}_util
+    libc.src.__support.macros.config
+)
diff --git a/libc/src/__support/OSUtil/freebsd/exit.cpp b/libc/src/__support/OSUtil/freebsd/exit.cpp
new file mode 100644
index 00000000000000..fd2ec67c3cf5b1
--- /dev/null
+++ b/libc/src/__support/OSUtil/freebsd/exit.cpp
@@ -0,0 +1,31 @@
+//===--------- Freebsd 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/freebsd/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 {
+
+// mark as no_stack_protector for x86 since TLS can be torn down before calling
+// exit so that the stack protector canary cannot be loaded.
+#ifdef LIBC_TARGET_ARCH_IS_X86
+__attribute__((no_stack_protector))
+#endif
+__attribute__((noreturn)) void
+exit(int status) {
+  for (;;) {
+    LIBC_NAMESPACE::syscall_impl<long>(SYS_exit, status);
+  }
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/freebsd/io.h b/libc/src/__support/OSUtil/freebsd/io.h
new file mode 100644
index 00000000000000..32e9d90149a6c2
--- /dev/null
+++ b/libc/src/__support/OSUtil/freebsd/io.h
@@ -0,0 +1,27 @@
+//===-------------- FreeBSD implementation of IO utils ----------*- 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___SUPPORT_OSUTIL_FREEBSD_IO_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_FREEBSD_IO_H
+
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/macros/config.h"
+#include "syscall.h" // For internal syscall function.
+
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE void write_to_stderr(cpp::string_view msg) {
+  LIBC_NAMESPACE::syscall_impl<long>(SYS_write, 2 /* stderr */, msg.data(),
+                                     msg.size());
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_FREEBSD_IO_H
diff --git a/libc/src/__support/OSUtil/freebsd/syscall.h b/libc/src/__support/OSUtil/freebsd/syscall.h
new file mode 100644
index 00000000000000..daaa437131c458
--- /dev/null
+++ b/libc/src/__support/OSUtil/freebsd/syscall.h
@@ -0,0 +1,39 @@
+//===----------------------- FreeBSD syscalls -------------------*- 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___SUPPORT_OSUTIL_FREEBSD_SYSCALL_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_FREEBSD_SYSCALL_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/architectures.h"
+
+#ifdef LIBC_TARGET_ARCH_IS_X86_32
+#include "i386/syscall.h"
+#elif defined(LIBC_TARGET_ARCH_IS_X86_64)
+#include "x86_64/syscall.h"
+#elif defined(LIBC_TARGET_ARCH_IS_AARCH64)
+#include "aarch64/syscall.h"
+#elif defined(LIBC_TARGET_ARCH_IS_ARM)
+#include "arm/syscall.h"
+#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
+#include "riscv/syscall.h"
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+
+template <typename R, typename... Ts>
+LIBC_INLINE R syscall_impl(long __number, Ts... ts) {
+  static_assert(sizeof...(Ts) <= 6, "Too many arguments for syscall");
+  return cpp::bit_or_static_cast<R>(syscall_impl(__number, (long)ts...));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_FREEBSD_SYSCALL_H
diff --git a/libc/src/__support/OSUtil/freebsd/x86_64/CMakeLists.txt b/libc/src/__support/OSUtil/freebsd/x86_64/CMakeLists.txt
new file mode 100644
index 00000000000000..9a853b74e72d17
--- /dev/null
+++ b/libc/src/__support/OSUtil/freebsd/x86_64/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_header_library(
+  freebsd_x86_64_util
+  HDRS
+    syscall.h
+  DEPENDS
+    libc.src.__support.common
+)
diff --git a/libc/src/__support/OSUtil/freebsd/x86_64/syscall.h b/libc/src/__support/OSUtil/freebsd/x86_64/syscall.h
new file mode 100644
index 00000000000000..437ff7c0ec0ac7
--- /dev/null
+++ b/libc/src/__support/OSUtil/freebsd/x86_64/syscall.h
@@ -0,0 +1,99 @@
+//===---------- inline implementation of x86_64 syscalls ----------* 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___SUPPORT_OSUTIL_FREEBSD_X86_64_SYSCALL_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_FREEBSD_X86_64_SYSCALL_H
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+#define SYSCALL_CLOBBER_LIST "rcx", "r11", "memory"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE long syscall_impl(long __number) {
+  long retcode;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+LIBC_INLINE long syscall_impl(long __number, long __arg1) {
+  long retcode;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number), "D"(__arg1)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+LIBC_INLINE long syscall_impl(long __number, long __arg1, long __arg2) {
+  long retcode;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number), "D"(__arg1), "S"(__arg2)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+LIBC_INLINE long syscall_impl(long __number, long __arg1, long __arg2,
+                              long __arg3) {
+  long retcode;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+LIBC_INLINE long syscall_impl(long __number, long __arg1, long __arg2,
+                              long __arg3, long __arg4) {
+  long retcode;
+  register long r10 __asm__("r10") = __arg4;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3),
+                    "r"(r10)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+LIBC_INLINE long syscall_impl(long __number, long __arg1, long __arg2,
+                              long __arg3, long __arg4, long __arg5) {
+  long retcode;
+  register long r10 __asm__("r10") = __arg4;
+  register long r8 __asm__("r8") = __arg5;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3),
+                    "r"(r10), "r"(r8)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+LIBC_INLINE long syscall_impl(long __number, long __arg1, long __arg2,
+                              long __arg3, long __arg4, long __arg5,
+                              long __arg6) {
+  long retcode;
+  register long r10 __asm__("r10") = __arg4;
+  register long r8 __asm__("r8") = __arg5;
+  register long r9 __asm__("r9") = __arg6;
+  LIBC_INLINE_ASM("syscall"
+                  : "=a"(retcode)
+                  : "a"(__number), "D"(__arg1), "S"(__arg2), "d"(__arg3),
+                    "r"(r10), "r"(r8), "r"(r9)
+                  : SYSCALL_CLOBBER_LIST);
+  return retcode;
+}
+
+#undef SYSCALL_CLOBBER_LIST
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_FREEBSD_X86_64_SYSCALL_H
diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h
index 80119da77fc027..7f6e66d2b70c93 100644
--- a/libc/src/__support/OSUtil/io.h
+++ b/libc/src/__support/OSUtil/io.h
@@ -21,6 +21,8 @@
 #include "fuchsia/io.h"
 #elif defined(_WIN32)
 #include "windows/io.h"
+#elif defined(__FreeBSD__)
+#include "freebsd/io.h"
 #elif defined(__ELF__)
 // TODO: Ideally we would have LIBC_TARGET_OS_IS_BAREMETAL.
 #include "baremetal/io.h"
diff --git a/libc/src/__support/OSUtil/syscall.h b/libc/src/__support/OSUtil/syscall.h
index fc697a7c098214..08f5e14a7122cb 100644
--- a/libc/src/__support/OSUtil/syscall.h
+++ b/libc/src/__support/OSUtil/syscall.h
@@ -13,6 +13,8 @@
 #include "darwin/syscall.h"
 #elif defined(__linux__)
 #include "linux/syscall.h"
+#elif defined(__FreeBSD__)
+#include "freebsd/syscall.h"
 #endif
 
 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_H
diff --git a/libc/test/UnitTest/FPExceptMatcher.cpp b/libc/test/UnitTest/FPExceptMatcher.cpp
index 119a06985b8f1c..e29049d1e5bdfd 100644
--- a/libc/test/UnitTest/FPExceptMatcher.cpp
+++ b/libc/test/UnitTest/FPExceptMatcher.cpp
@@ -28,6 +28,10 @@ namespace testing {
 #define siglongjmp(buf, val) longjmp(buf, val)
 #endif
 
+#ifdef __FreeBSD__
+using sighandler_t = __sighandler_t *;
+#endif
+
 static thread_local sigjmp_buf jumpBuffer;
 static thread_local bool caughtExcept;
 



More information about the libc-commits mailing list