[libc] [llvm] [libc] init uefi os target (PR #120687)

Tristan Ross via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 24 08:54:34 PST 2024


https://github.com/RossComputerGuy updated https://github.com/llvm/llvm-project/pull/120687

>From f35c1feac50f73906ea60cd0b067b5346c3a856c Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Thu, 19 Dec 2024 22:46:44 -0800
Subject: [PATCH 01/14] [libc] init uefi os target

---
 .../cmake/modules/LLVMLibCArchitectures.cmake |   6 +
 libc/config/uefi/config.json                  |  29 ++
 libc/config/uefi/entrypoints.txt              | 450 ++++++++++++++++++
 libc/config/uefi/headers.txt                  |  20 +
 libc/hdrgen/yaml/Uefi.yaml                    |  11 +
 libc/include/CMakeLists.txt                   |  15 +
 libc/include/Uefi.h.def                       |  16 +
 libc/include/llvm-libc-macros/CMakeLists.txt  |   6 +
 libc/include/llvm-libc-macros/EFIAPI-macros.h |  10 +
 libc/include/llvm-libc-types/CMakeLists.txt   | 121 +++++
 .../llvm-libc-types/EFI_ALLOCATE_TYPE.h       |  19 +
 .../llvm-libc-types/EFI_BOOT_SERVICES.h       | 249 ++++++++++
 libc/include/llvm-libc-types/EFI_CAPSULE.h    |  26 +
 .../llvm-libc-types/EFI_CONFIGURATION_TABLE.h |  19 +
 .../EFI_DEVICE_PATH_PROTOCOL.h                |  27 ++
 libc/include/llvm-libc-types/EFI_EVENT.h      |  21 +
 libc/include/llvm-libc-types/EFI_GUID.h       |  21 +
 libc/include/llvm-libc-types/EFI_HANDLE.h     |  14 +
 .../llvm-libc-types/EFI_INTERFACE_TYPE.h      |  16 +
 .../llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h  |  18 +
 .../llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h   |  43 ++
 .../include/llvm-libc-types/EFI_MEMORY_TYPE.h |  32 ++
 .../EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h     |  22 +
 .../llvm-libc-types/EFI_PHYSICAL_ADDRESS.h    |  16 +
 .../llvm-libc-types/EFI_RUNTIME_SERVICES.h    | 134 ++++++
 .../EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h          |  41 ++
 .../EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h         |  68 +++
 libc/include/llvm-libc-types/EFI_STATUS.h     |  16 +
 .../llvm-libc-types/EFI_SYSTEM_TABLE.h        |  63 +++
 .../llvm-libc-types/EFI_TABLE_HEADER.h        |  22 +
 libc/include/llvm-libc-types/EFI_TIME.h       |  37 ++
 .../include/llvm-libc-types/EFI_TIMER_DELAY.h |  18 +
 libc/include/llvm-libc-types/EFI_TPL.h        |  21 +
 .../llvm-libc-types/EFI_VIRTUAL_ADDRESS.h     |  16 +
 libc/src/__support/OSUtil/io.h                |   2 +
 libc/src/__support/OSUtil/uefi/CMakeLists.txt |  11 +
 libc/src/__support/OSUtil/uefi/exit.cpp       |  23 +
 libc/src/__support/OSUtil/uefi/io.cpp         |  26 +
 libc/src/__support/OSUtil/uefi/io.h           |  25 +
 libc/src/stdio/CMakeLists.txt                 |   2 +-
 libc/src/stdio/uefi/CMakeLists.txt            |   0
 libc/startup/uefi/CMakeLists.txt              |  56 +++
 libc/startup/uefi/crt1.cpp                    |  24 +
 libc/test/src/__support/CMakeLists.txt        |   4 +-
 44 files changed, 1833 insertions(+), 3 deletions(-)
 create mode 100644 libc/config/uefi/config.json
 create mode 100644 libc/config/uefi/entrypoints.txt
 create mode 100644 libc/config/uefi/headers.txt
 create mode 100644 libc/hdrgen/yaml/Uefi.yaml
 create mode 100644 libc/include/Uefi.h.def
 create mode 100644 libc/include/llvm-libc-macros/EFIAPI-macros.h
 create mode 100644 libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h
 create mode 100644 libc/include/llvm-libc-types/EFI_CAPSULE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h
 create mode 100644 libc/include/llvm-libc-types/EFI_EVENT.h
 create mode 100644 libc/include/llvm-libc-types/EFI_GUID.h
 create mode 100644 libc/include/llvm-libc-types/EFI_HANDLE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h
 create mode 100644 libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h
 create mode 100644 libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h
 create mode 100644 libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h
 create mode 100644 libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
 create mode 100644 libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h
 create mode 100644 libc/include/llvm-libc-types/EFI_STATUS.h
 create mode 100644 libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h
 create mode 100644 libc/include/llvm-libc-types/EFI_TABLE_HEADER.h
 create mode 100644 libc/include/llvm-libc-types/EFI_TIME.h
 create mode 100644 libc/include/llvm-libc-types/EFI_TIMER_DELAY.h
 create mode 100644 libc/include/llvm-libc-types/EFI_TPL.h
 create mode 100644 libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h
 create mode 100644 libc/src/__support/OSUtil/uefi/CMakeLists.txt
 create mode 100644 libc/src/__support/OSUtil/uefi/exit.cpp
 create mode 100644 libc/src/__support/OSUtil/uefi/io.cpp
 create mode 100644 libc/src/__support/OSUtil/uefi/io.h
 create mode 100644 libc/src/stdio/uefi/CMakeLists.txt
 create mode 100644 libc/startup/uefi/CMakeLists.txt
 create mode 100644 libc/startup/uefi/crt1.cpp

diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index fbb1091ddabab4..dd12d1d3ee4224 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -69,6 +69,10 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
     set(target_sys "darwin")
   endif()
 
+  if(target_sys STREQUAL "unknown")
+    list(GET triple_comps 2 target_sys)
+  endif()
+
   # Setting OS name for GPU architectures.
   list(GET triple_comps -1 gpu_target_sys)
   if(gpu_target_sys MATCHES "^amdhsa" OR gpu_target_sys MATCHES "^cuda")
@@ -187,6 +191,8 @@ elseif(LIBC_TARGET_OS STREQUAL "windows")
   set(LIBC_TARGET_OS_IS_WINDOWS TRUE)
 elseif(LIBC_TARGET_OS STREQUAL "gpu")
   set(LIBC_TARGET_OS_IS_GPU TRUE)
+elseif(LIBC_TARGET_OS STREQUAL "uefi")
+  set(LIBC_TARGET_OS_IS_UEFI TRUE)
 else()
   message(FATAL_ERROR
           "Unsupported libc target operating system ${LIBC_TARGET_OS}")
diff --git a/libc/config/uefi/config.json b/libc/config/uefi/config.json
new file mode 100644
index 00000000000000..b60dde9ef040ac
--- /dev/null
+++ b/libc/config/uefi/config.json
@@ -0,0 +1,29 @@
+{
+  "errno": {
+    "LIBC_CONF_ERRNO_MODE": {
+      "value": "LIBC_ERRNO_MODE_DEFAULT"
+    }
+  },
+  "printf": {
+    "LIBC_CONF_PRINTF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
+      "value": false
+    },
+    "LIBC_CONF_PRINTF_DISABLE_STRERROR": {
+      "value": true
+    }
+  },
+  "qsort": {
+    "LIBC_CONF_QSORT_IMPL": {
+      "value": "LIBC_QSORT_HEAP_SORT"
+    }
+  }
+}
diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt
new file mode 100644
index 00000000000000..664a4d2ca46405
--- /dev/null
+++ b/libc/config/uefi/entrypoints.txt
@@ -0,0 +1,450 @@
+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
+
+    # errno.h entrypoints
+    libc.src.errno.errno
+
+    # setjmp.h entrypoints
+    libc.src.setjmp.longjmp
+    libc.src.setjmp.setjmp
+
+    # 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.memset_explicit
+    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.strcoll
+    libc.src.string.strcpy
+    libc.src.string.strcspn
+    libc.src.string.strerror
+    libc.src.string.strerror_r
+    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.strsep
+    libc.src.string.strspn
+    libc.src.string.strstr
+    libc.src.string.strtok
+    libc.src.string.strtok_r
+    libc.src.string.strxfrm
+
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    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
+
+    # stdbit.h entrypoints
+    libc.src.stdbit.stdc_bit_ceil_uc
+    libc.src.stdbit.stdc_bit_ceil_ui
+    libc.src.stdbit.stdc_bit_ceil_ul
+    libc.src.stdbit.stdc_bit_ceil_ull
+    libc.src.stdbit.stdc_bit_ceil_us
+    libc.src.stdbit.stdc_bit_floor_uc
+    libc.src.stdbit.stdc_bit_floor_ui
+    libc.src.stdbit.stdc_bit_floor_ul
+    libc.src.stdbit.stdc_bit_floor_ull
+    libc.src.stdbit.stdc_bit_floor_us
+    libc.src.stdbit.stdc_bit_width_uc
+    libc.src.stdbit.stdc_bit_width_ui
+    libc.src.stdbit.stdc_bit_width_ul
+    libc.src.stdbit.stdc_bit_width_ull
+    libc.src.stdbit.stdc_bit_width_us
+    libc.src.stdbit.stdc_count_ones_uc
+    libc.src.stdbit.stdc_count_ones_ui
+    libc.src.stdbit.stdc_count_ones_ul
+    libc.src.stdbit.stdc_count_ones_ull
+    libc.src.stdbit.stdc_count_ones_us
+    libc.src.stdbit.stdc_count_zeros_uc
+    libc.src.stdbit.stdc_count_zeros_ui
+    libc.src.stdbit.stdc_count_zeros_ul
+    libc.src.stdbit.stdc_count_zeros_ull
+    libc.src.stdbit.stdc_count_zeros_us
+    libc.src.stdbit.stdc_first_leading_one_uc
+    libc.src.stdbit.stdc_first_leading_one_ui
+    libc.src.stdbit.stdc_first_leading_one_ul
+    libc.src.stdbit.stdc_first_leading_one_ull
+    libc.src.stdbit.stdc_first_leading_one_us
+    libc.src.stdbit.stdc_first_leading_zero_uc
+    libc.src.stdbit.stdc_first_leading_zero_ui
+    libc.src.stdbit.stdc_first_leading_zero_ul
+    libc.src.stdbit.stdc_first_leading_zero_ull
+    libc.src.stdbit.stdc_first_leading_zero_us
+    libc.src.stdbit.stdc_first_trailing_one_uc
+    libc.src.stdbit.stdc_first_trailing_one_ui
+    libc.src.stdbit.stdc_first_trailing_one_ul
+    libc.src.stdbit.stdc_first_trailing_one_ull
+    libc.src.stdbit.stdc_first_trailing_one_us
+    libc.src.stdbit.stdc_first_trailing_zero_uc
+    libc.src.stdbit.stdc_first_trailing_zero_ui
+    libc.src.stdbit.stdc_first_trailing_zero_ul
+    libc.src.stdbit.stdc_first_trailing_zero_ull
+    libc.src.stdbit.stdc_first_trailing_zero_us
+    libc.src.stdbit.stdc_has_single_bit_uc
+    libc.src.stdbit.stdc_has_single_bit_ui
+    libc.src.stdbit.stdc_has_single_bit_ul
+    libc.src.stdbit.stdc_has_single_bit_ull
+    libc.src.stdbit.stdc_has_single_bit_us
+    libc.src.stdbit.stdc_leading_ones_uc
+    libc.src.stdbit.stdc_leading_ones_ui
+    libc.src.stdbit.stdc_leading_ones_ul
+    libc.src.stdbit.stdc_leading_ones_ull
+    libc.src.stdbit.stdc_leading_ones_us
+    libc.src.stdbit.stdc_leading_zeros_uc
+    libc.src.stdbit.stdc_leading_zeros_ui
+    libc.src.stdbit.stdc_leading_zeros_ul
+    libc.src.stdbit.stdc_leading_zeros_ull
+    libc.src.stdbit.stdc_leading_zeros_us
+    libc.src.stdbit.stdc_trailing_ones_uc
+    libc.src.stdbit.stdc_trailing_ones_ui
+    libc.src.stdbit.stdc_trailing_ones_ul
+    libc.src.stdbit.stdc_trailing_ones_ull
+    libc.src.stdbit.stdc_trailing_ones_us
+    libc.src.stdbit.stdc_trailing_zeros_uc
+    libc.src.stdbit.stdc_trailing_zeros_ui
+    libc.src.stdbit.stdc_trailing_zeros_ul
+    libc.src.stdbit.stdc_trailing_zeros_ull
+    libc.src.stdbit.stdc_trailing_zeros_us
+
+    # stdlib.h entrypoints
+    libc.src.stdlib._Exit
+    libc.src.stdlib.abs
+    libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.atof
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.bsearch
+    libc.src.stdlib.calloc
+    libc.src.stdlib.div
+    libc.src.stdlib.free
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
+    libc.src.stdlib.malloc
+    libc.src.stdlib.qsort
+    libc.src.stdlib.rand
+    libc.src.stdlib.realloc
+    libc.src.stdlib.srand
+    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
+
+    # time.h entrypoints
+    libc.src.time.asctime
+    libc.src.time.asctime_r
+    libc.src.time.ctime
+    libc.src.time.ctime_r
+    libc.src.time.difftime
+    libc.src.time.gmtime
+    libc.src.time.gmtime_r
+    libc.src.time.mktime
+)
+
+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.feraiseexcept
+    libc.src.fenv.fesetenv
+    libc.src.fenv.fesetexcept
+    libc.src.fenv.fesetexceptflag
+    libc.src.fenv.fesetround
+    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.canonicalize
+    libc.src.math.canonicalizef
+    libc.src.math.canonicalizel
+    libc.src.math.cbrt
+    libc.src.math.cbrtf
+    libc.src.math.ceil
+    libc.src.math.ceilf
+    libc.src.math.ceill
+    libc.src.math.copysign
+    libc.src.math.copysignf
+    libc.src.math.copysignl
+    libc.src.math.cos
+    libc.src.math.cosf
+    libc.src.math.coshf
+    libc.src.math.erff
+    libc.src.math.exp
+    libc.src.math.exp10
+    libc.src.math.exp10f
+    libc.src.math.exp2
+    libc.src.math.exp2f
+    libc.src.math.exp2m1f
+    libc.src.math.expf
+    libc.src.math.expm1
+    libc.src.math.expm1f
+    libc.src.math.fabs
+    libc.src.math.fabsf
+    libc.src.math.fabsl
+    libc.src.math.fdim
+    libc.src.math.fdimf
+    libc.src.math.fdiml
+    libc.src.math.floor
+    libc.src.math.floorf
+    libc.src.math.floorl
+    libc.src.math.fma
+    libc.src.math.fmaf
+    libc.src.math.fmax
+    libc.src.math.fmaxf
+    libc.src.math.fmaximum
+    libc.src.math.fmaximum_mag
+    libc.src.math.fmaximum_mag_num
+    libc.src.math.fmaximum_mag_numf
+    libc.src.math.fmaximum_mag_numl
+    libc.src.math.fmaximum_magf
+    libc.src.math.fmaximum_magl
+    libc.src.math.fmaximum_num
+    libc.src.math.fmaximum_numf
+    libc.src.math.fmaximum_numl
+    libc.src.math.fmaximumf
+    libc.src.math.fmaximuml
+    libc.src.math.fmaxl
+    libc.src.math.fmin
+    libc.src.math.fminf
+    libc.src.math.fminimum
+    libc.src.math.fminimum_mag
+    libc.src.math.fminimum_mag_num
+    libc.src.math.fminimum_mag_numf
+    libc.src.math.fminimum_mag_numl
+    libc.src.math.fminimum_magf
+    libc.src.math.fminimum_magl
+    libc.src.math.fminimum_num
+    libc.src.math.fminimum_numf
+    libc.src.math.fminimum_numl
+    libc.src.math.fminimumf
+    libc.src.math.fminimuml
+    libc.src.math.fminl
+    libc.src.math.fmod
+    libc.src.math.fmodf
+    libc.src.math.fmodl
+    libc.src.math.fmul
+    libc.src.math.frexp
+    libc.src.math.frexpf
+    libc.src.math.frexpl
+    libc.src.math.fromfp
+    libc.src.math.fromfpf
+    libc.src.math.fromfpl
+    libc.src.math.fromfpx
+    libc.src.math.fromfpxf
+    libc.src.math.fromfpxl
+    libc.src.math.hypot
+    libc.src.math.hypotf
+    libc.src.math.ilogb
+    libc.src.math.ilogbf
+    libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
+    libc.src.math.ldexp
+    libc.src.math.ldexpf
+    libc.src.math.ldexpl
+    libc.src.math.llogb
+    libc.src.math.llogbf
+    libc.src.math.llogbl
+    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.log
+    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.logb
+    libc.src.math.logbf
+    libc.src.math.logbl
+    libc.src.math.logf
+    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.nextdown
+    libc.src.math.nextdownf
+    libc.src.math.nextdownl
+    libc.src.math.nexttoward
+    libc.src.math.nexttowardf
+    libc.src.math.nexttowardl
+    libc.src.math.nextup
+    libc.src.math.nextupf
+    libc.src.math.nextupl
+    libc.src.math.pow
+    libc.src.math.powf
+    libc.src.math.remainder
+    libc.src.math.remainderf
+    libc.src.math.remainderl
+    libc.src.math.remquo
+    libc.src.math.remquof
+    libc.src.math.remquol
+    libc.src.math.rint
+    libc.src.math.rintf
+    libc.src.math.rintl
+    libc.src.math.round
+    libc.src.math.roundeven
+    libc.src.math.roundevenf
+    libc.src.math.roundevenl
+    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.sincos
+    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
+    libc.src.math.ufromfp
+    libc.src.math.ufromfpf
+    libc.src.math.ufromfpl
+    libc.src.math.ufromfpx
+    libc.src.math.ufromfpxf
+    libc.src.math.ufromfpxl
+)
+
+if(LIBC_COMPILER_HAS_FIXED_POINT)
+  list(APPEND TARGET_LIBM_ENTRYPOINTS
+    # stdfix.h _Fract and _Accum entrypoints
+    libc.src.stdfix.abshk
+    libc.src.stdfix.abshr
+    libc.src.stdfix.absk
+    libc.src.stdfix.abslk
+    libc.src.stdfix.abslr
+    libc.src.stdfix.absr
+    libc.src.stdfix.exphk
+    libc.src.stdfix.expk
+    libc.src.stdfix.roundhk
+    libc.src.stdfix.roundhr
+    libc.src.stdfix.roundk
+    libc.src.stdfix.roundlk
+    libc.src.stdfix.roundlr
+    libc.src.stdfix.roundr
+    libc.src.stdfix.rounduhk
+    libc.src.stdfix.rounduhr
+    libc.src.stdfix.rounduk
+    libc.src.stdfix.roundulk
+    libc.src.stdfix.roundulr
+    libc.src.stdfix.roundur
+    libc.src.stdfix.sqrtuhk
+    libc.src.stdfix.sqrtuhr
+    libc.src.stdfix.sqrtuk
+    libc.src.stdfix.sqrtur
+    libc.src.stdfix.sqrtulr
+    libc.src.stdfix.uhksqrtus
+    libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
+  )
+endif()
+
+set(TARGET_LLVMLIBC_ENTRYPOINTS
+  ${TARGET_LIBC_ENTRYPOINTS}
+  ${TARGET_LIBM_ENTRYPOINTS}
+)
diff --git a/libc/config/uefi/headers.txt b/libc/config/uefi/headers.txt
new file mode 100644
index 00000000000000..bf8dee1e6f2a69
--- /dev/null
+++ b/libc/config/uefi/headers.txt
@@ -0,0 +1,20 @@
+set(TARGET_PUBLIC_HEADERS
+    libc.include.assert
+    libc.include.ctype
+    libc.include.errno
+    libc.include.features
+    libc.include.fenv
+    libc.include.float
+    libc.include.inttypes
+    libc.include.math
+    libc.include.setjmp
+    libc.include.stdfix
+    libc.include.stdint
+    libc.include.stdlib
+    libc.include.string
+    libc.include.strings
+    libc.include.sys_queue
+    libc.include.time
+    libc.include.uefi
+    libc.include.uchar
+)
diff --git a/libc/hdrgen/yaml/Uefi.yaml b/libc/hdrgen/yaml/Uefi.yaml
new file mode 100644
index 00000000000000..f17e629c87cc7e
--- /dev/null
+++ b/libc/hdrgen/yaml/Uefi.yaml
@@ -0,0 +1,11 @@
+header: Uefi.h
+standards: UEFI
+macros: []
+types:
+  - type_name: EFI_BOOT_SERVICES
+  - type_name: EFI_GUID
+  - type_name: EFI_STATUS
+  - type_name: EFI_SYSTEM_TABLE
+enums: []
+functions: []
+objects: []
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 3a05c01abba5a4..df33e7a9059a28 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -750,6 +750,21 @@ add_header_macro(
     .llvm-libc-types.struct_lconv
 )
 
