mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 14:44:28 +02:00
MdePkg: Added BaseOverflowLib library.
This commit is contained in:
parent
3c8b43637e
commit
fe0b6465de
445
MdePkg/Include/Library/BaseOverflowLib.h
Normal file
445
MdePkg/Include/Library/BaseOverflowLib.h
Normal file
@ -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__
|
36
MdePkg/Library/BaseOverflowLib/BaseAlignment.c
Normal file
36
MdePkg/Library/BaseOverflowLib/BaseAlignment.c
Normal file
@ -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;
|
||||||
|
}
|
442
MdePkg/Library/BaseOverflowLib/BaseBitOverflow.c
Normal file
442
MdePkg/Library/BaseOverflowLib/BaseBitOverflow.c
Normal file
@ -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
|
||||||
|
}
|
64
MdePkg/Library/BaseOverflowLib/BaseMath.c
Normal file
64
MdePkg/Library/BaseOverflowLib/BaseMath.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
156
MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.c
Normal file
156
MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.c
Normal file
@ -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
|
||||||
|
}
|
50
MdePkg/Library/BaseOverflowLib/BaseOverflowInternals.h
Normal file
50
MdePkg/Library/BaseOverflowLib/BaseOverflowInternals.h
Normal file
@ -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__
|
48
MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf
Normal file
48
MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf
Normal file
@ -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
|
429
MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.c
Normal file
429
MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.c
Normal file
@ -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.
|
## @libraryclass Provides function to support TDX processing.
|
||||||
TdxLib|Include/Library/TdxLib.h
|
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]
|
[LibraryClasses.RISCV64]
|
||||||
## @libraryclass Provides function to make ecalls to SBI
|
## @libraryclass Provides function to make ecalls to SBI
|
||||||
BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
|
BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h
|
||||||
|
@ -186,6 +186,7 @@
|
|||||||
MdePkg/Library/TdxLib/TdxLib.inf
|
MdePkg/Library/TdxLib/TdxLib.inf
|
||||||
MdePkg/Library/MipiSysTLib/MipiSysTLib.inf
|
MdePkg/Library/MipiSysTLib/MipiSysTLib.inf
|
||||||
MdePkg/Library/TraceHubDebugSysTLibNull/TraceHubDebugSysTLibNull.inf
|
MdePkg/Library/TraceHubDebugSysTLibNull/TraceHubDebugSysTLibNull.inf
|
||||||
|
MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf
|
||||||
|
|
||||||
[Components.EBC]
|
[Components.EBC]
|
||||||
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
||||||
|
Loading…
x
Reference in New Issue
Block a user