From d94f42f6e284e459f0141f986a2232f9867b1c4e Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 19 Jun 2021 16:19:41 +0200 Subject: crypto/rand: replace this package with a TinyGo version This package provides access to an operating system resource (cryptographic numbers) and so needs to be replaced with a TinyGo version that does this in a different way. I've made the following choices while adding this feature: - I'm using the getentropy call whenever possible (most POSIX like systems), because it is easier to use and more reliable. Linux is the exception: it only added getentropy relatively recently. - I've left bare-metal implementations to a future patch. This because it's hard to reliably get cryptographically secure random numbers on embedded devices: most devices do not have a hardware PRNG for this purpose. --- loader/goroot.go | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'loader') diff --git a/loader/goroot.go b/loader/goroot.go index 03c8919e7..6770d0458 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -2,6 +2,14 @@ package loader // This file constructs a new temporary GOROOT directory by merging both the // standard Go GOROOT and the GOROOT from TinyGo using symlinks. +// +// The goal is to replace specific packages from Go with a TinyGo version. It's +// never a partial replacement, either a package is fully replaced or it is not. +// This is important because if we did allow to merge packages (e.g. by adding +// files to a package), it would lead to a dependency on implementation details +// with all the maintenance burden that results in. Only allowing to replace +// packages as a whole avoids this as packages are already designed to have a +// public (backwards-compatible) API. import ( "crypto/sha512" @@ -139,6 +147,7 @@ func mergeDirectory(goroot, tinygoroot, tmpgoroot, importPath string, overrides if err != nil { return err } + hasTinyGoFiles := false for _, e := range tinygoEntries { if e.IsDir() { // A directory, so merge this thing. @@ -154,6 +163,7 @@ func mergeDirectory(goroot, tinygoroot, tmpgoroot, importPath string, overrides if err != nil { return err } + hasTinyGoFiles = true } } @@ -164,21 +174,30 @@ func mergeDirectory(goroot, tinygoroot, tmpgoroot, importPath string, overrides return err } for _, e := range gorootEntries { - if !e.IsDir() { - // Don't merge in files from Go. Otherwise we'd end up with a - // weird syscall package with files from both roots. - continue - } - if _, ok := overrides[path.Join(importPath, e.Name())+"/"]; ok { - // Already included above, so don't bother trying to create this - // symlink. - continue - } - newname := filepath.Join(tmpgoroot, "src", importPath, e.Name()) - oldname := filepath.Join(goroot, "src", importPath, e.Name()) - err := symlink(oldname, newname) - if err != nil { - return err + if e.IsDir() { + if _, ok := overrides[path.Join(importPath, e.Name())+"/"]; ok { + // Already included above, so don't bother trying to create this + // symlink. + continue + } + newname := filepath.Join(tmpgoroot, "src", importPath, e.Name()) + oldname := filepath.Join(goroot, "src", importPath, e.Name()) + err := symlink(oldname, newname) + if err != nil { + return err + } + } else { + // Only merge files from Go if TinyGo does not have any files. + // Otherwise we'd end up with a weird mix from both Go + // implementations. + if !hasTinyGoFiles { + newname := filepath.Join(tmpgoroot, "src", importPath, e.Name()) + oldname := filepath.Join(goroot, "src", importPath, e.Name()) + err := symlink(oldname, newname) + if err != nil { + return err + } + } } } } @@ -201,6 +220,8 @@ func needsSyscallPackage(buildTags []string) bool { func pathsToOverride(needsSyscallPackage bool) map[string]bool { paths := map[string]bool{ "/": true, + "crypto/": true, + "crypto/rand/": false, "device/": false, "examples/": false, "internal/": true, -- cgit v1.2.3