Home | History | Annotate | Line # | Download | only in debugger
dbfileio.c revision 1.1.1.2.20.1
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbfileio - Debugger file I/O commands. These can't usually
      4  *              be used when running the debugger in Ring 0 (Kernel mode)
      5  *
      6  ******************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2013, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 
     46 #include "acpi.h"
     47 #include "accommon.h"
     48 #include "acdebug.h"
     49 
     50 #ifdef ACPI_APPLICATION
     51 #include "actables.h"
     52 #endif
     53 
     54 #ifdef ACPI_ASL_COMPILER
     55 #include "aslcompiler.h"
     56 #endif
     57 
     58 #if (defined ACPI_DEBUGGER || defined ACPI_DISASSEMBLER)
     59 
     60 #define _COMPONENT          ACPI_CA_DEBUGGER
     61         ACPI_MODULE_NAME    ("dbfileio")
     62 
     63 #ifdef ACPI_DEBUGGER
     64 
     65 /* Local prototypes */
     66 
     67 #ifdef ACPI_APPLICATION
     68 
     69 static ACPI_STATUS
     70 AcpiDbCheckTextModeCorruption (
     71     UINT8                   *Table,
     72     UINT32                  TableLength,
     73     UINT32                  FileLength);
     74 
     75 #endif
     76 
     77 /*******************************************************************************
     78  *
     79  * FUNCTION:    AcpiDbCloseDebugFile
     80  *
     81  * PARAMETERS:  None
     82  *
     83  * RETURN:      None
     84  *
     85  * DESCRIPTION: If open, close the current debug output file
     86  *
     87  ******************************************************************************/
     88 
     89 void
     90 AcpiDbCloseDebugFile (
     91     void)
     92 {
     93 
     94 #ifdef ACPI_APPLICATION
     95 
     96     if (AcpiGbl_DebugFile)
     97     {
     98        fclose (AcpiGbl_DebugFile);
     99        AcpiGbl_DebugFile = NULL;
    100        AcpiGbl_DbOutputToFile = FALSE;
    101        AcpiOsPrintf ("Debug output file %s closed\n", AcpiGbl_DbDebugFilename);
    102     }
    103 #endif
    104 }
    105 
    106 
    107 /*******************************************************************************
    108  *
    109  * FUNCTION:    AcpiDbOpenDebugFile
    110  *
    111  * PARAMETERS:  Name                - Filename to open
    112  *
    113  * RETURN:      None
    114  *
    115  * DESCRIPTION: Open a file where debug output will be directed.
    116  *
    117  ******************************************************************************/
    118 
    119 void
    120 AcpiDbOpenDebugFile (
    121     char                    *Name)
    122 {
    123 
    124 #ifdef ACPI_APPLICATION
    125 
    126     AcpiDbCloseDebugFile ();
    127     AcpiGbl_DebugFile = fopen (Name, "w+");
    128     if (!AcpiGbl_DebugFile)
    129     {
    130         AcpiOsPrintf ("Could not open debug file %s\n", Name);
    131         return;
    132     }
    133 
    134     AcpiOsPrintf ("Debug output file %s opened\n", Name);
    135     ACPI_STRNCPY (AcpiGbl_DbDebugFilename, Name,
    136         sizeof (AcpiGbl_DbDebugFilename));
    137     AcpiGbl_DbOutputToFile = TRUE;
    138 
    139 #endif
    140 }
    141 #endif
    142 
    143 
    144 #ifdef ACPI_APPLICATION
    145 /*******************************************************************************
    146  *
    147  * FUNCTION:    AcpiDbCheckTextModeCorruption
    148  *
    149  * PARAMETERS:  Table           - Table buffer
    150  *              TableLength     - Length of table from the table header
    151  *              FileLength      - Length of the file that contains the table
    152  *
    153  * RETURN:      Status
    154  *
    155  * DESCRIPTION: Check table for text mode file corruption where all linefeed
    156  *              characters (LF) have been replaced by carriage return linefeed
    157  *              pairs (CR/LF).
    158  *
    159  ******************************************************************************/
    160 
    161 static ACPI_STATUS
    162 AcpiDbCheckTextModeCorruption (
    163     UINT8                   *Table,
    164     UINT32                  TableLength,
    165     UINT32                  FileLength)
    166 {
    167     UINT32                  i;
    168     UINT32                  Pairs = 0;
    169 
    170 
    171     if (TableLength != FileLength)
    172     {
    173         ACPI_WARNING ((AE_INFO,
    174             "File length (0x%X) is not the same as the table length (0x%X)",
    175             FileLength, TableLength));
    176     }
    177 
    178     /* Scan entire table to determine if each LF has been prefixed with a CR */
    179 
    180     for (i = 1; i < FileLength; i++)
    181     {
    182         if (Table[i] == 0x0A)
    183         {
    184             if (Table[i - 1] != 0x0D)
    185             {
    186                 /* The LF does not have a preceding CR, table not corrupted */
    187 
    188                 return (AE_OK);
    189             }
    190             else
    191             {
    192                 /* Found a CR/LF pair */
    193 
    194                 Pairs++;
    195             }
    196             i++;
    197         }
    198     }
    199 
    200     if (!Pairs)
    201     {
    202         return (AE_OK);
    203     }
    204 
    205     /*
    206      * Entire table scanned, each CR is part of a CR/LF pair --
    207      * meaning that the table was treated as a text file somewhere.
    208      *
    209      * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
    210      * original table are left untouched by the text conversion process --
    211      * meaning that we cannot simply replace CR/LF pairs with LFs.
    212      */
    213     AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
    214     AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
    215     AcpiOsPrintf ("Table cannot be repaired!\n");
    216     return (AE_BAD_VALUE);
    217 }
    218 
    219 
    220 /*******************************************************************************
    221  *
    222  * FUNCTION:    AcpiDbReadTable
    223  *
    224  * PARAMETERS:  fp              - File that contains table
    225  *              Table           - Return value, buffer with table
    226  *              TableLength     - Return value, length of table
    227  *
    228  * RETURN:      Status
    229  *
    230  * DESCRIPTION: Load the DSDT from the file pointer
    231  *
    232  ******************************************************************************/
    233 
    234 static ACPI_STATUS
    235 AcpiDbReadTable (
    236     FILE                    *fp,
    237     ACPI_TABLE_HEADER       **Table,
    238     UINT32                  *TableLength)
    239 {
    240     ACPI_TABLE_HEADER       TableHeader;
    241     UINT32                  Actual;
    242     ACPI_STATUS             Status;
    243     UINT32                  FileSize;
    244     BOOLEAN                 StandardHeader = TRUE;
    245 
    246 
    247     /* Get the file size */
    248 
    249     fseek (fp, 0, SEEK_END);
    250     FileSize = (UINT32) ftell (fp);
    251     fseek (fp, 0, SEEK_SET);
    252 
    253     if (FileSize < 4)
    254     {
    255         return (AE_BAD_HEADER);
    256     }
    257 
    258     /* Read the signature */
    259 
    260     if (fread (&TableHeader, 1, 4, fp) != 4)
    261     {
    262         AcpiOsPrintf ("Could not read the table signature\n");
    263         return (AE_BAD_HEADER);
    264     }
    265 
    266     fseek (fp, 0, SEEK_SET);
    267 
    268     /* The RSDP table does not have standard ACPI header */
    269 
    270     if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD "))
    271     {
    272         *TableLength = FileSize;
    273         StandardHeader = FALSE;
    274     }
    275     else
    276     {
    277         /* Read the table header */
    278 
    279         if (fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp) !=
    280                 sizeof (ACPI_TABLE_HEADER))
    281         {
    282             AcpiOsPrintf ("Could not read the table header\n");
    283             return (AE_BAD_HEADER);
    284         }
    285 
    286 #if 0
    287         /* Validate the table header/length */
    288 
    289         Status = AcpiTbValidateTableHeader (&TableHeader);
    290         if (ACPI_FAILURE (Status))
    291         {
    292             AcpiOsPrintf ("Table header is invalid!\n");
    293             return (Status);
    294         }
    295 #endif
    296 
    297         /* File size must be at least as long as the Header-specified length */
    298 
    299         if (TableHeader.Length > FileSize)
    300         {
    301             AcpiOsPrintf (
    302                 "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
    303                 TableHeader.Length, FileSize);
    304 
    305 #ifdef ACPI_ASL_COMPILER
    306             Status = FlCheckForAscii (fp, NULL, FALSE);
    307             if (ACPI_SUCCESS (Status))
    308             {
    309                 AcpiOsPrintf ("File appears to be ASCII only, must be binary\n",
    310                     TableHeader.Length, FileSize);
    311             }
    312 #endif
    313             return (AE_BAD_HEADER);
    314         }
    315 
    316 #ifdef ACPI_OBSOLETE_CODE
    317         /* We only support a limited number of table types */
    318 
    319         if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) &&
    320             !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) &&
    321             !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT))
    322         {
    323             AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
    324                 (char *) TableHeader.Signature);
    325             ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
    326             return (AE_ERROR);
    327         }
    328 #endif
    329 
    330         *TableLength = TableHeader.Length;
    331     }
    332 
    333     /* Allocate a buffer for the table */
    334 
    335     *Table = AcpiOsAllocate ((size_t) FileSize);
    336     if (!*Table)
    337     {
    338         AcpiOsPrintf (
    339             "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
    340             TableHeader.Signature, *TableLength);
    341         return (AE_NO_MEMORY);
    342     }
    343 
    344     /* Get the rest of the table */
    345 
    346     fseek (fp, 0, SEEK_SET);
    347     Actual = fread (*Table, 1, (size_t) FileSize, fp);
    348     if (Actual == FileSize)
    349     {
    350         if (StandardHeader)
    351         {
    352             /* Now validate the checksum */
    353 
    354             Status = AcpiTbVerifyChecksum ((void *) *Table,
    355                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length);
    356 
    357             if (Status == AE_BAD_CHECKSUM)
    358             {
    359                 Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table,
    360                             FileSize, (*Table)->Length);
    361                 return (Status);
    362             }
    363         }
    364         return (AE_OK);
    365     }
    366 
    367     if (Actual > 0)
    368     {
    369         AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
    370             FileSize, Actual);
    371         return (AE_OK);
    372     }
    373 
    374     AcpiOsPrintf ("Error - could not read the table file\n");
    375     AcpiOsFree (*Table);
    376     *Table = NULL;
    377     *TableLength = 0;
    378     return (AE_ERROR);
    379 }
    380 
    381 
    382 /*******************************************************************************
    383  *
    384  * FUNCTION:    AeLocalLoadTable
    385  *
    386  * PARAMETERS:  Table           - pointer to a buffer containing the entire
    387  *                                table to be loaded
    388  *
    389  * RETURN:      Status
    390  *
    391  * DESCRIPTION: This function is called to load a table from the caller's
    392  *              buffer. The buffer must contain an entire ACPI Table including
    393  *              a valid header. The header fields will be verified, and if it
    394  *              is determined that the table is invalid, the call will fail.
    395  *
    396  ******************************************************************************/
    397 
    398 static ACPI_STATUS
    399 AeLocalLoadTable (
    400     ACPI_TABLE_HEADER       *Table)
    401 {
    402     ACPI_STATUS             Status = AE_OK;
    403 /*    ACPI_TABLE_DESC         TableInfo; */
    404 
    405 
    406     ACPI_FUNCTION_TRACE (AeLocalLoadTable);
    407 #if 0
    408 
    409 
    410     if (!Table)
    411     {
    412         return_ACPI_STATUS (AE_BAD_PARAMETER);
    413     }
    414 
    415     TableInfo.Pointer = Table;
    416     Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL);
    417     if (ACPI_FAILURE (Status))
    418     {
    419         return_ACPI_STATUS (Status);
    420     }
    421 
    422     /* Install the new table into the local data structures */
    423 
    424     Status = AcpiTbInstallTable (&TableInfo);
    425     if (ACPI_FAILURE (Status))
    426     {
    427         if (Status == AE_ALREADY_EXISTS)
    428         {
    429             /* Table already exists, no error */
    430 
    431             Status = AE_OK;
    432         }
    433 
    434         /* Free table allocated by AcpiTbGetTable */
    435 
    436         AcpiTbDeleteSingleTable (&TableInfo);
    437         return_ACPI_STATUS (Status);
    438     }
    439 
    440 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
    441 
    442     Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
    443     if (ACPI_FAILURE (Status))
    444     {
    445         /* Uninstall table and free the buffer */
    446 
    447         AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT);
    448         return_ACPI_STATUS (Status);
    449     }
    450 #endif
    451 #endif
    452 
    453     return_ACPI_STATUS (Status);
    454 }
    455 
    456 
    457 /*******************************************************************************
    458  *
    459  * FUNCTION:    AcpiDbReadTableFromFile
    460  *
    461  * PARAMETERS:  Filename         - File where table is located
    462  *              Table            - Where a pointer to the table is returned
    463  *
    464  * RETURN:      Status
    465  *
    466  * DESCRIPTION: Get an ACPI table from a file
    467  *
    468  ******************************************************************************/
    469 
    470 ACPI_STATUS
    471 AcpiDbReadTableFromFile (
    472     char                    *Filename,
    473     ACPI_TABLE_HEADER       **Table)
    474 {
    475     FILE                    *File;
    476     UINT32                  TableLength;
    477     ACPI_STATUS             Status;
    478 
    479 
    480     /* Open the file */
    481 
    482     File = fopen (Filename, "rb");
    483     if (!File)
    484     {
    485         perror ("Could not open input file");
    486         return (AE_ERROR);
    487     }
    488 
    489     /* Get the entire file */
    490 
    491     fprintf (stderr, "Loading Acpi table from file %s\n", Filename);
    492     Status = AcpiDbReadTable (File, Table, &TableLength);
    493     fclose(File);
    494 
    495     if (ACPI_FAILURE (Status))
    496     {
    497         AcpiOsPrintf ("Could not get table from the file\n");
    498         return (Status);
    499     }
    500 
    501     return (AE_OK);
    502  }
    503 #endif
    504 
    505 
    506 /*******************************************************************************
    507  *
    508  * FUNCTION:    AcpiDbGetTableFromFile
    509  *
    510  * PARAMETERS:  Filename        - File where table is located
    511  *              ReturnTable     - Where a pointer to the table is returned
    512  *
    513  * RETURN:      Status
    514  *
    515  * DESCRIPTION: Load an ACPI table from a file
    516  *
    517  ******************************************************************************/
    518 
    519 ACPI_STATUS
    520 AcpiDbGetTableFromFile (
    521     char                    *Filename,
    522     ACPI_TABLE_HEADER       **ReturnTable)
    523 {
    524 #ifdef ACPI_APPLICATION
    525     ACPI_STATUS             Status;
    526     ACPI_TABLE_HEADER       *Table;
    527     BOOLEAN                 IsAmlTable = TRUE;
    528 
    529 
    530     Status = AcpiDbReadTableFromFile (Filename, &Table);
    531     if (ACPI_FAILURE (Status))
    532     {
    533         return (Status);
    534     }
    535 
    536 #ifdef ACPI_DATA_TABLE_DISASSEMBLY
    537     IsAmlTable = AcpiUtIsAmlTable (Table);
    538 #endif
    539 
    540     if (IsAmlTable)
    541     {
    542         /* Attempt to recognize and install the table */
    543 
    544         Status = AeLocalLoadTable (Table);
    545         if (ACPI_FAILURE (Status))
    546         {
    547             if (Status == AE_ALREADY_EXISTS)
    548             {
    549                 AcpiOsPrintf ("Table %4.4s is already installed\n",
    550                     Table->Signature);
    551             }
    552             else
    553             {
    554                 AcpiOsPrintf ("Could not install table, %s\n",
    555                     AcpiFormatException (Status));
    556             }
    557 
    558             return (Status);
    559         }
    560 
    561         fprintf (stderr,
    562             "Acpi table [%4.4s] successfully installed and loaded\n",
    563             Table->Signature);
    564     }
    565 
    566     AcpiGbl_AcpiHardwarePresent = FALSE;
    567     if (ReturnTable)
    568     {
    569         *ReturnTable = Table;
    570     }
    571 
    572 
    573 #endif  /* ACPI_APPLICATION */
    574     return (AE_OK);
    575 }
    576 
    577 #endif  /* ACPI_DEBUGGER */
    578