diff --git a/src/runtime/type.go b/src/runtime/type.go index a3a19b9be0..3ecc54c72c 100644 --- a/src/runtime/type.go +++ b/src/runtime/type.go @@ -199,11 +199,11 @@ func (t *_type) nameOff(off nameOff) name { return resolveNameOff(unsafe.Pointer(t), off) } -func (t *_type) typeOff(off typeOff) *_type { +func resolveTypeOff(ptrInModule unsafe.Pointer, off typeOff) *_type { if off == 0 { return nil } - base := uintptr(unsafe.Pointer(t)) + base := uintptr(ptrInModule) var md *moduledata for next := &firstmoduledata; next != nil; next = next.next { if base >= next.types && base < next.etypes { @@ -235,6 +235,10 @@ func (t *_type) typeOff(off typeOff) *_type { return (*_type)(unsafe.Pointer(res)) } +func (t *_type) typeOff(off typeOff) *_type { + return resolveTypeOff(unsafe.Pointer(t), off) +} + func (t *_type) textOff(off textOff) unsafe.Pointer { base := uintptr(unsafe.Pointer(t)) var md *moduledata @@ -596,15 +600,19 @@ func typesEqual(t, v *_type) bool { for i := range it.mhdr { tm := &it.mhdr[i] vm := &iv.mhdr[i] - tname := it.typ.nameOff(tm.name) - vname := iv.typ.nameOff(vm.name) + // Note the mhdr array can be relocated from + // another module. See #17724. + tname := resolveNameOff(unsafe.Pointer(tm), tm.name) + vname := resolveNameOff(unsafe.Pointer(vm), vm.name) if tname.name() != vname.name() { return false } if tname.pkgPath() != vname.pkgPath() { return false } - if !typesEqual(it.typ.typeOff(tm.ityp), iv.typ.typeOff(vm.ityp)) { + tityp := resolveTypeOff(unsafe.Pointer(tm), tm.ityp) + vityp := resolveTypeOff(unsafe.Pointer(vm), vm.ityp) + if !typesEqual(tityp, vityp) { return false } }