]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: record missing pcdata tables correctly
authorRuss Cox <rsc@golang.org>
Mon, 29 Jun 2015 02:26:35 +0000 (22:26 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 29 Jun 2015 16:07:14 +0000 (16:07 +0000)
The old code was recording the current table output offset,
so the table from the next function would be used instead of
the runtime realizing that there was no table at all.

Add debug constant in runtime to check this for every function
at startup. It's too expensive to do that by default, but we can
do the last five functions. The end of the table is usually where
the C symbols end up, so that's where the problems typically are.

Fixes #10747.
Fixes #11396.

Change-Id: I13592e78017969fc22979fa902e19e1b151d41b1
Reviewed-on: https://go-review.googlesource.com/11657
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>

src/cmd/link/internal/ld/pcln.go
src/runtime/symtab.go

index 56d813bfde7f9f616f7748f471095d8070cc8baa..669776244c19c31264e4398e26d5150ead8a2bab 100644 (file)
@@ -122,10 +122,12 @@ func addvarint(d *Pcdata, val uint32) {
 }
 
 func addpctab(ftab *LSym, off int32, d *Pcdata) int32 {
-       start := int32(len(ftab.P))
-       Symgrow(Ctxt, ftab, int64(start)+int64(len(d.P)))
-       copy(ftab.P[start:], d.P)
-
+       var start int32
+       if len(d.P) > 0 {
+               start = int32(len(ftab.P))
+               Symgrow(Ctxt, ftab, int64(start)+int64(len(d.P)))
+               copy(ftab.P[start:], d.P)
+       }
        return int32(setuint32(Ctxt, ftab, int64(off), uint32(start)))
 }
 
index 687f067cb920945b515ecfe724706d487492c276..f02f5924131019d26bf2c4e94641d1d323cef179 100644 (file)
@@ -98,6 +98,8 @@ func moduledataverify() {
        }
 }
 
+const debugPcln = false
+
 func moduledataverify1(datap *moduledata) {
        // See golang.org/s/go12symtab for header: 0xfffffffb,
        // two zero bytes, a byte giving the PC quantum,
@@ -126,6 +128,13 @@ func moduledataverify1(datap *moduledata) {
                        }
                        throw("invalid runtime symbol table")
                }
+
+               if debugPcln || nftab-i < 5 {
+                       f := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff]))
+                       pcvalue(f, f.pcfile, datap.ftab[i+1].entry-1, true)
+                       pcvalue(f, f.pcln, datap.ftab[i+1].entry-1, true)
+                       pcvalue(f, f.pcsp, datap.ftab[i+1].entry-1, true)
+               }
        }
 
        if datap.minpc != datap.ftab[0].entry ||
@@ -275,7 +284,7 @@ func funcline(f *_func, targetpc uintptr) (file string, line int32) {
 func funcspdelta(f *_func, targetpc uintptr) int32 {
        x := pcvalue(f, f.pcsp, targetpc, true)
        if x&(ptrSize-1) != 0 {
-               print("invalid spdelta ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
+               print("invalid spdelta ", funcname(f), " ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
        }
        return x
 }