[libc-commits] [libc] [libc] Extend the baremetal I/O vendor ABI (PR #98683)

Petr Hosek via libc-commits libc-commits at lists.llvm.org
Sun Jul 14 13:23:41 PDT 2024


https://github.com/petrhosek updated https://github.com/llvm/llvm-project/pull/98683

>From 57cf707b51dc7e261d866c21cb554c04a14d6ddb Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Fri, 12 Jul 2024 10:51:59 -0700
Subject: [PATCH 1/3] [libc] Extend the baremetal I/O vendor ABI

This refines and extends the external ABI for I/O, later changes will
update the baremetal implementations of I/O functions to use these.
---
 libc/src/__support/OSUtil/baremetal/io.cpp | 43 +++++++++++++++++++---
 libc/src/__support/OSUtil/baremetal/io.h   |  1 +
 2 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp
index c97bd5ae65b13..bd5946f267328 100644
--- a/libc/src/__support/OSUtil/baremetal/io.cpp
+++ b/libc/src/__support/OSUtil/baremetal/io.cpp
@@ -12,20 +12,51 @@
 
 namespace LIBC_NAMESPACE {
 
-// This is intended to be provided by the vendor.
+// These are intended to be provided by the vendor.
+//
+// The signature of these types and functions intentionally match `fopencookie`
+// which allows the following:
+//
+// ```
+// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
+// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read };
+// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func);
+// ...
+// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
+// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
+// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func);
+// ...
+// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
+// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
+// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func);
+// ```
+//
+// At the same time, implementation of functions like `printf` and `scanf` can
+// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid
+// the extra indirection.
 
-extern struct __llvm_libc_stdin __llvm_libc_stdin;
-extern "C" ssize_t __llvm_libc_stdin_read(void *cookie, char *buf, size_t size);
+struct __llvm_libc_stdio_cookie;
 
-extern "C" void __llvm_libc_log_write(const char *msg, size_t len);
+extern struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
+extern struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
+extern struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
+
+extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size);
+extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, size_t size);
 
 ssize_t read_from_stdin(char *buf, size_t size) {
-  return __llvm_libc_stdin_read(reinterpret_cast<void *>(&__llvm_libc_stdin),
+  return __llvm_libc_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie),
                                 buf, size);
 }
 
+void write_to_stdout(cpp::string_view msg) {
+  __llvm_libc_stdio_write(static_cast<void *>(&__llvm_libc_stdout_cookie),
+                                 msg.data(), msg.size());
+}
+
 void write_to_stderr(cpp::string_view msg) {
-  __llvm_libc_log_write(msg.data(), msg.size());
+  __llvm_libc_stdio_write(static_cast<void *>(&__llvm_libc_stderr_cookie),
+                                 msg.data(), msg.size());
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h
index b9ae0bde502be..95e8277860a82 100644
--- a/libc/src/__support/OSUtil/baremetal/io.h
+++ b/libc/src/__support/OSUtil/baremetal/io.h
@@ -17,6 +17,7 @@ namespace LIBC_NAMESPACE {
 
 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
 

>From efc4e87862168cbc203644ded6fab3a61b628ccb Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Fri, 12 Jul 2024 12:19:09 -0700
Subject: [PATCH 2/3] Fix formatting

---
 libc/src/__support/OSUtil/baremetal/io.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp
index bd5946f267328..6d024443de647 100644
--- a/libc/src/__support/OSUtil/baremetal/io.cpp
+++ b/libc/src/__support/OSUtil/baremetal/io.cpp
@@ -27,7 +27,7 @@ namespace LIBC_NAMESPACE {
 // FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func);
 // ...
 // struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
-// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
+// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write };
 // FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func);
 // ```
 //
@@ -42,7 +42,8 @@ extern struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
 extern struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
 
 extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size);
-extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, size_t size);
+extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
+                                           size_t size);
 
 ssize_t read_from_stdin(char *buf, size_t size) {
   return __llvm_libc_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie),
@@ -51,12 +52,12 @@ ssize_t read_from_stdin(char *buf, size_t size) {
 
 void write_to_stdout(cpp::string_view msg) {
   __llvm_libc_stdio_write(static_cast<void *>(&__llvm_libc_stdout_cookie),
-                                 msg.data(), msg.size());
+                          msg.data(), msg.size());
 }
 
 void write_to_stderr(cpp::string_view msg) {
   __llvm_libc_stdio_write(static_cast<void *>(&__llvm_libc_stderr_cookie),
-                                 msg.data(), msg.size());
+                          msg.data(), msg.size());
 }
 
 } // namespace LIBC_NAMESPACE

>From 04ced5c3027b2e8783c57f1fa45c974c70ca1692 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Sat, 13 Jul 2024 11:02:01 -0700
Subject: [PATCH 3/3] Update comment

---
 libc/src/__support/OSUtil/baremetal/io.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp
index 6d024443de647..d7287f297d7e6 100644
--- a/libc/src/__support/OSUtil/baremetal/io.cpp
+++ b/libc/src/__support/OSUtil/baremetal/io.cpp
@@ -18,6 +18,8 @@ namespace LIBC_NAMESPACE {
 // which allows the following:
 //
 // ```
+// struct __llvm_libc_stdio_cookie { ... };
+// ...
 // struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
 // cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read };
 // FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func);
@@ -34,6 +36,10 @@ namespace LIBC_NAMESPACE {
 // At the same time, implementation of functions like `printf` and `scanf` can
 // use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid
 // the extra indirection.
+//
+// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`,
+// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point
+// at anything.
 
 struct __llvm_libc_stdio_cookie;
 



More information about the libc-commits mailing list