Skip to content

Commit c4b6b72

Browse files
committed
cgo: add stdio support to picolibc
1 parent 0fe8147 commit c4b6b72

File tree

7 files changed

+134
-5
lines changed

7 files changed

+134
-5
lines changed

builder/ar.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"debug/elf"
66
"encoding/binary"
77
"errors"
8+
"fmt"
89
"io"
910
"os"
1011
"path/filepath"
@@ -49,7 +50,7 @@ func makeArchive(archivePath string, objs []string) error {
4950
// Read the symbols and add them to the symbol table.
5051
dbg, err := elf.NewFile(objfile)
5152
if err != nil {
52-
return err
53+
return fmt.Errorf("failed to open file %s: %w", objpath, err)
5354
}
5455
symbols, err := dbg.Symbols()
5556
if err != nil {
@@ -61,9 +62,8 @@ func makeArchive(archivePath string, objs []string) error {
6162
// Don't include local symbols (STB_LOCAL).
6263
continue
6364
}
64-
if elf.ST_TYPE(symbol.Info) != elf.STT_FUNC {
65+
if elf.ST_TYPE(symbol.Info) != elf.STT_FUNC && elf.ST_TYPE(symbol.Info) != elf.STT_OBJECT {
6566
// Not a function.
66-
// TODO: perhaps globals variables should also be included?
6767
continue
6868
}
6969
// Include in archive.

builder/picolibc.go

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,17 @@ var Picolibc = Library{
1212
name: "picolibc",
1313
cflags: func() []string {
1414
picolibcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc")
15-
return []string{"-Werror", "-Wall", "-std=gnu11", "-D_COMPILING_NEWLIB", "-nostdlibinc", "-Xclang", "-internal-isystem", "-Xclang", picolibcDir + "/include", "-I" + picolibcDir + "/tinystdio", "-I" + goenv.Get("TINYGOROOT") + "/lib/picolibc-include"}
15+
return []string{
16+
"-Werror",
17+
"-Wall",
18+
"-std=gnu11",
19+
"-D_COMPILING_NEWLIB",
20+
"-DTINY_STDIO",
21+
"-nostdlibinc",
22+
"-Xclang", "-internal-isystem", "-Xclang", picolibcDir + "/include",
23+
"-I" + picolibcDir + "/tinystdio",
24+
"-I" + goenv.Get("TINYGOROOT") + "/lib/picolibc-include",
25+
}
1626
},
1727
sourceDir: "lib/picolibc/newlib/libc",
1828
sources: func(target string) []string {
@@ -21,6 +31,105 @@ var Picolibc = Library{
2131
}
2232

2333
var picolibcSources = []string{
34+
"../../../picolibc-stdio.c",
35+
36+
"tinystdio/asprintf.c",
37+
"tinystdio/atod_engine.c",
38+
"tinystdio/atod_ryu.c",
39+
"tinystdio/atof_engine.c",
40+
"tinystdio/atof_ryu.c",
41+
//"tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
42+
"tinystdio/clearerr.c",
43+
"tinystdio/compare_exchange.c",
44+
"tinystdio/dtoa_data.c",
45+
"tinystdio/dtoa_engine.c",
46+
"tinystdio/dtoa_ryu.c",
47+
"tinystdio/ecvtbuf.c",
48+
"tinystdio/ecvt.c",
49+
"tinystdio/ecvt_data.c",
50+
"tinystdio/ecvtfbuf.c",
51+
"tinystdio/ecvtf.c",
52+
"tinystdio/ecvtf_data.c",
53+
"tinystdio/exchange.c",
54+
//"tinystdio/fclose.c", // posix-io
55+
"tinystdio/fcvtbuf.c",
56+
"tinystdio/fcvt.c",
57+
"tinystdio/fcvtfbuf.c",
58+
"tinystdio/fcvtf.c",
59+
"tinystdio/fdevopen.c",
60+
//"tinystdio/fdopen.c", // posix-io
61+
"tinystdio/feof.c",
62+
"tinystdio/ferror.c",
63+
"tinystdio/fflush.c",
64+
"tinystdio/fgetc.c",
65+
"tinystdio/fgets.c",
66+
"tinystdio/fileno.c",
67+
"tinystdio/filestrget.c",
68+
"tinystdio/filestrputalloc.c",
69+
"tinystdio/filestrput.c",
70+
//"tinystdio/fopen.c", // posix-io
71+
"tinystdio/fprintf.c",
72+
"tinystdio/fputc.c",
73+
"tinystdio/fputs.c",
74+
"tinystdio/fread.c",
75+
"tinystdio/fscanf.c",
76+
"tinystdio/fseek.c",
77+
"tinystdio/ftell.c",
78+
"tinystdio/ftoa_data.c",
79+
"tinystdio/ftoa_engine.c",
80+
"tinystdio/ftoa_ryu.c",
81+
"tinystdio/fwrite.c",
82+
"tinystdio/gcvtbuf.c",
83+
"tinystdio/gcvt.c",
84+
"tinystdio/gcvtfbuf.c",
85+
"tinystdio/gcvtf.c",
86+
"tinystdio/getchar.c",
87+
"tinystdio/gets.c",
88+
"tinystdio/matchcaseprefix.c",
89+
"tinystdio/perror.c",
90+
//"tinystdio/posixiob.c", // posix-io
91+
//"tinystdio/posixio.c", // posix-io
92+
"tinystdio/printf.c",
93+
"tinystdio/putchar.c",
94+
"tinystdio/puts.c",
95+
"tinystdio/ryu_divpow2.c",
96+
"tinystdio/ryu_log10.c",
97+
"tinystdio/ryu_log2pow5.c",
98+
"tinystdio/ryu_pow5bits.c",
99+
"tinystdio/ryu_table.c",
100+
"tinystdio/ryu_umul128.c",
101+
"tinystdio/scanf.c",
102+
"tinystdio/setbuf.c",
103+
"tinystdio/setvbuf.c",
104+
//"tinystdio/sflags.c", // posix-io
105+
"tinystdio/snprintf.c",
106+
"tinystdio/snprintfd.c",
107+
"tinystdio/snprintff.c",
108+
"tinystdio/sprintf.c",
109+
"tinystdio/sprintfd.c",
110+
"tinystdio/sprintff.c",
111+
"tinystdio/sscanf.c",
112+
"tinystdio/strfromd.c",
113+
"tinystdio/strfromf.c",
114+
"tinystdio/strtod.c",
115+
"tinystdio/strtod_l.c",
116+
"tinystdio/strtof.c",
117+
//"tinystdio/strtold.c", // have_long_double and not long_double_equals_double
118+
//"tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double
119+
"tinystdio/ungetc.c",
120+
"tinystdio/vasprintf.c",
121+
"tinystdio/vfiprintf.c",
122+
"tinystdio/vfiscanf.c",
123+
"tinystdio/vfprintf.c",
124+
"tinystdio/vfprintff.c",
125+
"tinystdio/vfscanf.c",
126+
"tinystdio/vfscanff.c",
127+
"tinystdio/vprintf.c",
128+
"tinystdio/vscanf.c",
129+
"tinystdio/vsnprintf.c",
130+
"tinystdio/vsprintf.c",
131+
"tinystdio/vsscanf.c",
132+
24133
"string/bcmp.c",
25134
"string/bcopy.c",
26135
"string/bzero.c",

lib/picolibc

lib/picolibc-stdio.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdio.h>
2+
3+
// Defined in the runtime package. Writes to the default console (usually, the
4+
// first UART or an USB-CDC device).
5+
int runtime_putchar(char, FILE*);
6+
7+
// Define stdin, stdout, and stderr as a single object.
8+
// This object must not reside in ROM.
9+
static FILE __stdio = FDEV_SETUP_STREAM(runtime_putchar, NULL, NULL, _FDEV_SETUP_WRITE);
10+
11+
// Define the underlying structs for stdin, stdout, and stderr.
12+
FILE *const __iob[3] = { &__stdio, &__stdio, &__stdio };

src/runtime/baremetal.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ func libc_abort() {
5151
abort()
5252
}
5353

54+
//export runtime_putchar
55+
func runtime_putchar(c byte) {
56+
putchar(c)
57+
}
58+
5459
//go:linkname syscall_Exit syscall.Exit
5560
func syscall_Exit(code int) {
5661
abort()

testdata/cgo/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ func main() {
139139

140140
// libc: test basic stdio functionality
141141
println("SEEK_CUR:", C.SEEK_CUR)
142+
putsBuf := []byte("line written using C puts\x00")
143+
C.puts((*C.char)(unsafe.Pointer(&putsBuf[0])))
142144
}
143145

144146
func printUnion(union C.joined_t) C.joined_t {

testdata/cgo/out.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,4 @@ enum width matches: true
6262
CFLAGS value: 17
6363
copied string: foobar
6464
SEEK_CUR: 1
65+
line written using C puts

0 commit comments

Comments
 (0)