Description
It would be good if go was able to generate bit-for-bit identical binaries, even if the build environment changes in unimportant ways. (For example, so users can reproduce binaries without requiring root.)
Up until recently, we have been able to reproduce go binaries whilst modifying many parts of the build environment, except that we kept the build-path constant. However recently, we started to also vary the build-path. (Why "recently", is irrelevant to this report, but I can go into it if you ask.)
Anyway, now we can see that .gopclntab
embeds the build path into the resulting binary. This patch will get rid of this environment-specific information, but I know it's not perfect:
--- src/cmd/link/internal/ld/pcln.go
+++ src/cmd/link/internal/ld/pcln.go
@@ -41,6 +41,8 @@
// iteration over encoded pcdata tables.
+var cwd, _ = os.Getwd()
+
func getvarint(pp *[]byte) uint32 {
v := uint32(0)
p := *pp
@@ -152,7 +154,8 @@
f.Value = int64(ctxt.Nhistfile)
f.Type = obj.SFILEPATH
f.Next = ctxt.Filesyms
- f.Name = expandGoroot(f.Name)
+ //f.Name = expandGoroot(f.Name)
+ f.Name, _ = filepath.Rel(cwd, f.Name)
ctxt.Filesyms = f
}
}
In particular, I'm not sure how this will interfere with readers of this information. I know that src/debug/pclntab.go
carries an API for this, but I'm not sure what sorts of contracts you have published for that, that people expect.
Also, the part where I comment out expandGoroot
is not strictly necessary for reproducibility, but would allow, e.g. a user to try to reproduce a binary from his own go toolchain - which is some extra assurance that the copies behave the same way.
The call to Getwd
during static initialisation is also a bit dirty; I could delay this for later but that may or may not require locks, or pass it in from an parent/ancestor caller but that would require adding extra arguments to some functions.
However if you give me some guidelines on how to make this patch acceptable, I'll be happy to do this work and submit a PR.