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 - 2014, 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                  FileSize;
 477     UINT32                  TableLength;
 478     ACPI_STATUS             Status;
 479 
 480 
 481     /* Open the file */
 482 
 483     File = fopen (Filename, "rb");
 484     if (!File)
 485     {
 486         perror ("Could not open input file");
 487         return (AE_ERROR);
 488     }
 489 
 490     /* Get the file size */
 491 
 492     fseek (File, 0, SEEK_END);
 493     FileSize = (UINT32) ftell (File);
 494     fseek (File, 0, SEEK_SET);
 495 
 496     /* Get the entire file */
 497 
 498     fprintf (stderr, "Loading Acpi table from file %10s - Length %.8u (%06X)\n",
 499         Filename, FileSize, FileSize);
 500 
 501     Status = AcpiDbReadTable (File, Table, &TableLength);
 502     fclose(File);
 503 
 504     if (ACPI_FAILURE (Status))
 505     {
 506         AcpiOsPrintf ("Could not get table from the file\n");
 507         return (Status);
 508     }
 509 
 510     return (AE_OK);
 511  }
 512 #endif
 513 
 514 
 515 /*******************************************************************************
 516  *
 517  * FUNCTION:    AcpiDbGetTableFromFile
 518  *
 519  * PARAMETERS:  Filename        - File where table is located
 520  *              ReturnTable     - Where a pointer to the table is returned
 521  *
 522  * RETURN:      Status
 523  *
 524  * DESCRIPTION: Load an ACPI table from a file
 525  *
 526  ******************************************************************************/
 527 
 528 ACPI_STATUS
 529 AcpiDbGetTableFromFile (
 530     char                    *Filename,
 531     ACPI_TABLE_HEADER       **ReturnTable)
 532 {
 533 #ifdef ACPI_APPLICATION
 534     ACPI_STATUS             Status;
 535     ACPI_TABLE_HEADER       *Table;
 536     BOOLEAN                 IsAmlTable = TRUE;
 537 
 538 
 539     Status = AcpiDbReadTableFromFile (Filename, &Table);
 540     if (ACPI_FAILURE (Status))
 541     {
 542         return (Status);
 543     }
 544 
 545 #ifdef ACPI_DATA_TABLE_DISASSEMBLY
 546     IsAmlTable = AcpiUtIsAmlTable (Table);
 547 #endif
 548 
 549     if (IsAmlTable)
 550     {
 551         /* Attempt to recognize and install the table */
 552 
 553         Status = AeLocalLoadTable (Table);
 554         if (ACPI_FAILURE (Status))
 555         {
 556             if (Status == AE_ALREADY_EXISTS)
 557             {
 558                 AcpiOsPrintf ("Table %4.4s is already installed\n",
 559                     Table->Signature);
 560             }
 561             else
 562             {
 563                 AcpiOsPrintf ("Could not install table, %s\n",
 564                     AcpiFormatException (Status));
 565             }
 566 
 567             return (Status);
 568         }
 569 
 570         fprintf (stderr,
 571             "Acpi table [%4.4s] successfully installed and loaded\n",
 572             Table->Signature);
 573     }
 574 
 575     AcpiGbl_AcpiHardwarePresent = FALSE;
 576     if (ReturnTable)
 577     {
 578         *ReturnTable = Table;
 579     }
 580 
 581 
 582 #endif  /* ACPI_APPLICATION */
 583     return (AE_OK);
 584 }
 585 
 586 #endif  /* ACPI_DEBUGGER */