]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link, runtime: use a sentinel value for unreachable method
authorCherry Zhang <cherryyz@google.com>
Thu, 24 Sep 2020 20:54:31 +0000 (16:54 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 29 Sep 2020 15:20:13 +0000 (15:20 +0000)
In the method table, the method's code pointer is stored as an
offset from the start of the text section. Currently, for an
unreachable method, the offset is left as 0, which resolves to
the start of the text section at run time. It is possible that
there is valid code there. If an unreachable method is ever
reached (due to a compiler or linker bug), the execution will
jump to a wrong location but may continue to run for a while,
until it fails with a seemingly unrelated error.

This CL changes it to use -1 for unreachable method instead. At
run time this will resolve to an invalid address, which makes it
fail immediately if it is ever reached.

Change-Id: Ied6ed7f1833c4f3b991fdf55d8810d70d307b2e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/257203
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/data.go
src/runtime/type.go

index 0a3418bfc9bf207be047dce91a373c0a02e4badc..ed948d51b15dd82709b1e5b9b6b6b6664b007d40 100644 (file)
@@ -390,6 +390,12 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                        o = ldr.SymValue(rs) + r.Add() - int64(ldr.SymSect(rs).Vaddr)
                case objabi.R_WEAKADDROFF, objabi.R_METHODOFF:
                        if !ldr.AttrReachable(rs) {
+                               if rt == objabi.R_METHODOFF {
+                                       // Set it to a sentinel value. The runtime knows this is not pointing to
+                                       // anything valid.
+                                       o = -1
+                                       break
+                               }
                                continue
                        }
                        fallthrough
index 52b6cb30b445ff71de814c1d010aec1ea6e89df5..81455f3532db83ed481d0c55afa54a2dc088271c 100644 (file)
@@ -217,7 +217,9 @@ func (t *_type) nameOff(off nameOff) name {
 }
 
 func resolveTypeOff(ptrInModule unsafe.Pointer, off typeOff) *_type {
-       if off == 0 {
+       if off == 0 || off == -1 {
+               // -1 is the sentinel value for unreachable code.
+               // See cmd/link/internal/ld/data.go:relocsym.
                return nil
        }
        base := uintptr(ptrInModule)
@@ -257,6 +259,11 @@ func (t *_type) typeOff(off typeOff) *_type {
 }
 
 func (t *_type) textOff(off textOff) unsafe.Pointer {
+       if off == -1 {
+               // -1 is the sentinel value for unreachable code.
+               // See cmd/link/internal/ld/data.go:relocsym.
+               return unsafe.Pointer(^uintptr(0))
+       }
        base := uintptr(unsafe.Pointer(t))
        var md *moduledata
        for next := &firstmoduledata; next != nil; next = next.next {