From 6ee3ed1711ea80064bf7211ddf8c5ea74d21873f Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 8 Feb 2026 01:44:08 +0900 Subject: [PATCH 1/7] internal/rosa/go: alternative bootstrap path For targets where the bootstrap toolchain is not available. Signed-off-by: Ophestra --- internal/rosa/go.go | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/internal/rosa/go.go b/internal/rosa/go.go index 31417ee..7f4a04b 100644 --- a/internal/rosa/go.go +++ b/internal/rosa/go.go @@ -63,18 +63,49 @@ ln -s \ } func (t Toolchain) newGoLatest() pkg.Artifact { + var ( + bootstrapEnv []string + bootstrapExtra []pkg.Artifact + ) + switch runtime.GOARCH { + case "amd64": + bootstrapExtra = append(bootstrapExtra, t.newGoBootstrap()) + + case "arm64": + bootstrapEnv = append(bootstrapEnv, + "GOROOT_BOOTSTRAP=/system", + ) + bootstrapExtra = append(bootstrapExtra, + t.Load(Binutils), + + t.Load(GMP), + t.Load(MPFR), + t.Load(MPC), + + t.Load(Zlib), + t.Load(Libucontext), + + t.Load(gcc), + ) + + default: + panic("unsupported target " + runtime.GOARCH) + } + go119 := t.newGo( "1.19", "9_e0aFHsIkVxWVGsp9T2RvvjOc3p4n9o9S8tkNe9Cvgzk_zI2FhRQB7ioQkeAAro", - []string{"CGO_ENABLED=0"}, ` + append(bootstrapEnv, "CGO_ENABLED=0"), ` rm \ crypto/tls/handshake_client_test.go \ os/os_unix_test.go +sed -i \ + 's/os\.Getenv("GCCGO")$/"nonexistent"/' \ + go/internal/gccgoimporter/importer_test.go echo \ 'type syscallDescriptor = int' >> \ os/rawconn_test.go -`, t.newGoBootstrap(), - ) +`, bootstrapExtra...) go121 := t.newGo( "1.21.13", From c60762fe85f16f0ed1e51fad4bacff5f072891d8 Mon Sep 17 00:00:00 2001 From: mae Date: Sat, 7 Feb 2026 20:34:23 -0600 Subject: [PATCH 2/7] cmd/irdump: create cli --- cmd/irdump/main.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 cmd/irdump/main.go diff --git a/cmd/irdump/main.go b/cmd/irdump/main.go new file mode 100644 index 0000000..432590f --- /dev/null +++ b/cmd/irdump/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "bytes" + "errors" + "io" + "log" + "os" + + "hakurei.app/command" +) + +func main() { + log.SetFlags(0) + log.SetPrefix("irdump: ") + + var ( + flagOutput string + flagReal bool + ) + c := command.New(os.Stderr, log.Printf, "irdump", func(args []string) (err error) { + var input *os.File + if len(args) < 1 { + return errors.New("irdump requires 1 argument") + } + if input, err = os.Open(args[0]); err != nil { + return + } + defer input.Close() + + var output *os.File + if flagOutput == "" { + output = os.Stdout + } else { + defer output.Close() + if output, err = os.Create(flagOutput); err != nil { + return + } + } + + inputData := bytes.NewBuffer(nil) + if _, err = io.Copy(inputData, input); err != nil { + return + } + var out string + if out, err = Disassemble(inputData.Bytes(), flagReal); err != nil { + return + } + if _, err = output.WriteString(out); err != nil { + return + } + return + }).Flag( + &flagOutput, + "o", command.StringFlag(""), + "Output file for asm (leave empty for stdout)", + ).Flag( + &flagReal, + "r", command.BoolFlag(false), + "skip label generation; idents print real value") + + c.MustParse(os.Args[1:], func(err error) { + log.Fatal(err) + }) +} +func Disassemble(ir []byte, real bool) (string, error) { + return "hello world", nil +} From 58431161b5fea93aef2794368a288bd3e1b34257 Mon Sep 17 00:00:00 2001 From: mae Date: Sun, 8 Feb 2026 00:30:43 -0600 Subject: [PATCH 3/7] cmd/irdump: basic disassembler --- cmd/irdump/main.go | 27 ++++---- internal/pkg/asm.go | 151 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 internal/pkg/asm.go diff --git a/cmd/irdump/main.go b/cmd/irdump/main.go index 432590f..8c608ab 100644 --- a/cmd/irdump/main.go +++ b/cmd/irdump/main.go @@ -1,13 +1,12 @@ package main import ( - "bytes" "errors" - "io" "log" "os" "hakurei.app/command" + "hakurei.app/internal/pkg" ) func main() { @@ -17,10 +16,12 @@ func main() { var ( flagOutput string flagReal bool + flagHeader bool + flagForce bool ) c := command.New(os.Stderr, log.Printf, "irdump", func(args []string) (err error) { var input *os.File - if len(args) < 1 { + if len(args) != 1 { return errors.New("irdump requires 1 argument") } if input, err = os.Open(args[0]); err != nil { @@ -38,12 +39,8 @@ func main() { } } - inputData := bytes.NewBuffer(nil) - if _, err = io.Copy(inputData, input); err != nil { - return - } var out string - if out, err = Disassemble(inputData.Bytes(), flagReal); err != nil { + if out, err = pkg.Disassemble(input, flagReal, flagHeader, flagForce); err != nil { return } if _, err = output.WriteString(out); err != nil { @@ -57,12 +54,18 @@ func main() { ).Flag( &flagReal, "r", command.BoolFlag(false), - "skip label generation; idents print real value") + "skip label generation; idents print real value", + ).Flag( + &flagHeader, + "h", command.BoolFlag(false), + "display artifact headers", + ).Flag( + &flagForce, + "f", command.BoolFlag(false), + "force display (skip validations)", + ) c.MustParse(os.Args[1:], func(err error) { log.Fatal(err) }) } -func Disassemble(ir []byte, real bool) (string, error) { - return "hello world", nil -} diff --git a/internal/pkg/asm.go b/internal/pkg/asm.go new file mode 100644 index 0000000..4344d01 --- /dev/null +++ b/internal/pkg/asm.go @@ -0,0 +1,151 @@ +package pkg + +import ( + "encoding/binary" + "fmt" + "io" + "strconv" + "strings" +) + +func Disassemble(r io.Reader, real bool, showHeader bool, force bool) (s string, err error) { + var values [][2]string + sb := new(strings.Builder) + header := true + for err == nil { + if header { + var kind uint64 + var size uint64 + hsb := new(strings.Builder) + + if kind, err = nextUint64(r); err != nil { + break + } + if size, err = nextUint64(r); err != nil { + break + } + for i := 0; uint64(i) < size; i++ { + var did Checksum + var dkind uint64 + if dkind, err = nextUint64(r); err != nil { + break + } + if did, err = nextIdent(r); err != nil { + break + } + + hsb.WriteString(fmt.Sprintf("\t\t\t%s\t%s\n", intToKind(dkind), Encode(did))) + } + header = false + if showHeader { + values = append(values, [2]string{"head", fmt.Sprintf("%s [\n%s]", intToKind(kind), hsb.String())}) + } + } + var k uint32 + if k, err = nextUint32(r); err != nil { + break + } + kind := IRValueKind(k) + switch kind { + case IRKindEnd: + var a uint32 + if a, err = nextUint32(r); err != nil { + break + } + if a&1 != 0 { + var sum Checksum + if sum, err = nextIdent(r); err != nil { + break + } + values = append(values, [2]string{"end", Encode(sum)}) + } else { + values = append(values, [2]string{"end", ""}) + } + header = true + continue + + case IRKindIdent: + // discard ancillary + if _, err = nextUint32(r); err != nil { + break + } + var sum Checksum + if sum, err = nextIdent(r); err != nil { + break + } + + values = append(values, [2]string{"id", Encode(sum)}) + continue + case IRKindUint32: + var i uint32 + if i, err = nextUint32(r); err != nil { + break + } + values = append(values, [2]string{"int", strconv.FormatUint(uint64(i), 10)}) + case IRKindString: + var l uint32 + if l, err = nextUint32(r); err != nil { + break + } + s := make([]byte, l+(wordSize-(l)%wordSize)%wordSize) + if _, err = r.Read(s); err != nil { + break + } + values = append(values, [2]string{"str", fmt.Sprintf("\"%s\"", string(s[:l]))}) + continue + default: + var i uint32 + if i, err = nextUint32(r); err != nil { + break + } + values = append(values, [2]string{fmt.Sprintf("$%x", uint32(kind)), strconv.FormatUint(uint64(i), 10)}) + } + } + if err != io.EOF { + return + } + err = nil + for i := 0; i < len(values); i++ { + sb.WriteString(fmt.Sprintf("%s\t\t%s\n", values[i][0], values[i][1])) + } + return sb.String(), err +} +func nextUint32(r io.Reader) (uint32, error) { + i := make([]byte, 4) + _, err := r.Read(i) + if err != nil { + return 0, err + } + return binary.LittleEndian.Uint32(i), nil +} +func nextUint64(r io.Reader) (uint64, error) { + i := make([]byte, 8) + _, err := r.Read(i) + if err != nil { + return 0, err + } + return binary.LittleEndian.Uint64(i), nil +} +func nextIdent(r io.Reader) (Checksum, error) { + i := make([]byte, 48) + if _, err := r.Read(i); err != nil { + return Checksum{}, err + } + return Checksum(i), nil +} +func intToKind(i uint64) string { + switch Kind(i) { + case KindHTTPGet: + return "http_get" + case KindTar: + return "tar" + case KindExec: + return "exec" + case KindExecNet: + return "exec_net" + case KindFile: + return "file" + default: + return fmt.Sprintf("$%d", i-KindCustomOffset) + } +} From 15dadee24ac02753b04465cda1bd7c6c5b163204 Mon Sep 17 00:00:00 2001 From: mae Date: Sun, 8 Feb 2026 03:09:02 -0600 Subject: [PATCH 4/7] cmd/irdump: formatted disassembly --- cmd/irdump/main.go | 9 ++- internal/pkg/asm.go | 153 +++++++++++++++++++++++++++++++------------- 2 files changed, 116 insertions(+), 46 deletions(-) diff --git a/cmd/irdump/main.go b/cmd/irdump/main.go index 8c608ab..e8faaeb 100644 --- a/cmd/irdump/main.go +++ b/cmd/irdump/main.go @@ -18,6 +18,7 @@ func main() { flagReal bool flagHeader bool flagForce bool + flagRaw bool ) c := command.New(os.Stderr, log.Printf, "irdump", func(args []string) (err error) { var input *os.File @@ -40,7 +41,7 @@ func main() { } var out string - if out, err = pkg.Disassemble(input, flagReal, flagHeader, flagForce); err != nil { + if out, err = pkg.Disassemble(input, flagReal, flagHeader, flagForce, flagRaw); err != nil { return } if _, err = output.WriteString(out); err != nil { @@ -57,12 +58,16 @@ func main() { "skip label generation; idents print real value", ).Flag( &flagHeader, - "h", command.BoolFlag(false), + "H", command.BoolFlag(false), "display artifact headers", ).Flag( &flagForce, "f", command.BoolFlag(false), "force display (skip validations)", + ).Flag( + &flagRaw, + "R", command.BoolFlag(false), + "don't format output", ) c.MustParse(os.Args[1:], func(err error) { diff --git a/internal/pkg/asm.go b/internal/pkg/asm.go index 4344d01..86fc1e4 100644 --- a/internal/pkg/asm.go +++ b/internal/pkg/asm.go @@ -8,144 +8,209 @@ import ( "strings" ) -func Disassemble(r io.Reader, real bool, showHeader bool, force bool) (s string, err error) { - var values [][2]string +type asmOutLine struct { + pos int + word int + kindData int64 + valueData []byte + indent int + kind string + value string +} + +var spacingLine = asmOutLine{ + pos: -1, + kindData: -1, + valueData: nil, + indent: 0, + kind: "", + value: "", +} + +func Disassemble(r io.Reader, real bool, showHeader bool, force bool, raw bool) (s string, err error) { + var lines []asmOutLine sb := new(strings.Builder) header := true + pos := new(int) + for err == nil { if header { var kind uint64 var size uint64 - hsb := new(strings.Builder) - - if kind, err = nextUint64(r); err != nil { + var bsize []byte + p := *pos + if _, kind, err = nextUint64(r, pos); err != nil { break } - if size, err = nextUint64(r); err != nil { + if bsize, size, err = nextUint64(r, pos); err != nil { break } + if showHeader { + lines = append(lines, asmOutLine{p, 8, int64(kind), bsize, 0, "head " + intToKind(kind), ""}) + } for i := 0; uint64(i) < size; i++ { var did Checksum var dkind uint64 - if dkind, err = nextUint64(r); err != nil { + p := *pos + if _, dkind, err = nextUint64(r, pos); err != nil { break } - if did, err = nextIdent(r); err != nil { + if _, did, err = nextIdent(r, pos); err != nil { break } - - hsb.WriteString(fmt.Sprintf("\t\t\t%s\t%s\n", intToKind(dkind), Encode(did))) + if showHeader { + lines = append(lines, asmOutLine{p, 8, int64(dkind), nil, 1, intToKind(dkind), Encode(did)}) + } } header = false - if showHeader { - values = append(values, [2]string{"head", fmt.Sprintf("%s [\n%s]", intToKind(kind), hsb.String())}) - } } var k uint32 - if k, err = nextUint32(r); err != nil { + p := *pos + if _, k, err = nextUint32(r, pos); err != nil { break } kind := IRValueKind(k) switch kind { case IRKindEnd: var a uint32 - if a, err = nextUint32(r); err != nil { + var ba []byte + if ba, a, err = nextUint32(r, pos); err != nil { break } if a&1 != 0 { var sum Checksum - if sum, err = nextIdent(r); err != nil { + if _, sum, err = nextIdent(r, pos); err != nil { break } - values = append(values, [2]string{"end", Encode(sum)}) + lines = append(lines, asmOutLine{p, 4, int64(kind), ba, 1, "end ", Encode(sum)}) } else { - values = append(values, [2]string{"end", ""}) + lines = append(lines, asmOutLine{p, 4, int64(kind), []byte{0, 0, 0, 0}, 1, "end ", ""}) } + lines = append(lines, spacingLine) header = true continue case IRKindIdent: + var a []byte // discard ancillary - if _, err = nextUint32(r); err != nil { + if a, _, err = nextUint32(r, pos); err != nil { break } var sum Checksum - if sum, err = nextIdent(r); err != nil { + if _, sum, err = nextIdent(r, pos); err != nil { break } - values = append(values, [2]string{"id", Encode(sum)}) + lines = append(lines, asmOutLine{p, 4, int64(kind), a, 1, "id ", Encode(sum)}) continue case IRKindUint32: var i uint32 - if i, err = nextUint32(r); err != nil { + var bi []byte + if bi, i, err = nextUint32(r, pos); err != nil { break } - values = append(values, [2]string{"int", strconv.FormatUint(uint64(i), 10)}) + lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "int ", strconv.FormatUint(uint64(i), 10)}) case IRKindString: var l uint32 - if l, err = nextUint32(r); err != nil { + var bl []byte + if bl, l, err = nextUint32(r, pos); err != nil { break } s := make([]byte, l+(wordSize-(l)%wordSize)%wordSize) - if _, err = r.Read(s); err != nil { + var n int + if n, err = r.Read(s); err != nil { break } - values = append(values, [2]string{"str", fmt.Sprintf("\"%s\"", string(s[:l]))}) + *pos = *pos + n + + lines = append(lines, asmOutLine{p, 4, int64(kind), bl, 1, "str ", strconv.Quote(string(s[:l]))}) continue default: - var i uint32 - if i, err = nextUint32(r); err != nil { + var bi []byte + if bi, _, err = nextUint32(r, pos); err != nil { break } - values = append(values, [2]string{fmt.Sprintf("$%x", uint32(kind)), strconv.FormatUint(uint64(i), 10)}) + lines = append(lines, asmOutLine{p, 4, int64(kind), bi, 1, "????", ""}) } } if err != io.EOF { return } err = nil - for i := 0; i < len(values); i++ { - sb.WriteString(fmt.Sprintf("%s\t\t%s\n", values[i][0], values[i][1])) + for _, line := range lines { + if raw { + if line.pos != -1 { + sb.WriteString(fmt.Sprintf("%s\t%s\n", line.kind, line.value)) + } + } else { + if line.pos == -1 { + sb.WriteString("\n") + } else if line.word == 4 { + sb.WriteString(fmt.Sprintf("%06x: %04x %04x%s %s %s\n", line.pos, binary.LittleEndian.AppendUint32(nil, uint32(line.kindData)), line.valueData, headerSpacing(showHeader), line.kind, line.value)) + } else { + kind := binary.LittleEndian.AppendUint64(nil, uint64(line.kindData)) + value := line.valueData + if len(value) == 8 { + sb.WriteString(fmt.Sprintf("%06x: %04x %04x %04x %04x %s %s\n", line.pos, kind[:4], kind[4:], value[:4], value[4:], line.kind, line.value)) + } else { + sb.WriteString(fmt.Sprintf("%06x: %04x %04x %s %s\n", line.pos, kind[:4], kind[4:], line.kind, line.value)) + } + + } + } + } return sb.String(), err } -func nextUint32(r io.Reader) (uint32, error) { +func nextUint32(r io.Reader, pos *int) ([]byte, uint32, error) { i := make([]byte, 4) _, err := r.Read(i) if err != nil { - return 0, err + return i, 0, err } - return binary.LittleEndian.Uint32(i), nil + p := *pos + 4 + *pos = p + return i, binary.LittleEndian.Uint32(i), nil } -func nextUint64(r io.Reader) (uint64, error) { +func nextUint64(r io.Reader, pos *int) ([]byte, uint64, error) { i := make([]byte, 8) _, err := r.Read(i) if err != nil { - return 0, err + return i, 0, err } - return binary.LittleEndian.Uint64(i), nil + p := *pos + 8 + *pos = p + return i, binary.LittleEndian.Uint64(i), nil } -func nextIdent(r io.Reader) (Checksum, error) { +func nextIdent(r io.Reader, pos *int) ([]byte, Checksum, error) { i := make([]byte, 48) if _, err := r.Read(i); err != nil { - return Checksum{}, err + return i, Checksum{}, err } - return Checksum(i), nil + p := *pos + 48 + *pos = p + return i, Checksum(i), nil } func intToKind(i uint64) string { switch Kind(i) { case KindHTTPGet: - return "http_get" + return "http" case KindTar: - return "tar" + return "tar " case KindExec: return "exec" case KindExecNet: - return "exec_net" + return "exen" case KindFile: return "file" default: - return fmt.Sprintf("$%d", i-KindCustomOffset) + return fmt.Sprintf("$%d ", i-KindCustomOffset) } } +func headerSpacing(showHeader bool) string { + if showHeader { + return " " + } + + return "" +} From 30405106704a84aecb00a5ac34851c9a96d5cb5c Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 8 Feb 2026 01:44:08 +0900 Subject: [PATCH 5/7] internal/rosa/go: alternative bootstrap path For targets where the bootstrap toolchain is not available. Signed-off-by: Ophestra --- internal/rosa/go.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/rosa/go.go b/internal/rosa/go.go index 7f4a04b..27bfa43 100644 --- a/internal/rosa/go.go +++ b/internal/rosa/go.go @@ -66,6 +66,8 @@ func (t Toolchain) newGoLatest() pkg.Artifact { var ( bootstrapEnv []string bootstrapExtra []pkg.Artifact + + finalEnv []string ) switch runtime.GOARCH { case "amd64": @@ -88,6 +90,8 @@ func (t Toolchain) newGoLatest() pkg.Artifact { t.Load(gcc), ) + finalEnv = append(finalEnv, "CGO_ENABLED=0") + default: panic("unsupported target " + runtime.GOARCH) } @@ -98,6 +102,7 @@ func (t Toolchain) newGoLatest() pkg.Artifact { append(bootstrapEnv, "CGO_ENABLED=0"), ` rm \ crypto/tls/handshake_client_test.go \ + cmd/pprof/pprof_test.go \ os/os_unix_test.go sed -i \ 's/os\.Getenv("GCCGO")$/"nonexistent"/' \ @@ -128,7 +133,7 @@ echo \ go123 := t.newGo( "1.23.12", "wcI32bl1tkqbgcelGtGWPI4RtlEddd-PTd76Eb-k7nXA5LbE9yTNdIL9QSOOxMOs", - nil, ` + []string{"CGO_ENABLED=0"}, ` sed -i \ 's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \ cmd/link/internal/`+runtime.GOARCH+`/obj.go @@ -138,7 +143,7 @@ sed -i \ go125 := t.newGo( "1.25.6", "x0z430qoDvQbbw_fftjW0rh_GSoh0VJhPzttWk_0hj9yz9AKOjuwRMupF_Q0dbt7", - nil, ` + finalEnv, ` sed -i \ 's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \ cmd/link/internal/`+runtime.GOARCH+`/obj.go From f698d6f324e09961e044b83f2ad2359bcb49c41c Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 8 Feb 2026 15:42:58 +0900 Subject: [PATCH 6/7] internal/rosa/go: 1.25.6 to 1.25.7 Signed-off-by: Ophestra --- internal/rosa/go.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/rosa/go.go b/internal/rosa/go.go index 27bfa43..e365287 100644 --- a/internal/rosa/go.go +++ b/internal/rosa/go.go @@ -141,8 +141,8 @@ sed -i \ ) go125 := t.newGo( - "1.25.6", - "x0z430qoDvQbbw_fftjW0rh_GSoh0VJhPzttWk_0hj9yz9AKOjuwRMupF_Q0dbt7", + "1.25.7", + "fyylHdBVRUobnBjYj3NKBaYPUw3kGmo2mEELiZonOYurPfbarNU1x77B99Fjut7Q", finalEnv, ` sed -i \ 's,/lib/ld-musl-`+linuxArch()+`.so.1,/system/bin/linker,' \ From ce881862f0379b3de79e3cb16c79d5c93db6fcd7 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 8 Feb 2026 16:03:41 +0900 Subject: [PATCH 7/7] dist: include target in filename Backport patch will be removed in the next release. Signed-off-by: Ophestra --- dist/release.sh | 2 +- internal/rosa/hakurei.go | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/dist/release.sh b/dist/release.sh index 0ba9104..2990ee1 100755 --- a/dist/release.sh +++ b/dist/release.sh @@ -1,7 +1,7 @@ #!/bin/sh -e cd "$(dirname -- "$0")/.." VERSION="${HAKUREI_VERSION:-untagged}" -pname="hakurei-${VERSION}" +pname="hakurei-${VERSION}-$(go env GOARCH)" out="${DESTDIR:-dist}/${pname}" echo '# Preparing distribution files.' diff --git a/internal/rosa/hakurei.go b/internal/rosa/hakurei.go index cefd224..f264284 100644 --- a/internal/rosa/hakurei.go +++ b/internal/rosa/hakurei.go @@ -49,7 +49,7 @@ HAKUREI_VERSION='v`+version+`' "v"+version+".tar.gz", mustDecode(checksum), pkg.TarGzip, - ), true, [2]string{"dist", `From 67e453f5c4de915de23ecbe5980e595758f0f2fb Mon Sep 17 00:00:00 2001 + ), true, [2]string{"dist-00-tests", `From 67e453f5c4de915de23ecbe5980e595758f0f2fb Mon Sep 17 00:00:00 2001 From: Ophestra Date: Tue, 27 Jan 2026 06:49:48 +0900 Subject: [PATCH] dist: run tests @@ -236,7 +236,20 @@ index d737a18..98713cb 100644 + if !cur.EqualWithIgnore(mnt[i], "\x00") { fail = true - log.Printf("[FAIL] %s", cur)`}), + log.Printf("[FAIL] %s", cur)`}, [2]string{"dist-01-tarball-name", `diff --git a/dist/release.sh b/dist/release.sh +index 0ba9104..2990ee1 100755 +--- a/dist/release.sh ++++ b/dist/release.sh +@@ -1,7 +1,7 @@ + #!/bin/sh -e + cd "$(dirname -- "$0")/.." + VERSION="${HAKUREI_VERSION:-untagged}" +-pname="hakurei-${VERSION}" ++pname="hakurei-${VERSION}-$(go env GOARCH)" + out="${DESTDIR:-dist}/${pname}" + + echo '# Preparing distribution files.' +`}), ), pkg.Path(AbsUsrSrc.Append("hostname", "main.go"), false, pkg.NewFile( "hostname.go", []byte(`