mirror of
https://github.com/golang/go.git
synced 2026-02-07 02:09:55 +00:00
reflect, runtime: adjust user-created GCData on AIX
On AIX the runtime adjusts the GCData field in getGCMaskOnDemand to account for the AIX dynamic loader moving the data section. That works fine for statically generated types, but it breaks user generated types. The user generated type will have a normal, correct, pointer, and adjusting the pointer will make it point elsewhere. This all happens to work OK when doing an external link, because in that case we do have dynamic relocs and there is no adjustment. But it fails with an internal link. This CL fixes the problem by applying a reverse adjustment to user generated types, so that the adjustment winds up with the original pointer value. Change-Id: Ibf3199b9ffb36e79af134fbed41db2853297de74 Reviewed-on: https://go-review.googlesource.com/c/go/+/740800 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
01299a31c2
commit
bd1b41eb81
2 changed files with 43 additions and 0 deletions
|
|
@ -2580,6 +2580,9 @@ func StructOf(fields []StructField) Type {
|
|||
// space to store it.
|
||||
typ.TFlag |= abi.TFlagGCMaskOnDemand
|
||||
typ.GCData = (*byte)(unsafe.Pointer(new(uintptr)))
|
||||
if runtime.GOOS == "aix" {
|
||||
typ.GCData = adjustAIXGCData(typ.GCData)
|
||||
}
|
||||
}
|
||||
|
||||
typ.Equal = nil
|
||||
|
|
@ -2745,6 +2748,9 @@ func ArrayOf(length int, elem Type) Type {
|
|||
// space to store it.
|
||||
array.TFlag |= abi.TFlagGCMaskOnDemand
|
||||
array.GCData = (*byte)(unsafe.Pointer(new(uintptr)))
|
||||
if runtime.GOOS == "aix" {
|
||||
array.GCData = adjustAIXGCData(array.GCData)
|
||||
}
|
||||
}
|
||||
|
||||
etyp := typ
|
||||
|
|
@ -2776,6 +2782,34 @@ func ArrayOf(length int, elem Type) Type {
|
|||
return ti.(Type)
|
||||
}
|
||||
|
||||
// adjustAIXGCData adjusts the GCData field pointer for AIX.
|
||||
// See runtime.getGCMaskOnDemand.
|
||||
func adjustAIXGCData(addr *byte) *byte {
|
||||
adjusted := adjustAIXGCDataForRuntime(addr)
|
||||
if adjusted != addr {
|
||||
pinAIXGCDataMu.Lock()
|
||||
pinAIXGCData = append(pinAIXGCData, addr)
|
||||
pinAIXGCDataMu.Unlock()
|
||||
}
|
||||
return adjusted
|
||||
}
|
||||
|
||||
// adjustAIXGCDataForRuntime adjusts the GCData field pointer
|
||||
// as the runtime requires for AIX. See runtime.getGCMaskOnDemand.
|
||||
//
|
||||
//go:linkname adjustAIXGCDataForRuntime
|
||||
//go:noescape
|
||||
func adjustAIXGCDataForRuntime(*byte) *byte
|
||||
|
||||
// pinAIXGCDataMu proects pinAIXGCData.
|
||||
var pinAIXGCDataMu sync.Mutex
|
||||
|
||||
// pinAIXGCData keeps the actual GCData pointer alive on AIX.
|
||||
// On AIX we need to use adjustAIXGCData to convert the GC pointer
|
||||
// to the value that the runtime expects. That means that the rtype
|
||||
// no longer refers to the original pointer. This slice keeps it alive.
|
||||
var pinAIXGCData []*byte
|
||||
|
||||
func appendVarint(x []byte, v uintptr) []byte {
|
||||
for ; v >= 0x80; v >>= 7 {
|
||||
x = append(x, byte(v|0x80))
|
||||
|
|
|
|||
|
|
@ -732,6 +732,15 @@ func reflect_addReflectOff(ptr unsafe.Pointer) int32 {
|
|||
return id
|
||||
}
|
||||
|
||||
// reflect_adjustAIXGCDataForRuntime takes a type.GCData address and returns
|
||||
// the new address to use. This is only called on AIX.
|
||||
// See getGCMaskOnDemand.
|
||||
//
|
||||
//go:linkname reflect_adjustAIXGCDataForRuntime reflect.adjustAIXGCDataForRuntime
|
||||
func reflect_adjustAIXGCDataForRuntime(addr *byte) *byte {
|
||||
return (*byte)(add(unsafe.Pointer(addr), aixStaticDataBase-firstmoduledata.data))
|
||||
}
|
||||
|
||||
//go:linkname fips_getIndicator crypto/internal/fips140.getIndicator
|
||||
func fips_getIndicator() uint8 {
|
||||
return getg().fipsIndicator
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue