aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/malloc.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/malloc.go')
-rw-r--r--src/runtime/malloc.go11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 20cb6818d2..d73d1ba6a6 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -477,6 +477,8 @@ func GC() {
// linker-provided
var noptrdata struct{}
+var enoptrdata struct{}
+var noptrbss struct{}
var enoptrbss struct{}
// SetFinalizer sets the finalizer associated with x to f.
@@ -553,8 +555,13 @@ func SetFinalizer(obj interface{}, finalizer interface{}) {
// func main() {
// runtime.SetFinalizer(Foo, nil)
// }
- // The segments are, in order: text, rodata, noptrdata, data, bss, noptrbss.
- if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
+ // The relevant segments are: noptrdata, data, bss, noptrbss.
+ // We cannot assume they are in any order or even contiguous,
+ // due to external linking.
+ if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrdata)) ||
+ uintptr(unsafe.Pointer(&data)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&edata)) ||
+ uintptr(unsafe.Pointer(&bss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&ebss)) ||
+ uintptr(unsafe.Pointer(&noptrbss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
return
}
gothrow("runtime.SetFinalizer: pointer not in allocated block")