+if(LIBC_TARGET_OS_IS_UEFI)
+  # UEFI spec references "Uefi.h" so we use that name for compatibility
+  add_header_macro(
+    uefi
+    ../libc/hdrgen/yaml/Uefi.yaml
+    Uefi.h.def
+    Uefi.h
+    DEPENDS
+      .llvm_libc_common_h
+      .llvm-libc-types.EFI_GUID
+      .llvm-libc-types.EFI_STATUS
+      .llvm-libc-types.EFI_SYSTEM_TABLE
+  )
+endif()
+
 if(NOT LLVM_LIBC_FULL_BUILD)
   # We don't install headers in non-fullbuild mode.
   return()
diff --git a/libc/include/Uefi.h.def b/libc/include/Uefi.h.def
new file mode 100644
index 00000000000000..6655e13579cd8d
--- /dev/null
+++ b/libc/include/Uefi.h.def
@@ -0,0 +1,16 @@
+//===-- UEFI header uefi.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_UEFI_H
+#define LLVM_LIBC_UEFI_H
+
+#include "__llvm-libc-common.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_UEFI_H
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 9d5d9f65442889..bdad3edbfb6d1c 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -321,3 +321,9 @@ add_macro_header(
   HDR
     pthread-macros.h
 )
+
+add_macro_header(
+  EFIAPI_macros
+  HDR
+    EFIAPI-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/EFIAPI-macros.h b/libc/include/llvm-libc-macros/EFIAPI-macros.h
new file mode 100644
index 00000000000000..d6cc1784bb7863
--- /dev/null
+++ b/libc/include/llvm-libc-macros/EFIAPI-macros.h
@@ -0,0 +1,10 @@
+#ifndef LLVM_LIBC_MACROS_EFIAPI_MACROS_H
+#define LLVM_LIBC_MACROS_EFIAPI_MACROS_H
+
+#if defined(__x86_64__) && !defined(__ILP32__)
+#define EFIAPI __attribute__((ms_abi))
+#else
+#define EFIAPI
+#endif
+
+#endif // LLVM_LIBC_MACROS_EFIAPI_MACROS_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index ee734eafce3620..699df893378d05 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -155,3 +155,124 @@ DEPENDS
 add_header(locale_t HDR locale_t.h)
 add_header(struct_lconv HDR struct_lconv.h)
 add_header(stdfix-types HDR stdfix-types.h)
+
+# UEFI
+add_header(EFI_GUID HDR EFI_GUID.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
+add_header(EFI_CONFIGURATION_TABLE HDR EFI_CONFIGURATION_TABLE.h DEPENDS .EFI_GUID)
+
+add_header(EFI_PHYSICAL_ADDRESS HDR EFI_PHYSICAL_ADDRESS.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
+add_header(EFI_VIRTUAL_ADDRESS HDR EFI_VIRTUAL_ADDRESS.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
+
+add_header(EFI_MEMORY_DESCRIPTOR
+  HDR
+    EFI_MEMORY_DESCRIPTOR.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+    .EFI_PHYSICAL_ADDRESS
+    .EFI_VIRTUAL_ADDRESS
+)
+
+add_header(EFI_ALLOCATE_TYPE HDR EFI_ALLOCATE_TYPE.h)
+add_header(EFI_EVENT HDR EFI_EVENT.h)
+add_header(EFI_INTERFACE_TYPE HDR EFI_INTERFACE_TYPE.h)
+add_header(EFI_LOCATE_SEARCH_TYPE HDR EFI_LOCATE_SEARCH_TYPE.h)
+add_header(EFI_MEMORY_TYPE HDR EFI_MEMORY_TYPE.h)
+add_header(EFI_HANDLE HDR EFI_HANDLE.h)
+add_header(EFI_TIME HDR EFI_TIME.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
+add_header(EFI_TIMER_DELAY HDR EFI_TIMER_DELAY.h)
+add_header(EFI_TPL HDR EFI_TPL.h DEPENDS .size_t)
+add_header(EFI_STATUS HDR EFI_STATUS.h DEPENDS .size_t)
+
+add_header(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
+  HDR
+    EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+    .EFI_HANDLE
+)
+
+add_header(EFI_CAPSULE
+  HDR
+    EFI_CAPSULE.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+    .EFI_GUID
+)
+
+add_header(EFI_TABLE_HEADER
+  HDR
+    EFI_TABLE_HEADER.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+)
+
+add_header(EFI_DEVICE_PATH_PROTOCOL
+  HDR
+    EFI_DEVICE_PATH_PROTOCOL.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+)
+
+add_header(EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+  HDR
+    EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+    .EFI_STATUS
+    .char16_t
+)
+
+add_header(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+  HDR
+    EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h
+  DEPENDS
+    libc.include.llvm-libc-macros.stdint_macros
+    .EFI_STATUS
+    .size_t
+)
+
+add_header(EFI_BOOT_SERVICES
+  HDR
+    EFI_BOOT_SERVICES.h
+  DEPENDS
+    libc.include.llvm-libc-macros.EFIAPI_macros
+    .EFI_ALLOCATE_TYPE
+    .EFI_DEVICE_PATH_PROTOCOL
+    .EFI_EVENT
+    .EFI_INTERFACE_TYPE
+    .EFI_LOCATE_SEARCH_TYPE
+    .EFI_MEMORY_DESCRIPTOR
+    .EFI_MEMORY_TYPE
+    .EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
+    .EFI_PHYSICAL_ADDRESS
+    .EFI_TABLE_HEADER
+    .EFI_TIMER_DELAY
+    .EFI_TPL
+    .char16_t
+)
+
+add_header(EFI_RUNTIME_SERVICES
+  HDR
+    EFI_RUNTIME_SERVICES.h
+  DEPENDS
+    .EFI_CAPSULE
+    .EFI_STATUS
+    .EFI_TABLE_HEADER
+    .EFI_TIME
+    .char16_t
+)
+
+add_header(EFI_SYSTEM_TABLE
+  HDR
+    EFI_SYSTEM_TABLE.h
+  DEPENDS
+    .EFI_BOOT_SERVICES
+    .EFI_CONFIGURATION_TABLE
+    .EFI_HANDLE
+    .EFI_RUNTIME_SERVICES
+    .EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+    .EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+    .EFI_STATUS
+    .EFI_TABLE_HEADER
+    .char16_t
+)
diff --git a/libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h b/libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h
new file mode 100644
index 00000000000000..90f23969678f43
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h
@@ -0,0 +1,19 @@
+//===-- Definition of EFI_ALLOCATE_TYPE type ------------------------------===//
+//
+// 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_EFI_ALLOCATE_TYPE_H
+#define LLVM_LIBC_TYPES_EFI_ALLOCATE_TYPE_H
+
+typedef enum {
+  AllocateAnyPages,
+  AllocateMaxAddress,
+  AllocateAddress,
+  MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+
+#endif // LLVM_LIBC_TYPES_EFI_ALLOCATE_TYPE_H
diff --git a/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h
new file mode 100644
index 00000000000000..362e64846e4fab
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h
@@ -0,0 +1,249 @@
+//===-- Definition of EFI_BOOT_SERVICES type ------------------------------===//
+//
+// 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_EFI_BOOT_SERVICES_H
+#define LLVM_LIBC_TYPES_EFI_BOOT_SERVICES_H
+
+#include "../llvm-libc-macros/EFIAPI-macros.h"
+#include "EFI_ALLOCATE_TYPE.h"
+#include "EFI_DEVICE_PATH_PROTOCOL.h"
+#include "EFI_EVENT.h"
+#include "EFI_GUID.h"
+#include "EFI_INTERFACE_TYPE.h"
+#include "EFI_LOCATE_SEARCH_TYPE.h"
+#include "EFI_MEMORY_DESCRIPTOR.h"
+#include "EFI_MEMORY_TYPE.h"
+#include "EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h"
+#include "EFI_PHYSICAL_ADDRESS.h"
+#include "EFI_TABLE_HEADER.h"
+#include "EFI_TIMER_DELAY.h"
+#include "EFI_TPL.h"
+#include "char16_t.h"
+#include "size_t.h"
+
+#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
+#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION
+
+typedef EFI_TPL(EFIAPI *EFI_RAISE_TPL)(EFI_TPL NewTpl);
+typedef void(EFIAPI *EFI_RESTORE_TPL)(EFI_TPL OldTpl);
+
+typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_PAGES)(EFI_ALLOCATE_TYPE Type,
+                                               EFI_MEMORY_TYPE MemoryType,
+                                               size_t Pages,
+                                               EFI_PHYSICAL_ADDRESS *Memory);
+typedef EFI_STATUS(EFIAPI *EFI_FREE_PAGES)(EFI_PHYSICAL_ADDRESS Memory,
+                                           size_t Pages);
+typedef EFI_STATUS(EFIAPI *EFI_GET_MEMORY_MAP)(size_t *MemoryMapSize,
+                                               EFI_MEMORY_DESCRIPTOR *MemoryMap,
+                                               size_t *MapKey,
+                                               size_t *DescriptorSize,
+                                               uint32_t *DescriptorVersion);
+
+typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_POOL)(EFI_MEMORY_TYPE PoolType,
+                                              size_t Size, void **Buffer);
+typedef EFI_STATUS(EFIAPI *EFI_FREE_POOL)(void *Buffer);
+
+typedef void(EFIAPI *EFI_EVENT_NOTIFY)(EFI_EVENT Event, void *Context);
+
+typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT)(uint32_t Type, EFI_TPL NotifyTpl,
+                                             EFI_EVENT_NOTIFY NotifyFunction,
+                                             void *NotifyContext,
+                                             EFI_EVENT *Event);
+typedef EFI_STATUS(EFIAPI *EFI_SET_TIMER)(EFI_EVENT Event, EFI_TIMER_DELAY Type,
+                                          uint64_t TriggerTime);
+typedef EFI_STATUS(EFIAPI *EFI_WAIT_FOR_EVENT)(size_t NumberOfEvents,
+                                               EFI_EVENT *Event, size_t *Index);
+typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(EFI_EVENT Event);
+typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(EFI_EVENT Event);
+typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(EFI_EVENT Event);
+
+typedef EFI_STATUS(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)(
+    EFI_HANDLE *Handle, EFI_GUID *Protocol, EFI_INTERFACE_TYPE InterfaceType,
+    void *Interface);
+typedef EFI_STATUS(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)(
+    EFI_HANDLE Handle, EFI_GUID *Protocol, void *OldInterface,
+    void *NewInterface);
+typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(EFI_HANDLE Handle,
+                                                             EFI_GUID *Protocol,
+                                                             void *Interface);
+
+typedef EFI_STATUS(EFIAPI *EFI_HANDLE_PROTOCOL)(EFI_HANDLE Handle,
+                                                EFI_GUID *Protocol,
+                                                void **Interface);
+typedef EFI_STATUS(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(EFI_GUID *Protocol,
+                                                         EFI_EVENT Event,
+                                                         void **Registration);
+
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE)(EFI_LOCATE_SEARCH_TYPE SearchType,
+                                              EFI_GUID *Protocol,
+                                              void *SearchKey,
+                                              size_t *BufferSize,
+                                              EFI_HANDLE *Buffer);
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_DEVICE_PATH)(
+    EFI_GUID *Protocol, EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+    EFI_HANDLE *Device);
+
+typedef EFI_STATUS(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(EFI_GUID *Guid,
+                                                            void *Table);
+typedef EFI_STATUS(EFIAPI *EFI_IMAGE_UNLOAD)(EFI_HANDLE ImageHandle);
+typedef EFI_STATUS(EFIAPI *EFI_IMAGE_START)(EFI_HANDLE ImageHandle,
+                                            size_t *ExitDataSize,
+                                            char16_t **ExitData);
+
+typedef EFI_STATUS(EFIAPI *EFI_EXIT)(EFI_HANDLE ImageHandle,
+                                     EFI_STATUS ExitStatus, size_t ExitDataSize,
+                                     char16_t *ExitData);
+typedef EFI_STATUS(EFIAPI *EFI_EXIT_BOOT_SERVICES)(EFI_HANDLE ImageHandle,
+                                                   size_t MapKey);
+typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(uint64_t *Count);
+typedef EFI_STATUS(EFIAPI *EFI_STALL)(size_t Microseconds);
+typedef EFI_STATUS(EFIAPI *EFI_SET_WATCHDOG_TIMER)(size_t Timeout,
+                                                   uint64_t WatchdogCode,
+                                                   size_t DataSize,
+                                                   char16_t *WatchdogData);
+
+typedef EFI_STATUS(EFIAPI *EFI_CONNECT_CONTROLLER)(
+    EFI_HANDLE ControllerHandle, EFI_HANDLE *DriverImageHandle,
+    EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, bool Recursive);
+
+typedef EFI_STATUS(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+    EFI_HANDLE ControllerHandle, EFI_HANDLE DriverImageHandle,
+    EFI_HANDLE ChildHandle);
+
+typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL)(
+    EFI_HANDLE Handle, EFI_GUID *Protocol, void **Interface,
+    EFI_HANDLE AgentHandle, EFI_HANDLE ControllerHandle, uint32_t Attributes);
+
+typedef EFI_STATUS(EFIAPI *EFI_CLOSE_PROTOCOL)(EFI_HANDLE Handle,
+                                               EFI_GUID *Protocol,
+                                               EFI_HANDLE AgentHandle,
+                                               EFI_HANDLE ControllerHandle);
+
+typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)(
+    EFI_HANDLE Handle, EFI_GUID *Protocol,
+    EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, size_t *EntryCount);
+
+typedef EFI_STATUS(EFIAPI *EFI_PROTOCOLS_PER_HANDLE)(
+    EFI_HANDLE Handle, EFI_GUID ***ProtocolBuffer, size_t *ProtocolBufferCount);
+
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
+    EFI_LOCATE_SEARCH_TYPE SearchType, EFI_GUID *Protocol, void *SearchKey,
+    size_t *NoHandles, EFI_HANDLE **Buffer);
+
+typedef EFI_STATUS(EFIAPI *EFI_LOCATE_PROTOCOL)(EFI_GUID *Protocol,
+                                                void *Registration,
+                                                void **Interface);
+
+typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+    EFI_HANDLE Handle, ...);
+typedef EFI_STATUS(EFIAPI *EFI_CALCULATE_CRC32)(void *Data, size_t DataSize,
+                                                uint32_t *Crc32);
+
+typedef void(EFIAPI *EFI_COPY_MEM)(void *Destination, void *Source,
+                                   size_t Length);
+typedef void(EFIAPI *EFI_SET_MEM)(void *Buffer, size_t Size, uint8_t Value);
+
+typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT_EX)(
+    uint32_t Type, EFI_TPL NotifyTpl, EFI_EVENT_NOTIFY NotifyFunction,
+    const void *NotifyContext, const EFI_GUID *EventGroup, EFI_EVENT *Event);
+
+typedef struct {
+  EFI_TABLE_HEADER Hdr;
+
+  //
+  // Task Priority Services
+  //
+  EFI_RAISE_TPL RaiseTPL;     // EFI 1.0+
+  EFI_RESTORE_TPL RestoreTPL; // EFI 1.0+
+
+  //
+  // Memory Services
+  //
+  EFI_ALLOCATE_PAGES AllocatePages; // EFI 1.0+
+  EFI_FREE_PAGES FreePages;         // EFI 1.0+
+  EFI_GET_MEMORY_MAP GetMemoryMap;  // EFI 1.0+
+  EFI_ALLOCATE_POOL AllocatePool;   // EFI 1.0+
+  EFI_FREE_POOL FreePool;           // EFI 1.0+
+
+  //
+  // Event & Timer Services
+  //
+  EFI_CREATE_EVENT CreateEvent;    // EFI 1.0+
+  EFI_SET_TIMER SetTimer;          // EFI 1.0+
+  EFI_WAIT_FOR_EVENT WaitForEvent; // EFI 1.0+
+  EFI_SIGNAL_EVENT SignalEvent;    // EFI 1.0+
+  EFI_CLOSE_EVENT CloseEvent;      // EFI 1.0+
+  EFI_CHECK_EVENT CheckEvent;      // EFI 1.0+
+
+  //
+  // Protocol Handler Services
+  //
+  EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;     // EFI 1.0+
+  EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; // EFI 1.0+
+  EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; // EFI 1.0+
+  EFI_HANDLE_PROTOCOL HandleProtocol;                          // EFI 1.0+
+  void *Reserved;                                              // EFI 1.0+
+  EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;         // EFI 1.0+
+  EFI_LOCATE_HANDLE LocateHandle;                              // EFI 1.+
+  EFI_LOCATE_DEVICE_PATH LocateDevicePath;                     // EFI 1.0+
+  EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;   // EFI 1.0+
+
+  //
+  // Image Services
+  //
+  EFI_IMAGE_UNLOAD LoadImage;              // EFI 1.0+
+  EFI_IMAGE_START StartImage;              // EFI 1.0+
+  EFI_EXIT Exit;                           // EFI 1.0+
+  EFI_IMAGE_UNLOAD UnloadImage;            // EFI 1.0+
+  EFI_EXIT_BOOT_SERVICES ExitBootServices; // EFI 1.0+
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; // EFI 1.0+
+  EFI_STALL Stall;                                    // EFI 1.0+
+  EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;            // EFI 1.0+
+
+  //
+  // DriverSupport Services
+  //
+  EFI_CONNECT_CONTROLLER ConnectController;       // EFI 1.1
+  EFI_DISCONNECT_CONTROLLER DisconnectController; // EFI 1.1+
+
+  //
+  // Open and Close Protocol Services
+  //
+  EFI_OPEN_PROTOCOL OpenProtocol;                        // EFI 1.1+
+  EFI_CLOSE_PROTOCOL CloseProtocol;                      // EFI 1.1+
+  EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; // EFI 1.1+
+
+  //
+  // Library Services
+  //
+  EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; // EFI 1.1+
+  EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; // EFI 1.1+
+  EFI_LOCATE_PROTOCOL LocateProtocol;          // EFI 1.1+
+  EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES
+  InstallMultipleProtocolInterfaces; // EFI 1.1+
+  EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES
+  UninstallMultipleProtocolInterfaces; // EFI 1.1+*
+
+  //
+  // 32-bit CRC Services
+  //
+  EFI_CALCULATE_CRC32 CalculateCrc32; // EFI 1.1+
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_COPY_MEM CopyMem;              // EFI 1.1+
+  EFI_SET_MEM SetMem;                // EFI 1.1+
+  EFI_CREATE_EVENT_EX CreateEventEx; // UEFI 2.0+
+} EFI_BOOT_SERVICES;
+
+#endif // LLVM_LIBC_TYPES_EFI_BOOT_SERVICES_H
diff --git a/libc/include/llvm-libc-types/EFI_CAPSULE.h b/libc/include/llvm-libc-types/EFI_CAPSULE.h
new file mode 100644
index 00000000000000..c7440c9b03b75d
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_CAPSULE.h
@@ -0,0 +1,26 @@
+//===-- Definition of EFI_CAPSULE type ------------------------------------===//
+//
+// 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_EFI_CAPSULE_H
+#define LLVM_LIBC_TYPES_EFI_CAPSULE_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+#include "EFI_GUID.h"
+
+typedef struct {
+  EFI_GUID CapsuleGuid;
+  uint32_t HeaderSize;
+  uint32_t Flags;
+  uint32_t CapsuleImageSize;
+} EFI_CAPSULE_HEADER;
+
+#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
+#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
+#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000
+
+#endif // LLVM_LIBC_TYPES_EFI_CAPSULE_H
diff --git a/libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h b/libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h
new file mode 100644
index 00000000000000..56cd3e4fbb587b
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h
@@ -0,0 +1,19 @@
+//===-- Definition of EFI_CONFIGURATION_TABLE type ------------------------===//
+//
+// 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_EFI_CONFIGURATION_TABLE_H
+#define LLVM_LIBC_TYPES_EFI_CONFIGURATION_TABLE_H
+
+#include "EFI_GUID.h"
+
+typedef struct {
+  EFI_GUID VendorGuid;
+  void *VendorTable;
+} EFI_CONFIGURATION_TABLE;
+
+#endif // LLVM_LIBC_TYPES_EFI_CONFIGURATION_TABLE_H
diff --git a/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h
new file mode 100644
index 00000000000000..3f186cf245d894
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h
@@ -0,0 +1,27 @@
+//===-- Definition of EFI_DEVICE_PATH_PROTOCOL type -----------------------===//
+//
+// 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_EFI_DEVICE_PATH_PROTOCOL_H
+#define LLVM_LIBC_TYPES_EFI_DEVICE_PATH_PROTOCOL_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+#define EFI_DEVICE_PATH_PROTOCOL_GUID                                          \
+  {                                                                            \
+    0x09576e91, 0x6d3f, 0x11d2, {                                              \
+      0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b                           \
+    }                                                                          \
+  }
+
+typedef struct _EFI_DEVICE_PATH_PROTOCOL {
+  uint8_t Type;
+  uint8_t SubType;
+  uint8_t Length[2];
+} EFI_DEVICE_PATH_PROTOCOL;
+
+#endif // LLVM_LIBC_TYPES_EFI_DEVICE_PATH_PROTOCOL_H
diff --git a/libc/include/llvm-libc-types/EFI_EVENT.h b/libc/include/llvm-libc-types/EFI_EVENT.h
new file mode 100644
index 00000000000000..938856b8e791ec
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_EVENT.h
@@ -0,0 +1,21 @@
+//===-- Definition of EFI_EVENT type --------------------------------------===//
+//
+// 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_EFI_EVENT_H
+#define LLVM_LIBC_TYPES_EFI_EVENT_H
+
+typedef void *EFI_EVENT;
+
+#define EVT_TIMER 0x80000000
+#define EVT_RUNTIME 0x40000000
+#define EVT_NOTIFY_WAIT 0x00000100
+#define EVT_NOTIFY_SIGNAL 0x00000200
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+#endif // LLVM_LIBC_TYPES_EFI_EVENT_H
diff --git a/libc/include/llvm-libc-types/EFI_GUID.h b/libc/include/llvm-libc-types/EFI_GUID.h
new file mode 100644
index 00000000000000..b3530008384dd4
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_GUID.h
@@ -0,0 +1,21 @@
+//===-- Definition of EFI_GUID type -----------------------------------===//
+//
+// 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_EFI_GUID_H
+#define LLVM_LIBC_TYPES_EFI_GUID_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef struct {
+  uint32_t Data1;
+  uint16_t Data2;
+  uint16_t Data3;
+  uint8_t Data4[8];
+} EFI_GUID;
+
+#endif // LLVM_LIBC_TYPES_EFI_GUID_H
diff --git a/libc/include/llvm-libc-types/EFI_HANDLE.h b/libc/include/llvm-libc-types/EFI_HANDLE.h
new file mode 100644
index 00000000000000..d4376dd247533a
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_HANDLE.h
@@ -0,0 +1,14 @@
+//===-- Definition of EFI_HANDLE type ---------------------------------===//
+//
+// 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_EFI_HANDLE_H
+#define LLVM_LIBC_TYPES_EFI_HANDLE_H
+
+typedef void *EFI_HANDLE;
+
+#endif // LLVM_LIBC_TYPES_EFI_HANDLE_H
diff --git a/libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h b/libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h
new file mode 100644
index 00000000000000..d463c5381b3f0a
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h
@@ -0,0 +1,16 @@
+//===-- Definition of EFI_INTERFACE_TYPE type -----------------------------===//
+//
+// 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_EFI_INTERFACE_TYPE_H
+#define LLVM_LIBC_TYPES_EFI_INTERFACE_TYPE_H
+
+typedef enum {
+  EFI_NATIVE_INTERFACE,
+} EFI_INTERFACE_TYPE;
+
+#endif // LLVM_LIBC_TYPES_EFI_INTERFACE_TYPE_H
diff --git a/libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h b/libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h
new file mode 100644
index 00000000000000..3a8fd7bc3e776a
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h
@@ -0,0 +1,18 @@
+//===-- Definition of EFI_LOCATE_SEARCH_TYPE type -------------------------===//
+//
+// 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_EFI_LOCATE_SEARCH_TYPE_H
+#define LLVM_LIBC_TYPES_EFI_LOCATE_SEARCH_TYPE_H
+
+typedef enum {
+  AllHandles,
+  ByRegisterNotify,
+  ByProtocol,
+} EFI_LOCATE_SEARCH_TYPE;
+
+#endif // LLVM_LIBC_TYPES_EFI_LOCATE_SEARCH_TYPE_H
diff --git a/libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h b/libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h
new file mode 100644
index 00000000000000..72d0579aef76c4
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h
@@ -0,0 +1,43 @@
+//===-- Definition of EFI_MEMORY_DESCRIPTOR type --------------------------===//
+//
+// 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_EFI_MEMORY_DESCRIPTOR_H
+#define LLVM_LIBC_TYPES_EFI_MEMORY_DESCRIPTOR_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+#include "EFI_PHYSICAL_ADDRESS.h"
+#include "EFI_VIRTUAL_ADDRESS.h"
+
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+
+#define EFI_MEMORY_UC 0x0000000000000001
+#define EFI_MEMORY_WC 0x0000000000000002
+#define EFI_MEMORY_WT 0x0000000000000004
+#define EFI_MEMORY_WB 0x0000000000000008
+#define EFI_MEMORY_UCE 0x0000000000000010
+#define EFI_MEMORY_WP 0x0000000000001000
+#define EFI_MEMORY_RP 0x0000000000002000
+#define EFI_MEMORY_XP 0x0000000000004000
+#define EFI_MEMORY_NV 0x0000000000008000
+#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000
+#define EFI_MEMORY_RO 0x0000000000020000
+#define EFI_MEMORY_SP 0x0000000000040000
+#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000
+#define EFI_MEMORY_RUNTIME 0x8000000000000000
+#define EFI_MEMORY_ISA_VALID 0x4000000000000000
+#define EFI_MEMORY_ISA_MASK 0x0FFFF00000000000
+
+typedef struct {
+  uint32_t Type;
+  EFI_PHYSICAL_ADDRESS PhysicalStart;
+  EFI_VIRTUAL_ADDRESS VirtualStart;
+  uint64_t NumberOfPages;
+  uint64_t Attribute;
+} EFI_MEMORY_DESCRIPTOR;
+
+#endif // LLVM_LIBC_TYPES_EFI_MEMORY_DESCRIPTOR_H
diff --git a/libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h b/libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h
new file mode 100644
index 00000000000000..c8921cda2c3887
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h
@@ -0,0 +1,32 @@
+//===-- Definition of EFI_MEMORY_TYPE type --------------------------------===//
+//
+// 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_EFI_MEMORY_TYPE_H
+#define LLVM_LIBC_TYPES_EFI_MEMORY_TYPE_H
+
+typedef enum {
+  EfiReservedMemoryType,
+  EfiLoaderCode,
+  EfiLoaderData,
+  EfiBootServicesCode,
+  EfiBootServicesData,
+  EfiRuntimeServicesCode,
+  EfiRuntimeServicesData,
+  EfiConventionalMemory,
+  EfiUnusableMemory,
+  EfiACPIReclaimMemory,
+  EfiACPIMemoryNVS,
+  EfiMemoryMappedIO,
+  EfiMemoryMappedIOPortSpace,
+  EfiPalCode,
+  EfiPersistentMemory,
+  EfiUnacceptedMemoryType,
+  EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+#endif // LLVM_LIBC_TYPES_EFI_MEMORY_TYPE_H
diff --git a/libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h b/libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h
new file mode 100644
index 00000000000000..de0c59c139efba
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h
@@ -0,0 +1,22 @@
+//===-- Definition of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY type ------------===//
+//
+// 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_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY_H
+#define LLVM_LIBC_TYPES_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+#include "EFI_HANDLE.h"
+
+typedef struct {
+  EFI_HANDLE AgentHandle;
+  EFI_HANDLE ControllerHandle;
+  uint32_t Attributes;
+  uint32_t OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+
+#endif // LLVM_LIBC_TYPES_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY_H
diff --git a/libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h b/libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h
new file mode 100644
index 00000000000000..8880ee66c0f8dd
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h
@@ -0,0 +1,16 @@
+//===-- Definition of EFI_PHYSICAL_ADDRESS type ---------------------------===//
+//
+// 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_EFI_PHYSICAL_ADDRESS_H
+#define LLVM_LIBC_TYPES_EFI_PHYSICAL_ADDRESS_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint64_t EFI_PHYSICAL_ADDRESS;
+
+#endif // LLVM_LIBC_TYPES_EFI_PHYSICAL_ADDRESS_H
diff --git a/libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h b/libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h
new file mode 100644
index 00000000000000..aca1fd6d66297a
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h
@@ -0,0 +1,134 @@
+//===-- Definition of EFI_RUNTIME_SERVICES type ---------------------------===//
+//
+// 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_EFI_RUNTIME_SERVICES_H
+#define LLVM_LIBC_TYPES_EFI_RUNTIME_SERVICES_H
+
+#include "../llvm-libc-macros/EFIAPI-macros.h"
+#include "EFI_CAPSULE.h"
+#include "EFI_MEMORY_DESCRIPTOR.h"
+#include "EFI_PHYSICAL_ADDRESS.h"
+#include "EFI_STATUS.h"
+#include "EFI_TABLE_HEADER.h"
+#include "EFI_TIME.h"
+#include "char16_t.h"
+
+#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552
+#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION
+
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+// This attribute is identified by the mnemonic 'HR' elsewhere
+// in this specification.
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+// NOTE: EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated
+// and should be considered reserved.
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS 0x00000080
+
+typedef enum {
+  EfiResetCold,
+  EfiResetWarm,
+  EfiResetShutdown,
+  EfiResetPlatformSpecific,
+} EFI_RESET_TYPE;
+
+#define EFI_VARIABLE_AUTHENTICATION_3_CERT_ID_SHA256 1
+
+typedef struct {
+  uint8_t Type;
+  uint32_t IdSize;
+  // uint8_t Id[IdSize];
+} EFI_VARIABLE_AUTHENTICATION_3_CERT_ID;
+
+typedef EFI_STATUS(EFIAPI *EFI_GET_TIME)(EFI_TIME *Time,
+                                         EFI_TIME_CAPABILITIES *Capabilities);
+typedef EFI_STATUS(EFIAPI *EFI_SET_TIME)(EFI_TIME *Time);
+typedef EFI_STATUS(EFIAPI *EFI_GET_WAKEUP_TIME)(bool *Enabled, bool *Pending,
+                                                EFI_TIME *Time);
+typedef EFI_STATUS(EFIAPI *EFI_SET_WAKEUP_TIME)(bool *Enabled, EFI_TIME *Time);
+
+typedef EFI_STATUS(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)(
+    size_t MemoryMapSize, size_t DescriptorSize, uint32_t DescriptorVersion,
+    EFI_MEMORY_DESCRIPTOR *VirtualMap);
+typedef EFI_STATUS(EFIAPI *EFI_CONVERT_POINTER)(size_t DebugDisposition,
+                                                void **Address);
+
+typedef EFI_STATUS(EFIAPI *EFI_GET_VARIABLE)(char16_t *VariableName,
+                                             EFI_GUID *VendorGuid,
+                                             uint32_t *Attributes,
+                                             size_t *DataSize, void *Data);
+typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(size_t *VariableNameSize,
+                                                       char16_t *VariableName,
+                                                       EFI_GUID *VendorGuid);
+typedef EFI_STATUS(EFIAPI *EFI_SET_VARIABLE)(char16_t *VariableName,
+                                             EFI_GUID *VendorGuid,
+                                             uint32_t Attributes,
+                                             size_t DataSize, void *Data);
+
+typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)(uint32_t *HighCount);
+typedef void(EFIAPI *EFI_RESET_SYSTEM)(EFI_RESET_TYPE ResetType,
+                                       EFI_STATUS ResetStatus, size_t DataSize,
+                                       void *ResetData);
+
+typedef EFI_STATUS(EFIAPI *EFI_UPDATE_CAPSULE)(
+    EFI_CAPSULE_HEADER **CapsuleHeaderArray, size_t CapsuleCount,
+    EFI_PHYSICAL_ADDRESS ScatterGatherList);
+typedef EFI_STATUS(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)(
+    EFI_CAPSULE_HEADER **CapsuleHeaderArray, size_t CapsuleCount,
+    uint64_t *MaximumCapsuleSize, EFI_RESET_TYPE ResetType);
+
+typedef EFI_STATUS(EFIAPI *EFI_QUERY_VARIABLE_INFO)(
+    uint32_t Attributes, uint64_t *MaximumVariableStorageSize,
+    uint64_t *RemainingVariableStorageSize, uint64_t *MaximumVariableSize);
+
+typedef struct {
+  EFI_TABLE_HEADER Hdr;
+
+  ///
+  /// Time Services
+  EFI_GET_TIME GetTime;
+  EFI_SET_TIME SetTime;
+  EFI_GET_WAKEUP_TIME GetWakeupTime;
+  EFI_SET_WAKEUP_TIME SetWakeupTime;
+
+  //
+  // Virtual Memory Services
+  //
+  EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
+  EFI_CONVERT_POINTER ConvertPointer;
+
+  //
+  // Variable Services
+  //
+  EFI_GET_VARIABLE GetVariable;
+  EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
+  EFI_SET_VARIABLE SetVariable;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
+  EFI_RESET_SYSTEM ResetSystem;
+
+  //
+  // UEFI 2.0 Capsule Services
+  //
+  EFI_UPDATE_CAPSULE UpdateCapsule;
+  EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
+
+  //
+  // Miscellaneous UEFI 2.0 Service
+  //
+  EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
+} EFI_RUNTIME_SERVICES;
+
+#endif // LLVM_LIBC_TYPES_EFI_RUNTIME_SERVICES_H
diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
new file mode 100644
index 00000000000000..a290c5c7c30951
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
@@ -0,0 +1,41 @@
+//===-- Definition of EFI_SIMPLE_TEXT_INPUT_PROTOCOL type -----------------===//
+//
+// 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_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
+#define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+#include "EFI_STATUS.h"
+#include "char16_t.h"
+
+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID                                    \
+  {                                                                            \
+    0x387477c1, 0x69c7, 0x11d2, {                                              \
+      0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b                           \
+    }                                                                          \
+  }
+
+typedef struct {
+  uint16_t ScanCode;
+  char16_t UnicodeChar;
+} EFI_INPUT_KEY;
+
+struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
+
+typedef EFI_STATUS(EFIAPI *EFI_INPUT_RESET)(
+    struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, bool ExtendedVerification);
+typedef EFI_STATUS(EFIAPI *EFI_INPUT_READ_KEY)(
+    struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, EFI_INPUT_KEY *Key);
+
+typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
+  EFI_INPUT_RESET Reset;
+  EFI_INPUT_READ_KEY ReadKeyStroke;
+  EFI_EVENT WaitForKey;
+} EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
+
+#endif // LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h
new file mode 100644
index 00000000000000..307db79e1b3186
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h
@@ -0,0 +1,68 @@
+//===-- Definition of EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL type ----------------===//
+//
+// 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_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_H
+#define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+#include "EFI_STATUS.h"
+#include "size_t.h"
+
+#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID                                   \
+  {                                                                            \
+    0x387477c2, 0x69c7, 0x11d2, {                                              \
+      0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b                           \
+    }                                                                          \
+  }
+
+struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_RESET)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool ExtendedVerification);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_STRING)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, const char16_t *String);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_TEST_STRING)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, const char16_t *String);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_QUERY_MODE)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t ModeNumber,
+    size_t *Columns, size_t *Rows);
+
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_MODE)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t ModeNumber);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_ATTRIBUTE)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t Attribute);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_CLEAR_SCREEN)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t Column, size_t Row);
+typedef EFI_STATUS(EFIAPI *EFI_TEXT_ENABLE_CURSOR)(
+    struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool Visible);
+
+typedef struct {
+  int32_t MaxMode;
+  int32_t Mode;
+  int32_t Attribute;
+  int32_t CursorColumn;
+  int32_t CursorRow;
+  bool CursorVisible;
+} SIMPLE_TEXT_OUTPUT_MODE;
+
+typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
+  EFI_TEXT_RESET Reset;
+  EFI_TEXT_STRING OutputString;
+  EFI_TEXT_TEST_STRING TestString;
+  EFI_TEXT_QUERY_MODE QueryMode;
+  EFI_TEXT_SET_MODE SetMode;
+  EFI_TEXT_SET_ATTRIBUTE SetAttribute;
+  EFI_TEXT_CLEAR_SCREEN ClearScreen;
+  EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;
+  EFI_TEXT_ENABLE_CURSOR EnableCursor;
+  SIMPLE_TEXT_OUTPUT_MODE *Mode;
+} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+
+#endif // LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_H
diff --git a/libc/include/llvm-libc-types/EFI_STATUS.h b/libc/include/llvm-libc-types/EFI_STATUS.h
new file mode 100644
index 00000000000000..f7fa6e52381e17
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_STATUS.h
@@ -0,0 +1,16 @@
+//===-- Definition of EFI_STATUS type ---------------------------------===//
+//
+// 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_EFI_STATUS_H
+#define LLVM_LIBC_TYPES_EFI_STATUS_H
+
+#include "size_t.h"
+
+typedef size_t EFI_STATUS;
+
+#endif // LLVM_LIBC_TYPES_EFI_STATUS_H
diff --git a/libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h b/libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h
new file mode 100644
index 00000000000000..c1fbdf98381db0
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h
@@ -0,0 +1,63 @@
+//===-- Definition of EFI_SYSTEM_TABLE type -------------------------------===//
+//
+// 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_EFI_SYSTEM_TABLE_H
+#define LLVM_LIBC_TYPES_EFI_SYSTEM_TABLE_H
+
+#include "EFI_BOOT_SERVICES.h"
+#include "EFI_CONFIGURATION_TABLE.h"
+#include "EFI_HANDLE.h"
+#include "EFI_RUNTIME_SERVICES.h"
+#include "EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h"
+#include "EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h"
+#include "EFI_STATUS.h"
+#include "EFI_TABLE_HEADER.h"
+
+#include "char16_t.h"
+
+#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
+#define EFI_2_100_SYSTEM_TABLE_REVISION ((2 << 16) | (100))
+#define EFI_2_90_SYSTEM_TABLE_REVISION ((2 << 16) | (90))
+#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80))
+#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70))
+#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60))
+#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50))
+#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40))
+#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31))
+#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30))
+#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20))
+#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10))
+#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
+#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
+#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
+#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
+#define EFI_SYSTEM_TABLE_REVISION EFI_2_100_SYSTEM_TABLE_REVISION
+
+typedef struct {
+  EFI_TABLE_HEADER Hdr;
+
+  char16_t *FirmwareVendor;
+  uint32_t FirmwareRevision;
+
+  EFI_HANDLE ConsoleInHandle;
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
+
+  EFI_HANDLE ConsoleOutHandle;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
+
+  EFI_HANDLE StandardErrorHandle;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
+
+  EFI_RUNTIME_SERVICES *RuntimeServices;
+  EFI_BOOT_SERVICES *BootServices;
+
+  size_t NumberOfTableEntries;
+  EFI_CONFIGURATION_TABLE *ConfigurationTable;
+} EFI_SYSTEM_TABLE;
+
+#endif // LLVM_LIBC_TYPES_EFI_SYSTEM_TABLE_H
diff --git a/libc/include/llvm-libc-types/EFI_TABLE_HEADER.h b/libc/include/llvm-libc-types/EFI_TABLE_HEADER.h
new file mode 100644
index 00000000000000..293968ecc4d1b1
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_TABLE_HEADER.h
@@ -0,0 +1,22 @@
+//===-- Definition of EFI_TABLE_HEADER type -------------------------------===//
+//
+// 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_EFI_TABLE_HEADER_H
+#define LLVM_LIBC_TYPES_EFI_TABLE_HEADER_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef struct {
+  uint64_t Signature;
+  uint32_t Revision;
+  uint32_t HeaderSize;
+  uint32_t CRC32;
+  uint32_t Reserved;
+} EFI_TABLE_HEADER;
+
+#endif // LLVM_LIBC_TYPES_EFI_TABLE_HEADER_H
diff --git a/libc/include/llvm-libc-types/EFI_TIME.h b/libc/include/llvm-libc-types/EFI_TIME.h
new file mode 100644
index 00000000000000..b0e38b987d44ec
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_TIME.h
@@ -0,0 +1,37 @@
+//===-- Definition of EFI_TIME type ---------------------------------------===//
+//
+// 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_EFI_TIME_H
+#define LLVM_LIBC_TYPES_EFI_TIME_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef struct {
+  uint16_t Year;  // 1900 - 9999
+  uint8_t Month;  // 1 - 12
+  uint8_t Day;    // 1 - 31
+  uint8_t Hour;   // 0 - 23
+  uint8_t Minute; // 0 - 59
+  uint8_t Second; // 0 - 59
+  uint8_t Pad1;
+  uint32_t Nanosecond; // 0 - 999,999,999
+  int16_t TimeZone;    // --1440 to 1440 or 2047
+} EFI_TIME;
+
+#define EFI_TIME_ADJUST_DAYLIGHT 0x01
+#define EFI_TIME_IN_DAYLIGHT 0x02
+
+#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
+
+typedef struct {
+  uint32_t Resolution;
+  uint32_t Accuracy;
+  bool SetsToZero;
+} EFI_TIME_CAPABILITIES;
+
+#endif // LLVM_LIBC_TYPES_EFI_TIME_H
diff --git a/libc/include/llvm-libc-types/EFI_TIMER_DELAY.h b/libc/include/llvm-libc-types/EFI_TIMER_DELAY.h
new file mode 100644
index 00000000000000..2a6872c69c8b31
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_TIMER_DELAY.h
@@ -0,0 +1,18 @@
+//===-- Definition of EFI_TIMER_DELAY type --------------------------------===//
+//
+// 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_EFI_TIMER_DELAY_H
+#define LLVM_LIBC_TYPES_EFI_TIMER_DELAY_H
+
+typedef enum {
+  TimerCancel,
+  TimerPeriodic,
+  TimerRelative,
+} EFI_TIMER_DELAY;
+
+#endif // LLVM_LIBC_TYPES_EFI_TIMER_DELAY_H
diff --git a/libc/include/llvm-libc-types/EFI_TPL.h b/libc/include/llvm-libc-types/EFI_TPL.h
new file mode 100644
index 00000000000000..8361ccfacd6f5f
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_TPL.h
@@ -0,0 +1,21 @@
+//===-- Definition of EFI_TPL type ----------------------------------------===//
+//
+// 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_EFI_TPL_H
+#define LLVM_LIBC_TYPES_EFI_TPL_H
+
+#include "size_t.h"
+
+typedef size_t EFI_TPL;
+
+#define TPL_APPLICATION 4
+#define TPL_CALLBACK 8
+#define TPL_NOTIFY 16
+#define TPL_HIGH_LEVEL 31
+
+#endif // LLVM_LIBC_TYPES_EFI_TPL_H
diff --git a/libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h b/libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h
new file mode 100644
index 00000000000000..46cbec734dadc3
--- /dev/null
+++ b/libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h
@@ -0,0 +1,16 @@
+//===-- Definition of EFI_VIRTUAL_ADDRESS type ----------------------------===//
+//
+// 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_EFI_VIRTUAL_ADDRESS_H
+#define LLVM_LIBC_TYPES_EFI_VIRTUAL_ADDRESS_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint64_t EFI_VIRTUAL_ADDRESS;
+
+#endif // LLVM_LIBC_TYPES_EFI_VIRTUAL_ADDRESS_H
diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h
index 80119da77fc027..86857da4c30a70 100644
--- a/libc/src/__support/OSUtil/io.h
+++ b/libc/src/__support/OSUtil/io.h
@@ -24,6 +24,8 @@
 #elif defined(__ELF__)
 // TODO: Ideally we would have LIBC_TARGET_OS_IS_BAREMETAL.
 #include "baremetal/io.h"
