Skip to content

Commit 254fcd4

Browse files
[libc] work on puts in uefi
1 parent 7af3dfe commit 254fcd4

File tree

15 files changed

+399
-18
lines changed

15 files changed

+399
-18
lines changed

libc/config/uefi/entrypoints.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ set(TARGET_LIBC_ENTRYPOINTS
152152
libc.src.stdbit.stdc_trailing_zeros_ull
153153
libc.src.stdbit.stdc_trailing_zeros_us
154154

155+
# stdio.h entrypoints
156+
libc.src.stdio.getchar
157+
libc.src.stdio.printf
158+
libc.src.stdio.putchar
159+
libc.src.stdio.puts
160+
libc.src.stdio.snprintf
161+
libc.src.stdio.sprintf
162+
libc.src.stdio.asprintf
163+
libc.src.stdio.vprintf
164+
libc.src.stdio.vsnprintf
165+
libc.src.stdio.vsprintf
166+
libc.src.stdio.vasprintf
167+
155168
# stdlib.h entrypoints
156169
libc.src.stdlib._Exit
157170
libc.src.stdlib.abort

libc/config/uefi/headers.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(TARGET_PUBLIC_HEADERS
1010
libc.include.setjmp
1111
libc.include.stdfix
1212
libc.include.stdint
13+
libc.include.stdio
1314
libc.include.stdlib
1415
libc.include.string
1516
libc.include.strings

libc/include/llvm-libc-types/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,9 @@ add_header(EFI_SIMPLE_TEXT_INPUT_PROTOCOL
217217
HDR
218218
EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h
219219
DEPENDS
220+
libc.include.llvm-libc-macros.EFIAPI_macros
220221
libc.include.llvm-libc-macros.stdint_macros
222+
.EFI_EVENT
221223
.EFI_STATUS
222224
.char16_t
223225
)

libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#ifndef LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
1010
#define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H
1111

12+
#include "../llvm-libc-macros/EFIAPI-macros.h"
1213
#include "../llvm-libc-macros/stdint-macros.h"
14+
#include "EFI_EVENT.h"
1315
#include "EFI_STATUS.h"
1416
#include "char16_t.h"
1517

libc/src/__support/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ add_subdirectory(StringUtil)
359359
add_subdirectory(GPU)
360360
add_subdirectory(RPC)
361361

362+
if(LIBC_TARGET_OS_IS_UEFI)
363+
add_subdirectory(UEFI)
364+
endif()
365+
362366
# Thread support is used by other "File". So, we add the "threads"
363367
# before "File".
364368
add_subdirectory(threads)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
add_object_library(
2+
file
3+
SRCS
4+
file.cpp
5+
HDRS
6+
file.h
7+
DEPENDS
8+
libc.include.uefi
9+
libc.hdr.types.FILE
10+
libc.src.__support.CPP.new
11+
)

libc/src/__support/UEFI/file.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include "file.h"
2+
#include "hdr/types/FILE.h"
3+
#include "src/__support/macros/config.h"
4+
#include <Uefi.h>
5+
6+
#define STDIN_FILENO 0
7+
#define STDOUT_FILENO 1
8+
#define STDERR_FILENO 2
9+
10+
namespace LIBC_NAMESPACE_DECL {
11+
bool File::needsReset() { return handle_type == FileHandleId; }
12+
13+
void File::reset() {
14+
if (handle_type != FileHandleId)
15+
return;
16+
17+
if (handle.id == STDIN_FILENO) {
18+
handle = (FileHandle){
19+
.simple_text_input = efi_system_table->ConIn,
20+
};
21+
handle_type = FileHandleSimpleTextInput;
22+
} else {
23+
handle = (FileHandle){
24+
.simple_text_output = handle.id == STDERR_FILENO
25+
? efi_system_table->StdErr
26+
: efi_system_table->ConOut,
27+
};
28+
handle_type = FileHandleSimpleTextOutput;
29+
}
30+
}
31+
32+
size_t File::write(const void *data, size_t data_len) {
33+
if (needsReset())
34+
reset();
35+
36+
if (handle_type == FileHandleSimpleTextOutput) {
37+
handle.simple_text_output->OutputString(
38+
handle.simple_text_output, reinterpret_cast<const char16_t *>(data));
39+
return data_len;
40+
}
41+
return 0;
42+
}
43+
44+
File stdin(
45+
(FileHandle){
46+
.id = STDIN_FILENO,
47+
},
48+
FileHandleId);
49+
50+
File stdout(
51+
(FileHandle){
52+
.id = STDOUT_FILENO,
53+
},
54+
FileHandleId);
55+
56+
File stderr(
57+
(FileHandle){
58+
.id = STDERR_FILENO,
59+
},
60+
FileHandleId);
61+
} // namespace LIBC_NAMESPACE_DECL
62+
63+
extern "C" {
64+
FILE *stdin = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stdin);
65+
FILE *stdout = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stdout);
66+
FILE *stderr = reinterpret_cast<FILE *>(&LIBC_NAMESPACE::stderr);
67+
}

