[BACK]Return to acfileio.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / external / bsd / acpica / dist / common

Annotation of src/sys/external/bsd/acpica/dist/common/acfileio.c, Revision 1.1.1.6.2.1

1.1       christos    1: /******************************************************************************
                      2:  *
                      3:  * Module Name: acfileio - Get ACPI tables from file
                      4:  *
                      5:  *****************************************************************************/
                      6:
                      7: /*
1.1.1.6.2.1! christos    8:  * Copyright (C) 2000 - 2019, Intel Corp.
1.1       christos    9:  * All rights reserved.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions, and the following disclaimer,
                     16:  *    without modification.
                     17:  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
                     18:  *    substantially similar to the "NO WARRANTY" disclaimer below
                     19:  *    ("Disclaimer") and any redistribution must be conditioned upon
                     20:  *    including a substantially similar Disclaimer requirement for further
                     21:  *    binary redistribution.
                     22:  * 3. Neither the names of the above-listed copyright holders nor the names
                     23:  *    of any contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * Alternatively, this software may be distributed under the terms of the
                     27:  * GNU General Public License ("GPL") version 2 as published by the Free
                     28:  * Software Foundation.
                     29:  *
                     30:  * NO WARRANTY
                     31:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     32:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     33:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
                     34:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
                     35:  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     36:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     37:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     38:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     39:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
                     40:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     41:  * POSSIBILITY OF SUCH DAMAGES.
                     42:  */
                     43:
                     44: #include "acpi.h"
                     45: #include "accommon.h"
                     46: #include "actables.h"
                     47: #include "acutils.h"