+#elif defined(__uefi__)
+#include "uefi/io.h"
 #endif
 
 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_IO_H
diff --git a/libc/src/__support/OSUtil/uefi/CMakeLists.txt b/libc/src/__support/OSUtil/uefi/CMakeLists.txt
new file mode 100644
index 00000000000000..79ec8ab6024560
--- /dev/null
+++ b/libc/src/__support/OSUtil/uefi/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_object_library(
+  uefi_util
+  SRCS
+    io.cpp
+    exit.cpp
+  HDRS
+    io.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.CPP.string_view
+)
diff --git a/libc/src/__support/OSUtil/uefi/exit.cpp b/libc/src/__support/OSUtil/uefi/exit.cpp
new file mode 100644
index 00000000000000..ab7530ef88786b
--- /dev/null
+++ b/libc/src/__support/OSUtil/uefi/exit.cpp
@@ -0,0 +1,23 @@
+//===-------- UEFI 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/exit.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+[[noreturn]] void exit(int status) {
+  (void)status;
+  // TODO: call boot services to exit
+  while (true) {
+  }
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/uefi/io.cpp b/libc/src/__support/OSUtil/uefi/io.cpp
new file mode 100644
index 00000000000000..c80731ea888d3b
--- /dev/null
+++ b/libc/src/__support/OSUtil/uefi/io.cpp
@@ -0,0 +1,26 @@
+//===---------- UEFI 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
+//
+//===-----------------------------------------------------------------===//
+
+#include "io.h"
+
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+ssize_t read_from_stdin(char *buf, size_t size) {
+  (void)buf;
+  (void)size;
+  return 0;
+}
+
+void write_to_stdout(cpp::string_view msg) { (void)msg; }
+
+void write_to_stderr(cpp::string_view msg) { (void)msg; }
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/uefi/io.h b/libc/src/__support/OSUtil/uefi/io.h
new file mode 100644
index 00000000000000..088ae09b8c602e
--- /dev/null
+++ b/libc/src/__support/OSUtil/uefi/io.h
@@ -0,0 +1,25 @@
+//===---------- UEFI 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_UEFI_IO_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_IO_H
+
+#include "include/llvm-libc-types/size_t.h"
+#include "include/llvm-libc-types/ssize_t.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+ssize_t read_from_stdin(char *buf, size_t size);
+void write_to_stderr(cpp::string_view msg);
+void write_to_stdout(cpp::string_view msg);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_IO_H
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index b9bc904471df9a..776ca103a841fd 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -22,7 +22,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
 endif()
 
