TianoCore EDK2 master
Loading...
Searching...
No Matches
SafeIntLib.c
Go to the documentation of this file.
1
12#include <Base.h>
13#include <Library/SafeIntLib.h>
14#include <Library/BaseLib.h>
15
16//
17// Magnitude of MIN_INT64 as expressed by a UINT64 number.
18//
19#define MIN_INT64_MAGNITUDE (((UINT64)(- (MIN_INT64 + 1))) + 1)
20
21//
22// Conversion functions
23//
24// There are three reasons for having conversion functions:
25//
26// 1. We are converting from a signed type to an unsigned type of the same
27// size, or vice-versa.
28//
29// 2. We are converting to a smaller type, and we could therefore possibly
30// overflow.
31//
32// 3. We are converting to a bigger type, and we are signed and the type we are
33// converting to is unsigned.
34//
35
56RETURN_STATUS
57EFIAPI
59 IN INT8 Operand,
60 OUT UINT8 *Result
61 )
62{
63 RETURN_STATUS Status;
64
65 if (Result == NULL) {
67 }
68
69 if (Operand >= 0) {
70 *Result = (UINT8)Operand;
71 Status = RETURN_SUCCESS;
72 } else {
73 *Result = UINT8_ERROR;
75 }
76
77 return Status;
78}
79
100RETURN_STATUS
101EFIAPI
103 IN INT8 Operand,
104 OUT CHAR8 *Result
105 )
106{
107 RETURN_STATUS Status;
108
109 if (Result == NULL) {
111 }
112
113 if (Operand >= 0) {
114 *Result = (CHAR8)Operand;
115 Status = RETURN_SUCCESS;
116 } else {
117 *Result = CHAR8_ERROR;
119 }
120
121 return Status;
122}
123
144RETURN_STATUS
145EFIAPI
147 IN INT8 Operand,
148 OUT UINT16 *Result
149 )
150{
151 RETURN_STATUS Status;
152
153 if (Result == NULL) {
155 }
156
157 if (Operand >= 0) {
158 *Result = (UINT16)Operand;
159 Status = RETURN_SUCCESS;
160 } else {
161 *Result = UINT16_ERROR;
163 }
164
165 return Status;
166}
167
188RETURN_STATUS
189EFIAPI
191 IN INT8 Operand,
192 OUT UINT32 *Result
193 )
194{
195 RETURN_STATUS Status;
196
197 if (Result == NULL) {
199 }
200
201 if (Operand >= 0) {
202 *Result = (UINT32)Operand;
203 Status = RETURN_SUCCESS;
204 } else {
205 *Result = UINT32_ERROR;
207 }
208
209 return Status;
210}
211
232RETURN_STATUS
233EFIAPI
235 IN INT8 Operand,
236 OUT UINTN *Result
237 )
238{
239 RETURN_STATUS Status;
240
241 if (Result == NULL) {
243 }
244
245 if (Operand >= 0) {
246 *Result = (UINTN)Operand;
247 Status = RETURN_SUCCESS;
248 } else {
249 *Result = UINTN_ERROR;
251 }
252
253 return Status;
254}
255
276RETURN_STATUS
277EFIAPI
279 IN INT8 Operand,
280 OUT UINT64 *Result
281 )
282{
283 RETURN_STATUS Status;
284
285 if (Result == NULL) {
287 }
288
289 if (Operand >= 0) {
290 *Result = (UINT64)Operand;
291 Status = RETURN_SUCCESS;
292 } else {
293 *Result = UINT64_ERROR;
295 }
296
297 return Status;
298}
299
320RETURN_STATUS
321EFIAPI
323 IN UINT8 Operand,
324 OUT INT8 *Result
325 )
326{
327 RETURN_STATUS Status;
328
329 if (Result == NULL) {
331 }
332
333 if (Operand <= MAX_INT8) {
334 *Result = (INT8)Operand;
335 Status = RETURN_SUCCESS;
336 } else {
337 *Result = INT8_ERROR;
339 }
340
341 return Status;
342}
343
364RETURN_STATUS
365EFIAPI
367 IN UINT8 Operand,
368 OUT CHAR8 *Result
369 )
370{
371 RETURN_STATUS Status;
372
373 if (Result == NULL) {
375 }
376
377 if (Operand <= MAX_INT8) {
378 *Result = (CHAR8)Operand;
379 Status = RETURN_SUCCESS;
380 } else {
381 *Result = CHAR8_ERROR;
383 }
384
385 return Status;
386}
387
408RETURN_STATUS
409EFIAPI
411 IN INT16 Operand,
412 OUT INT8 *Result
413 )
414{
415 RETURN_STATUS Status;
416
417 if (Result == NULL) {
419 }
420
421 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
422 *Result = (INT8)Operand;
423 Status = RETURN_SUCCESS;
424 } else {
425 *Result = INT8_ERROR;
427 }
428
429 return Status;
430}
431
452RETURN_STATUS
453EFIAPI
455 IN INT16 Operand,
456 OUT CHAR8 *Result
457 )
458{
459 RETURN_STATUS Status;
460
461 if (Result == NULL) {
463 }
464
465 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
466 *Result = (CHAR8)Operand;
467 Status = RETURN_SUCCESS;
468 } else {
469 *Result = CHAR8_ERROR;
471 }
472
473 return Status;
474}
475
496RETURN_STATUS
497EFIAPI
499 IN INT16 Operand,
500 OUT UINT8 *Result
501 )
502{
503 RETURN_STATUS Status;
504
505 if (Result == NULL) {
507 }
508
509 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
510 *Result = (UINT8)Operand;
511 Status = RETURN_SUCCESS;
512 } else {
513 *Result = UINT8_ERROR;
515 }
516
517 return Status;
518}
519
540RETURN_STATUS
541EFIAPI
543 IN INT16 Operand,
544 OUT UINT16 *Result
545 )
546{
547 RETURN_STATUS Status;
548
549 if (Result == NULL) {
551 }
552
553 if (Operand >= 0) {
554 *Result = (UINT16)Operand;
555 Status = RETURN_SUCCESS;
556 } else {
557 *Result = UINT16_ERROR;
559 }
560
561 return Status;
562}
563
584RETURN_STATUS
585EFIAPI
587 IN INT16 Operand,
588 OUT UINT32 *Result
589 )
590{
591 RETURN_STATUS Status;
592
593 if (Result == NULL) {
595 }
596
597 if (Operand >= 0) {
598 *Result = (UINT32)Operand;
599 Status = RETURN_SUCCESS;
600 } else {
601 *Result = UINT32_ERROR;
603 }
604
605 return Status;
606}
607
628RETURN_STATUS
629EFIAPI
631 IN INT16 Operand,
632 OUT UINTN *Result
633 )
634{
635 RETURN_STATUS Status;
636
637 if (Result == NULL) {
639 }
640
641 if (Operand >= 0) {
642 *Result = (UINTN)Operand;
643 Status = RETURN_SUCCESS;
644 } else {
645 *Result = UINTN_ERROR;
647 }
648
649 return Status;
650}
651
672RETURN_STATUS
673EFIAPI
675 IN INT16 Operand,
676 OUT UINT64 *Result
677 )
678{
679 RETURN_STATUS Status;
680
681 if (Result == NULL) {
683 }
684
685 if (Operand >= 0) {
686 *Result = (UINT64)Operand;
687 Status = RETURN_SUCCESS;
688 } else {
689 *Result = UINT64_ERROR;
691 }
692
693 return Status;
694}
695
716RETURN_STATUS
717EFIAPI
719 IN UINT16 Operand,
720 OUT INT8 *Result
721 )
722{
723 RETURN_STATUS Status;
724
725 if (Result == NULL) {
727 }
728
729 if (Operand <= MAX_INT8) {
730 *Result = (INT8)Operand;
731 Status = RETURN_SUCCESS;
732 } else {
733 *Result = INT8_ERROR;
735 }
736
737 return Status;
738}
739
760RETURN_STATUS
761EFIAPI
763 IN UINT16 Operand,
764 OUT CHAR8 *Result
765 )
766{
767 RETURN_STATUS Status;
768
769 if (Result == NULL) {
771 }
772
773 if (Operand <= MAX_INT8) {
774 *Result = (INT8)Operand;
775 Status = RETURN_SUCCESS;
776 } else {
777 *Result = CHAR8_ERROR;
779 }
780
781 return Status;
782}
783
804RETURN_STATUS
805EFIAPI
807 IN UINT16 Operand,
808 OUT UINT8 *Result
809 )
810{
811 RETURN_STATUS Status;
812
813 if (Result == NULL) {
815 }
816
817 if (Operand <= MAX_UINT8) {
818 *Result = (UINT8)Operand;
819 Status = RETURN_SUCCESS;
820 } else {
821 *Result = UINT8_ERROR;
823 }
824
825 return Status;
826}
827
848RETURN_STATUS
849EFIAPI
851 IN UINT16 Operand,
852 OUT INT16 *Result
853 )
854{
855 RETURN_STATUS Status;
856
857 if (Result == NULL) {
859 }
860
861 if (Operand <= MAX_INT16) {
862 *Result = (INT16)Operand;
863 Status = RETURN_SUCCESS;
864 } else {
865 *Result = INT16_ERROR;
867 }
868
869 return Status;
870}
871
892RETURN_STATUS
893EFIAPI
895 IN INT32 Operand,
896 OUT INT8 *Result
897 )
898{
899 RETURN_STATUS Status;
900
901 if (Result == NULL) {
903 }
904
905 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
906 *Result = (INT8)Operand;
907 Status = RETURN_SUCCESS;
908 } else {
909 *Result = INT8_ERROR;
911 }
912
913 return Status;
914}
915
936RETURN_STATUS
937EFIAPI
939 IN INT32 Operand,
940 OUT CHAR8 *Result
941 )
942{
943 RETURN_STATUS Status;
944
945 if (Result == NULL) {
947 }
948
949 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
950 *Result = (CHAR8)Operand;
951 Status = RETURN_SUCCESS;
952 } else {
953 *Result = CHAR8_ERROR;
955 }
956
957 return Status;
958}
959
980RETURN_STATUS
981EFIAPI
983 IN INT32 Operand,
984 OUT UINT8 *Result
985 )
986{
987 RETURN_STATUS Status;
988
989 if (Result == NULL) {
991 }
992
993 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
994 *Result = (UINT8)Operand;
995 Status = RETURN_SUCCESS;
996 } else {
997 *Result = UINT8_ERROR;
999 }
1000
1001 return Status;
1002}
1003
1024RETURN_STATUS
1025EFIAPI
1027 IN INT32 Operand,
1028 OUT INT16 *Result
1029 )
1030{
1031 RETURN_STATUS Status;
1032
1033 if (Result == NULL) {
1035 }
1036
1037 if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
1038 *Result = (INT16)Operand;
1039 Status = RETURN_SUCCESS;
1040 } else {
1041 *Result = INT16_ERROR;
1042 Status = RETURN_BUFFER_TOO_SMALL;
1043 }
1044
1045 return Status;
1046}
1047
1068RETURN_STATUS
1069EFIAPI
1071 IN INT32 Operand,
1072 OUT UINT16 *Result
1073 )
1074{
1075 RETURN_STATUS Status;
1076
1077 if (Result == NULL) {
1079 }
1080
1081 if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
1082 *Result = (UINT16)Operand;
1083 Status = RETURN_SUCCESS;
1084 } else {
1085 *Result = UINT16_ERROR;
1086 Status = RETURN_BUFFER_TOO_SMALL;
1087 }
1088
1089 return Status;
1090}
1091
1112RETURN_STATUS
1113EFIAPI
1115 IN INT32 Operand,
1116 OUT UINT32 *Result
1117 )
1118{
1119 RETURN_STATUS Status;
1120
1121 if (Result == NULL) {
1123 }
1124
1125 if (Operand >= 0) {
1126 *Result = (UINT32)Operand;
1127 Status = RETURN_SUCCESS;
1128 } else {
1129 *Result = UINT32_ERROR;
1130 Status = RETURN_BUFFER_TOO_SMALL;
1131 }
1132
1133 return Status;
1134}
1135
1156RETURN_STATUS
1157EFIAPI
1159 IN INT32 Operand,
1160 OUT UINT64 *Result
1161 )
1162{
1163 RETURN_STATUS Status;
1164
1165 if (Result == NULL) {
1167 }
1168
1169 if (Operand >= 0) {
1170 *Result = (UINT64)Operand;
1171 Status = RETURN_SUCCESS;
1172 } else {
1173 *Result = UINT64_ERROR;
1174 Status = RETURN_BUFFER_TOO_SMALL;
1175 }
1176
1177 return Status;
1178}
1179
1200RETURN_STATUS
1201EFIAPI
1203 IN UINT32 Operand,
1204 OUT INT8 *Result
1205 )
1206{
1207 RETURN_STATUS Status;
1208
1209 if (Result == NULL) {
1211 }
1212
1213 if (Operand <= MAX_INT8) {
1214 *Result = (INT8)Operand;
1215 Status = RETURN_SUCCESS;
1216 } else {
1217 *Result = INT8_ERROR;
1218 Status = RETURN_BUFFER_TOO_SMALL;
1219 }
1220
1221 return Status;
1222}
1223
1244RETURN_STATUS
1245EFIAPI
1247 IN UINT32 Operand,
1248 OUT CHAR8 *Result
1249 )
1250{
1251 RETURN_STATUS Status;
1252
1253 if (Result == NULL) {
1255 }
1256
1257 if (Operand <= MAX_INT8) {
1258 *Result = (INT8)Operand;
1259 Status = RETURN_SUCCESS;
1260 } else {
1261 *Result = CHAR8_ERROR;
1262 Status = RETURN_BUFFER_TOO_SMALL;
1263 }
1264
1265 return Status;
1266}
1267
1288RETURN_STATUS
1289EFIAPI
1291 IN UINT32 Operand,
1292 OUT UINT8 *Result
1293 )
1294{
1295 RETURN_STATUS Status;
1296
1297 if (Result == NULL) {
1299 }
1300
1301 if (Operand <= MAX_UINT8) {
1302 *Result = (UINT8)Operand;
1303 Status = RETURN_SUCCESS;
1304 } else {
1305 *Result = UINT8_ERROR;
1306 Status = RETURN_BUFFER_TOO_SMALL;
1307 }
1308
1309 return Status;
1310}
1311
1332RETURN_STATUS
1333EFIAPI
1335 IN UINT32 Operand,
1336 OUT INT16 *Result
1337 )
1338{
1339 RETURN_STATUS Status;
1340
1341 if (Result == NULL) {
1343 }
1344
1345 if (Operand <= MAX_INT16) {
1346 *Result = (INT16)Operand;
1347 Status = RETURN_SUCCESS;
1348 } else {
1349 *Result = INT16_ERROR;
1350 Status = RETURN_BUFFER_TOO_SMALL;
1351 }
1352
1353 return Status;
1354}
1355
1376RETURN_STATUS
1377EFIAPI
1379 IN UINT32 Operand,
1380 OUT UINT16 *Result
1381 )
1382{
1383 RETURN_STATUS Status;
1384
1385 if (Result == NULL) {
1387 }
1388
1389 if (Operand <= MAX_UINT16) {
1390 *Result = (UINT16)Operand;
1391 Status = RETURN_SUCCESS;
1392 } else {
1393 *Result = UINT16_ERROR;
1394 Status = RETURN_BUFFER_TOO_SMALL;
1395 }
1396
1397 return Status;
1398}
1399
1420RETURN_STATUS
1421EFIAPI
1423 IN UINT32 Operand,
1424 OUT INT32 *Result
1425 )
1426{
1427 RETURN_STATUS Status;
1428
1429 if (Result == NULL) {
1431 }
1432
1433 if (Operand <= MAX_INT32) {
1434 *Result = (INT32)Operand;
1435 Status = RETURN_SUCCESS;
1436 } else {
1437 *Result = INT32_ERROR;
1438 Status = RETURN_BUFFER_TOO_SMALL;
1439 }
1440
1441 return Status;
1442}
1443
1464RETURN_STATUS
1465EFIAPI
1467 IN INTN Operand,
1468 OUT INT8 *Result
1469 )
1470{
1471 RETURN_STATUS Status;
1472
1473 if (Result == NULL) {
1475 }
1476
1477 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
1478 *Result = (INT8)Operand;
1479 Status = RETURN_SUCCESS;
1480 } else {
1481 *Result = INT8_ERROR;
1482 Status = RETURN_BUFFER_TOO_SMALL;
1483 }
1484
1485 return Status;
1486}
1487
1508RETURN_STATUS
1509EFIAPI
1511 IN INTN Operand,
1512 OUT CHAR8 *Result
1513 )
1514{
1515 RETURN_STATUS Status;
1516
1517 if (Result == NULL) {
1519 }
1520
1521 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
1522 *Result = (CHAR8)Operand;
1523 Status = RETURN_SUCCESS;
1524 } else {
1525 *Result = CHAR8_ERROR;
1526 Status = RETURN_BUFFER_TOO_SMALL;
1527 }
1528
1529 return Status;
1530}
1531
1552RETURN_STATUS
1553EFIAPI
1555 IN INTN Operand,
1556 OUT UINT8 *Result
1557 )
1558{
1559 RETURN_STATUS Status;
1560
1561 if (Result == NULL) {
1563 }
1564
1565 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
1566 *Result = (UINT8)Operand;
1567 Status = RETURN_SUCCESS;
1568 } else {
1569 *Result = UINT8_ERROR;
1570 Status = RETURN_BUFFER_TOO_SMALL;
1571 }
1572
1573 return Status;
1574}
1575
1596RETURN_STATUS
1597EFIAPI
1599 IN INTN Operand,
1600 OUT INT16 *Result
1601 )
1602{
1603 RETURN_STATUS Status;
1604
1605 if (Result == NULL) {
1607 }
1608
1609 if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
1610 *Result = (INT16)Operand;
1611 Status = RETURN_SUCCESS;
1612 } else {
1613 *Result = INT16_ERROR;
1614 Status = RETURN_BUFFER_TOO_SMALL;
1615 }
1616
1617 return Status;
1618}
1619
1640RETURN_STATUS
1641EFIAPI
1643 IN INTN Operand,
1644 OUT UINT16 *Result
1645 )
1646{
1647 RETURN_STATUS Status;
1648
1649 if (Result == NULL) {
1651 }
1652
1653 if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
1654 *Result = (UINT16)Operand;
1655 Status = RETURN_SUCCESS;
1656 } else {
1657 *Result = UINT16_ERROR;
1658 Status = RETURN_BUFFER_TOO_SMALL;
1659 }
1660
1661 return Status;
1662}
1663
1684RETURN_STATUS
1685EFIAPI
1687 IN INTN Operand,
1688 OUT UINTN *Result
1689 )
1690{
1691 RETURN_STATUS Status;
1692
1693 if (Result == NULL) {
1695 }
1696
1697 if (Operand >= 0) {
1698 *Result = (UINTN)Operand;
1699 Status = RETURN_SUCCESS;
1700 } else {
1701 *Result = UINTN_ERROR;
1702 Status = RETURN_BUFFER_TOO_SMALL;
1703 }
1704
1705 return Status;
1706}
1707
1728RETURN_STATUS
1729EFIAPI
1731 IN INTN Operand,
1732 OUT UINT64 *Result
1733 )
1734{
1735 RETURN_STATUS Status;
1736
1737 if (Result == NULL) {
1739 }
1740
1741 if (Operand >= 0) {
1742 *Result = (UINT64)Operand;
1743 Status = RETURN_SUCCESS;
1744 } else {
1745 *Result = UINT64_ERROR;
1746 Status = RETURN_BUFFER_TOO_SMALL;
1747 }
1748
1749 return Status;
1750}
1751
1772RETURN_STATUS
1773EFIAPI
1775 IN UINTN Operand,
1776 OUT INT8 *Result
1777 )
1778{
1779 RETURN_STATUS Status;
1780
1781 if (Result == NULL) {
1783 }
1784
1785 if (Operand <= MAX_INT8) {
1786 *Result = (INT8)Operand;
1787 Status = RETURN_SUCCESS;
1788 } else {
1789 *Result = INT8_ERROR;
1790 Status = RETURN_BUFFER_TOO_SMALL;
1791 }
1792
1793 return Status;
1794}
1795
1816RETURN_STATUS
1817EFIAPI
1819 IN UINTN Operand,
1820 OUT CHAR8 *Result
1821 )
1822{
1823 RETURN_STATUS Status;
1824
1825 if (Result == NULL) {
1827 }
1828
1829 if (Operand <= MAX_INT8) {
1830 *Result = (INT8)Operand;
1831 Status = RETURN_SUCCESS;
1832 } else {
1833 *Result = CHAR8_ERROR;
1834 Status = RETURN_BUFFER_TOO_SMALL;
1835 }
1836
1837 return Status;
1838}
1839
1860RETURN_STATUS
1861EFIAPI
1863 IN UINTN Operand,
1864 OUT UINT8 *Result
1865 )
1866{
1867 RETURN_STATUS Status;
1868
1869 if (Result == NULL) {
1871 }
1872
1873 if (Operand <= MAX_UINT8) {
1874 *Result = (UINT8)Operand;
1875 Status = RETURN_SUCCESS;
1876 } else {
1877 *Result = UINT8_ERROR;
1878 Status = RETURN_BUFFER_TOO_SMALL;
1879 }
1880
1881 return Status;
1882}
1883
1904RETURN_STATUS
1905EFIAPI
1907 IN UINTN Operand,
1908 OUT INT16 *Result
1909 )
1910{
1911 RETURN_STATUS Status;
1912
1913 if (Result == NULL) {
1915 }
1916
1917 if (Operand <= MAX_INT16) {
1918 *Result = (INT16)Operand;
1919 Status = RETURN_SUCCESS;
1920 } else {
1921 *Result = INT16_ERROR;
1922 Status = RETURN_BUFFER_TOO_SMALL;
1923 }
1924
1925 return Status;
1926}
1927
1948RETURN_STATUS
1949EFIAPI
1951 IN UINTN Operand,
1952 OUT UINT16 *Result
1953 )
1954{
1955 RETURN_STATUS Status;
1956
1957 if (Result == NULL) {
1959 }
1960
1961 if (Operand <= MAX_UINT16) {
1962 *Result = (UINT16)Operand;
1963 Status = RETURN_SUCCESS;
1964 } else {
1965 *Result = UINT16_ERROR;
1966 Status = RETURN_BUFFER_TOO_SMALL;
1967 }
1968
1969 return Status;
1970}
1971
1992RETURN_STATUS
1993EFIAPI
1995 IN UINTN Operand,
1996 OUT INT32 *Result
1997 )
1998{
1999 RETURN_STATUS Status;
2000
2001 if (Result == NULL) {
2003 }
2004
2005 if (Operand <= MAX_INT32) {
2006 *Result = (INT32)Operand;
2007 Status = RETURN_SUCCESS;
2008 } else {
2009 *Result = INT32_ERROR;
2010 Status = RETURN_BUFFER_TOO_SMALL;
2011 }
2012
2013 return Status;
2014}
2015
2036RETURN_STATUS
2037EFIAPI
2039 IN UINTN Operand,
2040 OUT INTN *Result
2041 )
2042{
2043 RETURN_STATUS Status;
2044
2045 if (Result == NULL) {
2047 }
2048
2049 if (Operand <= MAX_INTN) {
2050 *Result = (INTN)Operand;
2051 Status = RETURN_SUCCESS;
2052 } else {
2053 *Result = INTN_ERROR;
2054 Status = RETURN_BUFFER_TOO_SMALL;
2055 }
2056
2057 return Status;
2058}
2059
2080RETURN_STATUS
2081EFIAPI
2083 IN INT64 Operand,
2084 OUT INT8 *Result
2085 )
2086{
2087 RETURN_STATUS Status;
2088
2089 if (Result == NULL) {
2091 }
2092
2093 if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
2094 *Result = (INT8)Operand;
2095 Status = RETURN_SUCCESS;
2096 } else {
2097 *Result = INT8_ERROR;
2098 Status = RETURN_BUFFER_TOO_SMALL;
2099 }
2100
2101 return Status;
2102}
2103
2124RETURN_STATUS
2125EFIAPI
2127 IN INT64 Operand,
2128 OUT CHAR8 *Result
2129 )
2130{
2131 RETURN_STATUS Status;
2132
2133 if (Result == NULL) {
2135 }
2136
2137 if ((Operand >= 0) && (Operand <= MAX_INT8)) {
2138 *Result = (CHAR8)Operand;
2139 Status = RETURN_SUCCESS;
2140 } else {
2141 *Result = CHAR8_ERROR;
2142 Status = RETURN_BUFFER_TOO_SMALL;
2143 }
2144
2145 return Status;
2146}
2147
2168RETURN_STATUS
2169EFIAPI
2171 IN INT64 Operand,
2172 OUT UINT8 *Result
2173 )
2174{
2175 RETURN_STATUS Status;
2176
2177 if (Result == NULL) {
2179 }
2180
2181 if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
2182 *Result = (UINT8)Operand;
2183 Status = RETURN_SUCCESS;
2184 } else {
2185 *Result = UINT8_ERROR;
2186 Status = RETURN_BUFFER_TOO_SMALL;
2187 }
2188
2189 return Status;
2190}
2191
2212RETURN_STATUS
2213EFIAPI
2215 IN INT64 Operand,
2216 OUT INT16 *Result
2217 )
2218{
2219 RETURN_STATUS Status;
2220
2221 if (Result == NULL) {
2223 }
2224
2225 if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
2226 *Result = (INT16)Operand;
2227 Status = RETURN_SUCCESS;
2228 } else {
2229 *Result = INT16_ERROR;
2230 Status = RETURN_BUFFER_TOO_SMALL;
2231 }
2232
2233 return Status;
2234}
2235
2256RETURN_STATUS
2257EFIAPI
2259 IN INT64 Operand,
2260 OUT UINT16 *Result
2261 )
2262{
2263 RETURN_STATUS Status;
2264
2265 if (Result == NULL) {
2267 }
2268
2269 if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
2270 *Result = (UINT16)Operand;
2271 Status = RETURN_SUCCESS;
2272 } else {
2273 *Result = UINT16_ERROR;
2274 Status = RETURN_BUFFER_TOO_SMALL;
2275 }
2276
2277 return Status;
2278}
2279
2300RETURN_STATUS
2301EFIAPI
2303 IN INT64 Operand,
2304 OUT INT32 *Result
2305 )
2306{
2307 RETURN_STATUS Status;
2308
2309 if (Result == NULL) {
2311 }
2312
2313 if ((Operand >= MIN_INT32) && (Operand <= MAX_INT32)) {
2314 *Result = (INT32)Operand;
2315 Status = RETURN_SUCCESS;
2316 } else {
2317 *Result = INT32_ERROR;
2318 Status = RETURN_BUFFER_TOO_SMALL;
2319 }
2320
2321 return Status;
2322}
2323
2344RETURN_STATUS
2345EFIAPI
2347 IN INT64 Operand,
2348 OUT UINT32 *Result
2349 )
2350{
2351 RETURN_STATUS Status;
2352
2353 if (Result == NULL) {
2355 }
2356
2357 if ((Operand >= 0) && (Operand <= MAX_UINT32)) {
2358 *Result = (UINT32)Operand;
2359 Status = RETURN_SUCCESS;
2360 } else {
2361 *Result = UINT32_ERROR;
2362 Status = RETURN_BUFFER_TOO_SMALL;
2363 }
2364
2365 return Status;
2366}
2367
2388RETURN_STATUS
2389EFIAPI
2391 IN INT64 Operand,
2392 OUT UINT64 *Result
2393 )
2394{
2395 RETURN_STATUS Status;
2396
2397 if (Result == NULL) {
2399 }
2400
2401 if (Operand >= 0) {
2402 *Result = (UINT64)Operand;
2403 Status = RETURN_SUCCESS;
2404 } else {
2405 *Result = UINT64_ERROR;
2406 Status = RETURN_BUFFER_TOO_SMALL;
2407 }
2408
2409 return Status;
2410}
2411
2432RETURN_STATUS
2433EFIAPI
2435 IN UINT64 Operand,
2436 OUT INT8 *Result
2437 )
2438{
2439 RETURN_STATUS Status;
2440
2441 if (Result == NULL) {
2443 }
2444
2445 if (Operand <= MAX_INT8) {
2446 *Result = (INT8)Operand;
2447 Status = RETURN_SUCCESS;
2448 } else {
2449 *Result = INT8_ERROR;
2450 Status = RETURN_BUFFER_TOO_SMALL;
2451 }
2452
2453 return Status;
2454}
2455
2476RETURN_STATUS
2477EFIAPI
2479 IN UINT64 Operand,
2480 OUT CHAR8 *Result
2481 )
2482{
2483 RETURN_STATUS Status;
2484
2485 if (Result == NULL) {
2487 }
2488
2489 if (Operand <= MAX_INT8) {
2490 *Result = (INT8)Operand;
2491 Status = RETURN_SUCCESS;
2492 } else {
2493 *Result = CHAR8_ERROR;
2494 Status = RETURN_BUFFER_TOO_SMALL;
2495 }
2496
2497 return Status;
2498}
2499
2520RETURN_STATUS
2521EFIAPI
2523 IN UINT64 Operand,
2524 OUT UINT8 *Result
2525 )
2526{
2527 RETURN_STATUS Status;
2528
2529 if (Result == NULL) {
2531 }
2532
2533 if (Operand <= MAX_UINT8) {
2534 *Result = (UINT8)Operand;
2535 Status = RETURN_SUCCESS;
2536 } else {
2537 *Result = UINT8_ERROR;
2538 Status = RETURN_BUFFER_TOO_SMALL;
2539 }
2540
2541 return Status;
2542}
2543
2564RETURN_STATUS
2565EFIAPI
2567 IN UINT64 Operand,
2568 OUT INT16 *Result
2569 )
2570{
2571 RETURN_STATUS Status;
2572
2573 if (Result == NULL) {
2575 }
2576
2577 if (Operand <= MAX_INT16) {
2578 *Result = (INT16)Operand;
2579 Status = RETURN_SUCCESS;
2580 } else {
2581 *Result = INT16_ERROR;
2582 Status = RETURN_BUFFER_TOO_SMALL;
2583 }
2584
2585 return Status;
2586}
2587
2608RETURN_STATUS
2609EFIAPI
2611 IN UINT64 Operand,
2612 OUT UINT16 *Result
2613 )
2614{
2615 RETURN_STATUS Status;
2616
2617 if (Result == NULL) {
2619 }
2620
2621 if (Operand <= MAX_UINT16) {
2622 *Result = (UINT16)Operand;
2623 Status = RETURN_SUCCESS;
2624 } else {
2625 *Result = UINT16_ERROR;
2626 Status = RETURN_BUFFER_TOO_SMALL;
2627 }
2628
2629 return Status;
2630}
2631
2652RETURN_STATUS
2653EFIAPI
2655 IN UINT64 Operand,
2656 OUT INT32 *Result
2657 )
2658{
2659 RETURN_STATUS Status;
2660
2661 if (Result == NULL) {
2663 }
2664
2665 if (Operand <= MAX_INT32) {
2666 *Result = (INT32)Operand;
2667 Status = RETURN_SUCCESS;
2668 } else {
2669 *Result = INT32_ERROR;
2670 Status = RETURN_BUFFER_TOO_SMALL;
2671 }
2672
2673 return Status;
2674}
2675
2696RETURN_STATUS
2697EFIAPI
2699 IN UINT64 Operand,
2700 OUT UINT32 *Result
2701 )
2702{
2703 RETURN_STATUS Status;
2704
2705 if (Result == NULL) {
2707 }
2708
2709 if (Operand <= MAX_UINT32) {
2710 *Result = (UINT32)Operand;
2711 Status = RETURN_SUCCESS;
2712 } else {
2713 *Result = UINT32_ERROR;
2714 Status = RETURN_BUFFER_TOO_SMALL;
2715 }
2716
2717 return Status;
2718}
2719
2740RETURN_STATUS
2741EFIAPI
2743 IN UINT64 Operand,
2744 OUT INTN *Result
2745 )
2746{
2747 RETURN_STATUS Status;
2748
2749 if (Result == NULL) {
2751 }
2752
2753 if (Operand <= MAX_INTN) {
2754 *Result = (INTN)Operand;
2755 Status = RETURN_SUCCESS;
2756 } else {
2757 *Result = INTN_ERROR;
2758 Status = RETURN_BUFFER_TOO_SMALL;
2759 }
2760
2761 return Status;
2762}
2763
2784RETURN_STATUS
2785EFIAPI
2787 IN UINT64 Operand,
2788 OUT INT64 *Result
2789 )
2790{
2791 RETURN_STATUS Status;
2792
2793 if (Result == NULL) {
2795 }
2796
2797 if (Operand <= MAX_INT64) {
2798 *Result = (INT64)Operand;
2799 Status = RETURN_SUCCESS;
2800 } else {
2801 *Result = INT64_ERROR;
2802 Status = RETURN_BUFFER_TOO_SMALL;
2803 }
2804
2805 return Status;
2806}
2807
2808//
2809// Addition functions
2810//
2811
2833RETURN_STATUS
2834EFIAPI
2836 IN UINT8 Augend,
2837 IN UINT8 Addend,
2838 OUT UINT8 *Result
2839 )
2840{
2841 RETURN_STATUS Status;
2842
2843 if (Result == NULL) {
2845 }
2846
2847 if (((UINT8)(Augend + Addend)) >= Augend) {
2848 *Result = (UINT8)(Augend + Addend);
2849 Status = RETURN_SUCCESS;
2850 } else {
2851 *Result = UINT8_ERROR;
2852 Status = RETURN_BUFFER_TOO_SMALL;
2853 }
2854
2855 return Status;
2856}
2857
2879RETURN_STATUS
2880EFIAPI
2882 IN UINT16 Augend,
2883 IN UINT16 Addend,
2884 OUT UINT16 *Result
2885 )
2886{
2887 RETURN_STATUS Status;
2888
2889 if (Result == NULL) {
2891 }
2892
2893 if (((UINT16)(Augend + Addend)) >= Augend) {
2894 *Result = (UINT16)(Augend + Addend);
2895 Status = RETURN_SUCCESS;
2896 } else {
2897 *Result = UINT16_ERROR;
2898 Status = RETURN_BUFFER_TOO_SMALL;
2899 }
2900
2901 return Status;
2902}
2903
2925RETURN_STATUS
2926EFIAPI
2928 IN UINT32 Augend,
2929 IN UINT32 Addend,
2930 OUT UINT32 *Result
2931 )
2932{
2933 RETURN_STATUS Status;
2934
2935 if (Result == NULL) {
2937 }
2938
2939 if ((Augend + Addend) >= Augend) {
2940 *Result = (Augend + Addend);
2941 Status = RETURN_SUCCESS;
2942 } else {
2943 *Result = UINT32_ERROR;
2944 Status = RETURN_BUFFER_TOO_SMALL;
2945 }
2946
2947 return Status;
2948}
2949
2971RETURN_STATUS
2972EFIAPI
2974 IN UINT64 Augend,
2975 IN UINT64 Addend,
2976 OUT UINT64 *Result
2977 )
2978{
2979 RETURN_STATUS Status;
2980
2981 if (Result == NULL) {
2983 }
2984
2985 if ((Augend + Addend) >= Augend) {
2986 *Result = (Augend + Addend);
2987 Status = RETURN_SUCCESS;
2988 } else {
2989 *Result = UINT64_ERROR;
2990 Status = RETURN_BUFFER_TOO_SMALL;
2991 }
2992
2993 return Status;
2994}
2995
2996//
2997// Subtraction functions
2998//
2999
3021RETURN_STATUS
3022EFIAPI
3024 IN UINT8 Minuend,
3025 IN UINT8 Subtrahend,
3026 OUT UINT8 *Result
3027 )
3028{
3029 RETURN_STATUS Status;
3030
3031 if (Result == NULL) {
3033 }
3034
3035 if (Minuend >= Subtrahend) {
3036 *Result = (UINT8)(Minuend - Subtrahend);
3037 Status = RETURN_SUCCESS;
3038 } else {
3039 *Result = UINT8_ERROR;
3040 Status = RETURN_BUFFER_TOO_SMALL;
3041 }
3042
3043 return Status;
3044}
3045
3067RETURN_STATUS
3068EFIAPI
3070 IN UINT16 Minuend,
3071 IN UINT16 Subtrahend,
3072 OUT UINT16 *Result
3073 )
3074{
3075 RETURN_STATUS Status;
3076
3077 if (Result == NULL) {
3079 }
3080
3081 if (Minuend >= Subtrahend) {
3082 *Result = (UINT16)(Minuend - Subtrahend);
3083 Status = RETURN_SUCCESS;
3084 } else {
3085 *Result = UINT16_ERROR;
3086 Status = RETURN_BUFFER_TOO_SMALL;
3087 }
3088
3089 return Status;
3090}
3091
3113RETURN_STATUS
3114EFIAPI
3116 IN UINT32 Minuend,
3117 IN UINT32 Subtrahend,
3118 OUT UINT32 *Result
3119 )
3120{
3121 RETURN_STATUS Status;
3122
3123 if (Result == NULL) {
3125 }
3126
3127 if (Minuend >= Subtrahend) {
3128 *Result = (Minuend - Subtrahend);
3129 Status = RETURN_SUCCESS;
3130 } else {
3131 *Result = UINT32_ERROR;
3132 Status = RETURN_BUFFER_TOO_SMALL;
3133 }
3134
3135 return Status;
3136}
3137
3159RETURN_STATUS
3160EFIAPI
3162 IN UINT64 Minuend,
3163 IN UINT64 Subtrahend,
3164 OUT UINT64 *Result
3165 )
3166{
3167 RETURN_STATUS Status;
3168
3169 if (Result == NULL) {
3171 }
3172
3173 if (Minuend >= Subtrahend) {
3174 *Result = (Minuend - Subtrahend);
3175 Status = RETURN_SUCCESS;
3176 } else {
3177 *Result = UINT64_ERROR;
3178 Status = RETURN_BUFFER_TOO_SMALL;
3179 }
3180
3181 return Status;
3182}
3183
3184//
3185// Multiplication functions
3186//
3187
3209RETURN_STATUS
3210EFIAPI
3212 IN UINT8 Multiplicand,
3213 IN UINT8 Multiplier,
3214 OUT UINT8 *Result
3215 )
3216{
3217 UINT32 IntermediateResult;
3218
3219 IntermediateResult = ((UINT32)Multiplicand) *((UINT32)Multiplier);
3220
3221 return SafeUint32ToUint8 (IntermediateResult, Result);
3222}
3223
3245RETURN_STATUS
3246EFIAPI
3248 IN UINT16 Multiplicand,
3249 IN UINT16 Multiplier,
3250 OUT UINT16 *Result
3251 )
3252{
3253 UINT32 IntermediateResult;
3254
3255 IntermediateResult = ((UINT32)Multiplicand) *((UINT32)Multiplier);
3256
3257 return SafeUint32ToUint16 (IntermediateResult, Result);
3258}
3259
3281RETURN_STATUS
3282EFIAPI
3284 IN UINT32 Multiplicand,
3285 IN UINT32 Multiplier,
3286 OUT UINT32 *Result
3287 )
3288{
3289 UINT64 IntermediateResult;
3290
3291 IntermediateResult = ((UINT64)Multiplicand) *((UINT64)Multiplier);
3292
3293 return SafeUint64ToUint32 (IntermediateResult, Result);
3294}
3295
3317RETURN_STATUS
3318EFIAPI
3320 IN UINT64 Multiplicand,
3321 IN UINT64 Multiplier,
3322 OUT UINT64 *Result
3323 )
3324{
3325 RETURN_STATUS Status;
3326 UINT32 DwordA;
3327 UINT32 DwordB;
3328 UINT32 DwordC;
3329 UINT32 DwordD;
3330 UINT64 ProductAD;
3331 UINT64 ProductBC;
3332 UINT64 ProductBD;
3333 UINT64 UnsignedResult;
3334
3335 if (Result == NULL) {
3337 }
3338
3339 ProductAD = 0;
3340 ProductBC = 0;
3341 ProductBD = 0;
3342 UnsignedResult = 0;
3343 Status = RETURN_BUFFER_TOO_SMALL;
3344
3345 //
3346 // 64x64 into 128 is like 32.32 x 32.32.
3347 //
3348 // a.b * c.d = a*(c.d) + .b*(c.d) = a*c + a*.d + .b*c + .b*.d
3349 // back in non-decimal notation where A=a*2^32 and C=c*2^32:
3350 // A*C + A*d + b*C + b*d
3351 // So there are four components to add together.
3352 // result = (a*c*2^64) + (a*d*2^32) + (b*c*2^32) + (b*d)
3353 //
3354 // a * c must be 0 or there would be bits in the high 64-bits
3355 // a * d must be less than 2^32 or there would be bits in the high 64-bits
3356 // b * c must be less than 2^32 or there would be bits in the high 64-bits
3357 // then there must be no overflow of the resulting values summed up.
3358 //
3359 DwordA = (UINT32)RShiftU64 (Multiplicand, 32);
3360 DwordC = (UINT32)RShiftU64 (Multiplier, 32);
3361
3362 //
3363 // common case -- if high dwords are both zero, no chance for overflow
3364 //
3365 if ((DwordA == 0) && (DwordC == 0)) {
3366 DwordB = (UINT32)Multiplicand;
3367 DwordD = (UINT32)Multiplier;
3368
3369 *Result = (((UINT64)DwordB) *(UINT64)DwordD);
3370 Status = RETURN_SUCCESS;
3371 } else {
3372 //
3373 // a * c must be 0 or there would be bits set in the high 64-bits
3374 //
3375 if ((DwordA == 0) ||
3376 (DwordC == 0))
3377 {
3378 DwordD = (UINT32)Multiplier;
3379
3380 //
3381 // a * d must be less than 2^32 or there would be bits set in the high 64-bits
3382 //
3383 ProductAD = MultU64x64 ((UINT64)DwordA, (UINT64)DwordD);
3384 if ((ProductAD & 0xffffffff00000000) == 0) {
3385 DwordB = (UINT32)Multiplicand;
3386
3387 //
3388 // b * c must be less than 2^32 or there would be bits set in the high 64-bits
3389 //
3390 ProductBC = MultU64x64 ((UINT64)DwordB, (UINT64)DwordC);
3391 if ((ProductBC & 0xffffffff00000000) == 0) {
3392 //
3393 // now sum them all up checking for overflow.
3394 // shifting is safe because we already checked for overflow above
3395 //
3396 if (!RETURN_ERROR (SafeUint64Add (LShiftU64 (ProductBC, 32), LShiftU64 (ProductAD, 32), &UnsignedResult))) {
3397 //
3398 // b * d
3399 //
3400 ProductBD = MultU64x64 ((UINT64)DwordB, (UINT64)DwordD);
3401
3402 if (!RETURN_ERROR (SafeUint64Add (UnsignedResult, ProductBD, &UnsignedResult))) {
3403 *Result = UnsignedResult;
3404 Status = RETURN_SUCCESS;
3405 }
3406 }
3407 }
3408 }
3409 }
3410 }
3411
3412 if (RETURN_ERROR (Status)) {
3413 *Result = UINT64_ERROR;
3414 }
3415
3416 return Status;
3417}
3418
3419//
3420// Signed operations
3421//
3422// Strongly consider using unsigned numbers.
3423//
3424// Signed numbers are often used where unsigned numbers should be used.
3425// For example file sizes and array indices should always be unsigned.
3426// Subtracting a larger positive signed number from a smaller positive
3427// signed number with SafeInt32Sub will succeed, producing a negative number,
3428// that then must not be used as an array index (but can occasionally be
3429// used as a pointer index.) Similarly for adding a larger magnitude
3430// negative number to a smaller magnitude positive number.
3431//
3432// This library does not protect you from such errors. It tells you if your
3433// integer operations overflowed, not if you are doing the right thing
3434// with your non-overflowed integers.
3435//
3436// Likewise you can overflow a buffer with a non-overflowed unsigned index.
3437//
3438
3439//
3440// Signed addition functions
3441//
3442
3464RETURN_STATUS
3465EFIAPI
3467 IN INT8 Augend,
3468 IN INT8 Addend,
3469 OUT INT8 *Result
3470 )
3471{
3472 return SafeInt32ToInt8 (((INT32)Augend) + ((INT32)Addend), Result);
3473}
3474
3496RETURN_STATUS
3497EFIAPI
3499 IN CHAR8 Augend,
3500 IN CHAR8 Addend,
3501 OUT CHAR8 *Result
3502 )
3503{
3504 INT32 Augend32;
3505 INT32 Addend32;
3506
3507 if (Result == NULL) {
3509 }
3510
3511 Augend32 = (INT32)Augend;
3512 Addend32 = (INT32)Addend;
3513 if ((Augend32 < 0) || (Augend32 > MAX_INT8)) {
3514 *Result = CHAR8_ERROR;
3516 }
3517
3518 if ((Addend32 < 0) || (Addend32 > MAX_INT8)) {
3519 *Result = CHAR8_ERROR;
3521 }
3522
3523 return SafeInt32ToChar8 (Augend32 + Addend32, Result);
3524}
3525
3547RETURN_STATUS
3548EFIAPI
3550 IN INT16 Augend,
3551 IN INT16 Addend,
3552 OUT INT16 *Result
3553 )
3554{
3555 return SafeInt32ToInt16 (((INT32)Augend) + ((INT32)Addend), Result);
3556}
3557
3579RETURN_STATUS
3580EFIAPI
3582 IN INT32 Augend,
3583 IN INT32 Addend,
3584 OUT INT32 *Result
3585 )
3586{
3587 return SafeInt64ToInt32 (((INT64)Augend) + ((INT64)Addend), Result);
3588}
3589
3611RETURN_STATUS
3612EFIAPI
3614 IN INT64 Augend,
3615 IN INT64 Addend,
3616 OUT INT64 *Result
3617 )
3618{
3619 RETURN_STATUS Status;
3620
3621 if (Result == NULL) {
3623 }
3624
3625 //
3626 // * An Addend of zero can never cause underflow or overflow.
3627 //
3628 // * A positive Addend can only cause overflow. The overflow condition is
3629 //
3630 // (Augend + Addend) > MAX_INT64
3631 //
3632 // Subtracting Addend from both sides yields
3633 //
3634 // Augend > (MAX_INT64 - Addend)
3635 //
3636 // This condition can be coded directly in C because the RHS will neither
3637 // underflow nor overflow. That is due to the starting condition:
3638 //
3639 // 0 < Addend <= MAX_INT64
3640 //
3641 // Multiplying all three sides by (-1) yields
3642 //
3643 // 0 > (-Addend) >= (-MAX_INT64)
3644 //
3645 // Adding MAX_INT64 to all three sides yields
3646 //
3647 // MAX_INT64 > (MAX_INT64 - Addend) >= 0
3648 //
3649 // * A negative Addend can only cause underflow. The underflow condition is
3650 //
3651 // (Augend + Addend) < MIN_INT64
3652 //
3653 // Subtracting Addend from both sides yields
3654 //
3655 // Augend < (MIN_INT64 - Addend)
3656 //
3657 // This condition can be coded directly in C because the RHS will neither
3658 // underflow nor overflow. That is due to the starting condition:
3659 //
3660 // MIN_INT64 <= Addend < 0
3661 //
3662 // Multiplying all three sides by (-1) yields
3663 //
3664 // (-MIN_INT64) >= (-Addend) > 0
3665 //
3666 // Adding MIN_INT64 to all three sides yields
3667 //
3668 // 0 >= (MIN_INT64 - Addend) > MIN_INT64
3669 //
3670 if (((Addend > 0) && (Augend > (MAX_INT64 - Addend))) ||
3671 ((Addend < 0) && (Augend < (MIN_INT64 - Addend))))
3672 {
3673 *Result = INT64_ERROR;
3674 Status = RETURN_BUFFER_TOO_SMALL;
3675 } else {
3676 *Result = Augend + Addend;
3677 Status = RETURN_SUCCESS;
3678 }
3679
3680 return Status;
3681}
3682
3683//
3684// Signed subtraction functions
3685//
3686
3708RETURN_STATUS
3709EFIAPI
3711 IN INT8 Minuend,
3712 IN INT8 Subtrahend,
3713 OUT INT8 *Result
3714 )
3715{
3716 return SafeInt32ToInt8 (((INT32)Minuend) - ((INT32)Subtrahend), Result);
3717}
3718
3740RETURN_STATUS
3741EFIAPI
3743 IN CHAR8 Minuend,
3744 IN CHAR8 Subtrahend,
3745 OUT CHAR8 *Result
3746 )
3747{
3748 INT32 Minuend32;
3749 INT32 Subtrahend32;
3750
3751 if (Result == NULL) {
3753 }
3754
3755 Minuend32 = (INT32)Minuend;
3756 Subtrahend32 = (INT32)Subtrahend;
3757 if ((Minuend32 < 0) || (Minuend32 > MAX_INT8)) {
3758 *Result = CHAR8_ERROR;
3760 }
3761
3762 if ((Subtrahend32 < 0) || (Subtrahend32 > MAX_INT8)) {
3763 *Result = CHAR8_ERROR;
3765 }
3766
3767 return SafeInt32ToChar8 (Minuend32 - Subtrahend32, Result);
3768}
3769
3791RETURN_STATUS
3792EFIAPI
3794 IN INT16 Minuend,
3795 IN INT16 Subtrahend,
3796 OUT INT16 *Result
3797 )
3798{
3799 return SafeInt32ToInt16 (((INT32)Minuend) - ((INT32)Subtrahend), Result);
3800}
3801
3823RETURN_STATUS
3824EFIAPI
3826 IN INT32 Minuend,
3827 IN INT32 Subtrahend,
3828 OUT INT32 *Result
3829 )
3830{
3831 return SafeInt64ToInt32 (((INT64)Minuend) - ((INT64)Subtrahend), Result);
3832}
3833
3855RETURN_STATUS
3856EFIAPI
3858 IN INT64 Minuend,
3859 IN INT64 Subtrahend,
3860 OUT INT64 *Result
3861 )
3862{
3863 RETURN_STATUS Status;
3864
3865 if (Result == NULL) {
3867 }
3868
3869 //
3870 // * A Subtrahend of zero can never cause underflow or overflow.
3871 //
3872 // * A positive Subtrahend can only cause underflow. The underflow condition
3873 // is:
3874 //
3875 // (Minuend - Subtrahend) < MIN_INT64
3876 //
3877 // Adding Subtrahend to both sides yields
3878 //
3879 // Minuend < (MIN_INT64 + Subtrahend)
3880 //
3881 // This condition can be coded directly in C because the RHS will neither
3882 // underflow nor overflow. That is due to the starting condition:
3883 //
3884 // 0 < Subtrahend <= MAX_INT64
3885 //
3886 // Adding MIN_INT64 to all three sides yields
3887 //
3888 // MIN_INT64 < (MIN_INT64 + Subtrahend) <= (MIN_INT64 + MAX_INT64) = -1
3889 //
3890 // * A negative Subtrahend can only cause overflow. The overflow condition is
3891 //
3892 // (Minuend - Subtrahend) > MAX_INT64
3893 //
3894 // Adding Subtrahend to both sides yields
3895 //
3896 // Minuend > (MAX_INT64 + Subtrahend)
3897 //
3898 // This condition can be coded directly in C because the RHS will neither
3899 // underflow nor overflow. That is due to the starting condition:
3900 //
3901 // MIN_INT64 <= Subtrahend < 0
3902 //
3903 // Adding MAX_INT64 to all three sides yields
3904 //
3905 // -1 = (MAX_INT64 + MIN_INT64) <= (MAX_INT64 + Subtrahend) < MAX_INT64
3906 //
3907 if (((Subtrahend > 0) && (Minuend < (MIN_INT64 + Subtrahend))) ||
3908 ((Subtrahend < 0) && (Minuend > (MAX_INT64 + Subtrahend))))
3909 {
3910 *Result = INT64_ERROR;
3911 Status = RETURN_BUFFER_TOO_SMALL;
3912 } else {
3913 *Result = Minuend - Subtrahend;
3914 Status = RETURN_SUCCESS;
3915 }
3916
3917 return Status;
3918}
3919
3920//
3921// Signed multiplication functions
3922//
3923
3945RETURN_STATUS
3946EFIAPI
3948 IN INT8 Multiplicand,
3949 IN INT8 Multiplier,
3950 OUT INT8 *Result
3951 )
3952{
3953 return SafeInt32ToInt8 (((INT32)Multiplier) *((INT32)Multiplicand), Result);
3954}
3955
3977RETURN_STATUS
3978EFIAPI
3980 IN CHAR8 Multiplicand,
3981 IN CHAR8 Multiplier,
3982 OUT CHAR8 *Result
3983 )
3984{
3985 INT32 Multiplicand32;
3986 INT32 Multiplier32;
3987
3988 if (Result == NULL) {
3990 }
3991
3992 Multiplicand32 = (INT32)Multiplicand;
3993 Multiplier32 = (INT32)Multiplier;
3994 if ((Multiplicand32 < 0) || (Multiplicand32 > MAX_INT8)) {
3995 *Result = CHAR8_ERROR;
3997 }
3998
3999 if ((Multiplier32 < 0) || (Multiplier32 > MAX_INT8)) {
4000 *Result = CHAR8_ERROR;
4002 }
4003
4004 return SafeInt32ToChar8 (Multiplicand32 * Multiplier32, Result);
4005}
4006
4028RETURN_STATUS
4029EFIAPI
4031 IN INT16 Multiplicand,
4032 IN INT16 Multiplier,
4033 OUT INT16 *Result
4034 )
4035{
4036 return SafeInt32ToInt16 (((INT32)Multiplicand) *((INT32)Multiplier), Result);
4037}
4038
4060RETURN_STATUS
4061EFIAPI
4063 IN INT32 Multiplicand,
4064 IN INT32 Multiplier,
4065 OUT INT32 *Result
4066 )
4067{
4068 return SafeInt64ToInt32 (MultS64x64 (Multiplicand, Multiplier), Result);
4069}
4070
4092RETURN_STATUS
4093EFIAPI
4095 IN INT64 Multiplicand,
4096 IN INT64 Multiplier,
4097 OUT INT64 *Result
4098 )
4099{
4100 RETURN_STATUS Status;
4101 UINT64 UnsignedMultiplicand;
4102 UINT64 UnsignedMultiplier;
4103 UINT64 UnsignedResult;
4104
4105 if (Result == NULL) {
4107 }
4108
4109 //
4110 // Split into sign and magnitude, do unsigned operation, apply sign.
4111 //
4112 if (Multiplicand < 0) {
4113 //
4114 // Avoid negating the most negative number.
4115 //
4116 UnsignedMultiplicand = ((UINT64)(-(Multiplicand + 1))) + 1;
4117 } else {
4118 UnsignedMultiplicand = (UINT64)Multiplicand;
4119 }
4120
4121 if (Multiplier < 0) {
4122 //
4123 // Avoid negating the most negative number.
4124 //
4125 UnsignedMultiplier = ((UINT64)(-(Multiplier + 1))) + 1;
4126 } else {
4127 UnsignedMultiplier = (UINT64)Multiplier;
4128 }
4129
4130 Status = SafeUint64Mult (UnsignedMultiplicand, UnsignedMultiplier, &UnsignedResult);
4131 if (!RETURN_ERROR (Status)) {
4132 if ((Multiplicand < 0) != (Multiplier < 0)) {
4133 if (UnsignedResult > MIN_INT64_MAGNITUDE) {
4134 *Result = INT64_ERROR;
4135 Status = RETURN_BUFFER_TOO_SMALL;
4136 } else if (UnsignedResult == MIN_INT64_MAGNITUDE) {
4137 *Result = MIN_INT64;
4138 } else {
4139 *Result = -((INT64)UnsignedResult);
4140 }
4141 } else {
4142 if (UnsignedResult > MAX_INT64) {
4143 *Result = INT64_ERROR;
4144 Status = RETURN_BUFFER_TOO_SMALL;
4145 } else {
4146 *Result = (INT64)UnsignedResult;
4147 }
4148 }
4149 } else {
4150 *Result = INT64_ERROR;
4151 }
4152
4153 return Status;
4154}
UINT64 UINTN
#define MAX_INTN
INT64 INTN
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
Definition: MultU64x64.c:27
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
INT64 EFIAPI MultS64x64(IN INT64 Multiplicand, IN INT64 Multiplier)
Definition: MultS64x64.c:27
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
#define NULL
Definition: Base.h:319
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define MIN_INT8
Definition: Base.h:342
#define RETURN_SUCCESS
Definition: Base.h:1066
#define MAX_INT8
Definition: Base.h:330
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
RETURN_STATUS EFIAPI SafeInt16ToUint32(IN INT16 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:586
RETURN_STATUS EFIAPI SafeUint64ToInt8(IN UINT64 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:2434
RETURN_STATUS EFIAPI SafeInt64ToInt32(IN INT64 Operand, OUT INT32 *Result)
Definition: SafeIntLib.c:2302
RETURN_STATUS EFIAPI SafeIntnToInt16(IN INTN Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:1598
RETURN_STATUS EFIAPI SafeInt32Sub(IN INT32 Minuend, IN INT32 Subtrahend, OUT INT32 *Result)
Definition: SafeIntLib.c:3825
RETURN_STATUS EFIAPI SafeUint64ToInt32(IN UINT64 Operand, OUT INT32 *Result)
Definition: SafeIntLib.c:2654
RETURN_STATUS EFIAPI SafeChar8Sub(IN CHAR8 Minuend, IN CHAR8 Subtrahend, OUT CHAR8 *Result)
Definition: SafeIntLib.c:3742
RETURN_STATUS EFIAPI SafeIntnToInt8(IN INTN Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:1466
RETURN_STATUS EFIAPI SafeUint16Sub(IN UINT16 Minuend, IN UINT16 Subtrahend, OUT UINT16 *Result)
Definition: SafeIntLib.c:3069
RETURN_STATUS EFIAPI SafeInt8ToUintn(IN INT8 Operand, OUT UINTN *Result)
Definition: SafeIntLib.c:234
RETURN_STATUS EFIAPI SafeUint8Sub(IN UINT8 Minuend, IN UINT8 Subtrahend, OUT UINT8 *Result)
Definition: SafeIntLib.c:3023
RETURN_STATUS EFIAPI SafeInt8Mult(IN INT8 Multiplicand, IN INT8 Multiplier, OUT INT8 *Result)
Definition: SafeIntLib.c:3947
RETURN_STATUS EFIAPI SafeUint32ToInt32(IN UINT32 Operand, OUT INT32 *Result)
Definition: SafeIntLib.c:1422
RETURN_STATUS EFIAPI SafeUint32Add(IN UINT32 Augend, IN UINT32 Addend, OUT UINT32 *Result)
Definition: SafeIntLib.c:2927
RETURN_STATUS EFIAPI SafeUintnToInt32(IN UINTN Operand, OUT INT32 *Result)
Definition: SafeIntLib.c:1994
RETURN_STATUS EFIAPI SafeChar8Mult(IN CHAR8 Multiplicand, IN CHAR8 Multiplier, OUT CHAR8 *Result)
Definition: SafeIntLib.c:3979
RETURN_STATUS EFIAPI SafeInt32ToUint32(IN INT32 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:1114
RETURN_STATUS EFIAPI SafeUint64ToUint16(IN UINT64 Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:2610
RETURN_STATUS EFIAPI SafeIntnToChar8(IN INTN Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:1510
RETURN_STATUS EFIAPI SafeInt32ToInt16(IN INT32 Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:1026
RETURN_STATUS EFIAPI SafeUint32Mult(IN UINT32 Multiplicand, IN UINT32 Multiplier, OUT UINT32 *Result)
Definition: SafeIntLib.c:3283
RETURN_STATUS EFIAPI SafeInt16ToChar8(IN INT16 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:454
RETURN_STATUS EFIAPI SafeInt8ToUint64(IN INT8 Operand, OUT UINT64 *Result)
Definition: SafeIntLib.c:278
RETURN_STATUS EFIAPI SafeInt16ToUint64(IN INT16 Operand, OUT UINT64 *Result)
Definition: SafeIntLib.c:674
RETURN_STATUS EFIAPI SafeInt16ToUintn(IN INT16 Operand, OUT UINTN *Result)
Definition: SafeIntLib.c:630
RETURN_STATUS EFIAPI SafeUintnToInt8(IN UINTN Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:1774
RETURN_STATUS EFIAPI SafeUint16Mult(IN UINT16 Multiplicand, IN UINT16 Multiplier, OUT UINT16 *Result)
Definition: SafeIntLib.c:3247
RETURN_STATUS EFIAPI SafeInt32ToUint64(IN INT32 Operand, OUT UINT64 *Result)
Definition: SafeIntLib.c:1158
RETURN_STATUS EFIAPI SafeUint64ToUint8(IN UINT64 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:2522
RETURN_STATUS EFIAPI SafeUint16ToInt16(IN UINT16 Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:850
RETURN_STATUS EFIAPI SafeInt64ToUint32(IN INT64 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:2346
RETURN_STATUS EFIAPI SafeUintnToIntn(IN UINTN Operand, OUT INTN *Result)
Definition: SafeIntLib.c:2038
RETURN_STATUS EFIAPI SafeUint64ToChar8(IN UINT64 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:2478
RETURN_STATUS EFIAPI SafeInt64ToInt16(IN INT64 Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:2214
RETURN_STATUS EFIAPI SafeUint8ToInt8(IN UINT8 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:322
RETURN_STATUS EFIAPI SafeUint16Add(IN UINT16 Augend, IN UINT16 Addend, OUT UINT16 *Result)
Definition: SafeIntLib.c:2881
RETURN_STATUS EFIAPI SafeUintnToUint16(IN UINTN Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:1950
RETURN_STATUS EFIAPI SafeInt32Mult(IN INT32 Multiplicand, IN INT32 Multiplier, OUT INT32 *Result)
Definition: SafeIntLib.c:4062
RETURN_STATUS EFIAPI SafeInt64Mult(IN INT64 Multiplicand, IN INT64 Multiplier, OUT INT64 *Result)
Definition: SafeIntLib.c:4094
RETURN_STATUS EFIAPI SafeUint32ToChar8(IN UINT32 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:1246
RETURN_STATUS EFIAPI SafeInt16Mult(IN INT16 Multiplicand, IN INT16 Multiplier, OUT INT16 *Result)
Definition: SafeIntLib.c:4030
RETURN_STATUS EFIAPI SafeInt32ToUint8(IN INT32 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:982
RETURN_STATUS EFIAPI SafeIntnToUint8(IN INTN Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:1554
RETURN_STATUS EFIAPI SafeUint64Sub(IN UINT64 Minuend, IN UINT64 Subtrahend, OUT UINT64 *Result)
Definition: SafeIntLib.c:3161
RETURN_STATUS EFIAPI SafeInt8Add(IN INT8 Augend, IN INT8 Addend, OUT INT8 *Result)
Definition: SafeIntLib.c:3466
RETURN_STATUS EFIAPI SafeInt64ToInt8(IN INT64 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:2082
RETURN_STATUS EFIAPI SafeUint64Add(IN UINT64 Augend, IN UINT64 Addend, OUT UINT64 *Result)
Definition: SafeIntLib.c:2973
RETURN_STATUS EFIAPI SafeInt16ToUint8(IN INT16 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:498
RETURN_STATUS EFIAPI SafeUint32ToUint16(IN UINT32 Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:1378
RETURN_STATUS EFIAPI SafeInt16ToInt8(IN INT16 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:410
RETURN_STATUS EFIAPI SafeInt32ToInt8(IN INT32 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:894
RETURN_STATUS EFIAPI SafeUintnToChar8(IN UINTN Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:1818
RETURN_STATUS EFIAPI SafeUint64ToIntn(IN UINT64 Operand, OUT INTN *Result)
Definition: SafeIntLib.c:2742
RETURN_STATUS EFIAPI SafeInt64ToChar8(IN INT64 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:2126
RETURN_STATUS EFIAPI SafeUint64Mult(IN UINT64 Multiplicand, IN UINT64 Multiplier, OUT UINT64 *Result)
Definition: SafeIntLib.c:3319
RETURN_STATUS EFIAPI SafeIntnToUint64(IN INTN Operand, OUT UINT64 *Result)
Definition: SafeIntLib.c:1730
RETURN_STATUS EFIAPI SafeUint32ToInt8(IN UINT32 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:1202
RETURN_STATUS EFIAPI SafeInt8ToUint8(IN INT8 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:58
RETURN_STATUS EFIAPI SafeUint8Mult(IN UINT8 Multiplicand, IN UINT8 Multiplier, OUT UINT8 *Result)
Definition: SafeIntLib.c:3211
RETURN_STATUS EFIAPI SafeChar8Add(IN CHAR8 Augend, IN CHAR8 Addend, OUT CHAR8 *Result)
Definition: SafeIntLib.c:3498
RETURN_STATUS EFIAPI SafeInt64Add(IN INT64 Augend, IN INT64 Addend, OUT INT64 *Result)
Definition: SafeIntLib.c:3613
RETURN_STATUS EFIAPI SafeUint16ToChar8(IN UINT16 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:762
RETURN_STATUS EFIAPI SafeInt8ToUint32(IN INT8 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:190
RETURN_STATUS EFIAPI SafeInt64ToUint64(IN INT64 Operand, OUT UINT64 *Result)
Definition: SafeIntLib.c:2390
RETURN_STATUS EFIAPI SafeInt8Sub(IN INT8 Minuend, IN INT8 Subtrahend, OUT INT8 *Result)
Definition: SafeIntLib.c:3710
RETURN_STATUS EFIAPI SafeInt8ToChar8(IN INT8 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:102
RETURN_STATUS EFIAPI SafeUint16ToInt8(IN UINT16 Operand, OUT INT8 *Result)
Definition: SafeIntLib.c:718
RETURN_STATUS EFIAPI SafeUint64ToInt64(IN UINT64 Operand, OUT INT64 *Result)
Definition: SafeIntLib.c:2786
RETURN_STATUS EFIAPI SafeInt32ToChar8(IN INT32 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:938
RETURN_STATUS EFIAPI SafeInt32ToUint16(IN INT32 Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:1070
RETURN_STATUS EFIAPI SafeUint32Sub(IN UINT32 Minuend, IN UINT32 Subtrahend, OUT UINT32 *Result)
Definition: SafeIntLib.c:3115
RETURN_STATUS EFIAPI SafeInt64ToUint8(IN INT64 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:2170
RETURN_STATUS EFIAPI SafeUintnToInt16(IN UINTN Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:1906
RETURN_STATUS EFIAPI SafeInt16Sub(IN INT16 Minuend, IN INT16 Subtrahend, OUT INT16 *Result)
Definition: SafeIntLib.c:3793
RETURN_STATUS EFIAPI SafeInt64ToUint16(IN INT64 Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:2258
RETURN_STATUS EFIAPI SafeUint16ToUint8(IN UINT16 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:806
RETURN_STATUS EFIAPI SafeIntnToUint16(IN INTN Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:1642
RETURN_STATUS EFIAPI SafeUint32ToInt16(IN UINT32 Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:1334
RETURN_STATUS EFIAPI SafeUint64ToInt16(IN UINT64 Operand, OUT INT16 *Result)
Definition: SafeIntLib.c:2566
RETURN_STATUS EFIAPI SafeIntnToUintn(IN INTN Operand, OUT UINTN *Result)
Definition: SafeIntLib.c:1686
RETURN_STATUS EFIAPI SafeInt8ToUint16(IN INT8 Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:146
RETURN_STATUS EFIAPI SafeInt16ToUint16(IN INT16 Operand, OUT UINT16 *Result)
Definition: SafeIntLib.c:542
RETURN_STATUS EFIAPI SafeUint32ToUint8(IN UINT32 Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:1290
RETURN_STATUS EFIAPI SafeUintnToUint8(IN UINTN Operand, OUT UINT8 *Result)
Definition: SafeIntLib.c:1862
RETURN_STATUS EFIAPI SafeUint64ToUint32(IN UINT64 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:2698
RETURN_STATUS EFIAPI SafeUint8Add(IN UINT8 Augend, IN UINT8 Addend, OUT UINT8 *Result)
Definition: SafeIntLib.c:2835
RETURN_STATUS EFIAPI SafeInt16Add(IN INT16 Augend, IN INT16 Addend, OUT INT16 *Result)
Definition: SafeIntLib.c:3549
RETURN_STATUS EFIAPI SafeUint8ToChar8(IN UINT8 Operand, OUT CHAR8 *Result)
Definition: SafeIntLib.c:366
RETURN_STATUS EFIAPI SafeInt32Add(IN INT32 Augend, IN INT32 Addend, OUT INT32 *Result)
Definition: SafeIntLib.c:3581
RETURN_STATUS EFIAPI SafeInt64Sub(IN INT64 Minuend, IN INT64 Subtrahend, OUT INT64 *Result)
Definition: SafeIntLib.c:3857