Skip to content

Commit

Permalink
cgo: add stdio support to picolibc
Browse files Browse the repository at this point in the history
  • Loading branch information
aykevl committed Sep 24, 2021
1 parent 0fe8147 commit c4b6b72
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 5 deletions.
6 changes: 3 additions & 3 deletions builder/ar.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"debug/elf"
"encoding/binary"
"errors"
"fmt"
"io"
"os"
"path/filepath"
Expand Down Expand Up @@ -49,7 +50,7 @@ func makeArchive(archivePath string, objs []string) error {
// Read the symbols and add them to the symbol table.
dbg, err := elf.NewFile(objfile)
if err != nil {
return err
return fmt.Errorf("failed to open file %s: %w", objpath, err)
}
symbols, err := dbg.Symbols()
if err != nil {
Expand All @@ -61,9 +62,8 @@ func makeArchive(archivePath string, objs []string) error {
// Don't include local symbols (STB_LOCAL).
continue
}
if elf.ST_TYPE(symbol.Info) != elf.STT_FUNC {
if elf.ST_TYPE(symbol.Info) != elf.STT_FUNC && elf.ST_TYPE(symbol.Info) != elf.STT_OBJECT {
// Not a function.
// TODO: perhaps globals variables should also be included?
continue
}
// Include in archive.
Expand Down
111 changes: 110 additions & 1 deletion builder/picolibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,17 @@ var Picolibc = Library{
name: "picolibc",
cflags: func() []string {
picolibcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc")
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"}
return []string{
"-Werror",
"-Wall",
"-std=gnu11",
"-D_COMPILING_NEWLIB",
"-DTINY_STDIO",
"-nostdlibinc",
"-Xclang", "-internal-isystem", "-Xclang", picolibcDir + "/include",
"-I" + picolibcDir + "/tinystdio",
"-I" + goenv.Get("TINYGOROOT") + "/lib/picolibc-include",
}
},
sourceDir: "lib/picolibc/newlib/libc",
sources: func(target string) []string {
Expand All @@ -21,6 +31,105 @@ var Picolibc = Library{
}

var picolibcSources = []string{
"../../../picolibc-stdio.c",

"tinystdio/asprintf.c",
"tinystdio/atod_engine.c",
"tinystdio/atod_ryu.c",
"tinystdio/atof_engine.c",
"tinystdio/atof_ryu.c",
//"tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
"tinystdio/clearerr.c",
"tinystdio/compare_exchange.c",
"tinystdio/dtoa_data.c",
"tinystdio/dtoa_engine.c",
"tinystdio/dtoa_ryu.c",
"tinystdio/ecvtbuf.c",
"tinystdio/ecvt.c",
"tinystdio/ecvt_data.c",
"tinystdio/ecvtfbuf.c",
"tinystdio/ecvtf.c",
"tinystdio/ecvtf_data.c",
"tinystdio/exchange.c",
//"tinystdio/fclose.c", // posix-io
"tinystdio/fcvtbuf.c",
"tinystdio/fcvt.c",
"tinystdio/fcvtfbuf.c",
"tinystdio/fcvtf.c",
"tinystdio/fdevopen.c",
//"tinystdio/fdopen.c", // posix-io
"tinystdio/feof.c",
"tinystdio/ferror.c",
"tinystdio/fflush.c",
"tinystdio/fgetc.c",
"tinystdio/fgets.c",
"tinystdio/fileno.c",
"tinystdio/filestrget.c",
"tinystdio/filestrputalloc.c",
"tinystdio/filestrput.c",
//"tinystdio/fopen.c", // posix-io
"tinystdio/fprintf.c",
"tinystdio/fputc.c",
"tinystdio/fputs.c",
"tinystdio/fread.c",
"tinystdio/fscanf.c",
"tinystdio/fseek.c",
"tinystdio/ftell.c",
"tinystdio/ftoa_data.c",
"tinystdio/ftoa_engine.c",
"tinystdio/ftoa_ryu.c",
"tinystdio/fwrite.c",
"tinystdio/gcvtbuf.c",
"tinystdio/gcvt.c",
"tinystdio/gcvtfbuf.c",
"tinystdio/gcvtf.c",
"tinystdio/getchar.c",
"tinystdio/gets.c",
"tinystdio/matchcaseprefix.c",
"tinystdio/perror.c",
//"tinystdio/posixiob.c", // posix-io
//"tinystdio/posixio.c", // posix-io
"tinystdio/printf.c",
"tinystdio/putchar.c",
"tinystdio/puts.c",
"tinystdio/ryu_divpow2.c",
"tinystdio/ryu_log10.c",
"tinystdio/ryu_log2pow5.c",
"tinystdio/ryu_pow5bits.c",
"tinystdio/ryu_table.c",
"tinystdio/ryu_umul128.c",
"tinystdio/scanf.c",
"tinystdio/setbuf.c",
"tinystdio/setvbuf.c",
//"tinystdio/sflags.c", // posix-io
"tinystdio/snprintf.c",
"tinystdio/snprintfd.c",
"tinystdio/snprintff.c",
"tinystdio/sprintf.c",
"tinystdio/sprintfd.c",
"tinystdio/sprintff.c",
"tinystdio/sscanf.c",
"tinystdio/strfromd.c",
"tinystdio/strfromf.c",
"tinystdio/strtod.c",
"tinystdio/strtod_l.c",
"tinystdio/strtof.c",
//"tinystdio/strtold.c", // have_long_double and not long_double_equals_double
//"tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double
"tinystdio/ungetc.c",
"tinystdio/vasprintf.c",
"tinystdio/vfiprintf.c",
"tinystdio/vfiscanf.c",
"tinystdio/vfprintf.c",
"tinystdio/vfprintff.c",
"tinystdio/vfscanf.c",
"tinystdio/vfscanff.c",
"tinystdio/vprintf.c",
"tinystdio/vscanf.c",
"tinystdio/vsnprintf.c",
"tinystdio/vsprintf.c",
"tinystdio/vsscanf.c",

"string/bcmp.c",
"string/bcopy.c",
"string/bzero.c",
Expand Down
2 changes: 1 addition & 1 deletion lib/picolibc
12 changes: 12 additions & 0 deletions lib/picolibc-stdio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <stdio.h>

// Defined in the runtime package. Writes to the default console (usually, the
// first UART or an USB-CDC device).
int runtime_putchar(char, FILE*);

// Define stdin, stdout, and stderr as a single object.
// This object must not reside in ROM.
static FILE __stdio = FDEV_SETUP_STREAM(runtime_putchar, NULL, NULL, _FDEV_SETUP_WRITE);

// Define the underlying structs for stdin, stdout, and stderr.
FILE *const __iob[3] = { &__stdio, &__stdio, &__stdio };
5 changes: 5 additions & 0 deletions src/runtime/baremetal.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func libc_abort() {
abort()
}

//export runtime_putchar
func runtime_putchar(c byte) {
putchar(c)
}

//go:linkname syscall_Exit syscall.Exit
func syscall_Exit(code int) {
abort()
Expand Down
2 changes: 2 additions & 0 deletions testdata/cgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ func main() {

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

func printUnion(union C.joined_t) C.joined_t {
Expand Down
1 change: 1 addition & 0 deletions testdata/cgo/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ enum width matches: true
CFLAGS value: 17
copied string: foobar
SEEK_CUR: 1
line written using C puts

0 comments on commit c4b6b72

Please sign in to comment.