Skip to content

[libc] init uefi #131246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2025
Merged

Conversation

RossComputerGuy
Copy link
Member

Initial UEFI OS target support after the headers. This just defines enough that stuff might try and compile. Test with:

$ cmake -S llvm -B build -G Ninja -DLLVM_RUNTIME_TARGETS=x86_64-unknown-uefi-llvm -DRUNTIMES_x86_64-unknown-uefi-llvm_LLVM_ENABLE_RUNTIMES=libc -DRUNTIMES_x86_64-unknown-uefi-llvm_LLVM_LIBC_FULL_BUILD=true -DCMAKE_C_COMPILER_WORKS=true -DCMAKE_CXX_COMPILER_WORKS=true -DLLVM_ENABLE_PROJECTS="clang;lld" -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_LIBCXX=true -DLLVM_HOST_TRIPLE=aarch64-unknown-linux-gnu -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-uefi-llvm -DCMAKE_INSTALL_LIBDIR=build/target/lib
$ ninja -C build

@llvmbot llvmbot added the libc label Mar 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 14, 2025

@llvm/pr-subscribers-libc

Author: Tristan Ross (RossComputerGuy)

Changes

Initial UEFI OS target support after the headers. This just defines enough that stuff might try and compile. Test with:

$ cmake -S llvm -B build -G Ninja -DLLVM_RUNTIME_TARGETS=x86_64-unknown-uefi-llvm -DRUNTIMES_x86_64-unknown-uefi-llvm_LLVM_ENABLE_RUNTIMES=libc -DRUNTIMES_x86_64-unknown-uefi-llvm_LLVM_LIBC_FULL_BUILD=true -DCMAKE_C_COMPILER_WORKS=true -DCMAKE_CXX_COMPILER_WORKS=true -DLLVM_ENABLE_PROJECTS="clang;lld" -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_LIBCXX=true -DLLVM_HOST_TRIPLE=aarch64-unknown-linux-gnu -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-uefi-llvm -DCMAKE_INSTALL_LIBDIR=build/target/lib
$ ninja -C build

Full diff: https://github.com/llvm/llvm-project/pull/131246.diff

11 Files Affected:

  • (modified) libc/cmake/modules/LLVMLibCArchitectures.cmake (+2)
  • (added) libc/config/uefi/config.json (+7)
  • (added) libc/config/uefi/entrypoints.txt (+11)
  • (added) libc/config/uefi/headers.txt (+4)
  • (modified) libc/include/Uefi.yaml (+2-1)
  • (modified) libc/src/__support/OSUtil/io.h (+2)
  • (added) libc/src/__support/OSUtil/uefi/CMakeLists.txt (+11)
  • (added) libc/src/__support/OSUtil/uefi/exit.cpp (+23)
  • (added) libc/src/__support/OSUtil/uefi/io.cpp (+36)
  • (added) libc/src/__support/OSUtil/uefi/io.h (+25)
  • (modified) libc/utils/hdrgen/hdrgen/header.py (+1)
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index b94534bb00980..62f3a2e3bdb59 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -191,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 0000000000000..51aa8fecf8b30
--- /dev/null
+++ b/libc/config/uefi/config.json
@@ -0,0 +1,7 @@
+{
+  "errno": {
+    "LIBC_CONF_ERRNO_MODE": {
+      "value": "LIBC_ERRNO_MODE_SHARED"
+    }
+  }
+}
diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt
new file mode 100644
index 0000000000000..2e11c534a4f3b
--- /dev/null
+++ b/libc/config/uefi/entrypoints.txt
@@ -0,0 +1,11 @@
+set(TARGET_LIBC_ENTRYPOINTS
+    # errno.h entrypoints
+    libc.src.errno.errno
+)
+
+set(TARGET_LIBM_ENTRYPOINTS)
+
+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 0000000000000..a8e7b5bc5e37b
--- /dev/null
+++ b/libc/config/uefi/headers.txt
@@ -0,0 +1,4 @@
+set(TARGET_PUBLIC_HEADERS
+    libc.include.errno
+    libc.include.uefi
+)
diff --git a/libc/include/Uefi.yaml b/libc/include/Uefi.yaml
index 28582eb2524b1..9f38ff3f4a497 100644
--- a/libc/include/Uefi.yaml
+++ b/libc/include/Uefi.yaml
@@ -1,5 +1,6 @@
 header: Uefi.h
-standards: UEFI
+standards:
+  - uefi
 macros: []
 types:
   - type_name: EFI_BOOT_SERVICES
diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h
index 80119da77fc02..66af31f3cc8c6 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 0000000000000..79ec8ab602456
--- /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 0000000000000..96bf818ad304a
--- /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"
+#include "include/llvm-libc-macros/stdlib-macros.h"
+#include "include/Uefi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+[[noreturn]] void exit(int status) {
+  efi_system_table->BootServices->Exit(efi_image_handle, status, 0, NULL);
+  __builtin_unreachable();
+}
+
+} // 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 0000000000000..756c5aaf8f452
--- /dev/null
+++ b/libc/src/__support/OSUtil/uefi/io.cpp
@@ -0,0 +1,36 @@
+//===---------- 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) { return 0; }
+
+void write_to_stdout(cpp::string_view msg) {
+  // TODO: use mbstowcs once implemented
+  for (size_t i = 0; i < msg.size(); i++) {
+    char16_t e[2] = {msg[i], 0};
+    efi_system_table->ConOut->OutputString(
+        efi_system_table->ConOut, reinterpret_cast<const char16_t *>(&e));
+  }
+}
+
+void write_to_stderr(cpp::string_view msg) {
+  // TODO: use mbstowcs once implemented
+  for (size_t i = 0; i < msg.size(); i++) {
+    char16_t e[2] = {msg[i], 0};
+    efi_system_table->StdErr->OutputString(
+        efi_system_table->StdErr, reinterpret_cast<const char16_t *>(&e));
+  }
+}
+
+} // 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 0000000000000..088ae09b8c602
--- /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/utils/hdrgen/hdrgen/header.py b/libc/utils/hdrgen/hdrgen/header.py
index 11e0234eda1cf..78444ed377be1 100644
--- a/libc/utils/hdrgen/hdrgen/header.py
+++ b/libc/utils/hdrgen/hdrgen/header.py
@@ -43,6 +43,7 @@
     "bsd": "BSD",
     "gnu": "GNU",
     "linux": "Linux",
+    "uefi": "UEFI",
 }
 
 HEADER_TEMPLATE = """\

Copy link

github-actions bot commented Mar 14, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@lntue lntue requested a review from frobtech March 14, 2025 01:47
namespace internal {

[[noreturn]] void exit(int status) {
efi_system_table->BootServices->Exit(efi_image_handle, status, 0, NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullptr instead of NULL

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine for now, but you need to get a buildbot ready before it lands.

@RossComputerGuy
Copy link
Member Author

How would one do that? Also, we cannot natively build in UEFI until someone writes a compiler that can run in UEFI lol.

@lntue
Copy link
Contributor

lntue commented Mar 14, 2025

This looks fine for now, but you need to get a buildbot ready before it lands.

I think for new targets like this, it's ok as long as there is a plan for a buildbot setup in the near future.
Essentially, these initial commits are needed in order to setting up a CI for the targets.

@RossComputerGuy
Copy link
Member Author

Yeah, I think we need to be able to essentially bootstrap a toolchain for UEFI by doing a cross compile of LLVM components. We can certainly set up the pre-commits to at least try and compile things.

@michaelrj-google
Copy link
Contributor

Here's the relevant policy: https://libc.llvm.org/porting.html#id5

You don't need a native UEFI builder, as long as you can provide a cmake command it should be straightforward to add it to one of our existing builders in the config: https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/annotated/libc-linux.py

@michaelrj-google
Copy link
Contributor

This looks fine for now, but you need to get a buildbot ready before it lands.

I think for new targets like this, it's ok as long as there is a plan for a buildbot setup in the near future. Essentially, these initial commits are needed in order to setting up a CI for the targets.

I'm fine with just having a plan, but that plan needs to be ready before the target lands. If we put off testing, it has a tendency to get forgotten.

@RossComputerGuy
Copy link
Member Author

Gotcha, yeah I might need some additional guidance on getting it set up. I'm very much open to having buildbots.

@lntue
Copy link
Contributor

lntue commented Mar 14, 2025

Here's the relevant policy: https://libc.llvm.org/porting.html#id5

You don't need a native UEFI builder, as long as you can provide a cmake command it should be straightforward to add it to one of our existing builders in the config: https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/annotated/libc-linux.py

Adding a build-only precommit one right after landing this SGTM.

@RossComputerGuy
Copy link
Member Author

Adding a build-only precommit one right after landing this SGTM.

That will be #131376

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for getting that set up

@RossComputerGuy RossComputerGuy merged commit bb69499 into llvm:main Mar 15, 2025
16 checks passed
@RossComputerGuy RossComputerGuy deleted the feat/uefi-target-init branch March 15, 2025 03:15
RossComputerGuy added a commit that referenced this pull request Mar 16, 2025
Adds documentation for the UEFI target since #131246 was merged.
RossComputerGuy added a commit that referenced this pull request Apr 30, 2025
Comes after #131246 to enable UEFI being build. Skips tests until we
have set up testing.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Comes after llvm#131246 to enable UEFI being build. Skips tests until we
have set up testing.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Comes after llvm#131246 to enable UEFI being build. Skips tests until we
have set up testing.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Comes after llvm#131246 to enable UEFI being build. Skips tests until we
have set up testing.
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
Comes after llvm#131246 to enable UEFI being build. Skips tests until we
have set up testing.
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
Comes after llvm#131246 to enable UEFI being build. Skips tests until we
have set up testing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants