From 9c1aa658bfb73018805fde0c6224a289aced0d03 Mon Sep 17 00:00:00 2001
From: Russ Cox <rsc@golang.org>
Date: Mon, 13 Jan 2014 23:07:40 -0500
Subject: [PATCH] cmd/link: replace golden binary files with hex dumps

The hex dumps will diff better, and I hope they will avoid
a repeat of http://bugs.debian.org/716853.

The CL will probably show the testdata diffs as "binary",
but in fact the binary versions are being replaced by
textual hex dumps (output of hexdump -C).

R=iant
CC=golang-codereviews
https://golang.org/cl/51000044
---
 src/cmd/link/hex_test.go                      |  74 ++++++++++++++++++
 src/cmd/link/prog_test.go                     |  12 +--
 src/cmd/link/testdata/link.hello.darwin.amd64 | Bin 4140 -> 3890 bytes
 src/cmd/link/testdata/macho.amd64.exit9       | Bin 4109 -> 1669 bytes
 src/cmd/link/testdata/macho.amd64.hello       | Bin 8204 -> 2776 bytes
 src/cmd/link/testdata/macho.amd64.helloro     | Bin 8204 -> 2381 bytes
 6 files changed, 81 insertions(+), 5 deletions(-)
 create mode 100644 src/cmd/link/hex_test.go
 mode change 100755 => 100644 src/cmd/link/testdata/link.hello.darwin.amd64
 mode change 100755 => 100644 src/cmd/link/testdata/macho.amd64.exit9
 mode change 100755 => 100644 src/cmd/link/testdata/macho.amd64.hello
 mode change 100755 => 100644 src/cmd/link/testdata/macho.amd64.helloro

diff --git a/src/cmd/link/hex_test.go b/src/cmd/link/hex_test.go
new file mode 100644
index 0000000000..b76b266558
--- /dev/null
+++ b/src/cmd/link/hex_test.go
@@ -0,0 +1,74 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"encoding/hex"
+	"fmt"
+	"io/ioutil"
+	"regexp"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+// mustParseHexdumpFile returns a block of data generated by
+// parsing the hex dump in the named file.
+// If the file cannot be read or does not contain a valid hex dump,
+// mustParseHexdumpFile calls t.Fatal.
+func mustParseHexdumpFile(t *testing.T, file string) []byte {
+	hex, err := ioutil.ReadFile(file)
+	if err != nil {
+		t.Fatal(err)
+	}
+	data, err := parseHexdump(string(hex))
+	if err != nil {
+		t.Fatal(err)
+	}
+	return data
+}
+
+// parseHexdump parses the hex dump in text, which should be the
+// output of "hexdump -C" or Plan 9's "xd -b",
+// and returns the original data used to produce the dump.
+// It is meant to enable storing golden binary files as text, so that
+// changes to the golden files can be seen during code reviews.
+func parseHexdump(text string) ([]byte, error) {
+	var out []byte
+	for _, line := range strings.Split(text, "\n") {
+		if i := strings.Index(line, "|"); i >= 0 { // remove text dump
+			line = line[:i]
+		}
+		f := strings.Fields(line)
+		if len(f) > 1+16 {
+			return nil, fmt.Errorf("parsing hex dump: too many fields on line %q", line)
+		}
+		if len(f) == 0 || len(f) == 1 && f[0] == "*" { // all zeros block omitted
+			continue
+		}
+		addr64, err := strconv.ParseUint(f[0], 16, 0)
+		if err != nil {
+			return nil, fmt.Errorf("parsing hex dump: invalid address %q", f[0])
+		}
+		addr := int(addr64)
+		if len(out) < addr {
+			out = append(out, make([]byte, addr-len(out))...)
+		}
+		for _, x := range f[1:] {
+			val, err := strconv.ParseUint(x, 16, 8)
+			if err != nil {
+				return nil, fmt.Errorf("parsing hexdump: invalid hex byte %q", x)
+			}
+			out = append(out, byte(val))
+		}
+	}
+	return out, nil
+}
+
+func hexdump(data []byte) string {
+	text := hex.Dump(data) + fmt.Sprintf("%08x\n", len(data))
+	text = regexp.MustCompile(`\n([0-9a-f]+(\s+00){16}.*\n)+`).ReplaceAllString(text, "\n*\n")
+	return text
+}
diff --git a/src/cmd/link/prog_test.go b/src/cmd/link/prog_test.go
index 8229b5b91f..34c06a262a 100644
--- a/src/cmd/link/prog_test.go
+++ b/src/cmd/link/prog_test.go
@@ -136,15 +136,17 @@ func cloneSection(sect *Section) *Section {
 	return t
 }
 
