aboutsummaryrefslogtreecommitdiffhomepage
path: root/loader/goroot.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2021-06-19 16:19:41 +0200
committerRon Evans <[email protected]>2021-06-21 18:22:31 +0200
commitd94f42f6e284e459f0141f986a2232f9867b1c4e (patch)
treee0be285f07bde22fb71afc0fe65925e5765bb5b4 /loader/goroot.go
parentd8ac7ccaae01986d60935469941eaf8f0003d43b (diff)
downloadtinygo-d94f42f6e284e459f0141f986a2232f9867b1c4e.tar.gz
tinygo-d94f42f6e284e459f0141f986a2232f9867b1c4e.zip
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.
Diffstat (limited to 'loader/goroot.go')
-rw-r--r--loader/goroot.go51
1 files changed, 36 insertions, 15 deletions
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,