diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 504a6eb..dfe4d2d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,11 +25,11 @@ jobs: test: strategy: matrix: - go-version: [1.25.x] + go-version: [1.26.x] os: [ubuntu-latest, macos-latest, windows-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 }} @@ -53,17 +53,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" @@ -78,9 +78,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 ./... diff --git a/README.md b/README.md index 452f40a..03c1170 100644 --- a/README.md +++ b/README.md @@ -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] diff --git a/cache_shared.go b/cache_shared.go index f0789a8..b5e5503 100644 --- a/cache_shared.go +++ b/cache_shared.go @@ -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": @@ -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 diff --git a/go.mod b/go.mod index 181cc8f..d9b9b08 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module mvdan.cc/garble -go 1.25 +go 1.26 require ( github.com/bluekeyes/go-gitdiff v0.8.1 diff --git a/go_std_tables.go b/go_std_tables.go index 8fdebde..e5ceedc 100644 --- a/go_std_tables.go +++ b/go_std_tables.go @@ -1,39 +1,43 @@ // Code generated by scripts/gen_go_std_tables.go; DO NOT EDIT. -// Generated from Go versions [go1.25.8]. +// Generated from Go versions [go1.26.1]. package main // runtimeAndDeps contains the runtime package and all of its transitive dependencies // as reported by 'go list -deps'. var runtimeAndDeps = map[string]bool{ - "internal/abi": true, // go1.25 linux/amd64 - "internal/asan": true, // go1.25 linux/amd64 - "internal/bytealg": true, // go1.25 linux/amd64 - "internal/byteorder": true, // go1.25 linux/amd64 - "internal/chacha8rand": true, // go1.25 linux/amd64 - "internal/coverage/rtcov": true, // go1.25 linux/amd64 - "internal/cpu": true, // go1.25 linux/amd64 - "internal/goarch": true, // go1.25 linux/amd64 - "internal/godebugs": true, // go1.25 linux/amd64 - "internal/goexperiment": true, // go1.25 linux/amd64 - "internal/goos": true, // go1.25 linux/amd64 - "internal/msan": true, // go1.25 linux/amd64 - "internal/profilerecord": true, // go1.25 linux/amd64 - "internal/race": true, // go1.25 linux/amd64 - "internal/runtime/atomic": true, // go1.25 linux/amd64 - "internal/runtime/cgroup": true, // go1.25 linux/amd64 - "internal/runtime/exithook": true, // go1.25 linux/amd64 - "internal/runtime/gc": true, // go1.25 linux/amd64 - "internal/runtime/maps": true, // go1.25 linux/amd64 - "internal/runtime/math": true, // go1.25 linux/amd64 - "internal/runtime/strconv": true, // go1.25 linux/amd64 - "internal/runtime/sys": true, // go1.25 linux/amd64 - "internal/runtime/syscall": true, // go1.25 linux/amd64 - "internal/stringslite": true, // go1.25 linux/amd64 - "internal/trace/tracev2": true, // go1.25 linux/amd64 - "runtime": true, // go1.25 linux/amd64 - "unsafe": true, // go1.25 linux/amd64 + "internal/abi": true, // go1.26 linux/amd64 + "internal/asan": true, // go1.26 linux/amd64 + "internal/bytealg": true, // go1.26 linux/amd64 + "internal/byteorder": true, // go1.26 linux/amd64 + "internal/chacha8rand": true, // go1.26 linux/amd64 + "internal/coverage/rtcov": true, // go1.26 linux/amd64 + "internal/cpu": true, // go1.26 linux/amd64 + "internal/goarch": true, // go1.26 linux/amd64 + "internal/godebugs": true, // go1.26 linux/amd64 + "internal/goexperiment": true, // go1.26 linux/amd64 + "internal/goos": true, // go1.26 linux/amd64 + "internal/msan": true, // go1.26 linux/amd64 + "internal/profilerecord": true, // go1.26 linux/amd64 + "internal/race": true, // go1.26 linux/amd64 + "internal/runtime/atomic": true, // go1.26 linux/amd64 + "internal/runtime/cgroup": true, // go1.26 linux/amd64 + "internal/runtime/exithook": true, // go1.26 linux/amd64 + "internal/runtime/gc": true, // go1.26 linux/amd64 + "internal/runtime/gc/scan": true, // go1.26 linux/amd64 + "internal/runtime/maps": true, // go1.26 linux/amd64 + "internal/runtime/math": true, // go1.26 linux/amd64 + "internal/runtime/pprof/label": true, // go1.26 linux/amd64 + "internal/runtime/sys": true, // go1.26 linux/amd64 + "internal/runtime/syscall/linux": true, // go1.26 linux/amd64 + "internal/runtime/syscall/windows": true, // go1.26 windows/386 + "internal/strconv": true, // go1.26 linux/amd64 + "internal/stringslite": true, // go1.26 linux/amd64 + "internal/trace/tracev2": true, // go1.26 linux/amd64 + "math/bits": true, // go1.26 linux/amd64 + "runtime": true, // go1.26 linux/amd64 + "unsafe": true, // go1.26 linux/amd64 } // runtimeAndLinknamed contains the runtime package and all the packages @@ -47,45 +51,48 @@ var runtimeAndDeps = map[string]bool{ // from the runtime package via //go:linkname directives on those platforms. // To make sure we have coverage on all platforms, we allow duplicates. var runtimeAndLinknamed = map[string]bool{ - "arena": true, // go1.25 - "crypto/internal/boring": true, // go1.25 - "crypto/internal/boring/bcache": true, // go1.25 - "crypto/internal/fips140": true, // go1.25 - "crypto/internal/sysrand": true, // go1.25 - "crypto/rand": true, // go1.25 - "crypto/x509/internal/macos": true, // go1.25 - "internal/bytealg": true, // go1.25 - "internal/coverage/cfile": true, // go1.25 - "internal/cpu": true, // go1.25 - "internal/godebug": true, // go1.25 - "internal/poll": true, // go1.25 - "internal/race": true, // go1.25 - "internal/reflectlite": true, // go1.25 - "internal/runtime/atomic": true, // go1.25 - "internal/runtime/cgroup": true, // go1.25 - "internal/runtime/maps": true, // go1.25 - "internal/sync": true, // go1.25 - "internal/synctest": true, // go1.25 - "internal/syscall/unix": true, // go1.25 - "internal/syscall/windows": true, // go1.25 - "maps": true, // go1.25 - "os": true, // go1.25 - "os/signal": true, // go1.25 - "plugin": true, // go1.25 - "reflect": true, // go1.25 - "runtime": true, // go1.25 - "runtime/debug": true, // go1.25 - "runtime/metrics": true, // go1.25 - "runtime/pprof": true, // go1.25 - "runtime/trace": true, // go1.25 - "sync": true, // go1.25 - "sync/atomic": true, // go1.25 - "sync_test": true, // go1.25 - "syscall": true, // go1.25 - "syscall/js": true, // go1.25 - "time": true, // go1.25 - "unique": true, // go1.25 - "weak": true, // go1.25 + "arena": true, // go1.26 + "crypto/fips140": true, // go1.26 + "crypto/internal/boring": true, // go1.26 + "crypto/internal/boring/bcache": true, // go1.26 + "crypto/internal/fips140": true, // go1.26 + "crypto/internal/sysrand": true, // go1.26 + "crypto/rand": true, // go1.26 + "crypto/subtle": true, // go1.26 + "crypto/x509/internal/macos": true, // go1.26 + "internal/bytealg": true, // go1.26 + "internal/coverage/cfile": true, // go1.26 + "internal/cpu": true, // go1.26 + "internal/godebug": true, // go1.26 + "internal/poll": true, // go1.26 + "internal/race": true, // go1.26 + "internal/reflectlite": true, // go1.26 + "internal/runtime/atomic": true, // go1.26 + "internal/runtime/cgroup": true, // go1.26 + "internal/runtime/maps": true, // go1.26 + "internal/sync": true, // go1.26 + "internal/synctest": true, // go1.26 + "internal/syscall/unix": true, // go1.26 + "internal/syscall/windows": true, // go1.26 + "maps": true, // go1.26 + "os": true, // go1.26 + "os/signal": true, // go1.26 + "plugin": true, // go1.26 + "reflect": true, // go1.26 + "runtime": true, // go1.26 + "runtime/debug": true, // go1.26 + "runtime/metrics": true, // go1.26 + "runtime/pprof": true, // go1.26 + "runtime/secret": true, // go1.26 + "runtime/trace": true, // go1.26 + "sync": true, // go1.26 + "sync/atomic": true, // go1.26 + "sync_test": true, // go1.26 + "syscall": true, // go1.26 + "syscall/js": true, // go1.26 + "time": true, // go1.26 + "unique": true, // go1.26 + "weak": true, // go1.26 // The net package linknames to the runtime, not the other way around. "net": true, // The testing package uses a //go:linkname directive pointing to testing/synctest, @@ -94,179 +101,189 @@ var runtimeAndLinknamed = map[string]bool{ } var compilerIntrinsics = map[string]map[string]bool{ + "crypto/internal/constanttime": { + "Select": true, // go1.26 + "boolToUint8": true, // go1.26 + }, "internal/runtime/atomic": { - "And": true, // go1.25 - "And32": true, // go1.25 - "And64": true, // go1.25 - "And8": true, // go1.25 - "Anduintptr": true, // go1.25 - "Cas": true, // go1.25 - "Cas64": true, // go1.25 - "CasRel": true, // go1.25 - "Casint32": true, // go1.25 - "Casint64": true, // go1.25 - "Casp1": true, // go1.25 - "Casuintptr": true, // go1.25 - "Load": true, // go1.25 - "Load64": true, // go1.25 - "Load8": true, // go1.25 - "LoadAcq": true, // go1.25 - "LoadAcq64": true, // go1.25 - "LoadAcquintptr": true, // go1.25 - "Loadint32": true, // go1.25 - "Loadint64": true, // go1.25 - "Loadp": true, // go1.25 - "Loaduint": true, // go1.25 - "Loaduintptr": true, // go1.25 - "Or": true, // go1.25 - "Or32": true, // go1.25 - "Or64": true, // go1.25 - "Or8": true, // go1.25 - "Oruintptr": true, // go1.25 - "Store": true, // go1.25 - "Store64": true, // go1.25 - "Store8": true, // go1.25 - "StoreRel": true, // go1.25 - "StoreRel64": true, // go1.25 - "StoreReluintptr": true, // go1.25 - "Storeint32": true, // go1.25 - "Storeint64": true, // go1.25 - "StorepNoWB": true, // go1.25 - "Storeuintptr": true, // go1.25 - "Xadd": true, // go1.25 - "Xadd64": true, // go1.25 - "Xaddint32": true, // go1.25 - "Xaddint64": true, // go1.25 - "Xadduintptr": true, // go1.25 - "Xchg": true, // go1.25 - "Xchg64": true, // go1.25 - "Xchg8": true, // go1.25 - "Xchgint32": true, // go1.25 - "Xchgint64": true, // go1.25 - "Xchguintptr": true, // go1.25 + "And": true, // go1.26 + "And32": true, // go1.26 + "And64": true, // go1.26 + "And8": true, // go1.26 + "Anduintptr": true, // go1.26 + "Cas": true, // go1.26 + "Cas64": true, // go1.26 + "CasRel": true, // go1.26 + "Casint32": true, // go1.26 + "Casint64": true, // go1.26 + "Casp1": true, // go1.26 + "Casuintptr": true, // go1.26 + "Load": true, // go1.26 + "Load64": true, // go1.26 + "Load8": true, // go1.26 + "LoadAcq": true, // go1.26 + "LoadAcq64": true, // go1.26 + "LoadAcquintptr": true, // go1.26 + "Loadint32": true, // go1.26 + "Loadint64": true, // go1.26 + "Loadp": true, // go1.26 + "Loaduint": true, // go1.26 + "Loaduintptr": true, // go1.26 + "Or": true, // go1.26 + "Or32": true, // go1.26 + "Or64": true, // go1.26 + "Or8": true, // go1.26 + "Oruintptr": true, // go1.26 + "Store": true, // go1.26 + "Store64": true, // go1.26 + "Store8": true, // go1.26 + "StoreRel": true, // go1.26 + "StoreRel64": true, // go1.26 + "StoreReluintptr": true, // go1.26 + "Storeint32": true, // go1.26 + "Storeint64": true, // go1.26 + "StorepNoWB": true, // go1.26 + "Storeuintptr": true, // go1.26 + "Xadd": true, // go1.26 + "Xadd64": true, // go1.26 + "Xaddint32": true, // go1.26 + "Xaddint64": true, // go1.26 + "Xadduintptr": true, // go1.26 + "Xchg": true, // go1.26 + "Xchg64": true, // go1.26 + "Xchg8": true, // go1.26 + "Xchgint32": true, // go1.26 + "Xchgint64": true, // go1.26 + "Xchguintptr": true, // go1.26 }, "internal/runtime/maps": { - "bitsetFirst": true, // go1.25 - "bitsetLowestSet": true, // go1.25 - "bitsetRemoveBelow": true, // go1.25 - "bitsetShiftOutLowest": true, // go1.25 - "ctrlGroupMatchEmpty": true, // go1.25 - "ctrlGroupMatchEmptyOrDeleted": true, // go1.25 - "ctrlGroupMatchFull": true, // go1.25 - "ctrlGroupMatchH2": true, // go1.25 + "bitsetFirst": true, // go1.26 + "bitsetLowestSet": true, // go1.26 + "bitsetRemoveBelow": true, // go1.26 + "bitsetShiftOutLowest": true, // go1.26 + "ctrlGroupMatchEmpty": true, // go1.26 + "ctrlGroupMatchEmptyOrDeleted": true, // go1.26 + "ctrlGroupMatchFull": true, // go1.26 + "ctrlGroupMatchH2": true, // go1.26 }, "internal/runtime/math": { - "Add64": true, // go1.25 - "Mul64": true, // go1.25 - "MulUintptr": true, // go1.25 + "Add64": true, // go1.26 + "Mul64": true, // go1.26 + "MulUintptr": true, // go1.26 }, "internal/runtime/sys": { - "Bswap32": true, // go1.25 - "Bswap64": true, // go1.25 - "Len64": true, // go1.25 - "Len8": true, // go1.25 - "OnesCount64": true, // go1.25 - "Prefetch": true, // go1.25 - "PrefetchStreamed": true, // go1.25 - "TrailingZeros32": true, // go1.25 - "TrailingZeros64": true, // go1.25 - "TrailingZeros8": true, // go1.25 + "Bswap32": true, // go1.26 + "Bswap64": true, // go1.26 + "GetCallerPC": true, // go1.26 + "GetCallerSP": true, // go1.26 + "GetClosurePtr": true, // go1.26 + "Len64": true, // go1.26 + "Len8": true, // go1.26 + "OnesCount64": true, // go1.26 + "Prefetch": true, // go1.26 + "PrefetchStreamed": true, // go1.26 + "TrailingZeros32": true, // go1.26 + "TrailingZeros64": true, // go1.26 + "TrailingZeros8": true, // go1.26 }, "math": { - "Abs": true, // go1.25 - "Ceil": true, // go1.25 - "Copysign": true, // go1.25 - "FMA": true, // go1.25 - "Floor": true, // go1.25 - "Round": true, // go1.25 - "RoundToEven": true, // go1.25 - "Trunc": true, // go1.25 - "sqrt": true, // go1.25 + "Abs": true, // go1.26 + "Ceil": true, // go1.26 + "Copysign": true, // go1.26 + "FMA": true, // go1.26 + "Floor": true, // go1.26 + "Round": true, // go1.26 + "RoundToEven": true, // go1.26 + "Trunc": true, // go1.26 + "sqrt": true, // go1.26 }, "math/big": { - "mulWW": true, // go1.25 + "mulWW": true, // go1.26 }, "math/bits": { - "Add": true, // go1.25 - "Add64": true, // go1.25 - "Div": true, // go1.25 - "Div64": true, // go1.25 - "Len": true, // go1.25 - "Len16": true, // go1.25 - "Len32": true, // go1.25 - "Len64": true, // go1.25 - "Len8": true, // go1.25 - "Mul": true, // go1.25 - "Mul64": true, // go1.25 - "OnesCount": true, // go1.25 - "OnesCount16": true, // go1.25 - "OnesCount32": true, // go1.25 - "OnesCount64": true, // go1.25 - "OnesCount8": true, // go1.25 - "Reverse": true, // go1.25 - "Reverse16": true, // go1.25 - "Reverse32": true, // go1.25 - "Reverse64": true, // go1.25 - "Reverse8": true, // go1.25 - "ReverseBytes16": true, // go1.25 - "ReverseBytes32": true, // go1.25 - "ReverseBytes64": true, // go1.25 - "RotateLeft": true, // go1.25 - "RotateLeft16": true, // go1.25 - "RotateLeft32": true, // go1.25 - "RotateLeft64": true, // go1.25 - "RotateLeft8": true, // go1.25 - "Sub": true, // go1.25 - "Sub64": true, // go1.25 - "TrailingZeros16": true, // go1.25 - "TrailingZeros32": true, // go1.25 - "TrailingZeros64": true, // go1.25 - "TrailingZeros8": true, // go1.25 + "Add": true, // go1.26 + "Add64": true, // go1.26 + "Div": true, // go1.26 + "Div64": true, // go1.26 + "Len": true, // go1.26 + "Len16": true, // go1.26 + "Len32": true, // go1.26 + "Len64": true, // go1.26 + "Len8": true, // go1.26 + "Mul": true, // go1.26 + "Mul64": true, // go1.26 + "OnesCount": true, // go1.26 + "OnesCount16": true, // go1.26 + "OnesCount32": true, // go1.26 + "OnesCount64": true, // go1.26 + "OnesCount8": true, // go1.26 + "Reverse": true, // go1.26 + "Reverse16": true, // go1.26 + "Reverse32": true, // go1.26 + "Reverse64": true, // go1.26 + "Reverse8": true, // go1.26 + "ReverseBytes16": true, // go1.26 + "ReverseBytes32": true, // go1.26 + "ReverseBytes64": true, // go1.26 + "RotateLeft": true, // go1.26 + "RotateLeft16": true, // go1.26 + "RotateLeft32": true, // go1.26 + "RotateLeft64": true, // go1.26 + "RotateLeft8": true, // go1.26 + "Sub": true, // go1.26 + "Sub64": true, // go1.26 + "TrailingZeros16": true, // go1.26 + "TrailingZeros32": true, // go1.26 + "TrailingZeros64": true, // go1.26 + "TrailingZeros8": true, // go1.26 }, "runtime": { - "publicationBarrier": true, // go1.25 + "KeepAlive": true, // go1.26 + "memequal": true, // go1.26 + "publicationBarrier": true, // go1.26 + "slicebytetostringtmp": true, // go1.26 }, "sync": { - "runtime_LoadAcquintptr": true, // go1.25 - "runtime_StoreReluintptr": true, // go1.25 + "runtime_LoadAcquintptr": true, // go1.26 + "runtime_StoreReluintptr": true, // go1.26 }, "sync/atomic": { - "AddInt32": true, // go1.25 - "AddInt64": true, // go1.25 - "AddUint32": true, // go1.25 - "AddUint64": true, // go1.25 - "AddUintptr": true, // go1.25 - "AndInt32": true, // go1.25 - "AndInt64": true, // go1.25 - "AndUint32": true, // go1.25 - "AndUint64": true, // go1.25 - "AndUintptr": true, // go1.25 - "CompareAndSwapInt32": true, // go1.25 - "CompareAndSwapInt64": true, // go1.25 - "CompareAndSwapUint32": true, // go1.25 - "CompareAndSwapUint64": true, // go1.25 - "CompareAndSwapUintptr": true, // go1.25 - "LoadInt32": true, // go1.25 - "LoadInt64": true, // go1.25 - "LoadPointer": true, // go1.25 - "LoadUint32": true, // go1.25 - "LoadUint64": true, // go1.25 - "LoadUintptr": true, // go1.25 - "OrInt32": true, // go1.25 - "OrInt64": true, // go1.25 - "OrUint32": true, // go1.25 - "OrUint64": true, // go1.25 - "OrUintptr": true, // go1.25 - "StoreInt32": true, // go1.25 - "StoreInt64": true, // go1.25 - "StoreUint32": true, // go1.25 - "StoreUint64": true, // go1.25 - "StoreUintptr": true, // go1.25 - "SwapInt32": true, // go1.25 - "SwapInt64": true, // go1.25 - "SwapUint32": true, // go1.25 - "SwapUint64": true, // go1.25 - "SwapUintptr": true, // go1.25 + "AddInt32": true, // go1.26 + "AddInt64": true, // go1.26 + "AddUint32": true, // go1.26 + "AddUint64": true, // go1.26 + "AddUintptr": true, // go1.26 + "AndInt32": true, // go1.26 + "AndInt64": true, // go1.26 + "AndUint32": true, // go1.26 + "AndUint64": true, // go1.26 + "AndUintptr": true, // go1.26 + "CompareAndSwapInt32": true, // go1.26 + "CompareAndSwapInt64": true, // go1.26 + "CompareAndSwapUint32": true, // go1.26 + "CompareAndSwapUint64": true, // go1.26 + "CompareAndSwapUintptr": true, // go1.26 + "LoadInt32": true, // go1.26 + "LoadInt64": true, // go1.26 + "LoadPointer": true, // go1.26 + "LoadUint32": true, // go1.26 + "LoadUint64": true, // go1.26 + "LoadUintptr": true, // go1.26 + "OrInt32": true, // go1.26 + "OrInt64": true, // go1.26 + "OrUint32": true, // go1.26 + "OrUint64": true, // go1.26 + "OrUintptr": true, // go1.26 + "StoreInt32": true, // go1.26 + "StoreInt64": true, // go1.26 + "StoreUint32": true, // go1.26 + "StoreUint64": true, // go1.26 + "StoreUintptr": true, // go1.26 + "SwapInt32": true, // go1.26 + "SwapInt64": true, // go1.26 + "SwapUint32": true, // go1.26 + "SwapUint64": true, // go1.26 + "SwapUintptr": true, // go1.26 }, } diff --git a/internal/linker/patches/go1.25/0001-add-custom-magic-value.patch b/internal/linker/patches/go1.26/0001-add-custom-magic-value.patch similarity index 84% rename from internal/linker/patches/go1.25/0001-add-custom-magic-value.patch rename to internal/linker/patches/go1.26/0001-add-custom-magic-value.patch index 1ce6dad..1aebf57 100644 --- a/internal/linker/patches/go1.25/0001-add-custom-magic-value.patch +++ b/internal/linker/patches/go1.26/0001-add-custom-magic-value.patch @@ -1,4 +1,4 @@ -From 1eb3d02d33155831067ca7db2c6517108c4305ae Mon Sep 17 00:00:00 2001 +From b59e8e940e82f488d5d688277046f6cd87c75908 Mon Sep 17 00:00:00 2001 From: pagran Date: Mon, 9 Jan 2023 13:30:00 +0100 Subject: [PATCH 1/3] add custom magic value @@ -8,7 +8,7 @@ Subject: [PATCH 1/3] add custom magic value 1 file changed, 17 insertions(+) diff --git a/cmd/link/internal/ld/pcln.go b/cmd/link/internal/ld/pcln.go -index ea08fd3d31..7bae9f18c5 100644 +index 08c4d4db83..ffe8fdf7a1 100644 --- a/cmd/link/internal/ld/pcln.go +++ b/cmd/link/internal/ld/pcln.go @@ -4,6 +4,10 @@ @@ -22,7 +22,7 @@ index ea08fd3d31..7bae9f18c5 100644 import ( "cmd/internal/goobj" "cmd/internal/objabi" -@@ -262,6 +266,19 @@ func (state *pclntab) generatePCHeader(ctxt *Link) { +@@ -282,6 +286,19 @@ func (state *pclntab) generatePCHeader(ctxt *Link) { if off != size { panic(fmt.Sprintf("pcHeader size: %d != %d", off, size)) } @@ -41,7 +41,7 @@ index ea08fd3d31..7bae9f18c5 100644 + header.SetUint32(ctxt.Arch, 0, garbleMagicVal) } - state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, writeHeader) + state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, int32(ctxt.Arch.PtrSize), writeHeader) -- -2.48.1 +2.53.0 diff --git a/internal/linker/patches/go1.25/0002-add-unexported-function-name-removing.patch b/internal/linker/patches/go1.26/0002-add-unexported-function-name-removing.patch similarity index 91% rename from internal/linker/patches/go1.25/0002-add-unexported-function-name-removing.patch rename to internal/linker/patches/go1.26/0002-add-unexported-function-name-removing.patch index 6839c27..91e4c24 100644 --- a/internal/linker/patches/go1.25/0002-add-unexported-function-name-removing.patch +++ b/internal/linker/patches/go1.26/0002-add-unexported-function-name-removing.patch @@ -1,4 +1,4 @@ -From 2a691e00bc659059133cd5604c7a099981cf684c Mon Sep 17 00:00:00 2001 +From 0d8063d9af410ceb914ba75b19a98686fe5f119c Mon Sep 17 00:00:00 2001 From: pagran Date: Mon, 9 Jan 2023 13:30:36 +0100 Subject: [PATCH 2/3] add unexported function name removing @@ -8,7 +8,7 @@ Subject: [PATCH 2/3] add unexported function name removing 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/cmd/link/internal/ld/pcln.go b/cmd/link/internal/ld/pcln.go -index 7bae9f18c5..b497573b15 100644 +index ffe8fdf7a1..c47b9eab72 100644 --- a/cmd/link/internal/ld/pcln.go +++ b/cmd/link/internal/ld/pcln.go @@ -8,6 +8,10 @@ import ( @@ -22,7 +22,7 @@ index 7bae9f18c5..b497573b15 100644 import ( "cmd/internal/goobj" "cmd/internal/objabi" -@@ -318,19 +322,56 @@ func walkFuncs(ctxt *Link, funcs []loader.Sym, f func(loader.Sym)) { +@@ -335,19 +339,56 @@ func walkFuncs(ctxt *Link, funcs []loader.Sym, f func(loader.Sym)) { func (state *pclntab) generateFuncnametab(ctxt *Link, funcs []loader.Sym) map[loader.Sym]uint32 { nameOffsets := make(map[loader.Sym]uint32, state.nfunc) @@ -79,7 +79,7 @@ index 7bae9f18c5..b497573b15 100644 + size += int64(len(name) + 1) // NULL terminate }) - state.funcnametab = state.addGeneratedSym(ctxt, "runtime.funcnametab", size, writeFuncNameTab) + state.funcnametab = state.addGeneratedSym(ctxt, "runtime.funcnametab", size, 1, writeFuncNameTab) -- -2.48.1 +2.53.0 diff --git a/internal/linker/patches/go1.25/0003-add-entryOff-encryption.patch b/internal/linker/patches/go1.26/0003-add-entryOff-encryption.patch similarity index 83% rename from internal/linker/patches/go1.25/0003-add-entryOff-encryption.patch rename to internal/linker/patches/go1.26/0003-add-entryOff-encryption.patch index b60a2b3..508204a 100644 --- a/internal/linker/patches/go1.25/0003-add-entryOff-encryption.patch +++ b/internal/linker/patches/go1.26/0003-add-entryOff-encryption.patch @@ -1,4 +1,4 @@ -From 03342e79193875d08bf3f88154e77a453b28c076 Mon Sep 17 00:00:00 2001 +From 16b978956b323d88ef4a48dbef124304f5206e90 Mon Sep 17 00:00:00 2001 From: pagran Date: Sat, 14 Jan 2023 21:36:16 +0100 Subject: [PATCH 3/3] add entryOff encryption @@ -8,11 +8,11 @@ Subject: [PATCH 3/3] add entryOff encryption 1 file changed, 20 insertions(+) diff --git a/cmd/link/internal/ld/pcln.go b/cmd/link/internal/ld/pcln.go -index b497573b15..f1021fcee3 100644 +index c47b9eab72..d58338f7c3 100644 --- a/cmd/link/internal/ld/pcln.go +++ b/cmd/link/internal/ld/pcln.go -@@ -806,6 +806,26 @@ func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSym - sb.SetUint32(ctxt.Arch, dataoff, uint32(ldr.SymValue(fdsym)-gofuncBase)) +@@ -980,6 +980,26 @@ func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSym + sb.SetUint32(ctxt.Arch, dataoff, uint32(ldr.SymValue(fdsym))) } } + @@ -39,5 +39,5 @@ index b497573b15..f1021fcee3 100644 // pclntab initializes the pclntab symbol with -- -2.48.1 +2.53.0 diff --git a/main.go b/main.go index ca5469b..6d04de3 100644 --- a/main.go +++ b/main.go @@ -544,8 +544,8 @@ func (f *seedFlag) Set(s string) error { func goVersionOK() bool { const ( - minGoVersion = "go1.25.0" // the minimum Go version we support; could be a bugfix release if needed - unsupportedGo = "go1.26" // the first major version we don't support + minGoVersion = "go1.26.0" // the minimum Go version we support; could be a bugfix release if needed + unsupportedGo = "go1.27" // the first major version we don't support ) toolchainVersion := sharedCache.GoEnv.GOVERSION diff --git a/runtime_patch.go b/runtime_patch.go index 4002b18..875a282 100644 --- a/runtime_patch.go +++ b/runtime_patch.go @@ -12,46 +12,30 @@ import ( ah "mvdan.cc/garble/internal/asthelper" ) -// updateMagicValue updates hardcoded value of hdr.magic -// when verifying header in symtab.go +// updateMagicValue updates the global constant +// `Go120PCLnTabMagic PCLnTabMagic = 0xfffffff1` +// to use the provided magic value integer. +// This is the latest magic value in use as of Go 1.26. func updateMagicValue(file *ast.File, magicValue uint32) { magicUpdated := false - // Find `hdr.magic != 0xfffffff?` in symtab.go and update to random magicValue - updateMagic := func(node ast.Node) bool { - binExpr, ok := node.(*ast.BinaryExpr) - if !ok || binExpr.Op != token.NEQ { - return true - } - - selectorExpr, ok := binExpr.X.(*ast.SelectorExpr) - if !ok { - return true - } - - if ident, ok := selectorExpr.X.(*ast.Ident); !ok || ident.Name != "hdr" { - return true - } - if selectorExpr.Sel.Name != "magic" { - return true - } - - if _, ok := binExpr.Y.(*ast.BasicLit); !ok { - return true - } - binExpr.Y = &ast.BasicLit{ - Kind: token.INT, - Value: strconv.FormatUint(uint64(magicValue), 10), - } - magicUpdated = true - return false - } - for _, decl := range file.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if ok && funcDecl.Name.Name == "moduledataverify1" { - ast.Inspect(funcDecl, updateMagic) - break + decl, ok := decl.(*ast.GenDecl) + if !ok || decl.Tok != token.CONST { + continue + } + for _, spec := range decl.Specs { + spec, ok := spec.(*ast.ValueSpec) + if !ok || len(spec.Names) != 1 || len(spec.Values) != 1 { + continue + } + if spec.Names[0].Name == "Go120PCLnTabMagic" { + spec.Values[0] = &ast.BasicLit{ + Kind: token.INT, + Value: strconv.FormatUint(uint64(magicValue), 10), + } + magicUpdated = true + } } } diff --git a/scripts/gen_go_std_tables.go b/scripts/gen_go_std_tables.go index 03d29ec..613fbaf 100644 --- a/scripts/gen_go_std_tables.go +++ b/scripts/gen_go_std_tables.go @@ -37,7 +37,7 @@ var goPlatforms = []goPlatform{ {"darwin", "arm64", 2}, {"windows", "386", 3}, } -var goVersions = []string{"go1.25.8"} +var goVersions = []string{"go1.26.1"} var tmplTables = template.Must(template.New("").Parse(` // Code generated by scripts/gen_go_std_tables.go; DO NOT EDIT. @@ -173,7 +173,7 @@ func lines(vs versionedString) []versionedString { } var rxLinkname = regexp.MustCompile(`^//go:linkname .* ([^.]*)\.[^.]*$`) -var rxIntrinsic = regexp.MustCompile(`\b(addF|alias)\("([^"]*)", "([^"]*)",`) +var rxIntrinsic = regexp.MustCompile(`\b(add|addF|alias)\("([^"]*)", "([^"]*)",`) func main() { var runtimeAndDeps []versionedString diff --git a/testdata/script/goversion.txtar b/testdata/script/goversion.txtar index 7d5278e..f32caf2 100644 --- a/testdata/script/goversion.txtar +++ b/testdata/script/goversion.txtar @@ -7,12 +7,12 @@ env PATH=${WORK}/.bin${:}${PATH} # An empty go version. env TOOLCHAIN_GOVERSION='' ! exec garble build -stderr 'Go version is too old; please upgrade to go1\.25\.0 or newer' +stderr 'Go version is too old; please upgrade to go1\.26\.0 or newer' # A clearly invalid go version. env TOOLCHAIN_GOVERSION='bogus version' ! exec garble build -stderr 'Go version "bogus" appears to be invalid or too old; use go1\.25\.0 or newer' +stderr 'Go version "bogus" appears to be invalid or too old; use go1\.26\.0 or newer' # We should error on a devel version that's too old; # note that they started with the string "devel", @@ -26,64 +26,60 @@ stderr 'Go version .* appears to be invalid or too old' # A current devel version should be fine. # Note that we don't look at devel version timestamps. -env GARBLE_TEST_GOVERSION='go1.25.0' -# TODO: we do not currently bother with supporting tip. -# env TOOLCHAIN_GOVERSION='go version go1.26-devel_36863d6194 2025-10-17 01:07:59 -0700 linux/amd64' -# ! exec garble build -# stderr 'mocking the real build' +env GARBLE_TEST_GOVERSION='go1.26.0' # We should error on a stable version that's too old. env TOOLCHAIN_GOVERSION='go1.14' ! exec garble build -stderr 'Go version "go1\.14" is too old; please upgrade to go1\.25\.0 or newer' +stderr 'Go version "go1\.14" is too old; please upgrade to go1\.26\.0 or newer' # We should reject a future stable version, as we don't have linker patches yet. # Note that we need to bump the version of Go that supposedly built it, too. -env GARBLE_TEST_GOVERSION='go1.28.2' -env TOOLCHAIN_GOVERSION='go1.28.2' +env GARBLE_TEST_GOVERSION='go1.38.2' +env TOOLCHAIN_GOVERSION='go1.38.2' ! exec garble build -stderr 'Go version "go1\.28\.2" is too new; Go linker patches aren''t available for go1\.26 or later yet' +stderr 'Go version "go1\.38\.2" is too new; Go linker patches aren''t available for go1\.27 or later yet' # We should accept custom devel strings. -env TOOLCHAIN_GOVERSION='go1.25.0-somecustomversion' +env TOOLCHAIN_GOVERSION='go1.26.0-somecustomversion' ! exec garble build stderr 'mocking the real build' # A stable version with a build-time GOEXPERIMENT. # See: https://github.com/golang/go/issues/75953 -env TOOLCHAIN_GOVERSION='go1.25.0 X:nodwarf5' +env TOOLCHAIN_GOVERSION='go1.26.0 X:nodwarf5' ! exec garble build stderr 'mocking the real build' # The current toolchain may be older than the one that built garble. -env GARBLE_TEST_GOVERSION='go1.25.1' -env TOOLCHAIN_GOVERSION='go1.25.0' +env GARBLE_TEST_GOVERSION='go1.26.1' +env TOOLCHAIN_GOVERSION='go1.26.0' ! exec garble build stderr 'mocking the real build' # The current toolchain may be equal to the one that built garble. -env GARBLE_TEST_GOVERSION='go1.25.0' -env TOOLCHAIN_GOVERSION='go1.25.0' +env GARBLE_TEST_GOVERSION='go1.26.0' +env TOOLCHAIN_GOVERSION='go1.26.0' ! exec garble build stderr 'mocking the real build' # The current toolchain must not be newer than the one that built garble. env GARBLE_TEST_GOVERSION='go1.18' -env TOOLCHAIN_GOVERSION='go1.25.0' +env TOOLCHAIN_GOVERSION='go1.26.0' ! exec garble build -stderr 'garble was built with "go1\.18" and can''t be used with the newer "go1\.25\.0"; rebuild ' +stderr 'garble was built with "go1\.18" and can''t be used with the newer "go1\.26\.0"; rebuild ' # We'll error even if the difference is a minor (bugfix) level. # In practice it probably wouldn't matter, but in theory it could still lead to tricky bugs. -env GARBLE_TEST_GOVERSION='go1.25.11' -env TOOLCHAIN_GOVERSION='go1.25.14' +env GARBLE_TEST_GOVERSION='go1.26.11' +env TOOLCHAIN_GOVERSION='go1.26.14' ! exec garble build -stderr 'garble was built with "go1\.25\.11" and can''t be used with the newer "go1\.25\.14"; rebuild ' +stderr 'garble was built with "go1\.26\.11" and can''t be used with the newer "go1\.26\.14"; rebuild ' # If garble builds itself and is then used, it won't know what version built it. # As a fallback, we drop the comparison against the toolchain's version. env GARBLE_TEST_GOVERSION='bogus version' -env TOOLCHAIN_GOVERSION='go1.25.0' +env TOOLCHAIN_GOVERSION='go1.26.0' ! exec garble build stderr 'mocking the real build' -- go.mod -- diff --git a/transformer.go b/transformer.go index b45374b..d6da74a 100644 --- a/transformer.go +++ b/transformer.go @@ -695,16 +695,20 @@ func (tf *transformer) transformCompile(args []string) ([]string, error) { for i, file := range files { basename := filepath.Base(paths[i]) log.Printf("obfuscating %s", basename) - if tf.curPkg.ImportPath == "runtime" { + switch tf.curPkg.ImportPath { + case "runtime": if flagTiny { // strip unneeded runtime code stripRuntime(basename, file) tf.useAllImports(file) } if basename == "symtab.go" { - updateMagicValue(file, magicValue()) updateEntryOffset(file, entryOffKey()) } + case "internal/abi": + if basename == "symtab.go" { + updateMagicValue(file, magicValue()) + } } if err := tf.transformDirectives(file.Comments); err != nil { return nil, err