-if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
+if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_OS_IS_UEFI)
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generic)
 endif()
 
diff --git a/libc/src/stdio/uefi/CMakeLists.txt b/libc/src/stdio/uefi/CMakeLists.txt
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/libc/startup/uefi/CMakeLists.txt b/libc/startup/uefi/CMakeLists.txt
new file mode 100644
index 00000000000000..01e95f8520c68e
--- /dev/null
+++ b/libc/startup/uefi/CMakeLists.txt
@@ -0,0 +1,56 @@
+function(add_startup_object name)
+  cmake_parse_arguments(
+    "ADD_STARTUP_OBJECT"
+    "ALIAS" # Option argument
+    "SRC"   # Single value arguments
+    "DEPENDS;COMPILE_OPTIONS" # Multi value arguments
+    ${ARGN}
+  )
+
+  get_fq_target_name(${name} fq_target_name)
+  if(ADD_STARTUP_OBJECT_ALIAS)
+    get_fq_deps_list(fq_dep_list ${ADD_STARTUP_OBJECT_DEPENDS})
+    add_library(${fq_target_name} ALIAS ${fq_dep_list})
+    return()
+  endif()
+
+  add_object_library(
+    ${name}
+    SRCS ${ADD_STARTUP_OBJECT_SRC}
+    COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS}
+    ${ADD_STARTUP_OBJECT_UNPARSED_ARGUMENTS}
+    DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS}
+  )
+  set_target_properties(
+    ${fq_target_name}
+    PROPERTIES
+      OUTPUT_NAME ${name}.o
+  )
+
+  # Make an executable target of relocatable bitcode for clang if needed.
+  if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
+    add_executable(${fq_target_name}.exe $<TARGET_OBJECTS:${fq_target_name}>)
+    set_target_properties(${fq_target_name}.exe PROPERTIES
+      RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}
+      RUNTIME_OUTPUT_NAME ${name}.o)
+    target_link_options(${fq_target_name}.exe PRIVATE
+                        "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
+  endif()
+endfunction()
+
+add_startup_object(
+  crt1
+  SRCS
+  crt1.cpp
+)
+
+add_custom_target(libc-startup)
+set(startup_components crt1)
+foreach(target IN LISTS startup_components)
+  set(fq_target_name libc.startup.uefi.${target})
+  add_dependencies(libc-startup ${fq_target_name})
+  install(FILES $<TARGET_OBJECTS:${fq_target_name}>
+          DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
+          RENAME $<TARGET_PROPERTY:${fq_target_name},OUTPUT_NAME>
+          COMPONENT libc)
+endforeach()
diff --git a/libc/startup/uefi/crt1.cpp b/libc/startup/uefi/crt1.cpp
new file mode 100644
index 00000000000000..c4c5e5fde7d646
--- /dev/null
+++ b/libc/startup/uefi/crt1.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of crt for UEFI ----------------------------------===//
+//
+// 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 "include/llvm-libc-macros/stdlib-macros.h"
+#include "include/llvm-libc-types/EFI_HANDLE.h"
+#include "include/llvm-libc-types/EFI_STATUS.h"
+#include "include/llvm-libc-types/EFI_SYSTEM_TABLE.h"
+#include "src/__support/macros/config.h"
+
+extern "C" int main(int argc, char **argv, char **envp);
+
+extern "C" EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
+                              EFI_SYSTEM_TABLE *SystemTable) {
+  (void)ImageHandle;
+  (void)SystemTable;
+  main(0, NULL, NULL);
+  // TODO: convert the return value of main to EFI_STATUS
+  return 0; // TODO: EFI_SUCCESS
+}
diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index aeb8edf305d059..78a2f0903ccf21 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -1,6 +1,6 @@
 add_custom_target(libc-support-tests)
 