1.1.1.3   christos   48: #include "acapps.h"
1.1       christos   49:
                     50: #define _COMPONENT          ACPI_UTILITIES
                     51:         ACPI_MODULE_NAME    ("acfileio")
                     52:
                     53:
                     54: /* Local prototypes */
                     55:
                     56: static ACPI_STATUS
                     57: AcGetOneTableFromFile (
                     58:     char                    *Filename,
                     59:     FILE                    *File,
                     60:     UINT8                   GetOnlyAmlTables,
                     61:     ACPI_TABLE_HEADER       **Table);
                     62:
                     63: static ACPI_STATUS
                     64: AcCheckTextModeCorruption (
                     65:     ACPI_TABLE_HEADER       *Table);
                     66:
                     67:
                     68: /*******************************************************************************
                     69:  *
1.1.1.5   christos   70:  * FUNCTION:    AcDeleteTableList
                     71:  *
                     72:  * PARAMETERS:  ListHead            - List to delete
                     73:  *
                     74:  * RETURN:      Status
                     75:  *
                     76:  * DESCRIPTION: Delete a list of tables. This is useful for removing memory
                     77:  *              allocated by AcGetAllTablesFromFile
                     78:  *
                     79:  ******************************************************************************/
                     80:
                     81: void
                     82: AcDeleteTableList (
                     83:     ACPI_NEW_TABLE_DESC     *ListHead)
                     84: {
                     85:     ACPI_NEW_TABLE_DESC     *Current = ListHead;
                     86:     ACPI_NEW_TABLE_DESC     *Previous = Current;
                     87:
                     88:
                     89:     while (Current)
                     90:     {
                     91:         Current = Current->Next;
                     92:         AcpiOsFree (Previous);
                     93:         Previous = Current;
                     94:     }
                     95: }
                     96:
                     97:
                     98: /*******************************************************************************
                     99:  *
1.1       christos  100:  * FUNCTION:    AcGetAllTablesFromFile
                    101:  *
                    102:  * PARAMETERS:  Filename            - Table filename
                    103:  *              GetOnlyAmlTables    - TRUE if the tables must be AML tables
                    104:  *              ReturnListHead      - Where table list is returned
                    105:  *
                    106:  * RETURN:      Status
                    107:  *
                    108:  * DESCRIPTION: Get all ACPI tables from within a single file.
                    109:  *
                    110:  ******************************************************************************/
                    111:
                    112: ACPI_STATUS
                    113: AcGetAllTablesFromFile (
                    114:     char                    *Filename,
                    115:     UINT8                   GetOnlyAmlTables,
                    116:     ACPI_NEW_TABLE_DESC     **ReturnListHead)
                    117: {
                    118:     ACPI_NEW_TABLE_DESC     *ListHead = NULL;
                    119:     ACPI_NEW_TABLE_DESC     *ListTail = NULL;
                    120:     ACPI_NEW_TABLE_DESC     *TableDesc;
                    121:     FILE                    *File;
                    122:     ACPI_TABLE_HEADER       *Table = NULL;
                    123:     UINT32                  FileSize;
                    124:     ACPI_STATUS             Status = AE_OK;
                    125:
                    126:
                    127:     File = fopen (Filename, "rb");
                    128:     if (!File)
                    129:     {
1.1.1.3   christos  130:         fprintf (stderr, "Could not open input file: %s\n", Filename);
1.1       christos  131:         if (errno == ENOENT)
                    132:         {
                    133:             return (AE_NOT_EXIST);
                    134:         }
                    135:
                    136:         return (AE_ERROR);
                    137:     }
                    138:
                    139:     /* Get the file size */
                    140:
                    141:     FileSize = CmGetFileSize (File);
                    142:     if (FileSize == ACPI_UINT32_MAX)
                    143:     {
1.1.1.2   christos  144:         Status = AE_ERROR;
1.1.1.4   christos  145:         goto Exit;
1.1       christos  146:     }
                    147:
                    148:     fprintf (stderr,
                    149:         "Input file %s, Length 0x%X (%u) bytes\n",
                    150:         Filename, FileSize, FileSize);
                    151:
                    152:     /* We must have at least one ACPI table header */
                    153:
                    154:     if (FileSize < sizeof (ACPI_TABLE_HEADER))
                    155:     {
1.1.1.2   christos  156:         Status = AE_BAD_HEADER;
1.1.1.4   christos  157:         goto Exit;
1.1       christos  158:     }
                    159:
                    160:     /* Check for an non-binary file */
                    161:
                    162:     if (!AcIsFileBinary (File))
                    163:     {
                    164:         fprintf (stderr,
                    165:             "    %s: File does not appear to contain a valid AML table\n",
                    166:             Filename);
1.1.1.4   christos  167:         Status = AE_TYPE;
                    168:         goto Exit;
1.1       christos  169:     }
                    170:
                    171:     /* Read all tables within the file */
                    172:
                    173:     while (ACPI_SUCCESS (Status))
                    174:     {
                    175:         /* Get one entire ACPI table */
                    176:
                    177:         Status = AcGetOneTableFromFile (
                    178:             Filename, File, GetOnlyAmlTables, &Table);
                    179:
                    180:         if (Status == AE_CTRL_TERMINATE)
                    181:         {
                    182:             Status = AE_OK;
                    183:             break;
                    184:         }
                    185:         else if (Status == AE_TYPE)
                    186:         {
1.1.1.4   christos  187:             Status = AE_OK;
                    188:             goto Exit;
1.1       christos  189:         }
                    190:         else if (ACPI_FAILURE (Status))
                    191:         {
1.1.1.4   christos  192:             goto Exit;
1.1       christos  193:         }
                    194:
                    195:         /* Print table header for iASL/disassembler only */
                    196:
                    197: #ifdef ACPI_ASL_COMPILER
                    198:
1.1.1.4   christos  199:         AcpiTbPrintTableHeader (0, Table);
1.1       christos  200: #endif
                    201:
                    202:         /* Allocate and link a table descriptor */
                    203:
                    204:         TableDesc = AcpiOsAllocate (sizeof (ACPI_NEW_TABLE_DESC));
1.1.1.4   christos  205:         if (!TableDesc)
                    206:         {
                    207:             AcpiOsFree (Table);
                    208:             Status = AE_NO_MEMORY;
                    209:             goto Exit;
                    210:         }
                    211:
1.1       christos  212:         TableDesc->Table = Table;
                    213:         TableDesc->Next = NULL;
                    214:
                    215:         /* Link at the end of the local table list */
                    216:
                    217:         if (!ListHead)
                    218:         {
                    219:             ListHead = TableDesc;
                    220:             ListTail = TableDesc;
                    221:         }
                    222:         else
                    223:         {
                    224:             ListTail->Next = TableDesc;
                    225:             ListTail = TableDesc;
                    226:         }
                    227:     }
                    228:
                    229:     /* Add the local table list to the end of the global list */
                    230:
                    231:     if (*ReturnListHead)
                    232:     {
                    233:         ListTail = *ReturnListHead;
                    234:         while (ListTail->Next)
                    235:         {
                    236:             ListTail = ListTail->Next;
                    237:         }
                    238:
                    239:         ListTail->Next = ListHead;
                    240:     }
                    241:     else
                    242:     {
                    243:         *ReturnListHead = ListHead;
                    244:     }
                    245:
1.1.1.4   christos  246: Exit:
1.1       christos  247:     fclose(File);
                    248:     return (Status);
                    249: }
                    250:
                    251:
                    252: /*******************************************************************************
                    253:  *
                    254:  * FUNCTION:    AcGetOneTableFromFile
                    255:  *
                    256:  * PARAMETERS:  Filename            - File where table is located
                    257:  *              File                - Open FILE pointer to Filename
                    258:  *              GetOnlyAmlTables    - TRUE if the tables must be AML tables.
                    259:  *              ReturnTable         - Where a pointer to the table is returned
                    260:  *
                    261:  * RETURN:      Status
                    262:  *
                    263:  * DESCRIPTION: Read the next ACPI table from a file. Implements support
                    264:  *              for multiple tables within a single file. File must already
                    265:  *              be open.
                    266:  *
                    267:  * Note: Loading an RSDP is not supported.
                    268:  *
                    269:  ******************************************************************************/
                    270:
                    271: static ACPI_STATUS
                    272: AcGetOneTableFromFile (
                    273:     char                    *Filename,
                    274:     FILE                    *File,
                    275:     UINT8                   GetOnlyAmlTables,
                    276:     ACPI_TABLE_HEADER       **ReturnTable)
                    277: {
                    278:     ACPI_STATUS             Status = AE_OK;
                    279:     ACPI_TABLE_HEADER       TableHeader;
                    280:     ACPI_TABLE_HEADER       *Table;
                    281:     INT32                   Count;
                    282:     long                    TableOffset;
                    283:
                    284:
                    285:     *ReturnTable = NULL;
                    286:
                    287:     /* Get the table header to examine signature and length */
                    288:
                    289:     TableOffset = ftell (File);
                    290:     Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File);
                    291:     if (Count != sizeof (ACPI_TABLE_HEADER))
                    292:     {
                    293:         return (AE_CTRL_TERMINATE);
                    294:     }
                    295:
                    296:     if (GetOnlyAmlTables)
                    297:     {
1.1.1.6.2.1! christos  298:         /* Validate the table signature/header (limited ASCII chars) */
        !           299:
        !           300:         Status = AcValidateTableHeader (File, TableOffset);
        !           301:         if (ACPI_FAILURE (Status))
        !           302:         {
        !           303:             return (Status);
        !           304:         }
        !           305:
1.1.1.3   christos  306:         /*
                    307:          * Table must be an AML table (DSDT/SSDT).
                    308:          * Used for iASL -e option only.
                    309:          */
                    310:         if (!AcpiUtIsAmlTable (&TableHeader))
1.1       christos  311:         {
                    312:             fprintf (stderr,
                    313:                 "    %s: Table [%4.4s] is not an AML table - ignoring\n",
                    314:                 Filename, TableHeader.Signature);
                    315:
                    316:             return (AE_TYPE);
                    317:         }
                    318:     }
                    319:
                    320:     /* Allocate a buffer for the entire table */
                    321:
1.1.1.3   christos  322:     Table = AcpiOsAllocate ((ACPI_SIZE) TableHeader.Length);
1.1       christos  323:     if (!Table)
                    324:     {
                    325:         return (AE_NO_MEMORY);
                    326:     }
                    327:
                    328:     /* Read the entire ACPI table, including header */
                    329:
                    330:     fseek (File, TableOffset, SEEK_SET);
                    331:
                    332:     Count = fread (Table, 1, TableHeader.Length, File);
1.1.1.6.2.1! christos  333:
        !           334:     /*
        !           335:      * Checks for data table headers happen later in the execution. Only verify
        !           336:      * for Aml tables at this point in the code.
        !           337:      */
        !           338:     if (GetOnlyAmlTables && Count != (INT32) TableHeader.Length)
1.1       christos  339:     {
                    340:         Status = AE_ERROR;
                    341:         goto ErrorExit;
                    342:     }
                    343:
                    344:     /* Validate the checksum (just issue a warning) */
                    345:
                    346:     Status = AcpiTbVerifyChecksum (Table, TableHeader.Length);
                    347:     if (ACPI_FAILURE (Status))
                    348:     {
                    349:         Status = AcCheckTextModeCorruption (Table);
                    350:         if (ACPI_FAILURE (Status))
                    351:         {
                    352:             goto ErrorExit;
                    353:         }
                    354:     }
                    355:
                    356:     *ReturnTable = Table;
                    357:     return (AE_OK);
                    358:
                    359:
                    360: ErrorExit:
                    361:     AcpiOsFree (Table);
                    362:     return (Status);
                    363: }
                    364:
                    365:
                    366: /*******************************************************************************
                    367:  *
                    368:  * FUNCTION:    AcIsFileBinary
                    369:  *
                    370:  * PARAMETERS:  File                - Open input file
                    371:  *
                    372:  * RETURN:      TRUE if file appears to be binary
                    373:  *
                    374:  * DESCRIPTION: Scan a file for any non-ASCII bytes.
                    375:  *
                    376:  * Note: Maintains current file position.
                    377:  *
                    378:  ******************************************************************************/
                    379:
                    380: BOOLEAN
                    381: AcIsFileBinary (
                    382:     FILE                    *File)
                    383: {
                    384:     UINT8                   Byte;
                    385:     BOOLEAN                 IsBinary = FALSE;
                    386:     long                    FileOffset;
                    387:
                    388:
                    389:     /* Scan entire file for any non-ASCII bytes */
                    390:
                    391:     FileOffset = ftell (File);
                    392:     while (fread (&Byte, 1, 1, File) == 1)
                    393:     {
                    394:         if (!isprint (Byte) && !isspace (Byte))
                    395:         {
                    396:             IsBinary = TRUE;
                    397:             goto Exit;
                    398:         }
                    399:     }
                    400:
                    401: Exit:
                    402:     fseek (File, FileOffset, SEEK_SET);
                    403:     return (IsBinary);
                    404: }
                    405:
                    406:
                    407: /*******************************************************************************
                    408:  *
                    409:  * FUNCTION:    AcValidateTableHeader
                    410:  *
                    411:  * PARAMETERS:  File                - Open input file
                    412:  *
                    413:  * RETURN:      Status
                    414:  *
                    415:  * DESCRIPTION: Determine if a file seems to contain one or more binary ACPI
                    416:  *              tables, via the
                    417:  *              following checks on what would be the table header:
                    418:  *              1) File must be at least as long as an ACPI_TABLE_HEADER
                    419:  *              2) There must be enough room in the file to hold entire table
                    420:  *              3) Signature, OemId, OemTableId, AslCompilerId must be ASCII
                    421:  *
                    422:  * Note: There can be multiple definition blocks per file, so we cannot
                    423:  * expect/compare the file size to be equal to the table length. 12/2015.
                    424:  *
                    425:  * Note: Maintains current file position.
                    426:  *
                    427:  ******************************************************************************/
                    428:
                    429: ACPI_STATUS
                    430: AcValidateTableHeader (
                    431:     FILE                    *File,
                    432:     long                    TableOffset)
                    433: {
                    434:     ACPI_TABLE_HEADER       TableHeader;
1.1.1.3   christos  435:     ACPI_SIZE               Actual;
1.1       christos  436:     long                    OriginalOffset;
                    437:     UINT32                  FileSize;
                    438:     UINT32                  i;
                    439:
                    440:
1.1.1.4   christos  441:     ACPI_FUNCTION_TRACE (AcValidateTableHeader);
1.1       christos  442:
                    443:
                    444:     /* Read a potential table header */
                    445:
                    446:     OriginalOffset = ftell (File);
                    447:     fseek (File, TableOffset, SEEK_SET);
                    448:
                    449:     Actual = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File);
                    450:     fseek (File, OriginalOffset, SEEK_SET);
                    451:
                    452:     if (Actual < sizeof (ACPI_TABLE_HEADER))
                    453:     {
                    454:         return (AE_ERROR);
                    455:     }
                    456:
                    457:     /* Validate the signature (limited ASCII chars) */
                    458:
