446 lines
7.0 KiB
C

/** @file
OcGuardLib
Copyright (c) 2018, vit9696
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_GUARD_LIB_H
#define OC_GUARD_LIB_H
//
// The macros below provide pointer alignment checking interfaces.
// TypedPtr - pointer of a dedicated type, which alignment is to be checked.
// Align - valid alignment for the target platform (power of two so far).
// Type - valid complete typename.
// Ptr - raw pointer value, must fit into UINTN, meant to be uintptr_t equivalent.
//
#define OC_ALIGNOF(Type) (_Alignof (Type))
#define OC_POT_ALIGNED(Align, Ptr) (0ULL == (((UINTN) (Ptr)) & (Align-1U)))
#define OC_TYPE_ALIGNED(Type, Ptr) (OC_POT_ALIGNED (OC_ALIGNOF (Type), Ptr))
//
// Force member alignment for the structure.
//
#if (defined (__STDC__) && __STDC_VERSION__ >= 201112L) || defined (__GNUC__) || defined (__clang__)
#define OC_ALIGNAS(Alignment) _Alignas(Alignment)
#else
#define OC_ALIGNAS(Alignment)
#endif
/**
Return the result of (Multiplicand * Multiplier / Divisor).
@param Multiplicand A 64-bit unsigned value.
@param Multiplier A 64-bit unsigned value.
@param Divisor A 32-bit unsigned value.
@param Remainder A pointer to a 32-bit unsigned value. This parameter is
optional and may be NULL.
@return Multiplicand * Multiplier / Divisor.
**/
UINT64
MultThenDivU64x64x32 (
IN UINT64 Multiplicand,
IN UINT64 Multiplier,
IN UINT32 Divisor,
OUT UINT32 *Remainder OPTIONAL
);
//
// The interfaces below provide base safe arithmetics, reporting
// signed integer overflow and unsigned integer wraparound similarly to
// os/overflow.h in macOS SDK.
//
// Each interface may be implemented not only as an actual function, but
// a macro as well. Macro implementations are allowed to evaluate the
// expressions no more than once, and are supposed to provide faster
// compiler builtins if available.
//
// Each interface returns FALSE when the the stored result is equal to
// the infinite precision result, otherwise TRUE. The operands should
// be read left to right with the last argument representing a non-NULL
// pointer to the resulting value of the same type.
//
// More information could be found in Clang Extensions documentation:
// http://releases.llvm.org/7.0.0/tools/clang/docs/LanguageExtensions.html#checked-arithmetic-builtins
//
//
// 32-bit integer addition, subtraction, multiplication, triple addition (A+B+C),
// triple multiplication (A*B*C), addition with multiplication ((A+B)*C),
// and multiplication with addition (A*B+C) support.
//
BOOLEAN
OcOverflowAddU16 (
UINT16 A,
UINT16 B,
UINT16 *Result
);
BOOLEAN
OcOverflowSubU16 (
UINT16 A,
UINT16 B,
UINT16 *Result
);
BOOLEAN
OcOverflowMulU16 (
UINT16 A,
UINT16 B,
UINT16 *Result
);
BOOLEAN
OcOverflowAddU32 (
UINT32 A,
UINT32 B,
UINT32 *Result
);
BOOLEAN
OcOverflowSubU32 (
UINT32 A,
UINT32 B,
UINT32 *Result
);
BOOLEAN
OcOverflowMulU32 (
UINT32 A,
UINT32 B,
UINT32 *Result
);
BOOLEAN
OcOverflowTriAddU32 (
UINT32 A,
UINT32 B,
UINT32 C,
UINT32 *Result
);
BOOLEAN
OcOverflowTriMulU32 (
UINT32 A,
UINT32 B,
UINT32 C,
UINT32 *Result
);
BOOLEAN
OcOverflowAddMulU32 (
UINT32 A,
UINT32 B,
UINT32 C,
UINT32 *Result
);
BOOLEAN
OcOverflowMulAddU32 (
UINT32 A,
UINT32 B,
UINT32 C,
UINT32 *Result
);
BOOLEAN
OcOverflowAlignUpU32 (
UINT32 Value,
UINT32 Alignment,
UINT32 *Result
);
BOOLEAN
OcOverflowAddS32 (
INT32 A,
INT32 B,
INT32 *Result
);
BOOLEAN
OcOverflowSubS32 (
INT32 A,
INT32 B,
INT32 *Result
);
BOOLEAN
OcOverflowMulS32 (
INT32 A,
INT32 B,
INT32 *Result
);
BOOLEAN
OcOverflowTriAddS32 (
INT32 A,
INT32 B,
INT32 C,
INT32 *Result
);
BOOLEAN
OcOverflowTriMulS32 (
INT32 A,
INT32 B,
INT32 C,
INT32 *Result
);
BOOLEAN
OcOverflowAddMulS32 (
INT32 A,
INT32 B,
INT32 C,
INT32 *Result
);
BOOLEAN
OcOverflowMulAddS32 (
INT32 A,
INT32 B,
INT32 C,
INT32 *Result
);
//
// 64-bit integer addition, subtraction, multiplication, triple addition (A+B+C),
// triple multiplication (A*B*C), addition with multiplication ((A+B)*C),
// and multiplication with addition (A*B+C) support.
//
BOOLEAN
OcOverflowAddU64 (
UINT64 A,
UINT64 B,
UINT64 *Result
);
BOOLEAN
OcOverflowSubU64 (
UINT64 A,
UINT64 B,
UINT64 *Result
);
BOOLEAN
OcOverflowMulU64 (
UINT64 A,
UINT64 B,
UINT64 *Result
);
BOOLEAN
OcOverflowTriAddU64 (
UINT64 A,
UINT64 B,
UINT64 C,
UINT64 *Result
);
BOOLEAN
OcOverflowTriMulU64 (
UINT64 A,
UINT64 B,
UINT64 C,
UINT64 *Result
);
BOOLEAN
OcOverflowAddMulU64 (
UINT64 A,
UINT64 B,
UINT64 C,
UINT64 *Result
);
BOOLEAN
OcOverflowMulAddU64 (
UINT64 A,
UINT64 B,
UINT64 C,
UINT64 *Result
);
BOOLEAN
OcOverflowAddS64 (
INT64 A,
INT64 B,
INT64 *Result
);
BOOLEAN
OcOverflowSubS64 (
INT64 A,
INT64 B,
INT64 *Result
);
BOOLEAN
OcOverflowMulS64 (
INT64 A,
INT64 B,
INT64 *Result
);
BOOLEAN
OcOverflowTriAddS64 (
INT64 A,
INT64 B,
INT64 C,
INT64 *Result
);
BOOLEAN
OcOverflowTriMulS64 (
INT64 A,
INT64 B,
INT64 C,
INT64 *Result
);
BOOLEAN
OcOverflowAddMulS64 (
INT64 A,
INT64 B,
INT64 C,
INT64 *Result
);
BOOLEAN
OcOverflowMulAddS64 (
INT64 A,
INT64 B,
INT64 C,
INT64 *Result
);
//
// Native integer addition, subtraction, multiplication, triple addition (A+B+C),
// triple multiplication (A*B*C), addition with multiplication ((A+B)*C),
// and multiplication with addition (A*B+C) support.
//
BOOLEAN
OcOverflowAddUN (
UINTN A,
UINTN B,
UINTN *Result
);
BOOLEAN
OcOverflowSubUN (
UINTN A,
UINTN B,
UINTN *Result
);
BOOLEAN
OcOverflowMulUN (
UINTN A,
UINTN B,
UINTN *Result
);
BOOLEAN
OcOverflowTriAddUN (
UINTN A,
UINTN B,
UINTN C,
UINTN *Result
);
BOOLEAN
OcOverflowTriMulUN (
UINTN A,
UINTN B,
UINTN C,
UINTN *Result
);
BOOLEAN
OcOverflowAddMulUN (
UINTN A,
UINTN B,
UINTN C,
UINTN *Result
);
BOOLEAN
OcOverflowMulAddUN (
UINTN A,
UINTN B,
UINTN C,
UINTN *Result
);
BOOLEAN
OcOverflowAddSN (
INTN A,
INTN B,
INTN *Result
);
BOOLEAN
OcOverflowSubSN (
INTN A,
INTN B,
INTN *Result
);
BOOLEAN
OcOverflowMulSN (
INTN A,
INTN B,
INTN *Result
);
BOOLEAN
OcOverflowTriAddSN (
INTN A,
INTN B,
INTN C,
INTN *Result
);
BOOLEAN
OcOverflowTriMulSN (
INTN A,
INTN B,
INTN C,
INTN *Result
);
BOOLEAN
OcOverflowAddMulSN (
INTN A,
INTN B,
INTN C,
INTN *Result
);
BOOLEAN
OcOverflowMulAddSN (
INTN A,
INTN B,
INTN C,
INTN *Result
);
#endif // OC_GUARD_LIB_H