Home | History | Annotate | Line # | Download | only in common
      1 /******************************************************************************
      2  *
      3  * Module Name: acfileio - Get ACPI tables from file
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "acpi.h"
    153 #include "accommon.h"
    154 #include "actables.h"
    155 #include "acutils.h"
    156 #include "acapps.h"
    157 
    158 #define _COMPONENT          ACPI_UTILITIES
    159         ACPI_MODULE_NAME    ("acfileio")
    160 
    161 
    162 /* Local prototypes */
    163 
    164 static ACPI_STATUS
    165 AcGetOneTableFromFile (
    166     char                    *Filename,
    167     FILE                    *File,
    168     UINT8                   GetOnlyAmlTables,
    169     ACPI_TABLE_HEADER       **Table);
    170 
    171 static ACPI_STATUS
    172 AcCheckTextModeCorruption (
    173     ACPI_TABLE_HEADER       *Table);
    174 
    175 
    176 /*******************************************************************************
    177  *
    178  * FUNCTION:    AcDeleteTableList
    179  *
    180  * PARAMETERS:  ListHead            - List to delete
    181  *
    182  * RETURN:      Status
    183  *
    184  * DESCRIPTION: Delete a list of tables. This is useful for removing memory
    185  *              allocated by AcGetAllTablesFromFile
    186  *
    187  ******************************************************************************/
    188 
    189 void
    190 AcDeleteTableList (
    191     ACPI_NEW_TABLE_DESC     *ListHead)
    192 {
    193     ACPI_NEW_TABLE_DESC     *Current = ListHead;
    194     ACPI_NEW_TABLE_DESC     *Previous = Current;
    195 
    196 
    197     while (Current)
    198     {
    199         Current = Current->Next;
    200         AcpiOsFree (Previous);
    201         Previous = Current;
    202     }
    203 }
    204 
    205 
    206 /*******************************************************************************
    207  *
    208  * FUNCTION:    AcGetAllTablesFromFile
    209  *
    210  * PARAMETERS:  Filename            - Table filename
    211  *              GetOnlyAmlTables    - TRUE if the tables must be AML tables
    212  *              ReturnListHead      - Where table list is returned
    213  *
    214  * RETURN:      Status
    215  *
    216  * DESCRIPTION: Get all ACPI tables from within a single file.
    217  *
    218  ******************************************************************************/
    219 
    220 ACPI_STATUS
    221 AcGetAllTablesFromFile (
    222     char                    *Filename,
    223     UINT8                   GetOnlyAmlTables,
    224     ACPI_NEW_TABLE_DESC     **ReturnListHead)
    225 {
    226     ACPI_NEW_TABLE_DESC     *ListHead = NULL;
    227     ACPI_NEW_TABLE_DESC     *ListTail = NULL;
    228     ACPI_NEW_TABLE_DESC     *TableDesc;
    229     FILE                    *File;
    230     ACPI_TABLE_HEADER       *Table = NULL;
    231     UINT32                  FileSize;
    232     ACPI_STATUS             Status = AE_OK;
    233 
    234 
    235     File = fopen (Filename, "rb");
    236     if (!File)
    237     {
    238         fprintf (stderr, "Could not open input file: %s\n", Filename);
    239         if (errno == ENOENT)
    240         {
    241             return (AE_NOT_EXIST);
    242         }
    243 
    244         return (AE_ERROR);
    245     }
    246 
    247     /* Get the file size */
    248 
    249     FileSize = CmGetFileSize (File);
    250     if (FileSize == ACPI_UINT32_MAX)
    251     {
    252         Status = AE_ERROR;
    253         goto Exit;
    254     }
    255 
    256     fprintf (stderr,
    257         "Input file %s, Length 0x%X (%u) bytes\n",
    258         Filename, FileSize, FileSize);
    259 
    260     /* We must have at least one ACPI table header */
    261 
    262     if (FileSize < sizeof (ACPI_TABLE_HEADER))
    263     {
    264         Status = AE_BAD_HEADER;
    265         goto Exit;
    266     }
    267 
    268     /* Check for an non-binary file */
    269 
    270     if (!AcIsFileBinary (File))
    271     {
    272         fprintf (stderr,
    273             "    %s: File does not appear to contain a valid AML table\n",
    274             Filename);
    275         Status = AE_TYPE;
    276         goto Exit;
    277     }
    278 
    279     /* Read all tables within the file */
    280 
    281     while (ACPI_SUCCESS (Status))
    282     {
    283         /* Get one entire ACPI table */
    284 
    285         Status = AcGetOneTableFromFile (
    286             Filename, File, GetOnlyAmlTables, &Table);
    287 
    288         if (Status == AE_CTRL_TERMINATE)
    289         {
    290             Status = AE_OK;
    291             break;
    292         }
    293         else if (Status == AE_TYPE)
    294         {
    295             Status = AE_OK;
    296             goto Exit;
    297         }
    298         else if (ACPI_FAILURE (Status))
    299         {
    300             goto Exit;
    301         }
    302 
    303         /* Print table header for iASL/disassembler only */
    304 
    305 #ifdef ACPI_ASL_COMPILER
    306 
    307         AcpiTbPrintTableHeader (0, Table);
    308 #endif
    309 
    310         /* Allocate and link a table descriptor */
    311 
    312         TableDesc = AcpiOsAllocate (sizeof (ACPI_NEW_TABLE_DESC));
    313         if (!TableDesc)
    314         {
    315             AcpiOsFree (Table);
    316             Status = AE_NO_MEMORY;
    317             goto Exit;
    318         }
    319 
    320         TableDesc->Table = Table;
    321         TableDesc->Next = NULL;
    322 
    323         /* Link at the end of the local table list */
    324 
    325         if (!ListHead)
    326         {
    327             ListHead = TableDesc;
    328             ListTail = TableDesc;
    329         }
    330         else
    331         {
    332             ListTail->Next = TableDesc;
    333             ListTail = TableDesc;
    334         }
    335     }
    336 
    337     /* Add the local table list to the end of the global list */
    338 
    339     if (*ReturnListHead)
    340     {
    341         ListTail = *ReturnListHead;
    342         while (ListTail->Next)
    343         {
    344             ListTail = ListTail->Next;
    345         }
    346 
    347         ListTail->Next = ListHead;
    348     }
    349     else
    350     {
    351         *ReturnListHead = ListHead;
    352     }
    353 
    354 Exit:
    355     fclose(File);
    356     return (Status);
    357 }
    358 
    359 
    360 /*******************************************************************************
    361  *
    362  * FUNCTION:    AcGetOneTableFromFile
    363  *
    364  * PARAMETERS:  Filename            - File where table is located
    365  *              File                - Open FILE pointer to Filename
    366  *              GetOnlyAmlTables    - TRUE if the tables must be AML tables.
    367  *              ReturnTable         - Where a pointer to the table is returned
    368  *
    369  * RETURN:      Status
    370  *
    371  * DESCRIPTION: Read the next ACPI table from a file. Implements support
    372  *              for multiple tables within a single file. File must already
    373  *              be open.
    374  *
    375  * Note: Loading an RSDP is not supported.
    376  *
    377  ******************************************************************************/
    378 
    379 static ACPI_STATUS
    380 AcGetOneTableFromFile (
    381     char                    *Filename,
    382     FILE                    *File,
    383     UINT8                   GetOnlyAmlTables,
    384     ACPI_TABLE_HEADER       **ReturnTable)
    385 {
    386     ACPI_STATUS             Status = AE_OK;
    387     ACPI_TABLE_HEADER       TableHeader;
    388     ACPI_TABLE_HEADER       *Table;
    389     INT32                   Count;
    390     UINT32                  TableLength;
    391     UINT32                  HeaderLength;
    392     long                    TableOffset = 0;
    393 
    394     *ReturnTable = NULL;
    395 
    396     /* Get the table header to examine signature and length */
    397     /*
    398      * Special handling for the CDAT table (both the Length field
    399      * and the Checksum field are not in the standard positions).
    400      * (The table header is non-standard).
    401      */
    402     if (AcpiGbl_CDAT)
    403     {
    404         HeaderLength = sizeof (ACPI_TABLE_CDAT);
    405     }
    406     else
    407     {
    408         HeaderLength = sizeof (ACPI_TABLE_HEADER);
    409     }
    410 
    411     Status = AcValidateTableHeader (File, TableOffset);
    412     if (ACPI_FAILURE (Status))
    413     {
    414         return (Status);
    415     }
    416 
    417     TableOffset = ftell (File);
    418     Count = fread (&TableHeader, 1, HeaderLength, File);
    419     if (Count != (INT32) HeaderLength)
    420     {
    421         return (AE_CTRL_TERMINATE);
    422     }
    423 
    424     if (GetOnlyAmlTables)
    425     {
    426         /* Validate the table signature/header (limited ASCII chars) */
    427 
    428         /*
    429          * Table must be an AML table (DSDT/SSDT).
    430          * Used for iASL -e option only.
    431          */
    432         if (!AcpiUtIsAmlTable (&TableHeader))
    433         {
    434             fprintf (stderr,
    435                 "    %s: Table [%4.4s] is not an AML table - ignoring\n",
    436                 Filename, TableHeader.Signature);
    437 
    438             return (AE_TYPE);
    439         }
    440     }
    441 
    442     /*
    443      * Special handling for the CDAT table (both the Length field
    444      * and the Checksum field are not in the standard positions).
    445      */
    446     if (AcpiGbl_CDAT)
    447     {
    448         TableLength = ACPI_CAST_PTR (ACPI_TABLE_CDAT, &TableHeader)->Length;
    449     }
    450     else
    451     {
    452         TableLength = TableHeader.Length;
    453     }
    454 
    455     /* Allocate a buffer for the entire table */
    456 
    457     Table = AcpiOsAllocate ((ACPI_SIZE) TableLength);
    458     if (!Table)
    459     {
    460         return (AE_NO_MEMORY);
    461     }
    462 
    463     /* Read the entire ACPI table, including header */
    464 
    465     fseek (File, TableOffset, SEEK_SET);
    466     Count = fread (Table, 1, TableLength, File);
    467 
    468     /*
    469      * Checks for data table headers happen later in the execution. Only verify
    470      * for Aml tables at this point in the code.
    471      */
    472     if (GetOnlyAmlTables && Count != (INT32) TableLength)
    473     {
    474         Status = AE_ERROR;
    475         goto ErrorExit;
    476     }
    477 
    478     /*
    479      * Validate the checksum (just issue a warning if incorrect).
    480      * Note: CDAT is special cased here because the table does
    481      * not have the checksum field in the standard position.
    482      */
    483     if (AcpiGbl_CDAT)
    484     {
    485         Status = AcpiUtVerifyCdatChecksum ((ACPI_TABLE_CDAT *) Table, TableLength);
    486     } else
    487     {
    488         Status = AcpiUtVerifyChecksum (Table, TableLength);
    489     }
    490 
    491     if (ACPI_FAILURE (Status))
    492     {
    493         Status = AcCheckTextModeCorruption (Table);
    494         if (ACPI_FAILURE (Status))
    495         {
    496             goto ErrorExit;
    497         }
    498     }
    499 
    500     *ReturnTable = Table;
    501     return (AE_OK);
    502 
    503 
    504 ErrorExit:
    505     AcpiOsFree (Table);
    506     return (Status);
    507 }
    508 
    509 
    510 /*******************************************************************************
    511  *
    512  * FUNCTION:    AcIsFileBinary
    513  *
    514  * PARAMETERS:  File                - Open input file
    515  *
    516  * RETURN:      TRUE if file appears to be binary
    517  *
    518  * DESCRIPTION: Scan a file for any non-ASCII bytes.
    519  *
    520  * Note: Maintains current file position.
    521  *
    522  ******************************************************************************/
    523 
    524 BOOLEAN
    525 AcIsFileBinary (
    526     FILE                    *File)
    527 {
    528     UINT8                   Byte;
    529     BOOLEAN                 IsBinary = FALSE;
    530     long                    FileOffset;
    531 
    532 
    533     /* Scan entire file for any non-ASCII bytes */
    534 
    535     FileOffset = ftell (File);
    536     while (fread (&Byte, 1, 1, File) == 1)
    537     {
    538         if (!isprint (Byte) && !isspace (Byte))
    539         {
    540             IsBinary = TRUE;
    541             goto Exit;
    542         }
    543     }
    544 
    545 Exit:
    546     fseek (File, FileOffset, SEEK_SET);
    547     return (IsBinary);
    548 }
    549 
    550 
    551 /*******************************************************************************
    552  *
    553  * FUNCTION:    AcValidateTableHeader
    554  *
    555  * PARAMETERS:  File                - Open input file
    556  *
    557  * RETURN:      Status
    558  *
    559  * DESCRIPTION: Determine if a file seems to contain one or more binary ACPI
    560  *              tables, via the
    561  *              following checks on what would be the table header:
    562  *              1) File must be at least as long as an ACPI_TABLE_HEADER
    563  *              2) There must be enough room in the file to hold entire table
    564  *              3) Signature, OemId, OemTableId, AslCompilerId must be ASCII
    565  *
    566  * Note: There can be multiple definition blocks per file, so we cannot
    567  * expect/compare the file size to be equal to the table length. 12/2015.
    568  *
    569  * Note: Maintains current file position.
    570  *
    571  ******************************************************************************/
    572 
    573 ACPI_STATUS
    574 AcValidateTableHeader (
    575     FILE                    *File,
    576     long                    TableOffset)
    577 {
    578     ACPI_TABLE_HEADER       TableHeader;
    579     ACPI_TABLE_CDAT         *CdatTableHeader = ACPI_CAST_PTR (ACPI_TABLE_CDAT, &TableHeader);
    580     UINT32                  HeaderLength;
    581     ACPI_SIZE               Actual;
    582     long                    OriginalOffset;
    583     UINT32                  FileSize;
    584     UINT32                  i;
    585 
    586 
    587     ACPI_FUNCTION_TRACE (AcValidateTableHeader);
    588 
    589     /* Determine the type of table header */
    590 
    591     if (AcpiGbl_CDAT)
    592     {
    593         HeaderLength = sizeof (ACPI_TABLE_CDAT);
    594     }
    595     else
    596     {
    597         HeaderLength = sizeof (ACPI_TABLE_HEADER);
    598     }
    599 
    600     /* Read a potential table header */
    601 
    602     OriginalOffset = ftell (File);
    603     if (fseek (File, TableOffset, SEEK_SET))
    604     {
    605         fprintf (stderr, "SEEK error\n");
    606     }
    607     Actual = fread (&TableHeader, 1, HeaderLength, File);
    608     if (fseek (File, OriginalOffset, SEEK_SET))
    609     {
    610         fprintf (stderr, "SEEK error\n");
    611     }
    612 
    613     if (Actual < HeaderLength)
    614     {
    615         fprintf (stderr,
    616             "Could not read entire table header: Actual %u, Requested %u\n",
    617             (UINT32) Actual, HeaderLength);
    618         return (AE_ERROR);
    619     }
    620 
    621     /* Validate the signature (limited ASCII chars) */
    622 
    623     if (!AcpiGbl_CDAT && !AcpiUtValidNameseg (TableHeader.Signature))
    624     {
    625         /*
    626          * The "-ds cdat" option was not used, and the signature is not valid.
    627          *
    628          * For CDAT we are assuming that there should be at least one non-ASCII
    629          * byte in the (normally) 4-character Signature field (at least the
    630          * high-order byte should be zero). Otherwise, this is OK.
    631          */
    632         fprintf (stderr,
    633             "\nTable appears to be a CDAT table, which has no signature.\n"
    634             "If this is in fact a CDAT table, use the -ds option on the\n"
    635             "command line to specify the table type (signature):\n"
    636             "\"iasl -d -ds CDAT <file>\" or \"iasl -ds CDAT -T CDAT\"\n\n");
    637 
    638         return (AE_BAD_SIGNATURE);
    639     }
    640 
    641     /* Validate table length against bytes remaining in the file */
    642 
    643     FileSize = CmGetFileSize (File);
    644     if (!AcpiGbl_CDAT)
    645     {
    646         /* Standard ACPI table header */
    647 
    648         if (TableHeader.Length > (UINT32) (FileSize - TableOffset))
    649         {
    650             fprintf (stderr, "Table [%4.4s] is too long for file - "
    651                 "needs: 0x%.2X, remaining in file: 0x%.2X\n",
    652                 TableHeader.Signature, TableHeader.Length,
    653                 (UINT32) (FileSize - TableOffset));
    654             return (AE_BAD_HEADER);
    655         }
    656     }
    657     else if (CdatTableHeader->Length > (UINT32) (FileSize - TableOffset))
    658     {
    659         /* Special header for CDAT table */
    660 
    661         fprintf (stderr, "Table [CDAT] is too long for file - "
    662             "needs: 0x%.2X, remaining in file: 0x%.2X\n",
    663             CdatTableHeader->Length,
    664             (UINT32) (FileSize - TableOffset));
    665         return (AE_BAD_HEADER);
    666     }
    667 
    668     /* For CDAT table, there are no ASCII fields in the header, we are done */
    669 
    670     if (AcpiGbl_CDAT)
    671     {
    672         return (AE_OK);
    673     }
    674 
    675     /*
    676      * These standard fields must be ASCII: OemId, OemTableId, AslCompilerId.
    677      * We allow a NULL terminator in OemId and OemTableId.
    678      */
    679     for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
    680     {
    681         if (!ACPI_IS_ASCII ((UINT8) TableHeader.AslCompilerId[i]))
    682         {
    683             goto BadCharacters;
    684         }
    685     }
    686 
    687     for (i = 0; (i < ACPI_OEM_ID_SIZE) && (TableHeader.OemId[i]); i++)
    688     {
    689         if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemId[i]))
    690         {
    691             goto BadCharacters;
    692         }
    693     }
    694 
    695     for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (TableHeader.OemTableId[i]); i++)
    696     {
    697         if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemTableId[i]))
    698         {
    699             goto BadCharacters;
    700         }
    701     }
    702 
    703     return (AE_OK);
    704 
    705 
    706 BadCharacters:
    707 
    708     ACPI_WARNING ((AE_INFO,
    709         "Table header for [%4.4s] has invalid ASCII character(s)",
    710         TableHeader.Signature));
    711     return (AE_OK);
    712 }
    713 
    714 
    715 /*******************************************************************************
    716  *
    717  * FUNCTION:    AcCheckTextModeCorruption
    718  *
    719  * PARAMETERS:  Table           - Table buffer starting with table header
    720  *
    721  * RETURN:      Status
    722  *
    723  * DESCRIPTION: Check table for text mode file corruption where all linefeed
    724  *              characters (LF) have been replaced by carriage return linefeed
    725  *              pairs (CR/LF).
    726  *
    727  ******************************************************************************/
    728 
    729 static ACPI_STATUS
    730 AcCheckTextModeCorruption (
    731     ACPI_TABLE_HEADER       *Table)
    732 {
    733     UINT32                  i;
    734     UINT32                  Pairs = 0;
    735     UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Table);
    736 
    737 
    738     /* Scan entire table to determine if each LF has been prefixed with a CR */
    739 
    740     for (i = 1; i < Table->Length; i++)
    741     {
    742         if (Buffer[i] == 0x0A)
    743         {
    744             if (Buffer[i - 1] != 0x0D)
    745             {
    746                 /* The LF does not have a preceding CR, table not corrupted */
    747 
    748                 return (AE_OK);
    749             }
    750             else
    751             {
    752                 /* Found a CR/LF pair */
    753 
    754                 Pairs++;
    755             }
    756 
    757             i++;
    758         }
    759     }
    760 
    761     if (!Pairs)
    762     {
    763         return (AE_OK);
    764     }
    765 
    766     /*
    767      * Entire table scanned, each CR is part of a CR/LF pair --
    768      * meaning that the table was treated as a text file somewhere.
    769      *
    770      * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
    771      * original table are left untouched by the text conversion process --
    772      * meaning that we cannot simply replace CR/LF pairs with LFs.
    773      */
    774     AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
    775     AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
    776     AcpiOsPrintf ("Table cannot be repaired!\n");
    777 
    778     return (AE_BAD_VALUE);
    779 }
    780