diff options
author | Ayke van Laethem <[email protected]> | 2023-03-28 21:47:19 +0200 |
---|---|---|
committer | Ayke van Laethem <[email protected]> | 2023-03-28 21:52:52 +0200 |
commit | 63b9500c3d351627bdeea3341df8c1b4605cdea5 (patch) | |
tree | 5ccf4e1e463b6c187a050ea182f43cdc5655e13d | |
parent | dfb8c996a158536f12db0fc1c9d04c5a7d26b491 (diff) | |
download | tinygo-63b9500c3d351627bdeea3341df8c1b4605cdea5.tar.gz tinygo-63b9500c3d351627bdeea3341df8c1b4605cdea5.zip |
builder: provide fallback code for nixnix-buildid
Change ReadBuildID to always use the fallback code if it can't find the
build ID in a conventional way.
This is the case when using Nix on MacOS, which for some reason decided
to pass `-no-uuid` to the linker breaking our support for reading the
build ID.
...I wish this was a feature of the standard library, but it appears we
have to invent it ourself.
-rw-r--r-- | builder/buildid.go | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/builder/buildid.go b/builder/buildid.go index 80592dc29..f0d710e38 100644 --- a/builder/buildid.go +++ b/builder/buildid.go @@ -77,27 +77,29 @@ func ReadBuildID() ([]byte, error) { } return raw[4:], nil } - default: - // On other platforms (such as Windows) there isn't such a convenient - // build ID. Luckily, Go does have an equivalent of the build ID, which - // is stored as a special symbol named go.buildid. You can read it - // using `go tool buildid`, but the code below extracts it directly - // from the binary. - // Unfortunately, because of stripping with the -w flag, no symbol - // table might be available. Therefore, we have to scan the binary - // directly. Luckily the build ID is always at the start of the file. - // For details, see: - // https://github.com/golang/go/blob/master/src/cmd/internal/buildid/buildid.go - fileStart := make([]byte, 4096) - _, err := io.ReadFull(f, fileStart) - index := bytes.Index(fileStart, []byte("\xff Go build ID: \"")) - if index < 0 || index > len(fileStart)-103 { - return nil, fmt.Errorf("could not find build id in %s", err) - } - buf := fileStart[index : index+103] - if bytes.HasPrefix(buf, []byte("\xff Go build ID: \"")) && bytes.HasSuffix(buf, []byte("\"\n \xff")) { - return buf[len("\xff Go build ID: \"") : len(buf)-1], nil - } + } + // We couldn't read the build ID from the binary. This could have two + // causes: + // 1. We're on an OS where this isn't implemented, like on Windows. + // 2. The build ID is not included in the binary. This is the default for + // example on Nix on MacOS. + // Luckily, Go does have an equivalent of the build ID, which is stored as a + // special symbol named go.buildid. You can read it using `go tool buildid`, + // for example. + // Unfortunately, because of stripping with the -w flag, no symbol table + // might be available. Therefore, we have to scan the binary directly. + // Luckily the build ID is always at the start of the file. + // For details, see: + // https://github.com/golang/go/blob/master/src/cmd/internal/buildid/buildid.go + fileStart := make([]byte, 4096) + _, err = io.ReadFull(f, fileStart) + index := bytes.Index(fileStart, []byte("\xff Go build ID: \"")) + if index < 0 || index > len(fileStart)-103 { + return nil, fmt.Errorf("could not find build id in %s", executable) + } + buf := fileStart[index : index+103] + if bytes.HasPrefix(buf, []byte("\xff Go build ID: \"")) && bytes.HasSuffix(buf, []byte("\"\n \xff")) { + return buf[len("\xff Go build ID: \"") : len(buf)-1], nil } return nil, fmt.Errorf("could not find build ID in %s", executable) } |