-if(NOT LIBC_TARGET_OS_IS_GPU)
+if(NOT LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_OS_IS_UEFI)
   add_libc_test(
     block_test
     SUITE
@@ -251,7 +251,7 @@ add_libc_test(
 
 # FIXME: We shouldn't have regular executables created because we could be
 #        cross-compiling the tests and running through an emulator.
-if(NOT LIBC_TARGET_OS_IS_GPU)
+if(NOT LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_OS_IS_UEFI)
   add_executable(
     libc_str_to_float_comparison_test
     str_to_float_comparison_test.cpp

>From a1f0016fc6ce5e97d414c89a43dc5aa6f076f6a7 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Fri, 20 Dec 2024 09:41:01 -0800
Subject: [PATCH 02/14] [libc] save efi image handle and system table in crt1

---
 libc/hdrgen/yaml/Uefi.yaml | 6 +++++-
 libc/startup/uefi/crt1.cpp | 8 ++++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/libc/hdrgen/yaml/Uefi.yaml b/libc/hdrgen/yaml/Uefi.yaml
index f17e629c87cc7e..28582eb2524b18 100644
--- a/libc/hdrgen/yaml/Uefi.yaml
+++ b/libc/hdrgen/yaml/Uefi.yaml
@@ -8,4 +8,8 @@ types:
   - type_name: EFI_SYSTEM_TABLE
 enums: []
 functions: []
-objects: []
+objects:
+  - object_name: efi_system_table
+    object_type: EFI_SYSTEM_TABLE *
+  - object_name: efi_image_handle
+    object_type: EFI_HANDLE
diff --git a/libc/startup/uefi/crt1.cpp b/libc/startup/uefi/crt1.cpp
index c4c5e5fde7d646..44570cb89010c4 100644
--- a/libc/startup/uefi/crt1.cpp
+++ b/libc/startup/uefi/crt1.cpp
@@ -12,12 +12,16 @@
 #include "include/llvm-libc-types/EFI_SYSTEM_TABLE.h"
 #include "src/__support/macros/config.h"
 
+EFI_HANDLE efi_image_handle;
+EFI_SYSTEM_TABLE *efi_system_table;
+
 extern "C" int main(int argc, char **argv, char **envp);
 
 extern "C" EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
                               EFI_SYSTEM_TABLE *SystemTable) {
-  (void)ImageHandle;
-  (void)SystemTable;
+  efi_image_handle = ImageHandle;
+  efi_system_table = SystemTable;
+
   main(0, NULL, NULL);
   // TODO: convert the return value of main to EFI_STATUS
   return 0; // TODO: EFI_SUCCESS

>From 722c410a3e25ee59640ec7541c8ebc0de3c3a11b Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Fri, 20 Dec 2024 09:47:11 -0800
Subject: [PATCH 03/14] [libc] implement uefi exit()

---
 libc/include/llvm-libc-types/CMakeLists.txt      | 1 +
 libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h | 1 +
 libc/src/__support/OSUtil/uefi/CMakeLists.txt    | 1 +
 libc/src/__support/OSUtil/uefi/exit.cpp          | 9 +++++----
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 699df893378d05..e94d1675bb6dca 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -245,6 +245,7 @@ add_header(EFI_BOOT_SERVICES
     .EFI_MEMORY_TYPE
     .EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
     .EFI_PHYSICAL_ADDRESS
+    .EFI_STATUS
     .EFI_TABLE_HEADER
     .EFI_TIMER_DELAY
     .EFI_TPL
diff --git a/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h
index 362e64846e4fab..8b7a6aadd7a24b 100644
--- a/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h
+++ b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h
@@ -20,6 +20,7 @@
 #include "EFI_MEMORY_TYPE.h"
 #include "EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h"
 #include "EFI_PHYSICAL_ADDRESS.h"
+#include "EFI_STATUS.h"
 #include "EFI_TABLE_HEADER.h"
 #include "EFI_TIMER_DELAY.h"
 #include "EFI_TPL.h"
diff --git a/libc/src/__support/OSUtil/uefi/CMakeLists.txt b/libc/src/__support/OSUtil/uefi/CMakeLists.txt
index 79ec8ab6024560..617c0002f94764 100644
--- a/libc/src/__support/OSUtil/uefi/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/uefi/CMakeLists.txt
@@ -6,6 +6,7 @@ add_object_library(
   HDRS
     io.h
   DEPENDS
+    libc.include.uefi
     libc.src.__support.common
     libc.src.__support.CPP.string_view
 )
diff --git a/libc/src/__support/OSUtil/uefi/exit.cpp b/libc/src/__support/OSUtil/uefi/exit.cpp
index ab7530ef88786b..fc8b9e6549b24c 100644
--- a/libc/src/__support/OSUtil/uefi/exit.cpp
+++ b/libc/src/__support/OSUtil/uefi/exit.cpp
@@ -7,16 +7,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/OSUtil/exit.h"
+#include "include/llvm-libc-macros/stdlib-macros.h"
 #include "src/__support/macros/config.h"
+#include <Uefi.h>
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
 [[noreturn]] void exit(int status) {
-  (void)status;
-  // TODO: call boot services to exit
-  while (true) {
-  }
+  efi_system_table->BootServices->Exit(efi_image_handle, status, 0, NULL);
+  while (true)
+    ;
 }
 
 } // namespace internal

>From 978cfaac725d88e497412aa169e449369c76ce06 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Fri, 20 Dec 2024 10:01:32 -0800
Subject: [PATCH 04/14] [libc] add __stack_chk_fail and abort to uefi

---
 libc/config/uefi/entrypoints.txt    |  3 +++
 libc/src/stdlib/uefi/CMakeLists.txt |  7 +++++++
 libc/src/stdlib/uefi/abort.cpp      | 18 ++++++++++++++++++
 3 files changed, 28 insertions(+)
 create mode 100644 libc/src/stdlib/uefi/CMakeLists.txt
 create mode 100644 libc/src/stdlib/uefi/abort.cpp

diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt
index 664a4d2ca46405..dec934b38f009f 100644
--- a/libc/config/uefi/entrypoints.txt
+++ b/libc/config/uefi/entrypoints.txt
@@ -1,4 +1,6 @@
 set(TARGET_LIBC_ENTRYPOINTS
+    libc.src.compiler.__stack_chk_fail
+
     # ctype.h entrypoints
     libc.src.ctype.isalnum
     libc.src.ctype.isalpha
@@ -152,6 +154,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdlib.h entrypoints
     libc.src.stdlib._Exit
+    libc.src.stdlib.abort
     libc.src.stdlib.abs
     libc.src.stdlib.aligned_alloc
     libc.src.stdlib.atof
diff --git a/libc/src/stdlib/uefi/CMakeLists.txt b/libc/src/stdlib/uefi/CMakeLists.txt
new file mode 100644
index 00000000000000..551a83a36b20e8
--- /dev/null
+++ b/libc/src/stdlib/uefi/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_entrypoint_object(
+  abort
+  SRCS
+    abort.cpp
+  HDRS
+    ../abort.h
+)
diff --git a/libc/src/stdlib/uefi/abort.cpp b/libc/src/stdlib/uefi/abort.cpp
new file mode 100644
index 00000000000000..98cf71084499ab
--- /dev/null
+++ b/libc/src/stdlib/uefi/abort.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of abort -------------------------------------------===//
+//
+// 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/common.h"
+#include "src/__support/macros/config.h"
+
+#include "src/stdlib/abort.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void, abort, ()) { __builtin_trap(); }
+
+} // namespace LIBC_NAMESPACE_DECL

>From 7af3dfe25e58d90af69bd37f3357060b81347f37 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Fri, 20 Dec 2024 13:13:34 -0800
Subject: [PATCH 05/14] [libc] support scudo in uefi

---
 libc/config/uefi/entrypoints.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt
index dec934b38f009f..1538602f6bd874 100644
--- a/libc/config/uefi/entrypoints.txt
+++ b/libc/config/uefi/entrypoints.txt
@@ -447,6 +447,13 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
   )
 endif()
 
+if(LLVM_LIBC_INCLUDE_SCUDO)
+  list(APPEND TARGET_LIBC_ENTRYPOINTS
+    # malloc.h external entrypoints
+    libc.src.stdlib.mallopt
+  )
+endif()
+
 set(TARGET_LLVMLIBC_ENTRYPOINTS
   ${TARGET_LIBC_ENTRYPOINTS}
   ${TARGET_LIBM_ENTRYPOINTS}

>From 254fcd41669f2353ec6406882262f5d67a225105 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Fri, 20 Dec 2024 15:47:36 -0800
Subject: [PATCH 06/14] [libc] work on puts in uefi

---
 libc/config/uefi/entrypoints.txt              | 13 ++++
 libc/config/uefi/headers.txt                  |  1 +
 libc/include/llvm-libc-types/CMakeLists.txt   |  2 +
 .../EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h          |  2 +
 libc/src/__support/CMakeLists.txt             |  4 ++
 libc/src/__support/UEFI/CMakeLists.txt        | 11 +++
 libc/src/__support/UEFI/file.cpp              | 67 +++++++++++++++++++
 libc/src/__support/UEFI/file.h                | 46 +++++++++++++
 libc/src/stdio/CMakeLists.txt                 | 38 ++++++-----
 libc/src/stdio/uefi/CMakeLists.txt            | 59 ++++++++++++++++
 libc/src/stdio/uefi/getchar.cpp               | 26 +++++++
 libc/src/stdio/uefi/printf.cpp                | 53 +++++++++++++++
 libc/src/stdio/uefi/putchar.cpp               | 24 +++++++
 libc/src/stdio/uefi/puts.cpp                  | 20 ++++++
 libc/src/stdio/uefi/vprintf.cpp               | 51 ++++++++++++++
 15 files changed, 399 insertions(+), 18 deletions(-)
 create mode 100644 libc/src/__support/UEFI/CMakeLists.txt
 create mode 100644 libc/src/__support/UEFI/file.cpp
 create mode 100644 libc/src/__support/UEFI/file.h
 create mode 100644 libc/src/stdio/uefi/getchar.cpp
 create mode 100644 libc/src/stdio/uefi/printf.cpp
 create mode 100644 libc/src/stdio/uefi/putchar.cpp
 create mode 100644 libc/src/stdio/uefi/puts.cpp
 create mode 100644 libc/src/stdio/uefi/vprintf.cpp

diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt
index 1538602f6bd874..09ab0da058251c 100644
--- a/libc/config/uefi/entrypoints.txt
+++ b/libc/config/uefi/entrypoints.txt
@@ -152,6 +152,19 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdbit.stdc_trailing_zeros_ull
     libc.src.stdbit.stdc_trailing_zeros_us
 
+    # stdio.h entrypoints
+    libc.src.stdio.getchar
+    libc.src.stdio.printf
+    libc.src.stdio.putchar
+    libc.src.stdio.puts
+    libc.src.stdio.snprintf
+    libc.src.stdio.sprintf
+    libc.src.stdio.asprintf
+    libc.src.stdio.vprintf
+    libc.src.stdio.vsnprintf
+    libc.src.stdio.vsprintf
+    libc.src.stdio.vasprintf
+
     # stdlib.h entrypoints
     libc.src.stdlib._Exit
     libc.src.stdlib.abort
diff --git a/libc/config/uefi/headers.txt b/libc/config/uefi/headers.txt
index bf8dee1e6f2a69..642d5a6b2f58bb 100644
--- a/libc/config/uefi/headers.txt
+++ b/libc/config/uefi/headers.txt
@@ -10,6 +10,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.setjmp
     libc.include.stdfix
     libc.include.stdint
+    libc.include.stdio
     libc.include.stdlib
     libc.include.string
     libc.include.strings
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index e94d1675bb6dca..995fae7f138d14 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -217,7 +217,9 @@ add_header(EFI_SIMPLE_TEXT_INPUT_PROTOCOL
   HDR
     EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
   DEPENDS
+    libc.include.llvm-libc-macros.EFIAPI_macros
     libc.include.llvm-libc-macros.stdint_macros
+    .EFI_EVENT
     .EFI_STATUS
     .char16_t
 )
diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
index a290c5c7c30951..0a7384e7de5224 100644
--- a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
+++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
@@ -9,7 +9,9 @@
 #ifndef LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
 #define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
 
+#include "../llvm-libc-macros/EFIAPI-macros.h"
 #include "../llvm-libc-macros/stdint-macros.h"
+#include "EFI_EVENT.h"
 #include "EFI_STATUS.h"
 #include "char16_t.h"
 
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 4e90aad9a45b40..05f43b8f660ffb 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -359,6 +359,10 @@ add_subdirectory(StringUtil)
 add_subdirectory(GPU)
 add_subdirectory(RPC)
 
+if(LIBC_TARGET_OS_IS_UEFI)
+  add_subdirectory(UEFI)
+endif()
+
 # Thread support is used by other "File". So, we add the "threads"
 # before "File".
 add_subdirectory(threads)
diff --git a/libc/src/__support/UEFI/CMakeLists.txt b/libc/src/__support/UEFI/CMakeLists.txt
new file mode 100644
index 00000000000000..46a2d6504b6d85
--- /dev/null
+++ b/libc/src/__support/UEFI/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_object_library(
+  file
+  SRCS
+    file.cpp
+  HDRS
+    file.h
+  DEPENDS
+    libc.include.uefi
+    libc.hdr.types.FILE
+    libc.src.__support.CPP.new
+)
diff --git a/libc/src/__support/UEFI/file.cpp b/libc/src/__support/UEFI/file.cpp
new file mode 100644
index 00000000000000..73309a46edcfea
--- /dev/null
+++ b/libc/src/__support/UEFI/file.cpp
@@ -0,0 +1,67 @@
+#include "file.h"
+#include "hdr/types/FILE.h"
+#include "src/__support/macros/config.h"
+#include <Uefi.h>
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+namespace LIBC_NAMESPACE_DECL {
+bool File::needsReset() { return handle_type == FileHandleId; }
+
+void File::reset() {
+  if (handle_type != FileHandleId)
+    return;
+
+  if (handle.id == STDIN_FILENO) {
+    handle = (FileHandle){
+        .simple_text_input = efi_system_table->ConIn,
+    };
+    handle_type = FileHandleSimpleTextInput;
+  } else {
+    handle = (FileHandle){
+        .simple_text_output = handle.id == STDERR_FILENO
+                                  ? efi_system_table->StdErr
+                                  : efi_system_table->ConOut,
+    };
+    handle_type = FileHandleSimpleTextOutput;
+  }
+}
+
+size_t File::write(const void *data, size_t data_len) {
+  if (needsReset())
+    reset();
+
+  if (handle_type == FileHandleSimpleTextOutput) {
+    handle.simple_text_output->OutputString(
+        handle.simple_text_output, reinterpret_cast<const char16_t *>(data));
+    return data_len;
+  }
+  return 0;
+}
+
+File stdin(
+    (FileHandle){
+        .id = STDIN_FILENO,
+    },
+    FileHandleId);
+
+File stdout(
+    (FileHandle){
+        .id = STDOUT_FILENO,
+    },
+    FileHandleId);
+
+File stderr(
+    (FileHandle){
+        .id = STDERR_FILENO,
+    },
+    FileHandleId);
+} // namespace LIBC_NAMESPACE_DECL
+
+extern "C" {
+FILE *stdin = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stdin);
+FILE *stdout = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stdout);
+FILE *stderr = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stderr);
+}
diff --git a/libc/src/__support/UEFI/file.h b/libc/src/__support/UEFI/file.h
new file mode 100644
index 00000000000000..b77c00e903b6c1
--- /dev/null
+++ b/libc/src/__support/UEFI/file.h
@@ -0,0 +1,46 @@
+#ifndef LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H
+#define LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H
+
+#include "include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h"
+#include "include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+enum FileHandleType {
+  FileHandleId,
+  FileHandleSimpleTextInput,
+  FileHandleSimpleTextOutput,
+};
+
+union FileHandle {
+  int id;
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL *simple_text_input;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *simple_text_output;
+};
+
+class File {
+  FileHandle handle;
+  FileHandleType handle_type;
+
+private:
+  bool needsReset();
+
+public:
+  constexpr File(FileHandle handle, FileHandleType handle_type)
+      : handle(handle), handle_type(handle_type) {}
+
+  void reset();
+
+  size_t read(void *data, size_t len);
+  size_t write(const void *data, size_t len);
+};
+
+extern File stdin;
+extern File stdout;
+extern File stderr;
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 776ca103a841fd..dd3477061c0f45 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -240,26 +240,28 @@ add_entrypoint_object(
 add_subdirectory(printf_core)
 add_subdirectory(scanf_core)
 
-add_entrypoint_object(
-  remove
-  ALIAS
-  DEPENDS
-    .${LIBC_TARGET_OS}.remove
-)
+if(NOT LIBC_TARGET_OS_IS_UEFI)
+  add_entrypoint_object(
+    remove
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.remove
+  )
 
-add_entrypoint_object(
-  rename
-  ALIAS
-  DEPENDS
-    .${LIBC_TARGET_OS}.rename
-)
+  add_entrypoint_object(
+    rename
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.rename
+  )
 
-add_entrypoint_object(
-  fdopen
-  ALIAS
-  DEPENDS
-    .${LIBC_TARGET_OS}.fdopen
-)
+  add_entrypoint_object(
+    fdopen
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.fdopen
+  )
+endif()
 
 # These entrypoints have multiple potential implementations.
 add_stdio_entrypoint_object(feof)
diff --git a/libc/src/stdio/uefi/CMakeLists.txt b/libc/src/stdio/uefi/CMakeLists.txt
index e69de29bb2d1d6..6fe527ea242370 100644
--- a/libc/src/stdio/uefi/CMakeLists.txt
+++ b/libc/src/stdio/uefi/CMakeLists.txt
@@ -0,0 +1,59 @@
+add_entrypoint_object(
+  getchar
+  SRCS
+    getchar.cpp
+  HDRS
+    ../getchar.h
+  DEPENDS
+    libc.hdr.stdio_macros
+    libc.src.__support.UEFI.file
+)
+
+add_entrypoint_object(
+  printf
+  SRCS
+    printf.cpp
+  HDRS
+    ../printf.h
+  DEPENDS
+    libc.src.stdio.printf_core.printf_main
+    libc.src.stdio.printf_core.writer
+    libc.src.__support.arg_list
+    libc.src.__support.OSUtil.osutil
+)
+
+add_entrypoint_object(
+  putchar
+  SRCS
+    putchar.cpp
+  HDRS
+    ../putchar.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.CPP.string_view
+    libc.src.__support.UEFI.file
+)
+
+add_entrypoint_object(
+  puts
+  SRCS
+    puts.cpp
+  HDRS
+    ../puts.h
+  DEPENDS
+    libc.src.__support.UEFI.file
+    libc.src.string.strlen
+)
+
+add_entrypoint_object(
+  vprintf
+  SRCS
+    vprintf.cpp
+  HDRS
+    ../vprintf.h
+  DEPENDS
+    libc.src.stdio.printf_core.printf_main
+    libc.src.stdio.printf_core.writer
+    libc.src.__support.arg_list
+    libc.src.__support.OSUtil.osutil
+)
diff --git a/libc/src/stdio/uefi/getchar.cpp b/libc/src/stdio/uefi/getchar.cpp
new file mode 100644
index 00000000000000..ecd7a8a54e9ea0
--- /dev/null
+++ b/libc/src/stdio/uefi/getchar.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of getchar -----------------------------------------===//
+//
+// 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/stdio/getchar.h"
+#include "src/__support/UEFI/file.h"
+
+#include "hdr/stdio_macros.h" // for EOF.
+#include "hdr/types/FILE.h"
+#include "src/__support/macros/config.h"
+#include "src/errno/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getchar, ()) {
+  unsigned char c;
+  if (stdin.read(&c, 1) != 1)
+    return EOF;
+  return c;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/uefi/printf.cpp b/libc/src/stdio/uefi/printf.cpp
new file mode 100644
index 00000000000000..04aa284ee0839d
--- /dev/null
+++ b/libc/src/stdio/uefi/printf.cpp
@@ -0,0 +1,53 @@
+//===-- Implementation of printf for baremetal ------------------*- 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/stdio/printf.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/printf_main.h"
+#include "src/stdio/printf_core/writer.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace {
+
+LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) {
+  write_to_stderr(new_str);
+  return printf_core::WRITE_OK;
+}
+
+} // namespace
+
+LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) {
+  va_list vlist;
+  va_start(vlist, format);
+  internal::ArgList args(vlist); // This holder class allows for easier copying
+                                 // and pointer semantics, as well as handling
+                                 // destruction automatically.
+  va_end(vlist);
+  constexpr size_t BUFF_SIZE = 1024;
+  char buffer[BUFF_SIZE];
+
+  printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr);
+  printf_core::Writer writer(&wb);
+
+  int retval = printf_core::printf_main(&writer, format, args);
+
+  int flushval = wb.overflow_write("");
+  if (flushval != printf_core::WRITE_OK)
+    retval = flushval;
+
+  return retval;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/uefi/putchar.cpp b/libc/src/stdio/uefi/putchar.cpp
new file mode 100644
index 00000000000000..0ba46a5ade6c9b
--- /dev/null
+++ b/libc/src/stdio/uefi/putchar.cpp
@@ -0,0 +1,24 @@
+//===-- Baremetal Implementation of putchar -------------------------------===//
+//
+// 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/stdio/putchar.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, putchar, (int c)) {
+  char uc = static_cast<char>(c);
+
+  write_to_stderr(cpp::string_view(&uc, 1));
+
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/uefi/puts.cpp b/libc/src/stdio/uefi/puts.cpp
new file mode 100644
index 00000000000000..07a33e49e644af
--- /dev/null
+++ b/libc/src/stdio/uefi/puts.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of puts for baremetal-------------------------------===//
+//
+// 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/stdio/puts.h"
+#include "src/__support/UEFI/file.h"
+#include "src/__support/macros/config.h"
+#include "src/string/strlen.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) {
+  return (int)stdout.write(reinterpret_cast<const void *>(str), strlen(str));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdio/uefi/vprintf.cpp b/libc/src/stdio/uefi/vprintf.cpp
new file mode 100644
index 00000000000000..617b5f488e7728
--- /dev/null
+++ b/libc/src/stdio/uefi/vprintf.cpp
@@ -0,0 +1,51 @@
+//===-- Implementation of vprintf -------------------------------*- 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/stdio/vprintf.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/arg_list.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/printf_main.h"
+#include "src/stdio/printf_core/writer.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace {
+
+LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) {
+  write_to_stderr(new_str);
+  return printf_core::WRITE_OK;
+}
+
+} // namespace
+
+LLVM_LIBC_FUNCTION(int, vprintf,
+                   (const char *__restrict format, va_list vlist)) {
+  internal::ArgList args(vlist); // This holder class allows for easier copying
+                                 // and pointer semantics, as well as handling
+                                 // destruction automatically.
+  constexpr size_t BUFF_SIZE = 1024;
+  char buffer[BUFF_SIZE];
+
+  printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr);
+  printf_core::Writer writer(&wb);
+
+  int retval = printf_core::printf_main(&writer, format, args);
+
+  int flushval = wb.overflow_write("");
+  if (flushval != printf_core::WRITE_OK)
+    retval = flushval;
+
+  return retval;
+}
+
+} // namespace LIBC_NAMESPACE_DECL

>From 21585ba8b6680c6f81c5c3e4cbe368c2cbfbcd97 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Fri, 20 Dec 2024 16:12:14 -0800
Subject: [PATCH 07/14] [libc] add os util out and err writes for uefi

---
 libc/src/__support/OSUtil/uefi/io.cpp | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/OSUtil/uefi/io.cpp b/libc/src/__support/OSUtil/uefi/io.cpp
index c80731ea888d3b..a4dad03ef1ff19 100644
--- a/libc/src/__support/OSUtil/uefi/io.cpp
+++ b/libc/src/__support/OSUtil/uefi/io.cpp
@@ -10,6 +10,7 @@
 
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/macros/config.h"
+#include <Uefi.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -19,8 +20,16 @@ ssize_t read_from_stdin(char *buf, size_t size) {
   return 0;
 }
 
-void write_to_stdout(cpp::string_view msg) { (void)msg; }
+void write_to_stdout(cpp::string_view msg) {
+  // TODO: use mbstowcs once implemented
+  efi_system_table->ConOut->OutputString(
+      efi_system_table->ConOut, reinterpret_cast<const char16_t *>(msg.data()));
+}
 
-void write_to_stderr(cpp::string_view msg) { (void)msg; }
+void write_to_stderr(cpp::string_view msg) {
+  // TODO: use mbstowcs once implemented
+  efi_system_table->StdErr->OutputString(
+      efi_system_table->StdErr, reinterpret_cast<const char16_t *>(msg.data()));
+}
 
 } // namespace LIBC_NAMESPACE_DECL

