Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libc/config/baremetal/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ set(TARGET_LIBC_ENTRYPOINTS

# stdio.h entrypoints
libc.src.stdio.asprintf
libc.src.stdio.fopencookie
libc.src.stdio.fprintf
libc.src.stdio.getchar
libc.src.stdio.printf
libc.src.stdio.putchar
Expand Down
2 changes: 2 additions & 0 deletions libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ set(TARGET_LIBC_ENTRYPOINTS

# stdio.h entrypoints
libc.src.stdio.asprintf
libc.src.stdio.fopencookie
libc.src.stdio.fprintf
libc.src.stdio.getchar
libc.src.stdio.printf
libc.src.stdio.putchar
Expand Down
2 changes: 2 additions & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ set(TARGET_LIBC_ENTRYPOINTS

# stdio.h entrypoints
libc.src.stdio.asprintf
libc.src.stdio.fopencookie
libc.src.stdio.fprintf
libc.src.stdio.getchar
libc.src.stdio.printf
libc.src.stdio.putchar
Expand Down
27 changes: 23 additions & 4 deletions libc/src/__support/File/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ add_object_library(
libc.src.__support.error_or
)

add_header_library(
cookie_file
HDRS
cookie_file.h
DEPENDS
.file
libc.hdr.errno_macros
libc.hdr.types.cookie_io_functions_t
libc.hdr.types.off_t
libc.src.__support.CPP.new
)

add_object_library(
dir
SRCS
Expand All @@ -41,10 +53,17 @@ endif()

add_subdirectory(${LIBC_TARGET_OS})

set(target_file libc.src.__support.File.${LIBC_TARGET_OS}.file)
set(target_stdout libc.src.__support.File.${LIBC_TARGET_OS}.stdout)
set(target_stderr libc.src.__support.File.${LIBC_TARGET_OS}.stderr)
set(target_stdin libc.src.__support.File.${LIBC_TARGET_OS}.stdin)
if(LIBC_TARGET_OS_IS_BAREMETAL)
set(target_file libc.src.__support.File.cookie_file)
set(target_stdout libc.src.__support.File.${LIBC_TARGET_OS}.stderr)
set(target_stderr libc.src.__support.File.${LIBC_TARGET_OS}.stderr)
set(target_stdin libc.src.__support.File.${LIBC_TARGET_OS}.stderr)
else()
set(target_file libc.src.__support.File.${LIBC_TARGET_OS}.file)
set(target_stdout libc.src.__support.File.${LIBC_TARGET_OS}.stdout)
set(target_stderr libc.src.__support.File.${LIBC_TARGET_OS}.stderr)
set(target_stdin libc.src.__support.File.${LIBC_TARGET_OS}.stdin)
endif()

set(file_targets "${target_file};${target_stdout};${target_stdin};${target_stderr}")
set(file_aliases "platform_file;platform_stdout;platform_stdin;platform_stderr")
Expand Down
10 changes: 10 additions & 0 deletions libc/src/__support/File/baremetal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_object_library(
stderr
SRCS
stderr.cpp
DEPENDS
libc.hdr.stdio_macros
libc.src.__support.File.cookie_file
libc.src.__support.File.file
libc.src.__support.OSUtil.osutil
)
38 changes: 38 additions & 0 deletions libc/src/__support/File/baremetal/stderr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===--- Definition of baremetal stderr -----------------------------------===//
//
// 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 "hdr/stdio_macros.h"
#include "src/__support/File/cookie_file.h"
#include "src/__support/File/file.h"
#include "src/__support/OSUtil/baremetal/io.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

// To save space, all streams are aliased to one stream. Furthermore, no
// buffering is used.
cookie_io_functions_t io_func = {.read = __llvm_libc_stdio_read,
.write = __llvm_libc_stdio_write,
.seek = nullptr,
.close = nullptr};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
static CookieFile StdErr(&__llvm_libc_stderr_cookie, io_func, nullptr, 0,
_IONBF, File::mode_flags("r+"));
#pragma clang diagnostic pop
File *stderr = &StdErr;
File *stdin = &StdErr;
File *stdout = &StdErr;

} // namespace LIBC_NAMESPACE_DECL

extern "C" {
FILE *stderr = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdErr);
FILE *stdin = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdErr);
FILE *stdout = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::StdErr);
}
75 changes: 75 additions & 0 deletions libc/src/__support/File/cookie_file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===--- A platform independent cookie file class -------------------------===//
//
// 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 "hdr/errno_macros.h"
#include "hdr/types/cookie_io_functions_t.h"
#include "hdr/types/off_t.h"
#include "src/__support/CPP/new.h"
#include "src/__support/File/file.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