1.1.1.2   christos  459:     if (!AcpiUtValidNameseg (TableHeader.Signature))
1.1       christos  460:     {
                    461:         return (AE_BAD_SIGNATURE);
                    462:     }
                    463:
                    464:     /* Validate table length against bytes remaining in the file */
                    465:
                    466:     FileSize = CmGetFileSize (File);
                    467:     if (TableHeader.Length > (UINT32) (FileSize - TableOffset))
                    468:     {
                    469:         fprintf (stderr, "Table [%4.4s] is too long for file - "
                    470:             "needs: 0x%.2X, remaining in file: 0x%.2X\n",
                    471:             TableHeader.Signature, TableHeader.Length,
                    472:             (UINT32) (FileSize - TableOffset));
                    473:         return (AE_BAD_HEADER);
                    474:     }
                    475:
                    476:     /*
                    477:      * These fields must be ASCII: OemId, OemTableId, AslCompilerId.
                    478:      * We allow a NULL terminator in OemId and OemTableId.
                    479:      */
1.1.1.6.2.1! christos  480:     for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
1.1       christos  481:     {
                    482:         if (!ACPI_IS_ASCII ((UINT8) TableHeader.AslCompilerId[i]))
                    483:         {
                    484:             goto BadCharacters;
                    485:         }
                    486:     }
                    487:
                    488:     for (i = 0; (i < ACPI_OEM_ID_SIZE) && (TableHeader.OemId[i]); i++)
                    489:     {
                    490:         if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemId[i]))
                    491:         {
                    492:             goto BadCharacters;
                    493:         }
                    494:     }
                    495:
                    496:     for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (TableHeader.OemTableId[i]); i++)
                    497:     {
                    498:         if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemTableId[i]))
                    499:         {
                    500:             goto BadCharacters;
                    501:         }
                    502:     }
                    503:
                    504:     return (AE_OK);
                    505:
                    506:
                    507: BadCharacters:
                    508:
                    509:     ACPI_WARNING ((AE_INFO,
                    510:         "Table header for [%4.4s] has invalid ASCII character(s)",
                    511:         TableHeader.Signature));
                    512:     return (AE_OK);
                    513: }
                    514:
                    515:
                    516: /*******************************************************************************
                    517:  *
                    518:  * FUNCTION:    AcCheckTextModeCorruption
                    519:  *
                    520:  * PARAMETERS:  Table           - Table buffer starting with table header
                    521:  *
                    522:  * RETURN:      Status
                    523:  *
                    524:  * DESCRIPTION: Check table for text mode file corruption where all linefeed
                    525:  *              characters (LF) have been replaced by carriage return linefeed
                    526:  *              pairs (CR/LF).
                    527:  *
                    528:  ******************************************************************************/
                    529:
                    530: static ACPI_STATUS
                    531: AcCheckTextModeCorruption (
                    532:     ACPI_TABLE_HEADER       *Table)
                    533: {
                    534:     UINT32                  i;
                    535:     UINT32                  Pairs = 0;
                    536:     UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Table);
                    537:
                    538:
                    539:     /* Scan entire table to determine if each LF has been prefixed with a CR */
                    540:
                    541:     for (i = 1; i < Table->Length; i++)
                    542:     {
                    543:         if (Buffer[i] == 0x0A)
                    544:         {
                    545:             if (Buffer[i - 1] != 0x0D)
                    546:             {
                    547:                 /* The LF does not have a preceding CR, table not corrupted */
                    548:
                    549:                 return (AE_OK);
                    550:             }
                    551:             else
                    552:             {
                    553:                 /* Found a CR/LF pair */
                    554:
                    555:                 Pairs++;
                    556:             }
                    557:
                    558:             i++;
                    559:         }
                    560:     }
                    561:
                    562:     if (!Pairs)
                    563:     {
                    564:         return (AE_OK);
                    565:     }
                    566:
                    567:     /*
                    568:      * Entire table scanned, each CR is part of a CR/LF pair --
                    569:      * meaning that the table was treated as a text file somewhere.
                    570:      *
                    571:      * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
                    572:      * original table are left untouched by the text conversion process --
                    573:      * meaning that we cannot simply replace CR/LF pairs with LFs.
                    574:      */
                    575:     AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
                    576:     AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
                    577:     AcpiOsPrintf ("Table cannot be repaired!\n");
                    578:
                    579:     return (AE_BAD_VALUE);
                    580: }

CVSweb <webmaster@jp.NetBSD.org>