>From 1cfba39e17862315b9421907602240f61cde5dfb Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Mon, 23 Dec 2024 19:11:13 -0800
Subject: [PATCH 08/14] [libc] revert target triple hack

---
 libc/cmake/modules/LLVMLibCArchitectures.cmake | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index dd12d1d3ee4224..f5dd32acc5ee33 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -69,10 +69,6 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
     set(target_sys "darwin")
   endif()
 
-  if(target_sys STREQUAL "unknown")
-    list(GET triple_comps 2 target_sys)
-  endif()
-
   # Setting OS name for GPU architectures.
   list(GET triple_comps -1 gpu_target_sys)
   if(gpu_target_sys MATCHES "^amdhsa" OR gpu_target_sys MATCHES "^cuda")

>From f080b2902323a8d9802354589cde4e169d3545a8 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Mon, 23 Dec 2024 19:41:47 -0800
Subject: [PATCH 09/14] [libc] add uefi to docs

---
 libc/docs/index.rst            |   1 +
 libc/docs/platform_support.rst |   2 +
 libc/docs/uefi/index.rst       |  15 +++
 libc/docs/uefi/support.rst     | 232 +++++++++++++++++++++++++++++++++
 libc/docs/uefi/using.rst       |  46 +++++++
 5 files changed, 296 insertions(+)
 create mode 100644 libc/docs/uefi/index.rst
 create mode 100644 libc/docs/uefi/support.rst
 create mode 100644 libc/docs/uefi/using.rst

diff --git a/libc/docs/index.rst b/libc/docs/index.rst
index 0cbf75f5e0ef2d..2f5d6dc7c0deb6 100644
--- a/libc/docs/index.rst
+++ b/libc/docs/index.rst
@@ -46,6 +46,7 @@ LLVM-libc aspires to a unique place in the software ecosystem.  The goals are:
    fullbuild_mode
    configure
    gpu/index.rst
+   uefi/index.rst
 
 .. toctree::
    :hidden:
diff --git a/libc/docs/platform_support.rst b/libc/docs/platform_support.rst
index 2ce3d7282b304f..37979be86a5192 100644
--- a/libc/docs/platform_support.rst
+++ b/libc/docs/platform_support.rst
@@ -20,3 +20,5 @@ have reached their EOL. Compatibility patches for obsolete operating systems
 will not be accepted.
 
 For GPU, reference `our GPU docs <gpu/index.html>`__.
+
+For UEFI, reference `our UEFI docs <uefi/index.html>`__.
diff --git a/libc/docs/uefi/index.rst b/libc/docs/uefi/index.rst
new file mode 100644
index 00000000000000..31a65cb063aa74
--- /dev/null
+++ b/libc/docs/uefi/index.rst
@@ -0,0 +1,15 @@
+.. libc_uefi:
+
+=============
+libc for UEFI
+=============
+
+.. note:: This feature is very experimental and may change in the future.
+
+The *UEFI* support for LLVM's libc project aims to make a subset of the standard
+C library available on UEFI systems.
+
+.. toctree::
+
+   using
+   support
diff --git a/libc/docs/uefi/support.rst b/libc/docs/uefi/support.rst
new file mode 100644
index 00000000000000..c105f0028cfa79
--- /dev/null
+++ b/libc/docs/uefi/support.rst
@@ -0,0 +1,232 @@
+.. _libc_uefi_support:
+
+===================
+Supported Functions
+===================
+
+.. include:: ../check.rst
+
+.. contents:: Table of Contents
+  :depth: 4
+  :local:
+
+
+The following functions and headers are supported at least partially.
+Some functions are implemented fully for UEFI.
+
+ctype.h
+-------
+
+=============  =========
+Function Name  Available
+=============  =========
+isalnum        |check|
+isalpha        |check|
+isascii        |check|
+isblank        |check|
+iscntrl        |check|
+isdigit        |check|
+isgraph        |check|
+islower        |check|
+isprint        |check|
+ispunct        |check|
+isspace        |check|
+isupper        |check|
+isxdigit       |check|
+toascii        |check|
+tolower        |check|
+toupper        |check|
+=============  =========
+
+string.h
+--------
+
+=============  =========
+Function Name  Available
+=============  =========
+bcmp           |check|
+bcopy          |check|
+bzero          |check|
+memccpy        |check|
+memchr         |check|
+memcmp         |check|
+memcpy         |check|
+memmem         |check|
+memmove        |check|
+mempcpy        |check|
+memrchr        |check|
+memset         |check|
+stpcpy         |check|
+stpncpy        |check|
+strcat         |check|
+strchr         |check|
+strchrnul      |check|
+strcmp         |check|
+strcoll        |check|
+strcpy         |check|
+strcspn        |check|
+strdup         |check|
+strerror       |check|
+strlcat        |check|
+strlcpy        |check|
+strlen         |check|
+strncat        |check|
+strncmp        |check|
+strncpy        |check|
+strndup        |check|
+strnlen        |check|
+strpbrk        |check|
+strrchr        |check|
+strsep         |check|
+strspn         |check|
+strstr         |check|
+strtok         |check|
+strtok_r       |check|
+strxfrm        |check|
+=============  =========
+
+strings.h
+---------
+
+=============  =========
+Function Name  Available
+=============  =========
+bcmp           |check|
+bcopy          |check|
+bzero          |check|
+strcasecmp     |check|
+strcasestr     |check|
+index          |check|
+rindex         |check|
+=============  =========
+
+stdbit.h
+--------
+
+============================  =========
+Function Name                 Available
+============================  =========
+stdc_leading_zeros_uc         |check|
+stdc_leading_zeros_us         |check|
+stdc_leading_zeros_ui         |check|
+stdc_leading_zeros_ul         |check|
+stdc_leading_zeros_ull        |check|
+stdc_trailing_zeros_uc        |check|
+stdc_trailing_zeros_us        |check|
+stdc_trailing_zeros_ui        |check|
+stdc_trailing_zeros_ul        |check|
+stdc_trailing_zeros_ull       |check|
+stdc_trailing_ones_uc         |check|
+stdc_trailing_ones_us         |check|
+stdc_trailing_ones_ui         |check|
+stdc_trailing_ones_ul         |check|
+stdc_trailing_ones_ull        |check|
+stdc_first_leading_zero_uc    |check|
+stdc_first_leading_zero_us    |check|
+stdc_first_leading_zero_ui    |check|
+stdc_first_leading_zero_ul    |check|
+stdc_first_leading_zero_ull   |check|
+stdc_first_leading_one_uc     |check|
+stdc_first_leading_one_us     |check|
+stdc_first_leading_one_ui     |check|
+stdc_first_leading_one_ul     |check|
+stdc_first_leading_one_ull    |check|
+stdc_first_trailing_zero_uc   |check|
+stdc_first_trailing_zero_us   |check|
+stdc_first_trailing_zero_ui   |check|
+stdc_first_trailing_zero_ul   |check|
+stdc_first_trailing_zero_ull  |check|
+stdc_first_trailing_one_uc    |check|
+stdc_first_trailing_one_us    |check|
+stdc_first_trailing_one_ui    |check|
+stdc_first_trailing_one_ul    |check|
+stdc_first_trailing_one_ull   |check|
+stdc_count_zeros_uc           |check|
+stdc_count_zeros_us           |check|
+stdc_count_zeros_ui           |check|
+stdc_count_zeros_ul           |check|
+stdc_count_zeros_ull          |check|
+stdc_count_ones_uc            |check|
+stdc_count_ones_us            |check|
+stdc_count_ones_ui            |check|
+stdc_count_ones_ul            |check|
+stdc_count_ones_ull           |check|
+stdc_has_single_bit_uc        |check|
+stdc_has_single_bit_us        |check|
+stdc_has_single_bit_ui        |check|
+stdc_has_single_bit_ul        |check|
+stdc_has_single_bit_ull       |check|
+stdc_bit_width_uc             |check|
+stdc_bit_width_us             |check|
+stdc_bit_width_ui             |check|
+stdc_bit_width_ul             |check|
+stdc_bit_width_ull            |check|
+stdc_bit_floor_uc             |check|
+stdc_bit_floor_us             |check|
+stdc_bit_floor_ui             |check|
+stdc_bit_floor_ul             |check|
+stdc_bit_floor_ull            |check|
+stdc_bit_ceil_uc              |check|
+stdc_bit_ceil_us              |check|
+stdc_bit_ceil_ui              |check|
+stdc_bit_ceil_ul              |check|
+stdc_bit_ceil_ull             |check|
+============================  =========
+
+stdlib.h
+--------
+
+=============  =========
+Function Name  Available
+=============  =========
+abs            |check|
+atoi           |check|
+atof           |check|
+atol           |check|
+atoll          |check|
+exit           |check|
+abort          |check|
+system         |check|
+labs           |check|
+llabs          |check|
+div            |check|
+ldiv           |check|
+lldiv          |check|
+bsearch        |check|
+qsort          |check|
+qsort_r        |check|
+strtod         |check|
+strtof         |check|
+strtol         |check|
+strtold        |check|
+strtoll        |check|
+strtoul        |check|
+strtoull       |check|
+srand          |check|
+rand           |check|
+=============  =========
+
+inttypes.h
+----------
+
+=============  =========
+Function Name  Available
+=============  =========
+imaxabs        |check|
+imaxdiv        |check|
+strtoimax      |check|
+strtoumax      |check|
+=============  =========
+
+stdio.h
+-------
+
+=============  =========
+Function Name  Available
+=============  =========
+getchar        |check|
+printf         |check|
+putchar        |check|
+puts           |check|
+vprintf        |check|
+=============  =========
diff --git a/libc/docs/uefi/using.rst b/libc/docs/uefi/using.rst
new file mode 100644
index 00000000000000..90d06df7734934
--- /dev/null
+++ b/libc/docs/uefi/using.rst
@@ -0,0 +1,46 @@
+.. libc_uefi_usage:
+
+===================
+Using libc for UEFI
+===================
+
+.. contents:: Table of Contents
+  :depth: 4
+  :local:
+
+Using the UEFI C library
+========================
+
+Once you have finished building the UEFI C library, it
+can be used to run libc or libm functions inside a UEFI
+environment. Current, not all C standard functions are
+supported in UEFI. Consult the :ref:`list of supported
+functions<libc_uefi_support>` for a comprehensive list.
+
+Running a UEFI C library program in QEMU
+========================================
+
+QEMU is the preferred way to test programs compiled using
+the UEFI C library, it only requires OVMF which is based
+on EDKII. It is recommended to create a directory which
+serves as a fat32 file system but passed through QEMU.
+The following flag is capable of doing that:
+
+.. code-block:: sh
+
+   -drive file=fat:rw:fat32-fs
+
+This will expose the ``fat32-fs`` directory as a fat32
+partition. Once QEMU starts, press ESQ a few times to
+bring up the EDKII menu. Enter the boot manager and
+load the option for the UEFI shell. Typically, EDKII
+will expose the fat32 filesystem as ``FS0``. From there,
+you can run the following command to run your program.
+Here, we are using ``a.out`` as the example since clang
+outputs to that filename by default.
+
+.. code-block:: sh
+
+   > FS0:
+   FS0:> a.out
+

