go-shrink

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2026 License: MIT

README

GoShrink

Go-aware binary pre-processor that makes Go ELF binaries dramatically more compressible by UPX.

What it does

GoShrink replaces high-entropy metadata in Go binaries with compressible stubs before UPX runs:

  1. Function name strings in pclntab — replaced with zeros
  2. Source file path strings in pclntab — replaced with zeros
  3. PC-to-line/file programs in pctab — replaced with minimal valid stubs
  4. Source paths in .rodata — zeroed

Runtime-critical data (pcsp for stack growth, pcdata for GC) is untouched.

Result

Tested on a 3.7 MB stripped Go binary (linux/arm, Go 1.26, FIPS):

Method Size
upx --brute only 1.06 MB
GoShrink + UPX 920 KB

Install

git clone https://github.com/awaistechnologist/go-shrink.git
cd go-shrink
./install.sh

Or directly:

cd go-shrink
go install ./cmd/goshrink/
export PATH="$HOME/go/bin:$PATH"

Usage

# Shrink a Go binary (pre-process + UPX --brute)
goshrink ./mybinary

# Pre-process only (skip UPX, for custom compression)
goshrink --no-upx -o output ./mybinary

# Analyze binary size (no modification)
goshrink --report ./mybinary

# Analyze with dead code advisory
goshrink --report --dce ./mybinary

Tradeoff

Stack traces will show ?:0 instead of file.go:42. This is acceptable for production embedded deployments where binary size matters more than debug readability.

Requirements

  • Go 1.20+ (for building goshrink)
  • Input binary must be ELF format (Linux). Mach-O/PE support planned.
  • UPX must be installed for compression (brew install upx / apt install upx)

How it works

Go binaries contain a pclntab section (PC-line table) that stores function names, source file paths, and line number mappings for every function. This metadata is used for stack traces and recover() but is not needed for correct execution.

The pclntab typically accounts for 25-35% of a stripped Go binary. Much of it is high-entropy string data that generic compressors like UPX struggle with. GoShrink replaces this data with zeros and minimal stubs that compress to almost nothing.

Critically, GoShrink preserves pcsp (stack pointer programs) and pcdata (GC pointer maps) which the Go runtime needs for stack growth and garbage collection.

Roadmap

  • pclntab function name and file path zeroing
  • Selective pcfile/pcln program stubbing (preserving pcsp/pcdata)
  • --report mode with per-package size breakdown
  • --dce advisory dead code analysis
  • Mach-O (macOS) support
  • PE (Windows) support
  • JSON output for --report
  • Profile-guided optimization hints

Contributing

Contributions are welcome! Here's how to get started:

  1. Fork the repo
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Make your changes
  4. Test against a real Go binary:
    go build ./cmd/goshrink/
    # Build any Go project as a test binary
    CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -ldflags="-s -w" -o /tmp/test-binary ./your-project
    # Run goshrink
    ./goshrink --report /tmp/test-binary
    ./goshrink /tmp/test-binary
    # Verify the shrunk binary still works
    
  5. Commit and open a PR
Areas where help is needed
  • Mach-O support — macOS binary format parsing and pclntab location
  • PE support — Windows binary format
  • More aggressive pctab stubbing — safely zeroing pcdata entries that are provably unused
  • Benchmarks — testing against popular Go projects (Docker, Hugo, CockroachDB, etc.)
  • CI pipeline — automated testing across Go versions and architectures
Code structure
cmd/goshrink/main.go       # CLI entry point
pkg/bininfo/bininfo.go     # ELF parsing, Go version detection, FIPS/UPX detection
pkg/pclntab/pclntab.go     # pclntab parser via debug/gosym
pkg/shrink/shrink.go       # Core shrink logic (pclntab zeroing + pctab stubbing)
pkg/callgraph/callgraph.go # Call graph construction + DCE analysis
pkg/report/report.go       # Report generation and formatting

Zero external dependencies — stdlib only.

License

MIT — see LICENSE

Directories

Path Synopsis
cmd
goshrink command
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL