mirror of https://github.com/acidanthera/audk.git
MdePkg: Added BaseOverflowLib library.
This commit is contained in:
parent
3c8b43637e
commit
fe0b6465de
|
@ -0,0 +1,445 @@
|
|||
/** @file
|
||||
|
||||
BaseOverflowLib
|
||||
|
||||
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 __BASE_OVERFLOW_LIB__
|
||||
#define __BASE_OVERFLOW_LIB__
|
||||
|
||||
//
|
||||
// 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 BASE_ALIGNOF(Type) (_Alignof (Type))
|
||||
#define BASE_POT_ALIGNED(Align, Ptr) (0ULL == (((UINTN) (Ptr)) & (Align-1U)))
|
||||
#define BASE_TYPE_ALIGNED(Type, Ptr) (BASE_POT_ALIGNED (BASE_ALIGNOF (Type), Ptr))
|
||||
|
||||
//
|
||||
// Force member alignment for the structure.
|
||||
//
|
||||
#if (defined (__STDC__) && __STDC_VERSION__ >= 201112L) || defined (__GNUC__) || defined (__clang__)
|
||||
#define BASE_ALIGNAS(Alignment) _Alignas(Alignment)
|
||||
#else
|
||||
#define BASE_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
|
||||
BaseMultThenDivU64x64x32 (
|
||||
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
|
||||
BaseOverflowAddU16 (
|
||||
UINT16 A,
|
||||
UINT16 B,
|
||||
UINT16 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubU16 (
|
||||
UINT16 A,
|
||||
UINT16 B,
|
||||
UINT16 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulU16 (
|
||||
UINT16 A,
|
||||
UINT16 B,
|
||||
UINT16 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAlignUpU32 (
|
||||
UINT32 Value,
|
||||
UINT32 Alignment,
|
||||
UINT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddS32 (
|
||||
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
|
||||
BaseOverflowAddU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddS64 (
|
||||
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
|
||||
BaseOverflowAddUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
);
|
||||
|
||||
#endif // __BASE_OVERFLOW_LIB__
|
|
@ -0,0 +1,36 @@
|
|||
/** @file
|
||||
|
||||
BaseOverflowLib
|
||||
|
||||
Copyright (c) 2020, Download-Fritz
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseOverflowLib.h>
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAlignUpU32 (
|
||||
UINT32 Value,
|
||||
UINT32 Alignment,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
BOOLEAN Status;
|
||||
|
||||
Status = BaseOverflowAddU32 (Value, Alignment - 1U, Result);
|
||||
*Result &= ~(Alignment - 1U);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,442 @@
|
|||
/** @file
|
||||
|
||||
BaseOverflowLib
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseOverflowLib.h>
|
||||
|
||||
#include "BaseOverflowInternals.h"
|
||||
|
||||
//
|
||||
// Software implementations provided try not to be obviously slow, but primarily
|
||||
// target C99 compliance rather than performance.
|
||||
//
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddU16 (
|
||||
UINT16 A,
|
||||
UINT16 B,
|
||||
UINT16 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#else
|
||||
UINT32 Temp;
|
||||
|
||||
//
|
||||
// I believe casting will be faster on X86 at least.
|
||||
//
|
||||
Temp = A + B;
|
||||
*Result = (UINT16)Temp;
|
||||
if (Temp <= MAX_UINT16) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubU16 (
|
||||
UINT16 A,
|
||||
UINT16 B,
|
||||
UINT16 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#else
|
||||
*Result = (UINT16)(A - B);
|
||||
|
||||
if (A >= B) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulU16 (
|
||||
UINT16 A,
|
||||
UINT16 B,
|
||||
UINT16 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#else
|
||||
UINT32 Temp;
|
||||
|
||||
Temp = (UINT32)A * B;
|
||||
*Result = (UINT16)Temp;
|
||||
if (Temp <= MAX_UINT32) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_uadd_overflow (A, B, Result);
|
||||
#else
|
||||
UINT32 Temp;
|
||||
|
||||
//
|
||||
// I believe casting will be faster on X86 at least.
|
||||
//
|
||||
Temp = A + B;
|
||||
*Result = Temp;
|
||||
if (Temp >= A) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_usub_overflow (A, B, Result);
|
||||
#else
|
||||
*Result = A - B;
|
||||
if (B <= A) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_umul_overflow (A, B, Result);
|
||||
#else
|
||||
UINT64 Temp;
|
||||
|
||||
Temp = (UINT64)A * B;
|
||||
*Result = (UINT32)Temp;
|
||||
if (Temp <= MAX_UINT32) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_sadd_overflow (A, B, Result);
|
||||
#else
|
||||
INT64 Temp;
|
||||
|
||||
Temp = (INT64)A + B;
|
||||
*Result = (INT32)Temp;
|
||||
if ((Temp >= MIN_INT32) && (Temp <= MAX_INT32)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_ssub_overflow (A, B, Result);
|
||||
#else
|
||||
INT64 Temp;
|
||||
|
||||
Temp = (INT64)A - B;
|
||||
*Result = (INT32)Temp;
|
||||
if ((Temp >= MIN_INT32) && (Temp <= MAX_INT32)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_smul_overflow (A, B, Result);
|
||||
#else
|
||||
INT64 Temp;
|
||||
|
||||
Temp = MultS64x64 (A, B);
|
||||
*Result = (INT32)Temp;
|
||||
if ((Temp >= MIN_INT32) && (Temp <= MAX_INT32)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_uaddll_overflow (A, B, Result);
|
||||
#else
|
||||
UINT64 Temp;
|
||||
|
||||
Temp = A + B;
|
||||
*Result = Temp;
|
||||
if (Temp >= A) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_usubll_overflow (A, B, Result);
|
||||
#else
|
||||
*Result = A - B;
|
||||
if (B <= A) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_umulll_overflow (A, B, Result);
|
||||
#else
|
||||
UINT64 AHi;
|
||||
UINT64 ALo;
|
||||
UINT64 BHi;
|
||||
UINT64 BLo;
|
||||
UINT64 LoBits;
|
||||
UINT64 HiBits1;
|
||||
UINT64 HiBits2;
|
||||
BOOLEAN Overflow;
|
||||
|
||||
//
|
||||
// Based on the 2nd option written by Charphacy, believed to be the fastest portable on x86.
|
||||
// See: https://stackoverflow.com/a/26320664
|
||||
// Implements overflow checking by a series of up to 3 multiplications.
|
||||
//
|
||||
|
||||
AHi = RShiftU64 (A, 32);
|
||||
ALo = A & MAX_UINT32;
|
||||
BHi = RShiftU64 (B, 32);
|
||||
BLo = B & MAX_UINT32;
|
||||
|
||||
LoBits = MultU64x64 (ALo, BLo);
|
||||
if ((AHi == 0) && (BHi == 0)) {
|
||||
*Result = LoBits;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Overflow = AHi > 0 && BHi > 0;
|
||||
HiBits1 = MultU64x64 (ALo, BHi);
|
||||
HiBits2 = MultU64x64 (AHi, BLo);
|
||||
|
||||
*Result = LoBits + LShiftU64 (HiBits1 + HiBits2, 32);
|
||||
return Overflow || *Result < LoBits || RShiftU64 (HiBits1, 32) != 0 || RShiftU64 (HiBits2, 32) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_saddll_overflow (A, B, Result);
|
||||
#else
|
||||
if (((B <= 0) || (A <= MAX_INT64 - B)) && ((B >= 0) || (A >= MIN_INT64 - B))) {
|
||||
*Result = A + B;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Assign some defined value to *Result.
|
||||
//
|
||||
*Result = 0;
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS)
|
||||
return __builtin_ssubll_overflow (A, B, Result);
|
||||
#else
|
||||
if (((B >= 0) || (A <= MAX_INT64 + B)) && ((B <= 0) || (A >= MIN_INT64 + B))) {
|
||||
*Result = A - B;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Assign some defined value to *Result.
|
||||
//
|
||||
*Result = 0;
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
//
|
||||
// Intel 32-bit architectures do not have hardware signed 64-bit
|
||||
// multiplication with overflow.
|
||||
//
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) && !defined (MDE_CPU_IA32)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) && !defined (MDE_CPU_IA32)
|
||||
return __builtin_smulll_overflow (A, B, Result);
|
||||
#else
|
||||
UINT64 AU;
|
||||
UINT64 BU;
|
||||
UINT64 ResultU;
|
||||
|
||||
//
|
||||
// It hurts to implement it without unsigned multiplication, maybe rewrite it one day.
|
||||
// The idea taken from BaseSafeIntLib.
|
||||
//
|
||||
|
||||
#define OC_ABS_64(X) (((X) < 0) ? (((UINT64) (-((X) + 1))) + 1) : (UINT64) (X))
|
||||
|
||||
AU = OC_ABS_64 (A);
|
||||
BU = OC_ABS_64 (B);
|
||||
|
||||
if (BaseOverflowMulU64 (AU, BU, &ResultU)) {
|
||||
*Result = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Split into positive and negative results and check just one range.
|
||||
//
|
||||
if ((A < 0) == (B < 0)) {
|
||||
if (ResultU <= MAX_INT64) {
|
||||
*Result = (INT64)ResultU;
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (ResultU < OC_ABS_64 (MIN_INT64)) {
|
||||
*Result = -((INT64)ResultU);
|
||||
return FALSE;
|
||||
} else if (ResultU == OC_ABS_64 (MIN_INT64)) {
|
||||
*Result = MIN_INT64;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#undef OC_ABS_64
|
||||
|
||||
*Result = 0;
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/** @file
|
||||
Copyright (C) 2019, vit9696. All rights reserved.
|
||||
|
||||
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.
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
/**
|
||||
BaseMultThenDivU64x64x32 is from MdeModulePkg's PciRootBridgeIo.c
|
||||
|
||||
Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
UINT64
|
||||
BaseMultThenDivU64x64x32 (
|
||||
IN UINT64 Multiplicand,
|
||||
IN UINT64 Multiplier,
|
||||
IN UINT32 Divisor,
|
||||
OUT UINT32 *Remainder OPTIONAL
|
||||
)
|
||||
{
|
||||
UINT64 Uint64;
|
||||
UINT32 LocalRemainder;
|
||||
UINT32 Uint32;
|
||||
|
||||
if (Multiplicand > DivU64x64Remainder (MAX_UINT64, Multiplier, NULL)) {
|
||||
//
|
||||
// Make sure Multiplicand is the bigger one.
|
||||
//
|
||||
if (Multiplicand < Multiplier) {
|
||||
Uint64 = Multiplicand;
|
||||
Multiplicand = Multiplier;
|
||||
Multiplier = Uint64;
|
||||
}
|
||||
|
||||
//
|
||||
// Because Multiplicand * Multiplier overflows,
|
||||
// Multiplicand * Multiplier / Divisor
|
||||
// = (2 * Multiplicand' + 1) * Multiplier / Divisor
|
||||
// = 2 * (Multiplicand' * Multiplier / Divisor) + Multiplier / Divisor
|
||||
//
|
||||
Uint64 = BaseMultThenDivU64x64x32 (RShiftU64 (Multiplicand, 1), Multiplier, Divisor, &LocalRemainder);
|
||||
Uint64 = LShiftU64 (Uint64, 1);
|
||||
Uint32 = 0;
|
||||
if ((Multiplicand & 0x1) == 1) {
|
||||
Uint64 += DivU64x32Remainder (Multiplier, Divisor, &Uint32);
|
||||
}
|
||||
|
||||
return Uint64 + DivU64x32Remainder (Uint32 + LShiftU64 (LocalRemainder, 1), Divisor, Remainder);
|
||||
} else {
|
||||
return DivU64x32Remainder (MultU64x64 (Multiplicand, Multiplier), Divisor, Remainder);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/** @file
|
||||
|
||||
BaseOverflowLib
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseOverflowLib.h>
|
||||
|
||||
#include "BaseOverflowInternals.h"
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_uaddll_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32)
|
||||
return __builtin_uadd_overflow (A, B, Result);
|
||||
#else
|
||||
if (sizeof (UINTN) == sizeof (UINT64)) {
|
||||
return BaseOverflowAddU64 (A, B, (UINT64 *)Result);
|
||||
}
|
||||
|
||||
return BaseOverflowAddU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_usubll_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32)
|
||||
return __builtin_usub_overflow (A, B, Result);
|
||||
#else
|
||||
if (sizeof (UINTN) == sizeof (UINT64)) {
|
||||
return BaseOverflowSubU64 (A, B, (UINT64 *)Result);
|
||||
}
|
||||
|
||||
return BaseOverflowSubU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_umulll_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32)
|
||||
return __builtin_umul_overflow (A, B, Result);
|
||||
#else
|
||||
if (sizeof (UINTN) == sizeof (UINT64)) {
|
||||
return BaseOverflowMulU64 (A, B, (UINT64 *)Result);
|
||||
}
|
||||
|
||||
return BaseOverflowMulU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_add_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_saddll_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32)
|
||||
return __builtin_sadd_overflow (A, B, Result);
|
||||
#else
|
||||
if (sizeof (INTN) == sizeof (INT64)) {
|
||||
return BaseOverflowAddS64 (A, B, (INT64 *)Result);
|
||||
}
|
||||
|
||||
return BaseOverflowAddS32 ((INT32)A, (INT32)B, (INT32 *)Result);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowSubSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_sub_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_ssubll_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32)
|
||||
return __builtin_ssub_overflow (A, B, Result);
|
||||
#else
|
||||
if (sizeof (INTN) == sizeof (INT64)) {
|
||||
return BaseOverflowSubS64 (A, B, (INT64 *)Result);
|
||||
}
|
||||
|
||||
return BaseOverflowSubS32 ((INT32)A, (INT32)B, (INT32 *)Result);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
#if defined (BASE_HAS_TYPE_GENERIC_BUILTINS)
|
||||
return __builtin_mul_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64)
|
||||
return __builtin_smulll_overflow (A, B, Result);
|
||||
#elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32)
|
||||
return __builtin_smul_overflow (A, B, Result);
|
||||
#else
|
||||
if (sizeof (INTN) == sizeof (INT64)) {
|
||||
return BaseOverflowMulS64 (A, B, (INT64 *)Result);
|
||||
}
|
||||
|
||||
return BaseOverflowMulS32 ((INT32)A, (INT32)B, (INT32 *)Result);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/** @file
|
||||
This header provides internal BaseOverflowLib definitions.
|
||||
|
||||
Copyright (c) 2020, vit9696. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
**/
|
||||
|
||||
#ifndef __OVERFLOW_INTERNALS__
|
||||
#define __OVERFLOW_INTERNALS__
|
||||
|
||||
#if defined (__has_builtin)
|
||||
#if __has_builtin (__builtin_add_overflow) && __has_builtin (__builtin_sub_overflow) && __has_builtin (__builtin_mul_overflow)
|
||||
#define BASE_HAS_TYPE_GENERIC_BUILTINS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_X64)
|
||||
STATIC_ASSERT (sizeof (INTN) == 8, "INTN is expected to be 8 bytes");
|
||||
STATIC_ASSERT (sizeof (UINTN) == 8, "UINTN is expected to be 8 bytes");
|
||||
#define BASE_HAS_TYPE_SPECIFIC_BUILTINS_64 1
|
||||
#elif defined (MDE_CPU_ARM) || defined (MDE_CPU_IA32)
|
||||
STATIC_ASSERT (sizeof (INTN) == 4, "INTN is expected to be 4 bytes");
|
||||
STATIC_ASSERT (sizeof (UINTN) == 4, "UINTN is expected to be 4 bytes");
|
||||
#define BASE_HAS_TYPE_SPECIFIC_BUILTINS_32 1
|
||||
#endif
|
||||
|
||||
STATIC_ASSERT (sizeof (int) == 4, "int is expected to be 4 bytes");
|
||||
STATIC_ASSERT (sizeof (unsigned) == 4, "unsigned is expected to be 4 bytes");
|
||||
STATIC_ASSERT (sizeof (long long) == 8, "long long is expected to be 8 bytes");
|
||||
STATIC_ASSERT (sizeof (unsigned long long) == 8, "unsigned long long is expected to be 8 bytes");
|
||||
#define BASE_HAS_TYPE_SPECIFIC_BUILTINS 1
|
||||
#endif
|
||||
|
||||
//
|
||||
// Currently no architectures provide UINTN and INTN different from 32-bit or 64-bit
|
||||
// integers. For this reason they are the only variants supported and are enforced here.
|
||||
//
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (INTN) == sizeof (INT64) || sizeof (INTN) == sizeof (INT32),
|
||||
"INTN must be 32 or 64 Bits wide."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UINTN) == sizeof (UINT64) || sizeof (UINTN) == sizeof (UINT32),
|
||||
"UINTN must be 32 or 64 Bits wide."
|
||||
);
|
||||
|
||||
#endif // __OVERFLOW_INTERNALS__
|
|
@ -0,0 +1,48 @@
|
|||
## @file
|
||||
# BaseOverflowLib
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = BaseOverflowLib
|
||||
FILE_GUID = 57D4B14C-CC2C-4779-8A80-0BA5AAC1B8F3
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = BaseOverflowLib
|
||||
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
BaseAlignment.c
|
||||
BaseBitOverflow.c
|
||||
BaseOverflowInternals.h
|
||||
BaseMath.c
|
||||
BaseNativeOverflow.c
|
||||
BaseTripleOverflow.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
|
||||
[BuildOptions]
|
||||
XCODE:DEBUG_*_*_CC_FLAGS = -fno-stack-protector
|
||||
XCODE:NOOPT_*_*_CC_FLAGS = -fno-stack-protector
|
||||
XCODE:RELEASE_*_*_CC_FLAGS = -fno-stack-protector
|
|
@ -0,0 +1,429 @@
|
|||
/** @file
|
||||
|
||||
BaseOverflowLib
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/BaseOverflowLib.h>
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
UINT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddU32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddU32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
UINT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulU32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulU32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
UINT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddU32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulU32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddU32 (
|
||||
UINT32 A,
|
||||
UINT32 B,
|
||||
UINT32 C,
|
||||
UINT32 *Result
|
||||
)
|
||||
{
|
||||
UINT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulU32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddU32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
INT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddS32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddS32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
INT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulS32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulS32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
INT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddS32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulS32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddS32 (
|
||||
INT32 A,
|
||||
INT32 B,
|
||||
INT32 C,
|
||||
INT32 *Result
|
||||
)
|
||||
{
|
||||
INT32 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulS32 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddS32 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
UINT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddU64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddU64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
UINT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulU64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulU64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
UINT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddU64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulU64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddU64 (
|
||||
UINT64 A,
|
||||
UINT64 B,
|
||||
UINT64 C,
|
||||
UINT64 *Result
|
||||
)
|
||||
{
|
||||
UINT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulU64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddU64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
INT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddS64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddS64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
INT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulS64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulS64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
INT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddS64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulS64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddS64 (
|
||||
INT64 A,
|
||||
INT64 B,
|
||||
INT64 C,
|
||||
INT64 *Result
|
||||
)
|
||||
{
|
||||
INT64 BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulS64 (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddS64 (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
UINTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddUN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddUN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
UINTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulUN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulUN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
UINTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddUN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulUN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddUN (
|
||||
UINTN A,
|
||||
UINTN B,
|
||||
UINTN C,
|
||||
UINTN *Result
|
||||
)
|
||||
{
|
||||
UINTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulUN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddUN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriAddSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
INTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddSN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddSN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowTriMulSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
INTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulSN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulSN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowAddMulSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
INTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowAddSN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowMulSN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
BaseOverflowMulAddSN (
|
||||
INTN A,
|
||||
INTN B,
|
||||
INTN C,
|
||||
INTN *Result
|
||||
)
|
||||
{
|
||||
INTN BaseTmp;
|
||||
BOOLEAN BaseFirst;
|
||||
BOOLEAN BaseSecond;
|
||||
|
||||
BaseFirst = BaseOverflowMulSN (A, B, &BaseTmp);
|
||||
BaseSecond = BaseOverflowAddSN (BaseTmp, C, Result);
|
||||
return BaseFirst | BaseSecond;
|
||||
}
|
|
@ -341,6 +341,11 @@
|
|||
## @libraryclass Provides function to support TDX processing.
|
||||
TdxLib|Include/Library/TdxLib.h
|
||||
|
||||
## @libraryclass Provides base safe arithmetics, reporting signed integer overflow
|
||||
# and unsigned integer wraparound similarly to os/overflow.h in macOS SDK.
|
||||
##
|
||||
BaseOverflowLib|Include/Library/BaseOverflowLib.h
|
||||
|
||||
[LibraryClasses.RISCV64]
|
||||
## @libraryclass Provides function to make ecalls to SBI
|
||||
BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
|
||||
|
|
|
@ -186,6 +186,7 @@
|
|||
MdePkg/Library/TdxLib/TdxLib.inf
|
||||
MdePkg/Library/MipiSysTLib/MipiSysTLib.inf
|
||||
MdePkg/Library/TraceHubDebugSysTLibNull/TraceHubDebugSysTLibNull.inf
|
||||
MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf
|
||||
|
||||
[Components.EBC]
|
||||
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
||||
|
|
Loading…
Reference in New Issue