+const saveMismatch = true
+
 // checkGolden checks that data matches the named file.
 // If not, it reports the error to the test.
 func checkGolden(t *testing.T, data []byte, name string) {
-	golden, err := ioutil.ReadFile(name)
-	if err != nil {
-		t.Errorf("%s: %v", name, err)
-		return
-	}
+	golden := mustParseHexdumpFile(t, name)
 	if !bytes.Equal(data, golden) {
+		if saveMismatch {
+			ioutil.WriteFile(name+".raw", data, 0666)
+			ioutil.WriteFile(name+".hex", []byte(hexdump(data)), 0666)
+		}
 		// TODO(rsc): A better diff would be nice, as needed.
 		i := 0
 		for i < len(data) && i < len(golden) && data[i] == golden[i] {
diff --git a/src/cmd/link/testdata/link.hello.darwin.amd64 b/src/cmd/link/testdata/link.hello.darwin.amd64
old mode 100755
new mode 100644
index 5d4db542a44a97b88d446299d021f8e1934e69a3..5027464521800c74d49a2b0cacd2f116b46ec8f2
GIT binary patch
literal 3890
zcmb_f%Wm5+5WMFr_S}O->ggN<G-z)viWCTXQDr@ngIfc(i}s+8?<^lnN|6j0v7yLo
ziX6?(E|(jn?1!iwXlSVKXy{2*q?EZdk;?oJ45h)QaWngjcNR=5tjfd8E?P)RhX?K@
z=2h!(Dd6;dSe0*sO~qg?MY*QDqP(D@;k$+V42E_6_2JXwk4Mig16+|(J_Houu`pzx
z(fIAl)LRdiv$Klev!IBvFy!H;V4KZ&_ra-GT0jAbjfoB!bns$M)!PEy^Q+ihD^hOc
z*;3(SbAex7KRrG_1(qIed&%9dT+v}QRqii2dp%skaFV<TNfBI}CUO+6sdntLcXlV*
zRXLRfRa=7LLKw#-wrQ;EbN}!BR=ZZ<5CP8A_k{x6in(BW#ILvZ@+h9cS+dOBmpI#7
zxc4WrEdqmui|c^UTp;XduO*6R>Nbt5l*)lh1VnQ*aK8Xo*T+NGoEsku7g^0E>UO(A
zbBV&=awx>@nL#7@7&v;K9hWFzT^ouSTBs?y5O>Rxs)EX%%FL@*MnyfQ$ca4s`Q4tI
z-HacXs2i%sC2Cc@UAY|Ib@jMJ-BdlUD)9ky|MmdNv7t2=R@|+Ip{msN$A_l}sVbVQ
zO008i^8-Xb9<p|T+bA0ipDbKeRJ*VQ3wd-oDZ@r{S>xeMRau3Ldx6M~*v(SKR28qu
z%q^Eg@m8KYTi15?dUn35EJ|ck@`_NTPNEqvM*?5hg(Bsua+6TFULfT{ut*Mrlf!Kn
zr(}rjG#IJrRr~=4h_ngl!J56$#`c4Q;xFk{Qj>d2u`v9u$UW;YsyzJKp)-pzW`};%
zM8YxLfpnCg@LaOb?F_%wv@!t^hf(JMT~MZJ81SB`f8xg0JZm$7)8ewtKCQ5oXxQ;$
zdpV^*79?WM?txK8*u8;s(Our4i>b%*$N}!X_3Svhz*>ewQH)86y;erG;xhx&mf_I4
z2!t41c!k}wbJw#oZEds)zhxmGM)CtEl-O3gpMYxdH{j31@tGmhW(L<4bO~q<AR_Ft
z;*J56LMZCvS=BEGfirDw>YWt>RPe6^CkGnI**$g6#;2}lXWClKx0hXO?Tg)tlT5xm
zoM~&LEwPPsq!i6PTGPxlsPH=D5x5_mO}?M{<0(0MI6i=QzMpArtCCra)&NbGd5nA6
zakoX|sZEZj_T`YAj&0KZ>O3450lczod0GbT@Os-WV=u84wQ4+X%S>rZ_FbBs`_q{#
zeDd0RI6i<F3)ett&rBu0!IB|s(74|pHYZUo6e-kr1~e}Xu!<^^6vk0QTs1WLjITW)
P>F?pV?_8Pys=fOUU{>F~

literal 4140
zcmX^A>+L^w1_nlE1_lNuAO_Jh7=Z#n8U!SP*aL{;;{zPsU87us{6V5fKmdu2hY2!g
z1`x-`hqy+BASs0E*D*j612T1>;y|}CumUm6J@N4+sTCy%wHW3pK;(2_O3>ZM0+WEy
zAhUM>F-TYoA~dk1!oXTTYWrvijE2By2#kinXb6mkz-S1JhQMeDjE2By2#kin@C<?d
rppNxE1qB9%T|7Y64q!i+iJ#T*{|=xyka0L8H76%up*+7RCxr_DBnTVB

diff --git a/src/cmd/link/testdata/macho.amd64.exit9 b/src/cmd/link/testdata/macho.amd64.exit9
old mode 100755
new mode 100644
index d068b128ba38abad2396e309dfa23a4347ca03ab..1adc814c33936afe1973a27747e9a59fb6203eb7
GIT binary patch
literal 1669
zcmbuA!ES>v42JK0ivQfhl+dKWaffQVZJK(Rc0o|c6ZEhH4?hQ!I8f55TZAeH@MrtC
zNtNOSTpV1Bp@$owN+>m58c>I@p<9L67@t;a+%Zh6rB_`+>Df`NIReKak1VdBhq{))
zhH%l#I`~V$XqXbl!nXdGaj%qN)4V^woW4#Wy942D0po-sxM-~mj2~~yY6H&rVil<7
zl?!b*Zt+X`VyTk6*KLH~aL0SNR8-%iP(nVtl5n%)X41NXHM67mM^MPFY0jt5v*;JJ
zt2n!ic6~<F?4Z>5id7HeT91og0*Pa##6OI27qu%5juvGFGG>WZlEp2?rnwH^*IVr_
z5l0>HWB<Qa^sF6yYcX~-K-$GkYS5rSGV@mG?7%qb>`@3}r7W`ZbLSYRf?lcP<2dbO
zrQPh(;ZK7Ut<aa*?WI^fop)QpO>uG$HpY0*2dJJ0In#_haJw0L8swZ;DrIUf%jMp3
jek331=QRt5I{htlbev9SbP$a87S2G{vS6MRV)eTp%RDkt

literal 4109
zcmX^A>+L^w1_nlE1_lNuAO_Jh7=Z#n8U!SP*aL{;;{zPsU87us{6V5fKmdu2hY2!g
z1`x-`hqy+BASs0E=S4FI#s|8Mffa~h?um~tNv$YB=*KWm0V2l>Qvx)X4aNr1EXW*)
z**l=ZTBuS3!&4X-Ye#Jz4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5E$Meumjk!
NX4=mQ^dvv)7XT%u6IlQN

diff --git a/src/cmd/link/testdata/macho.amd64.hello b/src/cmd/link/testdata/macho.amd64.hello
old mode 100755
new mode 100644
index 8e93969f7452d43a779ab7c6b39f176bc1bc7445..45e70d0ac538d927c7b94f32b980847f07bb53bf
GIT binary patch
literal 2776
zcmb_eJ#X7E5Z&`D4(OI4AZhBuqk$Uf)}ruGbP*(3LI(o@3IolcAKyD3$-BssTBj8h
z<wTK>kMEApG=?vLeuS}w;SA#drUGNaZ2`<Ky<n4*7^bJ$H9atxH8{#k&z%|w#>$5{
zNtlY^jDk#X4&m%xM)_J|D8_Ib@D_XpzJQ{oC&PV0xTg7Xcs_nVCOBjRg#$kdO6IZ9
z#NS~0`dLxKFu{3RtN~neM#;fKQ-XU7CU6DAWe6R-1FqbH)1vORsH>T+NIO>C2d!%;
zQldB5HO=Yx?IcT1+SOayx!sDWncatonBewXi@hJNCAhp3Fu#Q?@egGzOO?!aS-Z+Z
zSwK|-2C*J=nsp3Q(_Dwws{p3O_8AT{KxO}LsW`KCxYzXbksWGx+lno?$$**7Q!y}{
z?21wlB$|P)JIcs#+Ent``{686UoC#FZ;zr{DsFu8RKl)lJ|0eooLL+EZb>+r2mi?b
zZf=2lil!GcYsv3Szc3`iE$1ljij<NBM}D^sr!%W!#qRAUv%&9@CbMNlZz!?8EfqID
zxre|t&AGj{qTQz7-Jgn0ze6r}rh@!#T{{Dk3SHl;sfd0zQ!Prg*ouv!T{3}`*-gLG
zZq@ybx!d4($&qkk*GdgaG^5Gv9uqbEpV*P#%{u4T^$((5uDeG*R=BV)ZuSvl5}+hQ
zbyDg@tBU+w*cYm2CWpa0_@SxbI8r)G=%B+xM%V)pu*0*JD#EUvWtW_Q`B@WOMcV*k
z6=4E8lreFhL7k1%a<hJPD6=N07a+z=Fs(kprT2)wUVGO3XZ2iAudL~ZvFyV=QbMZ=
f$`PP)p$UnjV)~kX442Cb{CfF$IY;FXs(<(mXcqrp

literal 8204
zcmeH~u?oU45Qby5iX!OhR_NyBD-<lcDbhh)g3y9PL6CwzijPtp^bvd#Hzx=2t~Df8
z(4j+@Kkz4)OYU;{w!1!V&z2Cix)8!5HAo{eYP9kgkftOl=ibC$`HLBQjnOykA13EH
zlB5j$Wnf%<$GabS)ShY+Hc8bZWfC0{9siZj$<JJMh4MC)%`1P<7`m>p7kI|OD7U-H
z<rMeKi>2!d*U37+!?TqC^A+mSp_#>hPDxzuF!NMAITgQ;=Rp7jKmY_l00ck)1V8`;
zKmY_v5lE@Qv@YDmo&~kMC+>H9c1jNG($4IAsr(2A0T2KI5C8!X009sH0T2KI5C8!X
RsGh(kisP-b-|phD^8!EuB5MEu

diff --git a/src/cmd/link/testdata/macho.amd64.helloro b/src/cmd/link/testdata/macho.amd64.helloro
old mode 100755
new mode 100644
index 55a62495a504f208022df750245741292d58b0ae..4b70fbd0fa3c6270f1f2ff1d2fd46621d8c67292
GIT binary patch
literal 2381
zcmb_eJ#X7E5Z&`D4(OI4AQkE(V+JGLS`-<IE`lUW$Y8)gV4xlJ<NHqJkw@8bW2Ay0
zQ<U!U-FwHAjqwN3FwxY}xTk3(Q<E{vX^G6E++eCmW11gU$9(6(tjVLshKvn?X%trQ
z>mXtiuE0b4loob?i&5o7d>V3=TurW|vg50V`wE6_`~CT4_iHEY9sySt<fep@;NoaC
zp!vtQJX?WtoU9?_yb8hXg(?5icCyH1JL-Ief5BDP;Iydhk)*KAt_ECC+$~x+RJstD
z;v<l-Yune|&)1}%XxDgl8`=#7=T}&`RqV(^3f$ARWX;WR9mB<)04il-lkEh}QLzj8
z3cDU~Uc1^+RZ`s$20<bXp~p10?P>gTI@fN9aBzUj{&QCBy>^!sFLVn~o*>y^!IxFC
zqlZh*R$4m+ktdtd^dr%3@^D7<%A)j*9&cJ<@s?OoP&H8nLoB<2YvQS~I09C@ANSp<
z6PAIU<$m}7c7^4BhxO2>Rt%T~%J_ViAIuL%cxBpI?ss@0Ir~8?g0liD$%cM+nZ(6e
z&rWc{ufQ$+PHn7S_aW_f(WS(5XYT<ia98`?E$r_7x6Fn@PU<OF5}_4x+82_w@RLGT
zC^7aLoZv+DJU>)2+-1$;&M2tImu>mn2EZO4bX87$r&}lhxo$i^Yq*rN5(8GbERc4F
zUqNM%+rbnCZYkvjVu}PM@TPS6kA*d%l%ryLa1)$YuUOQp8t%r`u$&X`le*@nKs9;;
aW<eZ^>0^Ey4~HZDKE5CJAyq&PcYguozqz*n

literal 8204
zcmeH~u?oUK42G}ODoCNOZU=5ozJf#1O_2`baug~!6bhxFk5(M)BlsF!+?*W5gzLdk
z!L<s1ASCx+E*HKnx99ye6vF8VAzX5fwL=0$wh8%)T&c}s8ScaFnpMljR{kaBJ~g>g
zQMik&!sfj%EsauhrrCr?&a<&8RUFQR&h@#~PwKm=DWU!YlXL9b2kw_=NnFH6{g`jA
zZ+ufATm6jQM4q)I=Wk|>)@hKP{*KQ<00ck)1V8`;KmY_l00ck)1b&1-NsFpm@wR^z
zwCY}X&keki1h?W51Mk5B1_B@e0w4eaAOHd&00JNY0w4eaAn?Zoj)yeO<SEP3Wb_8M
Csv&Ox

-- 
2.30.9