Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@ name: Test
jobs:
test:
strategy:
# We mainly develop on Linux, so being able to see MacOS and Windows failures
# is useful even if we already know at least one job will fail.
fail-fast: false
matrix:
go-version: [1.25.x]
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: [1.26.x]
# TODO: re-enable windows once https://github.com/golang/go/issues/77975 is resolved
# os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
Expand All @@ -53,17 +58,17 @@ jobs:
# Static checks from this point forward. Only run on one Go version and on
# linux, since it's the fastest platform, and the tools behave the same.
- name: Test third-party project builds
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.25.x'
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.26.x'
run: |
go install
./scripts/check-third-party.sh
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.25.x'
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.26.x'
run: ./scripts/crlf-test.sh
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.25.x'
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.26.x'
run: diff <(echo -n) <(gofmt -d .)
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.25.x'
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.26.x'
run: go vet ./...
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.25.x'
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.26.x'
uses: dominikh/staticcheck-action@v1
with:
version: "2025.1"
Expand All @@ -78,9 +83,9 @@ jobs:
env:
GOARCH: 386
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions/setup-go@v5
with:
go-version: 1.25.x
go-version: 1.26.x
cache: false
- run: go test -short ./...
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

go install mvdan.cc/garble@latest

Obfuscate Go code by wrapping the Go toolchain. Requires Go 1.25 or later.
Obfuscate Go code by wrapping the Go toolchain. Requires Go 1.26 or later.

garble build [build flags] [packages]

Expand Down
25 changes: 20 additions & 5 deletions cache_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,6 @@ func (p *listedPackage) obfuscatedImportPath() string {
case "runtime", "reflect", "embed",
// TODO: collect directly from cmd/internal/objabi/pkgspecial.go,
// in this particular case from allowAsmABIPkgs.
"syscall",
"internal/bytealg",
"internal/chacha8rand",
"internal/runtime/syscall/linux",
"internal/runtime/syscall/windows",
"internal/runtime/startlinetest":
Expand All @@ -255,6 +252,17 @@ func (p *listedPackage) obfuscatedImportPath() string {
if _, ok := compilerIntrinsics[p.ImportPath]; ok {
return p.ImportPath
}
// The linker forbids linknaming to certain runtime declarations
// unless a package is known to be allowed by import path string.
// The alternative would be to use -checklinkname=false, but that disables all checks entirely.
//
// TODO: we could probably remove this once we obfuscate the runtime,
// because then these runtime package and declaration names will be obfuscated too,
// so the linker will stop recognising them for the extra checks.
if _, ok := runtimeAndLinknamed[p.ImportPath]; ok {
return p.ImportPath
}

newPath := hashWithPackage(p, p.ImportPath)
log.Printf("import path %q hashed with %x to %q", p.ImportPath, p.GarbleActionID, newPath)
return newPath
Expand Down Expand Up @@ -379,7 +387,12 @@ func appendListedPackages(packages []string, mainBuild bool) error {
// We do not support obfuscating the runtime nor its dependencies.
case runtimeAndDeps[path],
// "unknown pc" crashes on windows in the cgo test otherwise.
path == "runtime/cgo":
path == "runtime/cgo",
// Obfuscating any of the fips140 packages breaks builds,
// not just because their import paths get special treatment,
// but also because they have special vars like "RODATA"
// and forbid relocations caused by literal obfuscation.
path == "crypto/internal/fips140", strings.HasPrefix(path, "crypto/internal/fips140/"):

// No point in obfuscating empty packages, like OS-specific ones that don't match.
case len(pkg.CompiledGoFiles) == 0:
Expand Down Expand Up @@ -445,7 +458,7 @@ func listPackage(from *listedPackage, path string) (*listedPackage, error) {
}
startTime := time.Now()
missing := make([]string, 0, len(runtimeAndLinknamed))
for _, linknamed := range runtimeAndLinknamed {
for linknamed := range runtimeAndLinknamed {
switch {
case sharedCache.ListedPackages[linknamed] != nil:
// We already have it; skip.
Expand All @@ -457,6 +470,8 @@ func listPackage(from *listedPackage, path string) (*listedPackage, error) {
missing = append(missing, linknamed)
}
}
slices.Sort(missing) // ensure determinism after the map iteration above

// We don't need any information about their dependencies, in this case.
if err := appendListedPackages(missing, false); err != nil {
return nil, fmt.Errorf("failed to load missing runtime-linknamed packages: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module mvdan.cc/garble

go 1.25
go 1.26

require (
github.com/bluekeyes/go-gitdiff v0.8.1
Expand Down
Loading
Loading