Skip to content

[libc] Provide baremetal implementation of getchar #98059

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 3 commits into from
Jul 9, 2024

Conversation

petrhosek
Copy link
Member

This introduces opaque type struct __llvm_libc_stdin and a symbol __llvm_libc_stdin_read that's intended to be provided by the vendor.

__llvm_libc_stdin_read intentionally has the same signature as cookie_read_function_t so it can be used with fopencookie to represent stdin as FILE * in the future.

This introduces opaque type `struct __llvm_libc_stdin` and a symbol
`__llvm_libc_stdin_read` that's intended to be provided by the vendor.

`__llvm_libc_stdin_read` intentionally has the same signature as
`cookie_read_function_t` so it can be used with `fopencookie` to
represent `stdin` as `FILE *` in the future.
@llvmbot
Copy link
Member

llvmbot commented Jul 8, 2024

@llvm/pr-subscribers-libc

Author: Petr Hosek (petrhosek)

Changes

This introduces opaque type struct __llvm_libc_stdin and a symbol __llvm_libc_stdin_read that's intended to be provided by the vendor.

__llvm_libc_stdin_read intentionally has the same signature as cookie_read_function_t so it can be used with fopencookie to represent stdin as FILE * in the future.


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

6 Files Affected:

  • (modified) libc/config/baremetal/arm/entrypoints.txt (+1)
  • (modified) libc/config/baremetal/riscv/entrypoints.txt (+1)
  • (modified) libc/src/__support/OSUtil/baremetal/io.cpp (+8)
  • (modified) libc/src/__support/OSUtil/baremetal/io.h (+3)
  • (modified) libc/src/stdio/baremetal/CMakeLists.txt (+11)
  • (added) libc/src/stdio/baremetal/getchar.cpp (+24)
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 11f560ed2b90f..e613905fdf3d5 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -83,6 +83,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.inttypes.strtoumax
 
     # stdio.h entrypoints
+    libc.src.stdio.getchar
     libc.src.stdio.printf
     libc.src.stdio.putchar
     libc.src.stdio.remove
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index f203317e2839d..bb25991665212 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -79,6 +79,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.inttypes.strtoumax
 
     # stdio.h entrypoints
+    libc.src.stdio.getchar
     libc.src.stdio.printf
     libc.src.stdio.putchar
     libc.src.stdio.remove
diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp
index 347c7d405b0a9..0b81903a99f7e 100644
--- a/libc/src/__support/OSUtil/baremetal/io.cpp
+++ b/libc/src/__support/OSUtil/baremetal/io.cpp
@@ -11,10 +11,18 @@
 #include "src/__support/CPP/string_view.h"
 
 // This is intended to be provided by the vendor.
+
+extern struct __llvm_libc_stdin __llvm_libc_stdin;
+extern "C" ssize_t __llvm_libc_stdin_read(void *cookie, char *buf, size_t size);
+
 extern "C" void __llvm_libc_log_write(const char *msg, size_t len);
 
 namespace LIBC_NAMESPACE {
 
+ssize_t read_from_stdin(char *buf, size_t size) {
+  return __llvm_libc_stdin_read(static_cast<void*>(&__llvm_libc_stdin), buf, size);
+}
+
 void write_to_stderr(cpp::string_view msg) {
   __llvm_libc_log_write(msg.data(), msg.size());
 }
diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h
index 87534641b1fa4..b9ae0bde502be 100644
--- a/libc/src/__support/OSUtil/baremetal/io.h
+++ b/libc/src/__support/OSUtil/baremetal/io.h
@@ -9,10 +9,13 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_IO_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_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"
 
 namespace LIBC_NAMESPACE {
 
+ssize_t read_from_stdin(char *buf, size_t size);
 void write_to_stderr(cpp::string_view msg);
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdio/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt
index 45196ffc9de24..27b8e8444d8ef 100644
--- a/libc/src/stdio/baremetal/CMakeLists.txt
+++ b/libc/src/stdio/baremetal/CMakeLists.txt
@@ -1,3 +1,14 @@
+add_entrypoint_object(
+  getchar
+  SRCS
+    getchar.cpp
+  HDRS
+    ../getchar.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.CPP.string_view
+)
+
 add_entrypoint_object(
   remove
   SRCS
diff --git a/libc/src/stdio/baremetal/getchar.cpp b/libc/src/stdio/baremetal/getchar.cpp
new file mode 100644
index 0000000000000..bbd5ba7a954fb
--- /dev/null
+++ b/libc/src/stdio/baremetal/getchar.cpp
@@ -0,0 +1,24 @@
+//===-- Baremetal 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/OSUtil/io.h"
+
+#include <stdio.h>
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, getchar, ()) {
+  char buf[1];
+  auto result = read_from_stdin(buf, sizeof(buf));
+  if (result < 0)
+    return EOF;
+  return buf[0];
+}
+
+} // namespace LIBC_NAMESPACE

Copy link

github-actions bot commented Jul 8, 2024

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

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

extern "C" void __llvm_libc_log_write(const char *msg, size_t len);

namespace LIBC_NAMESPACE {

ssize_t read_from_stdin(char *buf, size_t size) {
return __llvm_libc_stdin_read(static_cast<void *>(&__llvm_libc_stdin), buf,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this should probably be a reinterpret_cast instead of static_cast

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

@petrhosek petrhosek merged commit cfa2d7d into llvm:main Jul 9, 2024
4 of 5 checks passed
@petrhosek petrhosek deleted the libc-baremetal-getchar branch July 9, 2024 08:55
aaryanshukla pushed a commit to aaryanshukla/llvm-project that referenced this pull request Jul 14, 2024
This introduces opaque type `struct __llvm_libc_stdin` and a symbol
`__llvm_libc_stdin_read` that's intended to be provided by the vendor.

`__llvm_libc_stdin_read` intentionally has the same signature as
`cookie_read_function_t` so it can be used with `fopencookie` to
represent `stdin` as `FILE *` in the future.
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.

4 participants