[libc-commits] [libc] [libc] Add ucontext types and headers (PR #191789)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Mon Apr 13 06:42:00 PDT 2026


https://github.com/kaladron updated https://github.com/llvm/llvm-project/pull/191789

>From 2cfdc3644786cac8514e858bc90a91f983b1f8ee Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Mon, 13 Apr 2026 10:39:41 +0100
Subject: [PATCH] [libc] Add ucontext types and headers

Added mcontext_t and ucontext_t types for x86_64 Linux, and the ucontext.h header definition. Used a dispatcher pattern for mcontext_t and ucontext_t to support future architecture ports, mirroring the pattern used in FPUtil.

Definitions are based on the Linux kernel ABI for x86_64.
---
 libc/include/CMakeLists.txt                   | 14 ++++
 libc/include/llvm-libc-types/CMakeLists.txt   | 25 +++++++
 libc/include/llvm-libc-types/mcontext_t.h     | 18 +++++
 libc/include/llvm-libc-types/ucontext_t.h     | 18 +++++
 .../llvm-libc-types/x86_64/mcontext_t.h       | 75 +++++++++++++++++++
 .../llvm-libc-types/x86_64/ucontext_t.h       | 26 +++++++
 libc/include/ucontext.h.def                   | 16 ++++
 libc/include/ucontext.yaml                    | 37 +++++++++
 8 files changed, 229 insertions(+)
 create mode 100644 libc/include/llvm-libc-types/mcontext_t.h
 create mode 100644 libc/include/llvm-libc-types/ucontext_t.h
 create mode 100644 libc/include/llvm-libc-types/x86_64/mcontext_t.h
 create mode 100644 libc/include/llvm-libc-types/x86_64/ucontext_t.h
 create mode 100644 libc/include/ucontext.h.def
 create mode 100644 libc/include/ucontext.yaml

diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 41d541f475290..41e3fc200ab71 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -460,6 +460,20 @@ add_header_macro(
     .llvm_libc_common_h
 )
 
+if(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
+  add_header_macro(
+    ucontext
+    ../libc/include/ucontext.yaml
+    ucontext.h
+    DEPENDS
+      .llvm_libc_common_h
+      .llvm-libc-types.mcontext_t
+      .llvm-libc-types.ucontext_t
+      .llvm-libc-types.sigset_t
+      .llvm-libc-types.stack_t
+  )
+endif()
+
 add_header_macro(
   sched
   ../libc/include/sched.yaml
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 0d6bc0982b847..e40f6e194ab3a 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -126,6 +126,31 @@ add_header(union_sigval HDR union_sigval.h)
 add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
 add_header(sig_atomic_t HDR sig_atomic_t.h)
 add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
+set(mcontext_deps)
+set(ucontext_deps .sigset_t .stack_t)
+
+if(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
+  file(COPY x86_64 DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+  add_header(
+    mcontext_t_arch
+    HDR
+      x86_64/mcontext_t.h
+  )
+  add_header(
+    ucontext_t_arch
+    HDR
+      x86_64/ucontext_t.h
+    DEPENDS
+      .mcontext_t_arch
+      .sigset_t
+      .stack_t
+  )
+  list(APPEND mcontext_deps .mcontext_t_arch)
+  list(APPEND ucontext_deps .ucontext_t_arch)
+endif()
+
+add_header(mcontext_t HDR mcontext_t.h DEPENDS ${mcontext_deps})
+add_header(ucontext_t HDR ucontext_t.h DEPENDS .mcontext_t ${ucontext_deps})
 add_header(__jmp_buf HDR __jmp_buf.h DEPENDS .sigset_t)
 add_header(jmp_buf HDR jmp_buf.h DEPENDS .__jmp_buf)
 add_header(sigjmp_buf HDR sigjmp_buf.h DEPENDS .__jmp_buf)
diff --git a/libc/include/llvm-libc-types/mcontext_t.h b/libc/include/llvm-libc-types/mcontext_t.h
new file mode 100644
index 0000000000000..f2226555c2ac8
--- /dev/null
+++ b/libc/include/llvm-libc-types/mcontext_t.h
@@ -0,0 +1,18 @@
+//===-- Definition of type mcontext_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_MCONTEXT_T_H
+#define LLVM_LIBC_TYPES_MCONTEXT_T_H
+
+#if defined(__x86_64__)
+#include "x86_64/mcontext_t.h"
+#else
+#error "mcontext_t not available for your target architecture."
+#endif
+
+#endif // LLVM_LIBC_TYPES_MCONTEXT_T_H
diff --git a/libc/include/llvm-libc-types/ucontext_t.h b/libc/include/llvm-libc-types/ucontext_t.h
new file mode 100644
index 0000000000000..1c5319bf807fa
--- /dev/null
+++ b/libc/include/llvm-libc-types/ucontext_t.h
@@ -0,0 +1,18 @@
+//===-- Definition of type ucontext_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_UCONTEXT_T_H
+#define LLVM_LIBC_TYPES_UCONTEXT_T_H
+
+#if defined(__x86_64__)
+#include "x86_64/ucontext_t.h"
+#else
+#error "ucontext_t not available for your target architecture."
+#endif
+
+#endif // LLVM_LIBC_TYPES_UCONTEXT_T_H
diff --git a/libc/include/llvm-libc-types/x86_64/mcontext_t.h b/libc/include/llvm-libc-types/x86_64/mcontext_t.h
new file mode 100644
index 0000000000000..4bf7023a85feb
--- /dev/null
+++ b/libc/include/llvm-libc-types/x86_64/mcontext_t.h
@@ -0,0 +1,75 @@
+//===-- Definition of type mcontext_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
+//
+//===----------------------------------------------------------------------===//
+
+// Note: Definitions in this file are based on the Linux kernel ABI.
+
+#ifndef LLVM_LIBC_TYPES_MCONTEXT_T_H
+#define LLVM_LIBC_TYPES_MCONTEXT_T_H
+
+typedef long long int greg_t;
+typedef greg_t gregset_t[23];
+
+enum {
+  __LIBC_REG_R8 = 0,
+  __LIBC_REG_R9,
+  __LIBC_REG_R10,
+  __LIBC_REG_R11,
+  __LIBC_REG_R12,
+  __LIBC_REG_R13,
+  __LIBC_REG_R14,
+  __LIBC_REG_R15,
+  __LIBC_REG_RDI,
+  __LIBC_REG_RSI,
+  __LIBC_REG_RBP,
+  __LIBC_REG_RBX,
+  __LIBC_REG_RDX,
+  __LIBC_REG_RAX,
+  __LIBC_REG_RCX,
+  __LIBC_REG_RSP,
+  __LIBC_REG_RIP,
+  __LIBC_REG_EFL,
+  __LIBC_REG_CSGSFS,
+  __LIBC_REG_ERR,
+  __LIBC_REG_TRAPNO,
+  __LIBC_REG_OLDMASK,
+  __LIBC_REG_CR2
+};
+
+struct _libc_fpxreg {
+  unsigned short significand[4];
+  unsigned short exponent;
+  unsigned short padding[3];
+};
+
+struct _libc_xmmreg {
+  unsigned int element[4];
+};
+
+struct _libc_fpstate {
+  unsigned short cwd;
+  unsigned short swd;
+  unsigned short ftw;
+  unsigned short fop;
+  unsigned long long rip;
+  unsigned long long rdp;
+  unsigned int mxcsr;
+  unsigned int mxcr_mask;
+  struct _libc_fpxreg _st[8];
+  struct _libc_xmmreg _xmm[16];
+  unsigned int padding[24];
+};
+
+typedef struct _libc_fpstate *fpregset_t;
+
+typedef struct {
+  gregset_t gregs;
+  fpregset_t fpregs;
+  unsigned long long __reserved1[8];
+} mcontext_t;
+
+#endif // LLVM_LIBC_TYPES_MCONTEXT_T_H
diff --git a/libc/include/llvm-libc-types/x86_64/ucontext_t.h b/libc/include/llvm-libc-types/x86_64/ucontext_t.h
new file mode 100644
index 0000000000000..d98ddf7819bb8
--- /dev/null
+++ b/libc/include/llvm-libc-types/x86_64/ucontext_t.h
@@ -0,0 +1,26 @@
+//===-- Definition of type ucontext_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
+//
+//===----------------------------------------------------------------------===//
+
+// Note: Definitions in this file are based on the Linux kernel ABI.
+
+#ifndef LLVM_LIBC_TYPES_UCONTEXT_T_H
+#define LLVM_LIBC_TYPES_UCONTEXT_T_H
+
+#include "../sigset_t.h"
+#include "../stack_t.h"
+#include "mcontext_t.h"
+
+typedef struct alignas(16) ucontext_t {
+  unsigned long uc_flags;
+  struct ucontext_t *uc_link;
+  stack_t uc_stack;
+  mcontext_t uc_mcontext;
+  sigset_t uc_sigmask;
+} ucontext_t;
+
+#endif // LLVM_LIBC_TYPES_UCONTEXT_T_H
diff --git a/libc/include/ucontext.h.def b/libc/include/ucontext.h.def
new file mode 100644
index 0000000000000..0750d99a4a0c5
--- /dev/null
+++ b/libc/include/ucontext.h.def
@@ -0,0 +1,16 @@
+//===-- POSIX header ucontext.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_UCONTEXT_H
+#define LLVM_LIBC_UCONTEXT_H
+
+#include "__llvm-libc-common.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_UCONTEXT_H
diff --git a/libc/include/ucontext.yaml b/libc/include/ucontext.yaml
new file mode 100644
index 0000000000000..05ae5e9d38602
--- /dev/null
+++ b/libc/include/ucontext.yaml
@@ -0,0 +1,37 @@
+header: ucontext.h
+standards:
+  - posix
+types:
+  - type_name: mcontext_t
+  - type_name: ucontext_t
+  - type_name: sigset_t
+  - type_name: stack_t
+functions:
+  - name: getcontext
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: ucontext_t *
+  - name: setcontext
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: const ucontext_t *
+  - name: makecontext
+    standards:
+      - posix
+    return_type: void
+    arguments:
+      - type: ucontext_t *
+      - type: void(*)(void)
+      - type: int
+      - type: ...
+  - name: swapcontext
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: ucontext_t *__restrict
+      - type: const ucontext_t *__restrict



More information about the libc-commits mailing list