Files
windows_exporter/internal/mi/layout.go
T

81 lines
3.5 KiB
Go

// SPDX-License-Identifier: Apache-2.0
//
// Copyright The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build windows
package mi
import "unsafe"
// Compile-time checks of the Go mirrors of native MI structures against
// mi.h. MI reads and writes these structures by offset, so a missing or
// reordered field corrupts memory instead of failing.
//
// Each check indexes a one-element array with the difference of two
// constants: it compiles only when both are equal. A smaller left side
// overflows uintptr, a larger one is out of bounds.
const ptrSize = unsafe.Sizeof(uintptr(0))
// handleSize is the size of the MI handle structures MI_Application,
// MI_Session, MI_Operation, MI_OperationOptions and MI_DestinationOptions:
// MI_Uint64 reserved1, ptrdiff_t reserved2 and a function table pointer.
const handleSize = 8 + 2*ptrSize
// miValueSize is the size of the MI_Value union. Its largest member is
// MI_Datetime: an MI_Boolean, padded to 4 bytes, and a 32-byte MI_Timestamp or
// MI_Interval union, 36 bytes, rounded up to the 8-byte alignment of the
// 64-bit members. Instance.GetElementByName passes a buffer of this size.
const miValueSize = 40
var (
// Handles without Go-only fields.
_ = [1]struct{}{}[unsafe.Sizeof(Application{})-handleSize]
_ = [1]struct{}{}[unsafe.Sizeof(OperationOptions{})-handleSize]
_ = [1]struct{}{}[unsafe.Sizeof(DestinationOptions{})-handleSize]
// Session and Operation append Go-only fields after the native layout,
// which MI never writes past. The first Go-only field must start right
// after the native fields, with the function table at the native offset.
_ = [1]struct{}{}[unsafe.Offsetof(Session{}.ft)-(8+ptrSize)]
_ = [1]struct{}{}[unsafe.Offsetof(Session{}.application)-handleSize]
_ = [1]struct{}{}[unsafe.Offsetof(Operation{}.ft)-(8+ptrSize)]
_ = [1]struct{}{}[unsafe.Offsetof(Operation{}.completed)-handleSize]
// MI_Instance: four pointers and ptrdiff_t reserved[4].
_ = [1]struct{}{}[unsafe.Sizeof(Instance{})-8*ptrSize]
// MI_OperationCallbacks: the callback context and eight callbacks.
_ = [1]struct{}{}[unsafe.Sizeof(operationCallbacks{})-9*ptrSize]
_ = [1]struct{}{}[unsafe.Offsetof(operationCallbacks{}.instanceResult)-5*ptrSize]
// MI_Timestamp and MI_Interval: eight 32-bit fields each.
_ = [1]struct{}{}[unsafe.Sizeof(Timestamp{})-32]
_ = [1]struct{}{}[unsafe.Sizeof(Interval{})-32]
// The MI_Value buffer of Instance.GetElementByName, kept in Element.raw.
_ = [1]struct{}{}[unsafe.Sizeof(Element{}.raw)-miValueSize]
_ = [1]struct{}{}[unsafe.Sizeof(ValueType(0))-4]
// Function tables, by the number of entries in mi.h. Calls use the slot
// offsets, so a missing entry would call the wrong function.
_ = [1]struct{}{}[unsafe.Sizeof(ApplicationFT{})-11*ptrSize]
_ = [1]struct{}{}[unsafe.Sizeof(SessionFT{})-15*ptrSize]
_ = [1]struct{}{}[unsafe.Sizeof(OperationFT{})-6*ptrSize]
_ = [1]struct{}{}[unsafe.Sizeof(OperationOptionsFT{})-13*ptrSize]
_ = [1]struct{}{}[unsafe.Sizeof(DestinationOptionsFT{})-15*ptrSize]
_ = [1]struct{}{}[unsafe.Sizeof(InstanceFT{})-18*ptrSize]
)