annotate libgo/go/runtime/checkptr.go @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 // Copyright 2019 The Go Authors. All rights reserved.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 // Use of this source code is governed by a BSD-style
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 // license that can be found in the LICENSE file.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 // +build ignore
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 package runtime
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 import "unsafe"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 type ptrAlignError struct {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 ptr unsafe.Pointer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 elem *_type
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 n uintptr
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 func (e ptrAlignError) RuntimeError() {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 func (e ptrAlignError) Error() string {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 return "runtime error: unsafe pointer conversion"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 // Check that (*[n]elem)(p) is appropriately aligned.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 // TODO(mdempsky): What about fieldAlign?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 if uintptr(p)&(uintptr(elem.align)-1) != 0 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 panic(ptrAlignError{p, elem, n})
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 // Check that (*[n]elem)(p) doesn't straddle multiple heap objects.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 if size := n * elem.size; size > 1 && checkptrBase(p) != checkptrBase(add(p, size-1)) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 panic(ptrAlignError{p, elem, n})
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 type ptrArithError struct {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 ptr unsafe.Pointer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 originals []unsafe.Pointer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 func (e ptrArithError) RuntimeError() {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 func (e ptrArithError) Error() string {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 return "runtime error: unsafe pointer arithmetic"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 if 0 < uintptr(p) && uintptr(p) < minLegalPointer {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 panic(ptrArithError{p, originals})
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 // Check that if the computed pointer p points into a heap
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 // object, then one of the original pointers must have pointed
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 // into the same object.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 base := checkptrBase(p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 if base == 0 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 for _, original := range originals {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 if base == checkptrBase(original) {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 return
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 panic(ptrArithError{p, originals})
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 // checkptrBase returns the base address for the allocation containing
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 // the address p.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 // Importantly, if p1 and p2 point into the same variable, then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 // checkptrBase(p1) == checkptrBase(p2). However, the converse/inverse
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 // is not necessarily true as allocations can have trailing padding,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 // and multiple variables may be packed into a single allocation.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 func checkptrBase(p unsafe.Pointer) uintptr {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 // stack
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 if gp := getg(); gp.stack.lo <= uintptr(p) && uintptr(p) < gp.stack.hi {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 // TODO(mdempsky): Walk the stack to identify the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 // specific stack frame or even stack object that p
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 // points into.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 //
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 // In the mean time, use "1" as a pseudo-address to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 // represent the stack. This is an invalid address on
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 // all platforms, so it's guaranteed to be distinct
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 // from any of the addresses we might return below.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 return 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 // heap (must check after stack because of #35068)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 if base, _, _ := findObject(uintptr(p), 0, 0); base != 0 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 return base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 // data or bss
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 for _, datap := range activeModules() {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 if datap.data <= uintptr(p) && uintptr(p) < datap.edata {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 return datap.data
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 return datap.bss
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 return 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 }