>From cc47f824b075bdbcff33a4cb74f4c12eae8f3096 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Mon, 23 Dec 2024 19:54:03 -0800
Subject: [PATCH 10/14] [libc] replace __uefi__ macro with __UEFI__

---
 libc/src/__support/OSUtil/io.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h
index 86857da4c30a70..66af31f3cc8c60 100644
--- a/libc/src/__support/OSUtil/io.h
+++ b/libc/src/__support/OSUtil/io.h
@@ -24,7 +24,7 @@
 #elif defined(__ELF__)
 // TODO: Ideally we would have LIBC_TARGET_OS_IS_BAREMETAL.
 #include "baremetal/io.h"
-#elif defined(__uefi__)
+#elif defined(__UEFI__)
 #include "uefi/io.h"
 #endif
 

>From 46b671f268578961509c2fe50c282c7e7d5cfc45 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Mon, 23 Dec 2024 23:12:17 -0800
Subject: [PATCH 11/14] [libc] add uefi timespec

---
 libc/config/uefi/entrypoints.txt    |  1 +
 libc/src/time/uefi/CMakeLists.txt   | 12 +++++++
 libc/src/time/uefi/timespec_get.cpp | 52 +++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+)
 create mode 100644 libc/src/time/uefi/CMakeLists.txt
 create mode 100644 libc/src/time/uefi/timespec_get.cpp

diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt
index 09ab0da058251c..bfc633c6e79c96 100644
--- a/libc/config/uefi/entrypoints.txt
+++ b/libc/config/uefi/entrypoints.txt
@@ -204,6 +204,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
+    libc.src.time.timespec_get
 )
 
 set(TARGET_LIBM_ENTRYPOINTS
diff --git a/libc/src/time/uefi/CMakeLists.txt b/libc/src/time/uefi/CMakeLists.txt
new file mode 100644
index 00000000000000..5c2b138f5d036a
--- /dev/null
+++ b/libc/src/time/uefi/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_entrypoint_object(
+  timespec_get
+  SRCS
+    timespec_get.cpp
+  HDRS
+    ../timespec_get.h
+  DEPENDS
+    libc.include.uefi
+    libc.hdr.time_macros
+    libc.hdr.types.struct_timespec
+    libc.src.time.mktime
+)
diff --git a/libc/src/time/uefi/timespec_get.cpp b/libc/src/time/uefi/timespec_get.cpp
new file mode 100644
index 00000000000000..9ba3d2e7dd15f8
--- /dev/null
+++ b/libc/src/time/uefi/timespec_get.cpp
@@ -0,0 +1,52 @@
+//===-- Implementation of timespec_get for UEFI ---------------------------===//
+//
+// 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/timespec_get.h"
+#include "hdr/time_macros.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/time/mktime.h"
+#include <Uefi.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+extern "C" bool __llvm_libc_timespec_get_utc(struct timespec *ts);
+
+LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) {
+  if (base != TIME_UTC)
+    return 0;
+
+  EFI_TIME efi_time;
+  EFI_STATUS status =
+      efi_system_table->RuntimeServices->GetTime(&efi_time, nullptr);
+  if (status != 0)
+    return 0;
+
+  struct tm t;
+  t.tm_year = efi_time.Year - 1900; // tm_year is years since 1900
+  t.tm_mon = efi_time.Month - 1;    // tm_mon is 0-11
+  t.tm_mday = efi_time.Day;
+  t.tm_hour = efi_time.Hour;
+  t.tm_min = efi_time.Minute;
+  t.tm_sec = efi_time.Second;
+  t.tm_isdst = -1; // Use system timezone settings
+
+  ts->tv_sec = LIBC_NAMESPACE::mktime(&t);
+  if (ts->tv_sec == -1)
+    return 0;
+
+  ts->tv_nsec = efi_time.Nanosecond;
+
+  // Handle timezone offset if specified
+  if (efi_time.TimeZone != 2047) {        // 2047 means timezone is unspecified
+    ts->tv_sec -= efi_time.TimeZone * 60; // EFI_TIME timezone is in minutes
+  }
+  return base;
+}
+
+} // namespace LIBC_NAMESPACE_DECL

>From 6a9d76bb961f82b1f9353cf3b7afc75665e762ad Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Mon, 23 Dec 2024 23:12:31 -0800
Subject: [PATCH 12/14] [libc] adjust testing for uefi

---
 libc/include/llvm-libc-macros/signal-macros.h |  2 ++
 .../llvm-libc-macros/uefi/CMakeLists.txt      |  5 ++++
 .../llvm-libc-macros/uefi/signal-macros.h     | 28 +++++++++++++++++++
 libc/test/UnitTest/CMakeLists.txt             |  6 ++--
 libc/test/UnitTest/LibcDeathTestExecutors.cpp |  2 +-
 libc/test/UnitTest/LibcTest.cpp               |  9 +++++-
 6 files changed, 48 insertions(+), 4 deletions(-)
 create mode 100644 libc/include/llvm-libc-macros/uefi/CMakeLists.txt
 create mode 100644 libc/include/llvm-libc-macros/uefi/signal-macros.h

diff --git a/libc/include/llvm-libc-macros/signal-macros.h b/libc/include/llvm-libc-macros/signal-macros.h
index fbe929a0fea25a..ab9825d9a24926 100644
--- a/libc/include/llvm-libc-macros/signal-macros.h
+++ b/libc/include/llvm-libc-macros/signal-macros.h
@@ -13,6 +13,8 @@
 #include "linux/signal-macros.h"
 #elif defined(__NVPTX__) || defined(__AMDGPU__)
 #include "gpu/signal-macros.h"
+#elif defined(__UEFI__)
+#include "uefi/signal-macros.h"
 #endif
 
 #endif // LLVM_LIBC_MACROS_SIGNAL_MACROS_H
diff --git a/libc/include/llvm-libc-macros/uefi/CMakeLists.txt b/libc/include/llvm-libc-macros/uefi/CMakeLists.txt
new file mode 100644
index 00000000000000..9ef86a8cb5479c
--- /dev/null
+++ b/libc/include/llvm-libc-macros/uefi/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_header(
+  signal_macros
+  HDR
+    signal-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/uefi/signal-macros.h b/libc/include/llvm-libc-macros/uefi/signal-macros.h
new file mode 100644
index 00000000000000..6ad69421fbd0fa
--- /dev/null
+++ b/libc/include/llvm-libc-macros/uefi/signal-macros.h
@@ -0,0 +1,28 @@
+//===-- Definition of UEFI signal number macros ---------------------------===//
+//
+// 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_UEFI_SIGNAL_MACROS_H
+#define LLVM_LIBC_MACROS_UEFI_SIGNAL_MACROS_H
+
+#define SIGINT 2
+#define SIGILL 4
+#define SIGABRT 6
+#define SIGFPE 8
+#define SIGSEGV 11
+#define SIGTERM 15
+
+#define SIG_DFL ((__sighandler_t)(0))
+#define SIG_IGN ((__sighandler_t)(1))
+#define SIG_ERR ((__sighandler_t)(-1))
+
+// Max signal number
+#define NSIG 64
+
+#define __NSIGSET_WORDS NSIG
+
+#endif // LLVM_LIBC_MACROS_UEFI_SIGNAL_MACROS_H
diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index 570bd600d1a430..7c37cb5a704b26 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -20,7 +20,7 @@ function(add_unittest_framework_library name)
       ${TEST_LIB_HDRS}
     )
     target_include_directories(${lib} PRIVATE ${LIBC_SOURCE_DIR})
-    if(TARGET libc.src.time.clock)
+    if(TARGET libc.src.time.${TARGET_OS}.clock)
       target_compile_definitions(${lib} PRIVATE TARGET_SUPPORTS_CLOCK)
     endif()
   endforeach()
@@ -30,7 +30,7 @@ function(add_unittest_framework_library name)
     # making LibcFPExceptionHelpers and LibcDeathTestExecutors hermetic.
     set(LLVM_LIBC_FULL_BUILD "")
     _get_common_test_compile_options(compile_options "" "")
-    target_compile_options(${name}.unit PRIVATE ${compile_options})
+    target_compile_options(${name}.unit PRIVATE ${compile_options} -I${CMAKE_BINARY_DIR}/libc/include)
     set(LLVM_LIBC_FULL_BUILD ON)
   else()
     _get_common_test_compile_options(compile_options "" "")
@@ -128,6 +128,7 @@ add_unittest_framework_library(
     libc.src.__support.FPUtil.rounding_mode
 )
 
+if(NOT LIBC_TARGET_OS_IS_UEFI)
 add_unittest_framework_library(
   LibcFPExceptionHelpers
   SRCS
@@ -140,6 +141,7 @@ add_unittest_framework_library(
     libc.src.__support.FPUtil.fenv_impl
     libc.hdr.types.fenv_t
 )
+endif()
 
 add_unittest_framework_library(
   LibcMemoryHelpers
diff --git a/libc/test/UnitTest/LibcDeathTestExecutors.cpp b/libc/test/UnitTest/LibcDeathTestExecutors.cpp
index 77b0559c7acea9..943e2c23c5fde9 100644
--- a/libc/test/UnitTest/LibcDeathTestExecutors.cpp
+++ b/libc/test/UnitTest/LibcDeathTestExecutors.cpp
@@ -12,7 +12,7 @@
 #include "test/UnitTest/ExecuteFunction.h"
 #include "test/UnitTest/TestLogger.h"
 
-#include <cassert>
+#include <assert.h>
 
 namespace {
 constexpr unsigned TIMEOUT_MS = 10000;
diff --git a/libc/test/UnitTest/LibcTest.cpp b/libc/test/UnitTest/LibcTest.cpp
index afb1368f009050..c1ff857e2f6360 100644
--- a/libc/test/UnitTest/LibcTest.cpp
+++ b/libc/test/UnitTest/LibcTest.cpp
@@ -19,7 +19,6 @@
 
 #if __STDC_HOSTED__
 #include <time.h>
-#define LIBC_TEST_USE_CLOCK
 #elif defined(TARGET_SUPPORTS_CLOCK)
 #include <time.h>
 
@@ -158,13 +157,21 @@ int Test::runTests(const TestOptions &Options) {
     }
 
     tlog << green << "[ RUN      ] " << reset << TestName << '\n';
+
+#ifdef LIBC_TEST_USE_CLOCK
     [[maybe_unused]] const uint64_t start_time = clock();
+#endif
+
     RunContext Ctx;
     T->SetUp();
     T->setContext(&Ctx);
     T->Run();
     T->TearDown();
+
+#ifdef LIBC_TEST_USE_CLOCK
     [[maybe_unused]] const uint64_t end_time = clock();
+#endif
+
     switch (Ctx.status()) {
     case RunContext::RunResult::Fail:
       tlog << red << "[  FAILED  ] " << reset << TestName << '\n';

>From 286db3134d581c45597bbfcada9a811054165176 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Tue, 24 Dec 2024 08:35:27 -0800
Subject: [PATCH 13/14] [libc] fix test building in clang with gcc c++ lib

---
 libc/test/UnitTest/ExecuteFunctionUnix.cpp | 8 +++-----
 libc/test/UnitTest/FPExceptMatcher.cpp     | 1 -
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/libc/test/UnitTest/ExecuteFunctionUnix.cpp b/libc/test/UnitTest/ExecuteFunctionUnix.cpp
index 3a657c00851c7b..02c1dfc46e55a7 100644
--- a/libc/test/UnitTest/ExecuteFunctionUnix.cpp
+++ b/libc/test/UnitTest/ExecuteFunctionUnix.cpp
@@ -8,13 +8,11 @@
 
 #include "ExecuteFunction.h"
 #include "src/__support/macros/config.h"
-#include <cassert>
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <memory>
+#include <assert.h>
 #include <poll.h>
 #include <signal.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
diff --git a/libc/test/UnitTest/FPExceptMatcher.cpp b/libc/test/UnitTest/FPExceptMatcher.cpp
index 37ba0a0a7abde4..2dea76eb8d4069 100644
--- a/libc/test/UnitTest/FPExceptMatcher.cpp
+++ b/libc/test/UnitTest/FPExceptMatcher.cpp
@@ -13,7 +13,6 @@
 
 #include "hdr/types/fenv_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
-#include <memory>
 #include <setjmp.h>
 #include <signal.h>
 

>From 6eb3a63b61eb19891ce6bcb2b1fb6db6608ac4b3 Mon Sep 17 00:00:00 2001
From: Tristan Ross <tristan.ross at midstall.com>
Date: Tue, 24 Dec 2024 08:54:11 -0800
Subject: [PATCH 14/14] [libc] add uefi fullbuild test to gha

---
 .github/workflows/libc-fullbuild-tests.yml | 25 +++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/libc-fullbuild-tests.yml b/.github/workflows/libc-fullbuild-tests.yml
index 58e15ce29546ef..29ac9730bbbf84 100644
--- a/.github/workflows/libc-fullbuild-tests.yml
+++ b/.github/workflows/libc-fullbuild-tests.yml
@@ -16,8 +16,22 @@ jobs:
       fail-fast: false
       matrix:
         include:
-          - c_compiler: clang
-            cpp_compiler: clang++
+          - target: aarch64-unknown-linux-llvm
+            compiler:
+              c_compiler: clang
+              cpp_compiler: clang++
+          - target: x86_64-unknown-linux-llvm
+            compiler:
+              c_compiler: clang
+              cpp_compiler: clang++
+          - target: aarch64-unknown-uefi-llvm
+            compiler:
+              c_compiler: clang
+              cpp_compiler: clang++
+          - target: x86_64-unknown-uefi-llvm
+            compiler:
+              c_compiler: clang
+              cpp_compiler: clang++
           # TODO: add back gcc build when it is fixed
           # - c_compiler: gcc
           #   cpp_compiler: g++
@@ -34,7 +48,7 @@ jobs:
       uses: hendrikmuhs/ccache-action at v1.2
       with:
         max-size: 1G
-        key: libc_fullbuild_${{ matrix.c_compiler }}
+        key: libc_fullbuild_${{ matrix.compiler.c_compiler }}
         variant: sccache
     
     # Notice:
@@ -59,8 +73,8 @@ jobs:
     - name: Configure CMake
       run: >
         cmake -B ${{ steps.strings.outputs.build-output-dir }}
-        -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-        -DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
+        -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cpp_compiler }}
+        -DCMAKE_C_COMPILER=${{ matrix.compiler.c_compiler }}
         -DCMAKE_BUILD_TYPE=MinSizeRel
         -DCMAKE_C_COMPILER_LAUNCHER=sccache
         -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
@@ -68,6 +82,7 @@ jobs:
         -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt"
         -DLLVM_LIBC_FULL_BUILD=ON
         -DLLVM_LIBC_INCLUDE_SCUDO=ON
+        -LLVM_RUNTIMES_TARGET=${{ matrix.target }}
         -DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON
         -DCOMPILER_RT_BUILD_GWP_ASAN=OFF
         -DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF



More information about the llvm-commits mailing list