// Copyright 2022 The Gc Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package gc // import "modernc.org/gc/v3" import ( "encoding/binary" "fmt" ) var ( byteOrders = map[string]binary.ByteOrder{ "386": binary.LittleEndian, "amd64": binary.LittleEndian, "arm": binary.LittleEndian, "arm64": binary.LittleEndian, "ppc64le": binary.LittleEndian, "riscv64": binary.LittleEndian, "s390x": binary.BigEndian, } abiTypes = map[[2]string]map[Kind]ABIType{ // go1.19.1 {"freebsd", "386"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19.1 {"freebsd", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.18.5 {"freebsd", "arm"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19 {"freebsd", "arm64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"darwin", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"darwin", "arm64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"linux", "386"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19.1 {"linux", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"linux", "arm"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19.1 {"linux", "arm64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"linux", "s390x"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"linux", "ppc64le"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"linux", "riscv64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.18.3 {"netbsd", "386"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.18.3 {"netbsd", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.18.3 {"netbsd", "arm"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19 {"openbsd", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19 {"openbsd", "arm64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19 {"openbsd", "386"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19.1 {"windows", "386"}: { Bool: {1, 1, 1}, Chan: {4, 4, 4}, Complex128: {16, 4, 4}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 4, 4}, Function: {4, 4, 4}, Int: {4, 4, 4}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 4, 4}, Int8: {1, 1, 1}, Interface: {8, 4, 4}, Map: {4, 4, 4}, Pointer: {4, 4, 4}, Slice: {12, 4, 4}, String: {8, 4, 4}, Uint: {4, 4, 4}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 4, 4}, Uint8: {1, 1, 1}, Uintptr: {4, 4, 4}, UnsafePointer: {4, 4, 4}, }, // go1.19.1 {"windows", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.1 {"windows", "arm64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, // go1.19.3 {"illumos", "amd64"}: { Bool: {1, 1, 1}, Chan: {8, 8, 8}, Complex128: {16, 8, 8}, Complex64: {8, 4, 4}, Float32: {4, 4, 4}, Float64: {8, 8, 8}, Function: {8, 8, 8}, Int: {8, 8, 8}, Int16: {2, 2, 2}, Int32: {4, 4, 4}, Int64: {8, 8, 8}, Int8: {1, 1, 1}, Interface: {16, 8, 8}, Map: {8, 8, 8}, Pointer: {8, 8, 8}, Slice: {24, 8, 8}, String: {16, 8, 8}, Uint: {8, 8, 8}, Uint16: {2, 2, 2}, Uint32: {4, 4, 4}, Uint64: {8, 8, 8}, Uint8: {1, 1, 1}, Uintptr: {8, 8, 8}, UnsafePointer: {8, 8, 8}, }, } ) // ABI describes selected parts of the Application Binary Interface. type ABI struct { ByteOrder binary.ByteOrder goarch string goos string Types map[Kind]ABIType } type ABIType struct { Size int64 Align int64 FieldAlign int64 } // NewABI creates an ABI based on the os+arch pair. func NewABI(os, arch string) (*ABI, error) { byteOrder, ok := byteOrders[arch] if !ok { return nil, fmt.Errorf("unsupported arch: %s", arch) } types0, ok := abiTypes[[2]string{os, arch}] if !ok { return nil, fmt.Errorf("unsupported os/arch: %s/%s", os, arch) } types := make(map[Kind]ABIType, len(types0)) for k, v := range types0 { types[k] = v } return &ABI{ ByteOrder: byteOrder, Types: types, }, nil }