class CookieFile : public LIBC_NAMESPACE::File {
void *cookie;
cookie_io_functions_t ops;

static FileIOResult cookie_write(File *f, const void *data, size_t size);
static FileIOResult cookie_read(File *f, void *data, size_t size);
static ErrorOr<off_t> cookie_seek(File *f, off_t offset, int whence);
static int cookie_close(File *f);

public:
CookieFile(void *c, cookie_io_functions_t cops, uint8_t *buffer,
size_t bufsize, int buffer_mode, File::ModeFlags mode)
: File(&cookie_write, &cookie_read, &CookieFile::cookie_seek,
&cookie_close, buffer, bufsize, buffer_mode,
true /* File owns buffer */, mode),
cookie(c), ops(cops) {}
};

FileIOResult CookieFile::cookie_write(File *f, const void *data, size_t size) {
auto cookie_file = reinterpret_cast<CookieFile *>(f);
if (cookie_file->ops.write == nullptr)
return 0;
return static_cast<size_t>(cookie_file->ops.write(
cookie_file->cookie, reinterpret_cast<const char *>(data), size));
}

FileIOResult CookieFile::cookie_read(File *f, void *data, size_t size) {
auto cookie_file = reinterpret_cast<CookieFile *>(f);
if (cookie_file->ops.read == nullptr)
return 0;
return static_cast<size_t>(cookie_file->ops.read(
cookie_file->cookie, reinterpret_cast<char *>(data), size));
}

ErrorOr<off_t> CookieFile::cookie_seek(File *f, off_t offset, int whence) {
auto cookie_file = reinterpret_cast<CookieFile *>(f);
if (cookie_file->ops.seek == nullptr) {
return Error(EINVAL);
}
off64_t offset64 = offset;
int result = cookie_file->ops.seek(cookie_file->cookie, &offset64, whence);
if (result == 0)
return offset64;
return -1;
}

int CookieFile::cookie_close(File *f) {
auto cookie_file = reinterpret_cast<CookieFile *>(f);
if (cookie_file->ops.close == nullptr)
return 0;
int retval = cookie_file->ops.close(cookie_file->cookie);
if (retval != 0)
return retval;
delete cookie_file;
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
39 changes: 0 additions & 39 deletions libc/src/__support/OSUtil/baremetal/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,6 @@

namespace LIBC_NAMESPACE_DECL {

// 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.

struct __llvm_libc_stdio_cookie;

extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
extern "C" 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_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie),
buf, size);
Expand Down
38 changes: 38 additions & 0 deletions libc/src/__support/OSUtil/baremetal/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,46 @@
#include "src/__support/CPP/string_view.h"
#include "src/__support/macros/config.h"

// 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.
namespace LIBC_NAMESPACE_DECL {

struct __llvm_libc_stdio_cookie;

extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
extern "C" 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);
void write_to_stderr(cpp::string_view msg);
void write_to_stdout(cpp::string_view msg);
Expand Down
1 change: 1 addition & 0 deletions libc/src/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ add_entrypoint_object(
libc.hdr.types.cookie_io_functions_t
libc.hdr.types.FILE
libc.src.__support.CPP.new
libc.src.__support.File.cookie_file
libc.src.__support.File.file
)

Expand Down
96 changes: 0 additions & 96 deletions libc/src/stdio/baremetal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
add_entrypoint_object(
getchar
SRCS
getchar.cpp
HDRS
../getchar.h
DEPENDS
libc.hdr.stdio_macros
libc.src.__support.OSUtil.osutil
libc.src.__support.CPP.string_view
)

add_entrypoint_object(
remove
SRCS
Expand All @@ -19,87 +7,3 @@ add_entrypoint_object(
DEPENDS
libc.include.stdio
)

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
)

add_entrypoint_object(
puts
SRCS
puts.cpp
HDRS
../puts.h
DEPENDS
libc.src.__support.OSUtil.osutil
libc.src.__support.CPP.string_view
)

add_header_library(
scanf_internal
HDRS
scanf_internal.h
DEPENDS
libc.src.stdio.scanf_core.reader
libc.src.__support.OSUtil.osutil
)

add_entrypoint_object(
scanf
SRCS
scanf.cpp
HDRS
../scanf.h
DEPENDS
.scanf_internal
libc.include.inttypes
libc.src.stdio.scanf_core.scanf_main
libc.src.__support.arg_list
libc.src.__support.OSUtil.osutil
)

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
)

add_entrypoint_object(
vscanf
SRCS
vscanf.cpp
HDRS
../vscanf.h
DEPENDS
.scanf_internal
libc.src.stdio.scanf_core.scanf_main
libc.src.__support.arg_list
libc.src.__support.OSUtil.osutil
)
Loading
Loading