github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/cmd/go/internal/work/gosec.go (about) 1 package work 2 3 import ( 4 "cmd/go/internal/load" 5 "fmt" 6 "log" 7 "os" 8 "path/filepath" 9 "text/template" 10 ) 11 12 type Entry struct { 13 Functions []string 14 Imports []string 15 } 16 17 const ( 18 gosectmpl = ` 19 package main 20 21 import( 22 "gosecu" 23 //"runtime" 24 {{range .Imports}} 25 {{ printf "%q" . }}{{end}} 26 ) 27 28 func main() { 29 // Starting the functions. 30 31 {{range .Functions}} 32 33 gosecu.RegisterSecureFunction({{ . }}) 34 35 {{end}} 36 gosecu.EcallServer() 37 } 38 ` 39 ) 40 41 // generateMain creates a temporary file _encl.o that corresponds contains 42 // a main with go calls to all the gosecure targets. 43 func generateMain(outfile string, functions, packages []string) string { 44 if len(functions) == 0 { 45 log.Fatalf("Missing target callees for gosecure keyword.") 46 } 47 48 if outfile == "" { 49 log.Fatalf("Missing argument `outfile` for gosec command") 50 } 51 52 data := Entry{functions, packages} 53 tmpl, err := template.New("gosec").Parse(gosectmpl) 54 if tmpl == nil || err != nil { 55 log.Fatalf(`gosec: parsing error "%s"`, err) 56 } 57 58 f, e := os.Create(outfile) 59 defer f.Close() 60 if e != nil { 61 log.Fatalf(`gosec creating outfile failed: "%s"`, e) 62 } 63 64 if err = tmpl.Execute(f, data); err != nil { 65 log.Fatalf(`"%s"`, err) 66 } 67 if _, err := os.Stat(outfile); os.IsNotExist(err) { 68 log.Fatalf("The file doesn't exist.") 69 } 70 71 return outfile 72 } 73 74 // gosec generates calls generateMain to create the main go file for the enclave 75 // executable. 76 func (b *Builder) gosec(a *Action) (err error) { 77 var functions, packages []string 78 ofile := filepath.Dir(a.Objdir) + "encl.go" 79 for p, m := range a.Package.PackagePublic.Gosectargets { 80 if p == "main" { 81 return fmt.Errorf("Invalid gosecure callee defined in main.") 82 } 83 packages = append(packages, p) 84 if len(m) != 0 { 85 for _, call := range m { 86 functions = append(functions, p+"."+call) 87 } 88 } 89 } 90 fname := generateMain(ofile, functions, packages) 91 if _, err := os.Stat(fname); os.IsNotExist(err) { 92 return err 93 } 94 // Define the output dir. 95 dir, err := os.Getwd() 96 if err != nil { 97 return err 98 } 99 efile := dir + "/enclave.out" 100 args := []string{"-o", efile, "-relocencl", fname} 101 cmd := CmdBuild 102 cmd.Flag.Parse(args) 103 args = cmd.Flag.Args() 104 cmd.Run(cmd, args) 105 a.Package.PackagePublic.Efile = efile 106 return nil 107 } 108 109 // CreateEnclaveExec returns an Action that creates the temporary files necessary 110 // to create the enclave executable. 111 func (b *Builder) CreateEnclaveExec(p *load.Package) *Action { 112 a := &Action{ 113 Mode: "build", 114 Package: p, 115 Func: (*Builder).gosec, 116 Objdir: b.NewObjdir(), 117 } 118 a.Target = a.Objdir + "_pkg_.a" 119 a.built = a.Target 120 return a 121 }