libc/src/__support/UEFI/file.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H
2+
#define LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H
3+
4+
#include "include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h"
5+
#include "include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h"
6+
#include "src/__support/CPP/new.h"
7+
#include "src/__support/macros/config.h"
8+
9+
namespace LIBC_NAMESPACE_DECL {
10+
11+
enum FileHandleType {
12+
FileHandleId,
13+
FileHandleSimpleTextInput,
14+
FileHandleSimpleTextOutput,
15+
};
16+
17+
union FileHandle {
18+
int id;
19+
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *simple_text_input;
20+
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *simple_text_output;
21+
};
22+
23+
class File {
24+
FileHandle handle;
25+
FileHandleType handle_type;
26+
27+
private:
28+
bool needsReset();
29+
30+
public:
31+
constexpr File(FileHandle handle, FileHandleType handle_type)
32+
: handle(handle), handle_type(handle_type) {}
33+
34+
void reset();
35+
36+
size_t read(void *data, size_t len);
37+
size_t write(const void *data, size_t len);
38+
};
39+
40+
extern File stdin;
41+
extern File stdout;
42+
extern File stderr;
43+
44+
} // namespace LIBC_NAMESPACE_DECL
45+
46+
#endif // LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H

libc/src/stdio/CMakeLists.txt

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -240,26 +240,28 @@ add_entrypoint_object(
240240
add_subdirectory(printf_core)
241241
add_subdirectory(scanf_core)
242242

243-
add_entrypoint_object(
244-
remove
245-
ALIAS
246-
DEPENDS
247-
.${LIBC_TARGET_OS}.remove
248-
)
243+
if(NOT LIBC_TARGET_OS_IS_UEFI)
244+
add_entrypoint_object(
245+
remove
246+
ALIAS
247+
DEPENDS
248+
.${LIBC_TARGET_OS}.remove
249+
)
249250

250-
add_entrypoint_object(
251-
rename
252-
ALIAS
253-
DEPENDS
254-
.${LIBC_TARGET_OS}.rename
255-
)
251+
add_entrypoint_object(
252+
rename
253+
ALIAS
254+
DEPENDS
255+
.${LIBC_TARGET_OS}.rename
256+
)
256257

257-
add_entrypoint_object(
258-
fdopen
259-
ALIAS
260-
DEPENDS
261-
.${LIBC_TARGET_OS}.fdopen
262-
)
258+
add_entrypoint_object(
259+
fdopen
260+
ALIAS
261+
DEPENDS
262+
.${LIBC_TARGET_OS}.fdopen
263+
)
264+
endif()
263265

264266
# These entrypoints have multiple potential implementations.
265267
add_stdio_entrypoint_object(feof)

libc/src/stdio/uefi/CMakeLists.txt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
add_entrypoint_object(
2+
getchar
3+
SRCS
4+
getchar.cpp
5+
HDRS
6+
../getchar.h
7+
DEPENDS
8+
libc.hdr.stdio_macros
9+
libc.src.__support.UEFI.file
10+
)
11+
12+
add_entrypoint_object(
13+
printf
14+
SRCS
15+
printf.cpp
16+
HDRS
17+
../printf.h
18+
DEPENDS
19+
libc.src.stdio.printf_core.printf_main
20+
libc.src.stdio.printf_core.writer
21+
libc.src.__support.arg_list
22+
libc.src.__support.OSUtil.osutil
23+
)
24+
25+
add_entrypoint_object(
26+
putchar
27+
SRCS
28+
putchar.cpp
29+
HDRS
30+
../putchar.h
31+
DEPENDS
32+
libc.src.__support.OSUtil.osutil
33+
libc.src.__support.CPP.string_view
34+
libc.src.__support.UEFI.file
35+
)
36+
37+
add_entrypoint_object(
38+
puts
39+
SRCS
40+
puts.cpp
41+
HDRS
42+
../puts.h
43+
DEPENDS
44+
libc.src.__support.UEFI.file
45+
libc.src.string.strlen
46+
)
47+
48+
add_entrypoint_object(
49+
vprintf
50+
SRCS
51+
vprintf.cpp
52+
HDRS
53+
../vprintf.h
54+
DEPENDS
55+
libc.src.stdio.printf_core.printf_main
56+
libc.src.stdio.printf_core.writer
57+
libc.src.__support.arg_list
58+
libc.src.__support.OSUtil.osutil
59+
)

libc/src/stdio/uefi/getchar.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Implementation of getchar -----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/getchar.h"
10+
#include "src/__support/UEFI/file.h"
11+
12+
#include "hdr/stdio_macros.h" // for EOF.
13+
#include "hdr/types/FILE.h"
14+
#include "src/__support/macros/config.h"
15+
#include "src/errno/libc_errno.h"
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
LLVM_LIBC_FUNCTION(int, getchar, ()) {
20+
unsigned char c;
21+
if (stdin.read(&c, 1) != 1)
22+
return EOF;
23+
return c;
24+
}
25+
26+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/uefi/printf.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===-- Implementation of printf for baremetal ------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/printf.h"
10+
#include "src/__support/OSUtil/io.h"
11+
#include "src/__support/arg_list.h"
12+
#include "src/__support/macros/config.h"
13+
#include "src/stdio/printf_core/core_structs.h"
14+
#include "src/stdio/printf_core/printf_main.h"
15+
#include "src/stdio/printf_core/writer.h"
16+
17+
#include <stdarg.h>
18+
#include <stddef.h>
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
namespace {
23+
24+
LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) {
25+
write_to_stderr(new_str);
26+
return printf_core::WRITE_OK;
27+
}
28+
29+
} // namespace
30+
31+
LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) {
32+
va_list vlist;
33+
va_start(vlist, format);
34+
internal::ArgList args(vlist); // This holder class allows for easier copying
35+
// and pointer semantics, as well as handling
36+
// destruction automatically.
37+
va_end(vlist);
38+
constexpr size_t BUFF_SIZE = 1024;
39+
char buffer[BUFF_SIZE];
40+
41+
printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr);
42+
printf_core::Writer writer(&wb);
43+
44+
int retval = printf_core::printf_main(&writer, format, args);
45+
46+
int flushval = wb.overflow_write("");
47+
if (flushval != printf_core::WRITE_OK)
48+
retval = flushval;
49+
50+
return retval;
51+
}
52+
53+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/uefi/putchar.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-- Baremetal Implementation of putchar -------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/putchar.h"
10+
#include "src/__support/CPP/string_view.h"
11+
#include "src/__support/OSUtil/io.h"
12+
#include "src/__support/macros/config.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
LLVM_LIBC_FUNCTION(int, putchar, (int c)) {
17+
char uc = static_cast<char>(c);
18+
19+
write_to_stderr(cpp::string_view(&uc, 1));
20+
21+
return 0;
22+
}
23+
24+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)