aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2020-04-22 19:21:30 -0400
committerCherry Zhang <cherryyz@google.com>2020-04-24 17:47:14 +0000
commite08f10b8b5fbb82ff1e2c263ad57e19d2de1e323 (patch)
tree1a7332196907af1966807e1664e2734ba6bb41f7 /src/cmd/internal/obj
parent880ef2da7b81fe2e4e9fb75f4677377eeba70d1e (diff)
downloadgo-e08f10b8b5fbb82ff1e2c263ad57e19d2de1e323.tar.xz
[dev.link] cmd/internal/goobj2: add index fingerprint to object file
The new object files use indices for symbol references, instead of names. Fundamental to the design, it requires that the importing and imported packages have consistent view of symbol indices. The Go command should already ensure this, when using "go build". But in case it goes wrong, it could lead to obscure errors like run-time crashes. It would be better to check the index consistency at build time. To do that, we add a fingerprint to each object file, which is a hash of symbol indices. In the object file it records the fingerprints of all imported packages, as well as its own fingerprint. At link time, the linker checks that a package's fingerprint matches the fingerprint recorded in the importing packages, and issue an error if they don't match. This CL does the first part: introducing the fingerprint in the object file, and propagating fingerprints through importing/exporting by the compiler. It is not yet used by the linker. Next CL will do. Change-Id: I0aa372da652e4afb11f2867cb71689a3e3f9966e Reviewed-on: https://go-review.googlesource.com/c/go/+/229617 Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Jeremy Faller <jeremy@golang.org>
Diffstat (limited to 'src/cmd/internal/obj')
-rw-r--r--src/cmd/internal/obj/line.go5
-rw-r--r--src/cmd/internal/obj/link.go5
-rw-r--r--src/cmd/internal/obj/objfile.go5
-rw-r--r--src/cmd/internal/obj/objfile2.go14
-rw-r--r--src/cmd/internal/obj/sym.go10
5 files changed, 29 insertions, 10 deletions
diff --git a/src/cmd/internal/obj/line.go b/src/cmd/internal/obj/line.go
index fecf90c491..79ecb0068f 100644
--- a/src/cmd/internal/obj/line.go
+++ b/src/cmd/internal/obj/line.go
@@ -5,12 +5,13 @@
package obj
import (
+ "cmd/internal/goobj2"
"cmd/internal/src"
)
// AddImport adds a package to the list of imported packages.
-func (ctxt *Link) AddImport(pkg string) {
- ctxt.Imports = append(ctxt.Imports, pkg)
+func (ctxt *Link) AddImport(pkg string, fingerprint goobj2.FingerprintType) {
+ ctxt.Imports = append(ctxt.Imports, goobj2.ImportedPkg{Pkg: pkg, Fingerprint: fingerprint})
}
func linkgetlineFromPos(ctxt *Link, xpos src.XPos) (f string, l int32) {
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index 046ad53ac7..e6f917dedb 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -33,6 +33,7 @@ package obj
import (
"bufio"
"cmd/internal/dwarf"
+ "cmd/internal/goobj2"
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
@@ -666,7 +667,7 @@ type Link struct {
PosTable src.PosTable
InlTree InlTree // global inlining tree used by gc/inl.go
DwFixups *DwarfFixupTable
- Imports []string
+ Imports []goobj2.ImportedPkg
DiagFunc func(string, ...interface{})
DiagFlush func()
DebugInfo func(fn *LSym, info *LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) // if non-nil, curfn is a *gc.Node
@@ -698,6 +699,8 @@ type Link struct {
defs []*LSym // list of defined symbols in the current package
nonpkgdefs []*LSym // list of defined non-package symbols
nonpkgrefs []*LSym // list of referenced non-package symbols
+
+ Fingerprint goobj2.FingerprintType // fingerprint of symbol indices, to catch index mismatch
}
func (ctxt *Link) Diag(format string, args ...interface{}) {
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
index 2b0c45d6b2..6d7f42ed0b 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -98,8 +98,9 @@ func WriteObjFile(ctxt *Link, bout *bio.Writer, pkgpath string) {
w.wr.WriteByte(1)
// Autolib
- for _, pkg := range ctxt.Imports {
- w.writeString(pkg)
+ for _, p := range ctxt.Imports {
+ w.writeString(p.Pkg)
+ // This object format ignores p.Fingerprint.
}
w.writeString("")
diff --git a/src/cmd/internal/obj/objfile2.go b/src/cmd/internal/obj/objfile2.go
index 9792ef0846..061e43c434 100644
--- a/src/cmd/internal/obj/objfile2.go
+++ b/src/cmd/internal/obj/objfile2.go
@@ -38,7 +38,11 @@ func WriteObjFile2(ctxt *Link, b *bio.Writer, pkgpath string) {
if ctxt.Flag_shared {
flags |= goobj2.ObjFlagShared
}
- h := goobj2.Header{Magic: goobj2.Magic, Flags: flags}
+ h := goobj2.Header{
+ Magic: goobj2.Magic,
+ Fingerprint: ctxt.Fingerprint,
+ Flags: flags,
+ }
h.Write(w.Writer)
// String table
@@ -46,8 +50,8 @@ func WriteObjFile2(ctxt *Link, b *bio.Writer, pkgpath string) {
// Autolib
h.Offsets[goobj2.BlkAutolib] = w.Offset()
- for _, pkg := range ctxt.Imports {
- w.StringRef(pkg)
+ for i := range ctxt.Imports {
+ ctxt.Imports[i].Write(w.Writer)
}
// Package references
@@ -180,8 +184,8 @@ func (w *writer) init() {
func (w *writer) StringTable() {
w.AddString("")
- for _, pkg := range w.ctxt.Imports {
- w.AddString(pkg)
+ for _, p := range w.ctxt.Imports {
+ w.AddString(p.Pkg)
}
for _, pkg := range w.pkglist {
w.AddString(pkg)
diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go
index 03ce8ddc5a..4a8b0ebb6f 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -34,6 +34,7 @@ package obj
import (
"cmd/internal/goobj2"
"cmd/internal/objabi"
+ "crypto/md5"
"fmt"
"log"
"math"
@@ -241,6 +242,15 @@ func (ctxt *Link) NumberSyms(asm bool) {
ctxt.pkgIdx[pkg] = ipkg
ipkg++
})
+
+ // Compute a fingerprint of the indices, for exporting.
+ if !asm {
+ h := md5.New()
+ for _, s := range ctxt.defs {
+ h.Write([]byte(s.Name))
+ }
+ copy(ctxt.Fingerprint[:], h.Sum(nil)[:])
+ }
}
// Returns whether s is a non-package symbol, which needs to be referenced