]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c
MdePkg/BaseLib: Add bit field population calculating methods
[mirror_edk2.git] / MdePkg / Library / BaseSafeIntLib / SafeIntLib64.c
CommitLineData
d7a09cb8
SB
1/** @file\r
2 This library provides helper functions to prevent integer overflow during\r
3 type conversion, addition, subtraction, and multiplication.\r
4\r
5 Copyright (c) 2017, Microsoft Corporation\r
6\r
7 All rights reserved.\r
8 Redistribution and use in source and binary forms, with or without\r
9 modification, are permitted provided that the following conditions are met:\r
10 1. Redistributions of source code must retain the above copyright notice,\r
11 this list of conditions and the following disclaimer.\r
12 2. Redistributions in binary form must reproduce the above copyright notice,\r
13 this list of conditions and the following disclaimer in the documentation\r
14 and/or other materials provided with the distribution.\r
15\r
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
19 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
20 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
21 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
24 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
25 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
26\r
27**/\r
28\r
29#include <Base.h>\r
30#include <Library/SafeIntLib.h>\r
31\r
32/**\r
33 INT32 -> UINTN conversion\r
34\r
35 Converts the value specified by Operand to a value specified by Result type\r
36 and stores the converted value into the caller allocated output buffer\r
37 specified by Result. The caller must pass in a Result buffer that is at\r
38 least as large as the Result type.\r
39\r
40 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
41\r
42 If the conversion results in an overflow or an underflow condition, then\r
43 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
44\r
45 @param[in] Operand Operand to be converted to new type\r
46 @param[out] Result Pointer to the result of conversion\r
47\r
48 @retval RETURN_SUCCESS Successful conversion\r
49 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
50 @retval RETURN_INVALID_PARAMETER Result is NULL\r
51**/\r
52RETURN_STATUS\r
53EFIAPI\r
54SafeInt32ToUintn (\r
55 IN INT32 Operand,\r
56 OUT UINTN *Result\r
57 )\r
58{\r
59 return SafeInt32ToUint64 (Operand, (UINT64 *) Result);\r
60}\r
61\r
62/**\r
63 UINT32 -> INTN conversion\r
64\r
65 Converts the value specified by Operand to a value specified by Result type\r
66 and stores the converted value into the caller allocated output buffer\r
67 specified by Result. The caller must pass in a Result buffer that is at\r
68 least as large as the Result type.\r
69\r
70 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
71\r
72 If the conversion results in an overflow or an underflow condition, then\r
73 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
74\r
75 @param[in] Operand Operand to be converted to new type\r
76 @param[out] Result Pointer to the result of conversion\r
77\r
78 @retval RETURN_SUCCESS Successful conversion\r
79 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
80 @retval RETURN_INVALID_PARAMETER Result is NULL\r
81**/\r
82RETURN_STATUS\r
83EFIAPI\r
84SafeUint32ToIntn (\r
85 IN UINT32 Operand,\r
86 OUT INTN *Result\r
87 )\r
88{\r
89 if (Result == NULL) {\r
90 return RETURN_INVALID_PARAMETER;\r
91 }\r
92\r
93 *Result = Operand;\r
94 return RETURN_SUCCESS;\r
95}\r
96\r
97/**\r
98 INTN -> INT32 conversion\r
99\r
100 Converts the value specified by Operand to a value specified by Result type\r
101 and stores the converted value into the caller allocated output buffer\r
102 specified by Result. The caller must pass in a Result buffer that is at\r
103 least as large as the Result type.\r
104\r
105 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
106\r
107 If the conversion results in an overflow or an underflow condition, then\r
108 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
109\r
110 @param[in] Operand Operand to be converted to new type\r
111 @param[out] Result Pointer to the result of conversion\r
112\r
113 @retval RETURN_SUCCESS Successful conversion\r
114 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
115 @retval RETURN_INVALID_PARAMETER Result is NULL\r
116**/\r
117RETURN_STATUS\r
118EFIAPI\r
119SafeIntnToInt32 (\r
120 IN INTN Operand,\r
121 OUT INT32 *Result\r
122 )\r
123{\r
124 return SafeInt64ToInt32 ((INT64) Operand, Result);\r
125}\r
126\r
127/**\r
128 INTN -> UINT32 conversion\r
129\r
130 Converts the value specified by Operand to a value specified by Result type\r
131 and stores the converted value into the caller allocated output buffer\r
132 specified by Result. The caller must pass in a Result buffer that is at\r
133 least as large as the Result type.\r
134\r
135 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
136\r
137 If the conversion results in an overflow or an underflow condition, then\r
138 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
139\r
140 @param[in] Operand Operand to be converted to new type\r
141 @param[out] Result Pointer to the result of conversion\r
142\r
143 @retval RETURN_SUCCESS Successful conversion\r
144 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
145 @retval RETURN_INVALID_PARAMETER Result is NULL\r
146**/\r
147RETURN_STATUS\r
148EFIAPI\r
149SafeIntnToUint32 (\r
150 IN INTN Operand,\r
151 OUT UINT32 *Result\r
152 )\r
153{\r
154 return SafeInt64ToUint32 ((INT64)Operand, Result);\r
155}\r
156\r
157/**\r
158 UINTN -> UINT32 conversion\r
159\r
160 Converts the value specified by Operand to a value specified by Result type\r
161 and stores the converted value into the caller allocated output buffer\r
162 specified by Result. The caller must pass in a Result buffer that is at\r
163 least as large as the Result type.\r
164\r
165 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
166\r
167 If the conversion results in an overflow or an underflow condition, then\r
168 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
169\r
170 @param[in] Operand Operand to be converted to new type\r
171 @param[out] Result Pointer to the result of conversion\r
172\r
173 @retval RETURN_SUCCESS Successful conversion\r
174 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
175 @retval RETURN_INVALID_PARAMETER Result is NULL\r
176**/\r
177RETURN_STATUS\r
178EFIAPI\r
179SafeUintnToUint32 (\r
180 IN UINTN Operand,\r
181 OUT UINT32 *Result\r
182 )\r
183{\r
184 return SafeUint64ToUint32 ((UINT64)Operand, Result);\r
185}\r
186\r
187/**\r
188 UINTN -> INT64 conversion\r
189\r
190 Converts the value specified by Operand to a value specified by Result type\r
191 and stores the converted value into the caller allocated output buffer\r
192 specified by Result. The caller must pass in a Result buffer that is at\r
193 least as large as the Result type.\r
194\r
195 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
196\r
197 If the conversion results in an overflow or an underflow condition, then\r
198 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
199\r
200 @param[in] Operand Operand to be converted to new type\r
201 @param[out] Result Pointer to the result of conversion\r
202\r
203 @retval RETURN_SUCCESS Successful conversion\r
204 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
205 @retval RETURN_INVALID_PARAMETER Result is NULL\r
206**/\r
207RETURN_STATUS\r
208EFIAPI\r
209SafeUintnToInt64 (\r
210 IN UINTN Operand,\r
211 OUT INT64 *Result\r
212 )\r
213{\r
214 return SafeUint64ToInt64 ((UINT64)Operand, Result);\r
215}\r
216\r
217/**\r
218 INT64 -> INTN conversion\r
219\r
220 Converts the value specified by Operand to a value specified by Result type\r
221 and stores the converted value into the caller allocated output buffer\r
222 specified by Result. The caller must pass in a Result buffer that is at\r
223 least as large as the Result type.\r
224\r
225 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
226\r
227 If the conversion results in an overflow or an underflow condition, then\r
228 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
229\r
230 @param[in] Operand Operand to be converted to new type\r
231 @param[out] Result Pointer to the result of conversion\r
232\r
233 @retval RETURN_SUCCESS Successful conversion\r
234 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
235 @retval RETURN_INVALID_PARAMETER Result is NULL\r
236**/\r
237RETURN_STATUS\r
238EFIAPI\r
239SafeInt64ToIntn (\r
240 IN INT64 Operand,\r
241 OUT INTN *Result\r
242 )\r
243{\r
244 if (Result == NULL) {\r
245 return RETURN_INVALID_PARAMETER;\r
246 }\r
247\r
248 *Result = (INTN)Operand;\r
249 return RETURN_SUCCESS;\r
250}\r
251\r
252/**\r
253 INT64 -> UINTN conversion\r
254\r
255 Converts the value specified by Operand to a value specified by Result type\r
256 and stores the converted value into the caller allocated output buffer\r
257 specified by Result. The caller must pass in a Result buffer that is at\r
258 least as large as the Result type.\r
259\r
260 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
261\r
262 If the conversion results in an overflow or an underflow condition, then\r
263 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
264\r
265 @param[in] Operand Operand to be converted to new type\r
266 @param[out] Result Pointer to the result of conversion\r
267\r
268 @retval RETURN_SUCCESS Successful conversion\r
269 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
270 @retval RETURN_INVALID_PARAMETER Result is NULL\r
271**/\r
272RETURN_STATUS\r
273EFIAPI\r
274SafeInt64ToUintn (\r
275 IN INT64 Operand,\r
276 OUT UINTN *Result\r
277 )\r
278{\r
279 return SafeInt64ToUint64 (Operand, (UINT64 *)Result);\r
280}\r
281\r
282/**\r
283 UINT64 -> UINTN conversion\r
284\r
285 Converts the value specified by Operand to a value specified by Result type\r
286 and stores the converted value into the caller allocated output buffer\r
287 specified by Result. The caller must pass in a Result buffer that is at\r
288 least as large as the Result type.\r
289\r
290 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
291\r
292 If the conversion results in an overflow or an underflow condition, then\r
293 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
294\r
295 @param[in] Operand Operand to be converted to new type\r
296 @param[out] Result Pointer to the result of conversion\r
297\r
298 @retval RETURN_SUCCESS Successful conversion\r
299 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
300 @retval RETURN_INVALID_PARAMETER Result is NULL\r
301**/\r
302RETURN_STATUS\r
303EFIAPI\r
304SafeUint64ToUintn (\r
305 IN UINT64 Operand,\r
306 OUT UINTN *Result\r
307 )\r
308{\r
309 if (Result == NULL) {\r
310 return RETURN_INVALID_PARAMETER;\r
311 }\r
312\r
313 *Result = Operand;\r
314 return RETURN_SUCCESS;\r
315}\r
316\r
317/**\r
318 UINTN addition\r
319\r
320 Performs the requested operation using the input parameters into a value\r
321 specified by Result type and stores the converted value into the caller\r
322 allocated output buffer specified by Result. The caller must pass in a\r
323 Result buffer that is at least as large as the Result type.\r
324\r
325 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
326\r
327 If the requested operation results in an overflow or an underflow condition,\r
328 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
329\r
330 @param[in] Augend A number to which addend will be added\r
331 @param[in] Addend A number to be added to another\r
332 @param[out] Result Pointer to the result of addition\r
333\r
334 @retval RETURN_SUCCESS Successful addition\r
335 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
336 @retval RETURN_INVALID_PARAMETER Result is NULL\r
337**/\r
338RETURN_STATUS\r
339EFIAPI\r
340SafeUintnAdd (\r
341 IN UINTN Augend,\r
342 IN UINTN Addend,\r
343 OUT UINTN *Result\r
344 )\r
345{\r
346 return SafeUint64Add ((UINT64)Augend, (UINT64)Addend, (UINT64 *)Result);\r
347}\r
348\r
349/**\r
350 UINTN subtraction\r
351\r
352 Performs the requested operation using the input parameters into a value\r
353 specified by Result type and stores the converted value into the caller\r
354 allocated output buffer specified by Result. The caller must pass in a\r
355 Result buffer that is at least as large as the Result type.\r
356\r
357 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
358\r
359 If the requested operation results in an overflow or an underflow condition,\r
360 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
361\r
362 @param[in] Minuend A number from which another is to be subtracted.\r
363 @param[in] Subtrahend A number to be subtracted from another\r
364 @param[out] Result Pointer to the result of subtraction\r
365\r
366 @retval RETURN_SUCCESS Successful subtraction\r
367 @retval RETURN_BUFFER_TOO_SMALL Underflow\r
368 @retval RETURN_INVALID_PARAMETER Result is NULL\r
369**/\r
370RETURN_STATUS\r
371EFIAPI\r
372SafeUintnSub (\r
373 IN UINTN Minuend,\r
374 IN UINTN Subtrahend,\r
375 OUT UINTN *Result\r
376 )\r
377{\r
378 return SafeUint64Sub ((UINT64)Minuend, (UINT64)Subtrahend, (UINT64 *)Result);\r
379}\r
380\r
381/**\r
382 UINTN multiplication\r
383\r
384 Performs the requested operation using the input parameters into a value\r
385 specified by Result type and stores the converted value into the caller\r
386 allocated output buffer specified by Result. The caller must pass in a\r
387 Result buffer that is at least as large as the Result type.\r
388\r
389 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
390\r
391 If the requested operation results in an overflow or an underflow condition,\r
392 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
393\r
394 @param[in] Multiplicand A number that is to be multiplied by another\r
395 @param[in] Multiplier A number by which the multiplicand is to be multiplied\r
396 @param[out] Result Pointer to the result of multiplication\r
397\r
398 @retval RETURN_SUCCESS Successful multiplication\r
399 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
400 @retval RETURN_INVALID_PARAMETER Result is NULL\r
401**/\r
402RETURN_STATUS\r
403EFIAPI\r
404SafeUintnMult (\r
405 IN UINTN Multiplicand,\r
406 IN UINTN Multiplier,\r
407 OUT UINTN *Result\r
408 )\r
409{\r
410 return SafeUint64Mult ((UINT64)Multiplicand, (UINT64)Multiplier, (UINT64 *)Result);\r
411}\r
412\r
413/**\r
414 INTN Addition\r
415\r
416 Performs the requested operation using the input parameters into a value\r
417 specified by Result type and stores the converted value into the caller\r
418 allocated output buffer specified by Result. The caller must pass in a\r
419 Result buffer that is at least as large as the Result type.\r
420\r
421 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
422\r
423 If the requested operation results in an overflow or an underflow condition,\r
424 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
425\r
426 @param[in] Augend A number to which addend will be added\r
427 @param[in] Addend A number to be added to another\r
428 @param[out] Result Pointer to the result of addition\r
429\r
430 @retval RETURN_SUCCESS Successful addition\r
431 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
432 @retval RETURN_INVALID_PARAMETER Result is NULL\r
433**/\r
434RETURN_STATUS\r
435EFIAPI\r
436SafeIntnAdd (\r
437 IN INTN Augend,\r
438 IN INTN Addend,\r
439 OUT INTN *Result\r
440 )\r
441{\r
442 return SafeInt64Add ((INT64)Augend, (INT64)Addend, (INT64 *)Result);\r
443}\r
444\r
445/**\r
446 INTN Subtraction\r
447\r
448 Performs the requested operation using the input parameters into a value\r
449 specified by Result type and stores the converted value into the caller\r
450 allocated output buffer specified by Result. The caller must pass in a\r
451 Result buffer that is at least as large as the Result type.\r
452\r
453 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
454\r
455 If the requested operation results in an overflow or an underflow condition,\r
456 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
457\r
458 @param[in] Minuend A number from which another is to be subtracted.\r
459 @param[in] Subtrahend A number to be subtracted from another\r
460 @param[out] Result Pointer to the result of subtraction\r
461\r
462 @retval RETURN_SUCCESS Successful subtraction\r
463 @retval RETURN_BUFFER_TOO_SMALL Underflow\r
464 @retval RETURN_INVALID_PARAMETER Result is NULL\r
465**/\r
466RETURN_STATUS\r
467EFIAPI\r
468SafeIntnSub (\r
469 IN INTN Minuend,\r
470 IN INTN Subtrahend,\r
471 OUT INTN *Result\r
472 )\r
473{\r
474 return SafeInt64Sub ((INT64)Minuend, (INT64)Subtrahend, (INT64 *)Result);\r
475}\r
476\r
477/**\r
478 INTN multiplication\r
479\r
480 Performs the requested operation using the input parameters into a value\r
481 specified by Result type and stores the converted value into the caller\r
482 allocated output buffer specified by Result. The caller must pass in a\r
483 Result buffer that is at least as large as the Result type.\r
484\r
485 If Result is NULL, RETURN_INVALID_PARAMETER is returned.\r
486\r
487 If the requested operation results in an overflow or an underflow condition,\r
488 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.\r
489\r
490 @param[in] Multiplicand A number that is to be multiplied by another\r
491 @param[in] Multiplier A number by which the multiplicand is to be multiplied\r
492 @param[out] Result Pointer to the result of multiplication\r
493\r
494 @retval RETURN_SUCCESS Successful multiplication\r
495 @retval RETURN_BUFFER_TOO_SMALL Overflow\r
496 @retval RETURN_INVALID_PARAMETER Result is NULL\r
497**/\r
498RETURN_STATUS\r
499EFIAPI\r
500SafeIntnMult (\r
501 IN INTN Multiplicand,\r
502 IN INTN Multiplier,\r
503 OUT INTN *Result\r
504 )\r
505{\r
506 return SafeInt64Mult ((INT64)Multiplicand, (INT64)Multiplier, (INT64 *)Result);\r
507}\r
508\r