Skip to content

bin: Support macOS universal binaries #120

@nscuro

Description

@nscuro

go version -m can't currently deal with macOS universal binaries.

However, with Go 1.18, we will get the necessary tools to implement support for them ourselves, using buildinfo.Read(io.ReaderAt).
Also, Go has had support for reading fat mach-o binaries since 1.3 using macho.OpenFat.

I tinkered a bit, and it's now almost trivial to get go version -m results for all embedded binaries:

import (
	"debug/buildinfo"
	"debug/macho"
	"io"
	"log"
	"os"
)

func LoadBuildInfo118(binaryPath string) error {
	ff, err := macho.OpenFat(binaryPath)
	if err != nil {
		return err
	}
	ff.Close()

	binaryFile, err := os.Open(binaryPath)
	if err != nil {
		return err
	}
	defer binaryFile.Close()

	for i, arch := range ff.Arches {
		header := ff.Arches[i].FatArchHeader

		bi, err := buildinfo.Read(io.NewSectionReader(binaryFile, int64(header.Offset), int64(header.Size)))
		if err != nil {
			return err
		}

		log.Printf("%s: %s@%s (%s)", arch.Cpu, bi.Main.Path, bi.Main.Version, bi.Main.Sum)
	}

	return nil
}

Example output for the universal binary of goreleaser:

2022/02/05 12:34:35 CpuAmd64: github.com/goreleaser/goreleaser@v1.4.1 (h1:gW8sdjDEo2H2ZgcJmWsNZUcaJSD4MLvA/bw7+GYQ8kU=)
2022/02/05 12:34:35 CpuArm64: github.com/goreleaser/goreleaser@v1.4.1 (h1:gW8sdjDEo2H2ZgcJmWsNZUcaJSD4MLvA/bw7+GYQ8kU=)

Still torn on what the correct output would be though. Two SBOMs? A merged SBOM?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions