rewrite private name map storage to support build caching

We now store how we obfuscated unexported names in the object file
itself, not a separate file. This means that the data can survive in the
build cache, whereas the separate file was being lost. Luckily, we can
just add an extra header to the archive, and other programs like the Go
linker will just ignore it.
pull/145/head
pagran 4 years ago committed by GitHub
parent 5c6fa4575f
commit 406036d433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,10 +7,8 @@ import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
@ -47,18 +45,18 @@ type privateImports struct {
privateNames []string
}
func appendPrivateNameMap(nameMap map[string]string, packageDirectory string) error {
file, err := os.Open(filepath.Join(packageDirectory, garbleMapFile))
if errors.Is(err, os.ErrNotExist) {
return nil
}
if err != nil {
return err
}
defer file.Close()
func appendPrivateNameMap(pkg *goobj2.Package, nameMap map[string]string) error {
for _, member := range pkg.ArchiveMembers {
if member.ArchiveHeader.Name != garbleMapHeaderName {
continue
}
if err := json.NewDecoder(file).Decode(&nameMap); err != nil {
return err
serializedMap := member.ArchiveHeader.Data
serializedMap = serializedMap[:bytes.IndexByte(serializedMap, 0x00)]
if err := json.Unmarshal(serializedMap, &nameMap); err != nil {
return err
}
return nil
}
return nil
}
@ -87,8 +85,7 @@ func obfuscateImports(objPath, importCfgPath string) (garbledImports, privateNam
pkgs = append(pkgs, pkgInfo{pkg, info.Path, private})
packageDir := filepath.Dir(info.Path)
if err := appendPrivateNameMap(privateNameMap, packageDir); err != nil {
if err := appendPrivateNameMap(pkg, privateNameMap); err != nil {
return nil, nil, fmt.Errorf("error parsing name map %s at %s: %v", pkgPath, info.Path, err)
}
}

@ -31,6 +31,7 @@ import (
"time"
"unicode"
"github.com/Binject/debug/goobj2"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
"golang.org/x/tools/go/ast/astutil"
@ -115,7 +116,7 @@ var (
seed []byte
)
const garbleMapFile = "garble.map"
const garbleMapHeaderName = "garble/nameMap"
func saveListedPackages(w io.Writer, flags, patterns []string) error {
args := []string{"list", "-json", "-deps", "-export"}
@ -664,17 +665,36 @@ func transformCompile(args []string) ([]string, error) {
}
if len(privateNameMap) > 0 {
outputDirectory := filepath.Dir(flagValue(flags, "-o"))
objPath := flagValue(flags, "-o")
importcfg := flagValue(flags, "-importcfg")
deferred = append(deferred, func() error {
importCfg, err := goobj2.ParseImportCfg(importcfg)
if err != nil {
return err
}
file, err := os.Create(filepath.Join(outputDirectory, garbleMapFile))
if err != nil {
return nil, err
}
defer file.Close()
pkg, err := goobj2.Parse(objPath, pkgPath, importCfg)
if err != nil {
return err
}
if err := json.NewEncoder(file).Encode(privateNameMap); err != nil {
return nil, err
}
data, err := json.Marshal(privateNameMap)
if err != nil {
return err
}
// Adding an extra archive header is safe,
// and shouldn't break other tools like the linker since our header name is unique
pkg.ArchiveMembers = append(pkg.ArchiveMembers, goobj2.ArchiveMember{
ArchiveHeader: goobj2.ArchiveHeader{
Name: garbleMapHeaderName,
Size: int64(len(data)),
Data: data,
},
})
return pkg.Write(objPath)
})
}
return append(flags, newPaths...), nil

Loading…
Cancel
Save