-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Extend the baremetal I/O vendor ABI #98683
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,20 +12,58 @@ | |
|
||
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 { ... }; | ||
// ... | ||
// 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 stderr_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. | ||
// | ||
// 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. | ||
|
||
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), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The cast is superfluous but does no harm. |
||
buf, size); | ||
} | ||
|
||
void write_to_stdout(cpp::string_view msg) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should change these to propagate return values, and leave it to the embedder to decide if they want to return apparent success in error (or bit-bucket) cases. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, but I'd like to do that in a follow-up change since I'll also need to update the callers. |
||
__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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the comments here need to be a bit more clear that these three symbols must be provided, even if they don't point at anything, and give examples of how to meet the ABI.
All these declarations belong in some header file. Eventually such a header file should be installed somewhere so embedders can use it for the ABI contract they're meeting. But that can be a later cleanup, a comment here is enough for now.