xref: /illumos-gate/usr/src/common/acpica/utilities/utstrtoul64.c (revision 1a2d662a91cee3bf82f41cd47c7ae6f3825d9db2)
1 /*******************************************************************************
2  *
3  * Module Name: utstrtoul64 - String-to-integer conversion support for both
4  *                            64-bit and 32-bit integers
5  *
6  ******************************************************************************/
7 
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights. You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code. No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision. In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change. Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee. Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution. In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government. In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************
116  *
117  * Alternatively, you may choose to be licensed under the terms of the
118  * following license:
119  *
120  * Redistribution and use in source and binary forms, with or without
121  * modification, are permitted provided that the following conditions
122  * are met:
123  * 1. Redistributions of source code must retain the above copyright
124  *    notice, this list of conditions, and the following disclaimer,
125  *    without modification.
126  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127  *    substantially similar to the "NO WARRANTY" disclaimer below
128  *    ("Disclaimer") and any redistribution must be conditioned upon
129  *    including a substantially similar Disclaimer requirement for further
130  *    binary redistribution.
131  * 3. Neither the names of the above-listed copyright holders nor the names
132  *    of any contributors may be used to endorse or promote products derived
133  *    from this software without specific prior written permission.
134  *
135  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146  *
147  * Alternatively, you may choose to be licensed under the terms of the
148  * GNU General Public License ("GPL") version 2 as published by the Free
149  * Software Foundation.
150  *
151  *****************************************************************************/
152 
153 #include "acpi.h"
154 #include "accommon.h"
155 
156 #define _COMPONENT          ACPI_UTILITIES
157         ACPI_MODULE_NAME    ("utstrtoul64")
158 
159 
160 /*******************************************************************************
161  *
162  * This module contains the top-level string to 64/32-bit unsigned integer
163  * conversion functions:
164  *
165  *  1) A standard strtoul() function that supports 64-bit integers, base
166  *     8/10/16, with integer overflow support. This is used mainly by the
167  *     iASL compiler, which implements tighter constraints on integer
168  *     constants than the runtime (interpreter) integer-to-string conversions.
169  *  2) Runtime "Explicit conversion" as defined in the ACPI specification.
170  *  3) Runtime "Implicit conversion" as defined in the ACPI specification.
171  *
172  * Current users of this module:
173  *
174  *  iASL        - Preprocessor (constants and math expressions)
175  *  iASL        - Main parser, conversion of constants to integers
176  *  iASL        - Data Table Compiler parser (constants and math expressions)
177  *  Interpreter - Implicit and explicit conversions, GPE method names
178  *  Interpreter - Repair code for return values from predefined names
179  *  Debugger    - Command line input string conversion
180  *  AcpiDump    - ACPI table physical addresses
181  *  AcpiExec    - Support for namespace overrides
182  *
183  * Notes concerning users of these interfaces:
184  *
185  * AcpiGbl_IntegerByteWidth is used to set the 32/64 bit limit for explicit
186  * and implicit conversions. This global must be set to the proper width.
187  * For the core ACPICA code, the width depends on the DSDT version. For the
188  * AcpiUtStrtoul64 interface, all conversions are 64 bits. This interface is
189  * used primarily for iASL, where the default width is 64 bits for all parsers,
190  * but error checking is performed later to flag cases where a 64-bit constant
191  * is wrongly defined in a 32-bit DSDT/SSDT.
192  *
193  * In ACPI, the only place where octal numbers are supported is within
194  * the ASL language itself. This is implemented via the main AcpiUtStrtoul64
195  * interface. According the ACPI specification, there is no ACPI runtime
196  * support (explicit/implicit) for octal string conversions.
197  *
198  ******************************************************************************/
199 
200 
201 /*******************************************************************************
202  *
203  * FUNCTION:    AcpiUtStrtoul64
204  *
205  * PARAMETERS:  String                  - Null terminated input string,
206  *                                        must be a valid pointer
207  *              ReturnValue             - Where the converted integer is
208  *                                        returned. Must be a valid pointer
209  *
210  * RETURN:      Status and converted integer. Returns an exception on a
211  *              64-bit numeric overflow
212  *
213  * DESCRIPTION: Convert a string into an unsigned integer. Always performs a
214  *              full 64-bit conversion, regardless of the current global
215  *              integer width. Supports Decimal, Hex, and Octal strings.
216  *
217  * Current users of this function:
218  *
219  *  iASL        - Preprocessor (constants and math expressions)
220  *  iASL        - Main ASL parser, conversion of ASL constants to integers
221  *  iASL        - Data Table Compiler parser (constants and math expressions)
222  *  Interpreter - Repair code for return values from predefined names
223  *  AcpiDump    - ACPI table physical addresses
224  *  AcpiExec    - Support for namespace overrides
225  *
226  ******************************************************************************/
227 
228 ACPI_STATUS
229 AcpiUtStrtoul64 (
230     char                    *String,
231     UINT64                  *ReturnValue)
232 {
233     ACPI_STATUS             Status = AE_OK;
234     UINT8                   OriginalBitWidth;
235     UINT32                  Base = 10;          /* Default is decimal */
236 
237 
238     ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
239 
240 
241     *ReturnValue = 0;
242 
243     /* A NULL return string returns a value of zero */
244 
245     if (*String == 0)
246     {
247         return_ACPI_STATUS (AE_OK);
248     }
249 
250     if (!AcpiUtRemoveWhitespace (&String))
251     {
252         return_ACPI_STATUS (AE_OK);
253     }
254 
255     /*
256      * 1) Check for a hex constant. A "0x" prefix indicates base 16.
257      */
258     if (AcpiUtDetectHexPrefix (&String))
259     {
260         Base = 16;
261     }
262 
263     /*
264      * 2) Check for an octal constant, defined to be a leading zero
265      * followed by sequence of octal digits (0-7)
266      */
267     else if (AcpiUtDetectOctalPrefix (&String))
268     {
269         Base = 8;
270     }
271 
272     if (!AcpiUtRemoveLeadingZeros (&String))
273     {
274         return_ACPI_STATUS (AE_OK);     /* Return value 0 */
275     }
276 
277     /*
278      * Force a full 64-bit conversion. The caller (usually iASL) must
279      * check for a 32-bit overflow later as necessary (If current mode
280      * is 32-bit, meaning a 32-bit DSDT).
281      */
282     OriginalBitWidth = AcpiGbl_IntegerBitWidth;
283     AcpiGbl_IntegerBitWidth = 64;
284 
285     /*
286      * Perform the base 8, 10, or 16 conversion. A 64-bit numeric overflow
287      * will return an exception (to allow iASL to flag the statement).
288      */
289     switch (Base)
290     {
291     case 8:
292         Status = AcpiUtConvertOctalString (String, ReturnValue);
293         break;
294 
295     case 10:
296         Status = AcpiUtConvertDecimalString (String, ReturnValue);
297         break;
298 
299     case 16:
300     default:
301         Status = AcpiUtConvertHexString (String, ReturnValue);
302         break;
303     }
304 
305     /* Only possible exception from above is a 64-bit overflow */
306 
307     AcpiGbl_IntegerBitWidth = OriginalBitWidth;
308     return_ACPI_STATUS (Status);
309 }
310 
311 
312 /*******************************************************************************
313  *
314  * FUNCTION:    AcpiUtImplicitStrtoul64
315  *
316  * PARAMETERS:  String                  - Null terminated input string,
317  *                                        must be a valid pointer
318  *
319  * RETURN:      Converted integer
320  *
321  * DESCRIPTION: Perform a 64-bit conversion with restrictions placed upon
322  *              an "implicit conversion" by the ACPI specification. Used by
323  *              many ASL operators that require an integer operand, and support
324  *              an automatic (implicit) conversion from a string operand
325  *              to the final integer operand. The major restriction is that
326  *              only hex strings are supported.
327  *
328  * -----------------------------------------------------------------------------
329  *
330  * Base is always 16, either with or without the 0x prefix. Decimal and
331  * Octal strings are not supported, as per the ACPI specification.
332  *
333  * Examples (both are hex values):
334  *      Add ("BA98", Arg0, Local0)
335  *      Subtract ("0x12345678", Arg1, Local1)
336  *
337  * Conversion rules as extracted from the ACPI specification:
338  *
339  *  The converted integer is initialized to the value zero.
340  *  The ASCII string is always interpreted as a hexadecimal constant.
341  *
342  *  1)  According to the ACPI specification, a "0x" prefix is not allowed.
343  *      However, ACPICA allows this as an ACPI extension on general
344  *      principle. (NO ERROR)
345  *
346  *  2)  The conversion terminates when the size of an integer is reached
347  *      (32 or 64 bits). There are no numeric overflow conditions. (NO ERROR)
348  *
349  *  3)  The first non-hex character terminates the conversion and returns
350  *      the current accumulated value of the converted integer (NO ERROR).
351  *
352  *  4)  Conversion of a null (zero-length) string to an integer is
353  *      technically not allowed. However, ACPICA allows this as an ACPI
354  *      extension. The conversion returns the value 0. (NO ERROR)
355  *
356  * NOTE: There are no error conditions returned by this function. At
357  * the minimum, a value of zero is returned.
358  *
359  * Current users of this function:
360  *
361  *  Interpreter - All runtime implicit conversions, as per ACPI specification
362  *  iASL        - Data Table Compiler parser (constants and math expressions)
363  *
364  ******************************************************************************/
365 
366 UINT64
367 AcpiUtImplicitStrtoul64 (
368     char                    *String)
369 {
370     UINT64                  ConvertedInteger = 0;
371 
372 
373     ACPI_FUNCTION_TRACE_STR (UtImplicitStrtoul64, String);
374 
375 
376     if (!AcpiUtRemoveWhitespace (&String))
377     {
378         return_VALUE (0);
379     }
380 
381     /*
382      * Per the ACPI specification, only hexadecimal is supported for
383      * implicit conversions, and the "0x" prefix is "not allowed".
384      * However, allow a "0x" prefix as an ACPI extension.
385      */
386     AcpiUtDetectHexPrefix (&String);
387 
388     if (!AcpiUtRemoveLeadingZeros (&String))
389     {
390         return_VALUE (0);
391     }
392 
393     /*
394      * Ignore overflow as per the ACPI specification. This is implemented by
395      * ignoring the return status from the conversion function called below.
396      * On overflow, the input string is simply truncated.
397      */
398     AcpiUtConvertHexString (String, &ConvertedInteger);
399     return_VALUE (ConvertedInteger);
400 }
401 
402 
403 /*******************************************************************************
404  *
405  * FUNCTION:    AcpiUtExplicitStrtoul64
406  *
407  * PARAMETERS:  String                  - Null terminated input string,
408  *                                        must be a valid pointer
409  *
410  * RETURN:      Converted integer
411  *
412  * DESCRIPTION: Perform a 64-bit conversion with the restrictions placed upon
413  *              an "explicit conversion" by the ACPI specification. The
414  *              main restriction is that only hex and decimal are supported.
415  *
416  * -----------------------------------------------------------------------------
417  *
418  * Base is either 10 (default) or 16 (with 0x prefix). Octal (base 8) strings
419  * are not supported, as per the ACPI specification.
420  *
421  * Examples:
422  *      ToInteger ("1000")      Decimal
423  *      ToInteger ("0xABCD")    Hex
424  *
425  * Conversion rules as extracted from the ACPI specification:
426  *
427  *  1)  The input string is either a decimal or hexadecimal numeric string.
428  *      A hex value must be prefixed by "0x" or it is interpreted as decimal.
429  *
430  *  2)  The value must not exceed the maximum of an integer value
431  *      (32 or 64 bits). The ACPI specification states the behavior is
432  *      "unpredictable", so ACPICA matches the behavior of the implicit
433  *      conversion case. There are no numeric overflow conditions. (NO ERROR)
434  *
435  *  3)  Behavior on the first non-hex character is not defined by the ACPI
436  *      specification (for the ToInteger operator), so ACPICA matches the
437  *      behavior of the implicit conversion case. It terminates the
438  *      conversion and returns the current accumulated value of the converted
439  *      integer. (NO ERROR)
440  *
441  *  4)  Conversion of a null (zero-length) string to an integer is
442  *      technically not allowed. However, ACPICA allows this as an ACPI
443  *      extension. The conversion returns the value 0. (NO ERROR)
444  *
445  * NOTE: There are no error conditions returned by this function. At the
446  * minimum, a value of zero is returned.
447  *
448  * Current users of this function:
449  *
450  *  Interpreter - Runtime ASL ToInteger operator, as per the ACPI specification
451  *
452  ******************************************************************************/
453 
454 UINT64
455 AcpiUtExplicitStrtoul64 (
456     char                    *String)
457 {
458     UINT64                  ConvertedInteger = 0;
459     UINT32                  Base = 10;          /* Default is decimal */
460 
461 
462     ACPI_FUNCTION_TRACE_STR (UtExplicitStrtoul64, String);
463 
464 
465     if (!AcpiUtRemoveWhitespace (&String))
466     {
467         return_VALUE (0);
468     }
469 
470     /*
471      * Only Hex and Decimal are supported, as per the ACPI specification.
472      * A "0x" prefix indicates hex; otherwise decimal is assumed.
473      */
474     if (AcpiUtDetectHexPrefix (&String))
475     {
476         Base = 16;
477     }
478 
479     if (!AcpiUtRemoveLeadingZeros (&String))
480     {
481         return_VALUE (0);
482     }
483 
484     /*
485      * Ignore overflow as per the ACPI specification. This is implemented by
486      * ignoring the return status from the conversion functions called below.
487      * On overflow, the input string is simply truncated.
488      */
489     switch (Base)
490     {
491     case 10:
492     default:
493         AcpiUtConvertDecimalString (String, &ConvertedInteger);
494         break;
495 
496     case 16:
497         AcpiUtConvertHexString (String, &ConvertedInteger);
498         break;
499     }
500 
501     return_VALUE (ConvertedInteger);
502 }
503