From b49a13c556a2b8ba9dbf04711326df496c7686e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 27 Aug 2024 00:32:21 +0100 Subject: [PATCH] code generate a single compiler intrinsics table This simplifies the code generator and global variables a bit. --- go_std_tables.go | 290 ++++++++++++++++++----------------- main.go | 8 +- scripts/gen_go_std_tables.go | 74 +++++---- shared.go | 2 +- 4 files changed, 192 insertions(+), 182 deletions(-) diff --git a/go_std_tables.go b/go_std_tables.go index d5cabbc..75b549f 100644 --- a/go_std_tables.go +++ b/go_std_tables.go @@ -1,6 +1,6 @@ // Code generated by scripts/gen_go_std_tables.go; DO NOT EDIT. -// Generated from Go version go1.22.0. +// Generated from Go version go1.22.6. package main @@ -53,148 +53,152 @@ var runtimeLinknamed = []string{ "net", } -var compilerIntrinsicsPkgs = map[string]bool{ - "math": true, - "math/big": true, - "math/bits": true, - "runtime": true, - "runtime/internal/atomic": true, - "runtime/internal/math": true, - "runtime/internal/sys": true, - "sync": true, - "sync/atomic": true, -} - -var compilerIntrinsicsFuncs = map[string]bool{ - "math.Abs": true, - "math.Ceil": true, - "math.Copysign": true, - "math.FMA": true, - "math.Floor": true, - "math.Round": true, - "math.RoundToEven": true, - "math.Trunc": true, - "math.sqrt": true, - "math/big.mulWW": true, - "math/bits.Add": true, - "math/bits.Add64": true, - "math/bits.Div": true, - "math/bits.Div64": true, - "math/bits.Len": true, - "math/bits.Len16": true, - "math/bits.Len32": true, - "math/bits.Len64": true, - "math/bits.Len8": true, - "math/bits.Mul": true, - "math/bits.Mul64": true, - "math/bits.OnesCount": true, - "math/bits.OnesCount16": true, - "math/bits.OnesCount32": true, - "math/bits.OnesCount64": true, - "math/bits.OnesCount8": true, - "math/bits.Reverse": true, - "math/bits.Reverse16": true, - "math/bits.Reverse32": true, - "math/bits.Reverse64": true, - "math/bits.Reverse8": true, - "math/bits.ReverseBytes16": true, - "math/bits.ReverseBytes32": true, - "math/bits.ReverseBytes64": true, - "math/bits.RotateLeft": true, - "math/bits.RotateLeft16": true, - "math/bits.RotateLeft32": true, - "math/bits.RotateLeft64": true, - "math/bits.RotateLeft8": true, - "math/bits.Sub": true, - "math/bits.Sub64": true, - "math/bits.TrailingZeros16": true, - "math/bits.TrailingZeros32": true, - "math/bits.TrailingZeros64": true, - "math/bits.TrailingZeros8": true, - "runtime.publicationBarrier": true, - "runtime/internal/atomic.And": true, - "runtime/internal/atomic.And8": true, - "runtime/internal/atomic.Cas": true, - "runtime/internal/atomic.Cas64": true, - "runtime/internal/atomic.CasRel": true, - "runtime/internal/atomic.Casint32": true, - "runtime/internal/atomic.Casint64": true, - "runtime/internal/atomic.Casp1": true, - "runtime/internal/atomic.Casuintptr": true, - "runtime/internal/atomic.Load": true, - "runtime/internal/atomic.Load64": true, - "runtime/internal/atomic.Load8": true, - "runtime/internal/atomic.LoadAcq": true, - "runtime/internal/atomic.LoadAcq64": true, - "runtime/internal/atomic.LoadAcquintptr": true, - "runtime/internal/atomic.Loadint32": true, - "runtime/internal/atomic.Loadint64": true, - "runtime/internal/atomic.Loadp": true, - "runtime/internal/atomic.Loaduint": true, - "runtime/internal/atomic.Loaduintptr": true, - "runtime/internal/atomic.Or": true, - "runtime/internal/atomic.Or8": true, - "runtime/internal/atomic.Store": true, - "runtime/internal/atomic.Store64": true, - "runtime/internal/atomic.Store8": true, - "runtime/internal/atomic.StoreRel": true, - "runtime/internal/atomic.StoreRel64": true, - "runtime/internal/atomic.StoreReluintptr": true, - "runtime/internal/atomic.Storeint32": true, - "runtime/internal/atomic.Storeint64": true, - "runtime/internal/atomic.StorepNoWB": true, - "runtime/internal/atomic.Storeuintptr": true, - "runtime/internal/atomic.Xadd": true, - "runtime/internal/atomic.Xadd64": true, - "runtime/internal/atomic.Xaddint32": true, - "runtime/internal/atomic.Xaddint64": true, - "runtime/internal/atomic.Xadduintptr": true, - "runtime/internal/atomic.Xchg": true, - "runtime/internal/atomic.Xchg64": true, - "runtime/internal/atomic.Xchgint32": true, - "runtime/internal/atomic.Xchgint64": true, - "runtime/internal/atomic.Xchguintptr": true, - "runtime/internal/math.Add64": true, - "runtime/internal/math.Mul64": true, - "runtime/internal/math.MulUintptr": true, - "runtime/internal/sys.Bswap32": true, - "runtime/internal/sys.Bswap64": true, - "runtime/internal/sys.Len64": true, - "runtime/internal/sys.Len8": true, - "runtime/internal/sys.OnesCount64": true, - "runtime/internal/sys.Prefetch": true, - "runtime/internal/sys.PrefetchStreamed": true, - "runtime/internal/sys.TrailingZeros32": true, - "runtime/internal/sys.TrailingZeros64": true, - "runtime/internal/sys.TrailingZeros8": true, - "sync.runtime_LoadAcquintptr": true, - "sync.runtime_StoreReluintptr": true, - "sync/atomic.AddInt32": true, - "sync/atomic.AddInt64": true, - "sync/atomic.AddUint32": true, - "sync/atomic.AddUint64": true, - "sync/atomic.AddUintptr": true, - "sync/atomic.CompareAndSwapInt32": true, - "sync/atomic.CompareAndSwapInt64": true, - "sync/atomic.CompareAndSwapUint32": true, - "sync/atomic.CompareAndSwapUint64": true, - "sync/atomic.CompareAndSwapUintptr": true, - "sync/atomic.LoadInt32": true, - "sync/atomic.LoadInt64": true, - "sync/atomic.LoadPointer": true, - "sync/atomic.LoadUint32": true, - "sync/atomic.LoadUint64": true, - "sync/atomic.LoadUintptr": true, - "sync/atomic.StoreInt32": true, - "sync/atomic.StoreInt64": true, - "sync/atomic.StoreUint32": true, - "sync/atomic.StoreUint64": true, - "sync/atomic.StoreUintptr": true, - "sync/atomic.SwapInt32": true, - "sync/atomic.SwapInt64": true, - "sync/atomic.SwapUint32": true, - "sync/atomic.SwapUint64": true, - "sync/atomic.SwapUintptr": true, +var compilerIntrinsics = map[string]map[string]bool{ + "math": { + "Abs": true, + "Ceil": true, + "Copysign": true, + "FMA": true, + "Floor": true, + "Round": true, + "RoundToEven": true, + "Trunc": true, + "sqrt": true, + }, + "math/big": { + "mulWW": true, + }, + "math/bits": { + "Add": true, + "Add64": true, + "Div": true, + "Div64": true, + "Len": true, + "Len16": true, + "Len32": true, + "Len64": true, + "Len8": true, + "Mul": true, + "Mul64": true, + "OnesCount": true, + "OnesCount16": true, + "OnesCount32": true, + "OnesCount64": true, + "OnesCount8": true, + "Reverse": true, + "Reverse16": true, + "Reverse32": true, + "Reverse64": true, + "Reverse8": true, + "ReverseBytes16": true, + "ReverseBytes32": true, + "ReverseBytes64": true, + "RotateLeft": true, + "RotateLeft16": true, + "RotateLeft32": true, + "RotateLeft64": true, + "RotateLeft8": true, + "Sub": true, + "Sub64": true, + "TrailingZeros16": true, + "TrailingZeros32": true, + "TrailingZeros64": true, + "TrailingZeros8": true, + }, + "runtime": { + "publicationBarrier": true, + }, + "runtime/internal/atomic": { + "And": true, + "And8": true, + "Cas": true, + "Cas64": true, + "CasRel": true, + "Casint32": true, + "Casint64": true, + "Casp1": true, + "Casuintptr": true, + "Load": true, + "Load64": true, + "Load8": true, + "LoadAcq": true, + "LoadAcq64": true, + "LoadAcquintptr": true, + "Loadint32": true, + "Loadint64": true, + "Loadp": true, + "Loaduint": true, + "Loaduintptr": true, + "Or": true, + "Or8": true, + "Store": true, + "Store64": true, + "Store8": true, + "StoreRel": true, + "StoreRel64": true, + "StoreReluintptr": true, + "Storeint32": true, + "Storeint64": true, + "StorepNoWB": true, + "Storeuintptr": true, + "Xadd": true, + "Xadd64": true, + "Xaddint32": true, + "Xaddint64": true, + "Xadduintptr": true, + "Xchg": true, + "Xchg64": true, + "Xchgint32": true, + "Xchgint64": true, + "Xchguintptr": true, + }, + "runtime/internal/math": { + "MulUintptr": true, + }, + "runtime/internal/sys": { + "Bswap32": true, + "Bswap64": true, + "Len64": true, + "Len8": true, + "OnesCount64": true, + "Prefetch": true, + "PrefetchStreamed": true, + "TrailingZeros32": true, + "TrailingZeros64": true, + "TrailingZeros8": true, + }, + "sync": { + "runtime_LoadAcquintptr": true, + "runtime_StoreReluintptr": true, + }, + "sync/atomic": { + "AddInt32": true, + "AddInt64": true, + "AddUint32": true, + "AddUint64": true, + "AddUintptr": true, + "CompareAndSwapInt32": true, + "CompareAndSwapInt64": true, + "CompareAndSwapUint32": true, + "CompareAndSwapUint64": true, + "CompareAndSwapUintptr": true, + "LoadInt32": true, + "LoadInt64": true, + "LoadPointer": true, + "LoadUint32": true, + "LoadUint64": true, + "LoadUintptr": true, + "StoreInt32": true, + "StoreInt64": true, + "StoreUint32": true, + "StoreUint64": true, + "StoreUintptr": true, + "SwapInt32": true, + "SwapInt64": true, + "SwapUint32": true, + "SwapUint64": true, + "SwapUintptr": true, + }, } var reflectSkipPkg = map[string]bool{ diff --git a/main.go b/main.go index 39b9969..cf68659 100644 --- a/main.go +++ b/main.go @@ -869,7 +869,7 @@ func (tf *transformer) replaceAsmNames(buf *bytes.Buffer, remaining []byte) { name := string(remaining[:nameEnd]) remaining = remaining[nameEnd:] - if lpkg.ToObfuscate && !compilerIntrinsicsFuncs[lpkg.ImportPath+"."+name] { + if lpkg.ToObfuscate && !compilerIntrinsics[lpkg.ImportPath][name] { newName := hashWithPackage(lpkg, name) if flagDebug { // TODO(mvdan): remove once https://go.dev/issue/53465 if fixed log.Printf("asm name %q hashed with %x to %q", name, tf.curPkg.GarbleActionID, newName) @@ -1107,7 +1107,7 @@ func (tf *transformer) transformDirectives(comments []*ast.CommentGroup) { func (tf *transformer) transformLinkname(localName, newName string) (string, string) { // obfuscate the local name, if the current package is obfuscated - if tf.curPkg.ToObfuscate && !compilerIntrinsicsFuncs[tf.curPkg.ImportPath+"."+localName] { + if tf.curPkg.ToObfuscate && !compilerIntrinsics[tf.curPkg.ImportPath][localName] { localName = hashWithPackage(tf.curPkg, localName) } if newName == "" { @@ -1169,7 +1169,7 @@ func (tf *transformer) transformLinkname(localName, newName string) (string, str panic(err) // shouldn't happen } - if !lpkg.ToObfuscate || compilerIntrinsicsFuncs[lpkg.ImportPath+"."+foreignName] { + if !lpkg.ToObfuscate || compilerIntrinsics[lpkg.ImportPath][foreignName] { // We're not obfuscating that package or name. return localName, newName } @@ -2010,7 +2010,7 @@ func (tf *transformer) transformGoFile(file *ast.File) *ast.File { case *types.TypeName: debugName = "type" case *types.Func: - if compilerIntrinsicsFuncs[path+"."+name] { + if compilerIntrinsics[path][name] { return true } diff --git a/scripts/gen_go_std_tables.go b/scripts/gen_go_std_tables.go index e31bc84..a602bb6 100644 --- a/scripts/gen_go_std_tables.go +++ b/scripts/gen_go_std_tables.go @@ -1,6 +1,8 @@ // Copyright (c) 2024, The Garble Authors. // See LICENSE for licensing information. +//go:build ignore + // This is a program used with `go generate`, so it handles errors via panic. package main @@ -40,40 +42,35 @@ var runtimeLinknamed = []string{ "net", } -var compilerIntrinsicsPkgs = map[string]bool{ -{{- range $path := .CompilerIntrinsicsPaths }} - "{{ $path }}": true, -{{- end }} -} - -var compilerIntrinsicsFuncs = map[string]bool{ +var compilerIntrinsics = map[string]map[string]bool{ {{- range $intr := .CompilerIntrinsics }} - "{{ $intr.Path }}.{{ $intr.Name }}": true, + "{{ $intr.Path }}": { +{{- range $name := $intr.Names }} + "{{ $name }}": true, +{{- end }} + }, {{- end }} } var reflectSkipPkg = map[string]bool{ "fmt": true, } -`)) +`[1:])) type tmplData struct { - GoVersion string - RuntimeAndDeps []string - RuntimeLinknamed []string - CompilerIntrinsics []tmplIntrinsic - CompilerIntrinsicsPaths []string + GoVersion string + RuntimeAndDeps []string + RuntimeLinknamed []string + CompilerIntrinsics []tmplIntrinsic } type tmplIntrinsic struct { - Path, Name string + Path string + Names []string } func (t tmplIntrinsic) Compare(t2 tmplIntrinsic) int { - if c := cmp.Compare(t.Path, t2.Path); c != 0 { - return c - } - return cmp.Compare(t.Name, t2.Name) + return cmp.Compare(t.Path, t2.Path) } func (t tmplIntrinsic) Equal(t2 tmplIntrinsic) bool { @@ -141,8 +138,8 @@ func main() { return slices.Contains(runtimeAndDeps, path) }) + compilerIntrinsicsIndexByPath := make(map[string]int) var compilerIntrinsics []tmplIntrinsic - var compilerIntrinsicsPaths []string for _, line := range strings.Split(readFile(filepath.Join( goroot, "src", "cmd", "compile", "internal", "ssagen", "ssa.go", )), "\n") { @@ -150,25 +147,34 @@ func main() { if m == nil { continue } - compilerIntrinsics = append(compilerIntrinsics, tmplIntrinsic{ - Path: m[2], - Name: m[3], - }) - compilerIntrinsicsPaths = append(compilerIntrinsicsPaths, m[2]) + path, name := m[2], m[3] + if i := compilerIntrinsicsIndexByPath[path]; i == 0 { + compilerIntrinsicsIndexByPath[path] = len(compilerIntrinsics) + compilerIntrinsics = append(compilerIntrinsics, tmplIntrinsic{ + Path: path, + Names: []string{name}, + }) + } else { + compilerIntrinsics[i].Names = append(compilerIntrinsics[i].Names, name) + } } slices.SortFunc(compilerIntrinsics, tmplIntrinsic.Compare) compilerIntrinsics = slices.CompactFunc(compilerIntrinsics, tmplIntrinsic.Equal) - slices.Sort(compilerIntrinsicsPaths) - compilerIntrinsicsPaths = slices.Compact(compilerIntrinsicsPaths) + for path := range compilerIntrinsics { + intr := &compilerIntrinsics[path] + slices.Sort(intr.Names) + intr.Names = slices.Compact(intr.Names) + } var buf bytes.Buffer - tmplTables.Execute(&buf, tmplData{ - GoVersion: goversion, - RuntimeAndDeps: runtimeAndDeps, - RuntimeLinknamed: runtimeLinknamed, - CompilerIntrinsics: compilerIntrinsics, - CompilerIntrinsicsPaths: compilerIntrinsicsPaths, - }) + if err := tmplTables.Execute(&buf, tmplData{ + GoVersion: goversion, + RuntimeAndDeps: runtimeAndDeps, + RuntimeLinknamed: runtimeLinknamed, + CompilerIntrinsics: compilerIntrinsics, + }); err != nil { + panic(err) + } out := buf.Bytes() formatted, err := format.Source(out) if err != nil { diff --git a/shared.go b/shared.go index a77ee81..43c4df3 100644 --- a/shared.go +++ b/shared.go @@ -191,7 +191,7 @@ func (p *listedPackage) obfuscatedImportPath() string { return p.ImportPath } // Intrinsics are matched by package import path as well. - if compilerIntrinsicsPkgs[p.ImportPath] { + if _, ok := compilerIntrinsics[p.ImportPath]; ok { return p.ImportPath } if !p.ToObfuscate {