]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
MdePkg/PeiServicesLib.c: Change comments of PeiServicesResetSystem2
[mirror_edk2.git] / MdePkg / Library / BaseSafeIntLib / SafeIntLib.c
index 8e857927b0672e1b022ed9430ce1fe2dd07619c3..0f6be6e064663cfbfa40f034e7d3fbacd23955c4 100644 (file)
@@ -5,35 +5,19 @@
   Copyright (c) 2017, Microsoft Corporation\r
 \r
   All rights reserved.\r
-  Redistribution and use in source and binary forms, with or without\r
-  modification, are permitted provided that the following conditions are met:\r
-  1. Redistributions of source code must retain the above copyright notice,\r
-  this list of conditions and the following disclaimer.\r
-  2. Redistributions in binary form must reproduce the above copyright notice,\r
-  this list of conditions and the following disclaimer in the documentation\r
-  and/or other materials provided with the distribution.\r
-\r
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
-  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
-  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
-  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
-  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
-  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
-  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
-  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <Base.h>\r
 #include <Library/SafeIntLib.h>\r
+#include <Library/BaseLib.h>\r
 \r
 \r
 //\r
 // Magnitude of MIN_INT64 as expressed by a UINT64 number.\r
 //\r
-#define MIN_INT64_MAGNITUDE ((((UINT64) - (MIN_INT64 + 1))) + 1)\r
+#define MIN_INT64_MAGNITUDE (((UINT64)(- (MIN_INT64 + 1))) + 1)\r
 \r
 //\r
 // Conversion functions\r
@@ -3373,8 +3357,8 @@ SafeUint64Mult (
   // b * c must be less than 2^32 or there would be bits in the high 64-bits\r
   // then there must be no overflow of the resulting values summed up.\r
   //\r
-  DwordA = (UINT32)(Multiplicand >> 32);\r
-  DwordC = (UINT32)(Multiplier >> 32);\r
+  DwordA = (UINT32)RShiftU64 (Multiplicand, 32);\r
+  DwordC = (UINT32)RShiftU64 (Multiplier, 32);\r
 \r
   //\r
   // common case -- if high dwords are both zero, no chance for overflow\r
@@ -3409,7 +3393,7 @@ SafeUint64Mult (
           // now sum them all up checking for overflow.\r
           // shifting is safe because we already checked for overflow above\r
           //\r
-          if (!RETURN_ERROR (SafeUint64Add (ProductBC << 32, ProductAD << 32, &UnsignedResult))) {\r
+          if (!RETURN_ERROR (SafeUint64Add (LShiftU64 (ProductBC, 32), LShiftU64 (ProductAD, 32), &UnsignedResult))) {\r
             //\r
             // b * d\r
             //\r
@@ -3631,26 +3615,62 @@ SafeInt64Add (
   )\r
 {\r
   RETURN_STATUS  Status;\r
-  INT64          SignedResult;\r
 \r
   if (Result == NULL) {\r
     return RETURN_INVALID_PARAMETER;\r
   }\r
 \r
-  SignedResult = Augend + Addend;\r
-\r
   //\r
-  // Adding positive to negative never overflows.\r
-  // If you add two positive numbers, you expect a positive result.\r
-  // If you add two negative numbers, you expect a negative result.\r
-  // Overflow if inputs are the same sign and output is not that sign.\r
+  // * An Addend of zero can never cause underflow or overflow.\r
+  //\r
+  // * A positive Addend can only cause overflow. The overflow condition is\r
+  //\r
+  //     (Augend + Addend) > MAX_INT64\r
+  //\r
+  //   Subtracting Addend from both sides yields\r
+  //\r
+  //     Augend > (MAX_INT64 - Addend)\r
+  //\r
+  //   This condition can be coded directly in C because the RHS will neither\r
+  //   underflow nor overflow. That is due to the starting condition:\r
+  //\r
+  //     0 < Addend <= MAX_INT64\r
+  //\r
+  //   Multiplying all three sides by (-1) yields\r
+  //\r
+  //     0 > (-Addend) >= (-MAX_INT64)\r
+  //\r
+  //   Adding MAX_INT64 to all three sides yields\r
+  //\r
+  //     MAX_INT64 > (MAX_INT64 - Addend) >= 0\r
+  //\r
+  // * A negative Addend can only cause underflow. The underflow condition is\r
+  //\r
+  //     (Augend + Addend) < MIN_INT64\r
+  //\r
+  //   Subtracting Addend from both sides yields\r
+  //\r
+  //     Augend < (MIN_INT64 - Addend)\r
+  //\r
+  //   This condition can be coded directly in C because the RHS will neither\r
+  //   underflow nor overflow. That is due to the starting condition:\r
+  //\r
+  //     MIN_INT64 <= Addend < 0\r
+  //\r
+  //   Multiplying all three sides by (-1) yields\r
+  //\r
+  //     (-MIN_INT64) >= (-Addend) > 0\r
+  //\r
+  //   Adding MIN_INT64 to all three sides yields\r
+  //\r
+  //     0 >= (MIN_INT64 - Addend) > MIN_INT64\r
   //\r
-  if (((Augend < 0) == (Addend < 0))  &&\r
-      ((Augend < 0) != (SignedResult < 0))) {\r
+  if (((Addend > 0) && (Augend > (MAX_INT64 - Addend))) ||\r
+      ((Addend < 0) && (Augend < (MIN_INT64 - Addend)))) {\r
     *Result = INT64_ERROR;\r
     Status = RETURN_BUFFER_TOO_SMALL;\r
   } else {\r
-    *Result = SignedResult;\r
+    *Result = Augend + Addend;\r
     Status = RETURN_SUCCESS;\r
   }\r
 \r
@@ -4039,7 +4059,7 @@ SafeInt32Mult (
   OUT INT32  *Result\r
   )\r
 {\r
-  return SafeInt64ToInt32 (((INT64)Multiplicand) *((INT64)Multiplier), Result);\r
+  return SafeInt64ToInt32 (MultS64x64 (Multiplicand, Multiplier), Result);\r
 }\r
 \r
 /**\r
@@ -4107,6 +4127,8 @@ SafeInt64Mult (
       if (UnsignedResult > MIN_INT64_MAGNITUDE) {\r
         *Result = INT64_ERROR;\r
         Status = RETURN_BUFFER_TOO_SMALL;\r
+      } else if (UnsignedResult == MIN_INT64_MAGNITUDE) {\r
+        *Result = MIN_INT64;\r
       } else {\r
         *Result = - ((INT64)UnsignedResult);\r
       }\r