aboutsummaryrefslogtreecommitdiff
path: root/source/common
diff options
context:
space:
mode:
Diffstat (limited to 'source/common')
-rw-r--r--source/common/acfileio.c226
-rw-r--r--source/common/adisasm.c13
-rw-r--r--source/common/getopt.c1
3 files changed, 210 insertions, 30 deletions
diff --git a/source/common/acfileio.c b/source/common/acfileio.c
index b94adf8c4900..96f323f74909 100644
--- a/source/common/acfileio.c
+++ b/source/common/acfileio.c
@@ -55,20 +55,20 @@
/* Local prototypes */
static ACPI_STATUS
-AcpiAcGetOneTableFromFile (
+AcGetOneTableFromFile (
char *Filename,
FILE *File,
UINT8 GetOnlyAmlTables,
ACPI_TABLE_HEADER **Table);
static ACPI_STATUS
-AcpiAcCheckTextModeCorruption (
+AcCheckTextModeCorruption (
ACPI_TABLE_HEADER *Table);
/*******************************************************************************
*
- * FUNCTION: AcpiAcGetAllTablesFromFile
+ * FUNCTION: AcGetAllTablesFromFile
*
* PARAMETERS: Filename - Table filename
* GetOnlyAmlTables - TRUE if the tables must be AML tables
@@ -81,7 +81,7 @@ AcpiAcCheckTextModeCorruption (
******************************************************************************/
ACPI_STATUS
-AcpiAcGetAllTablesFromFile (
+AcGetAllTablesFromFile (
char *Filename,
UINT8 GetOnlyAmlTables,
ACPI_NEW_TABLE_DESC **ReturnListHead)
@@ -115,19 +115,36 @@ AcpiAcGetAllTablesFromFile (
return (AE_ERROR);
}
- if (FileSize < 4)
+ fprintf (stderr,
+ "Input file %s, Length 0x%X (%u) bytes\n",
+ Filename, FileSize, FileSize);
+
+ /* We must have at least one ACPI table header */
+
+ if (FileSize < sizeof (ACPI_TABLE_HEADER))
{
return (AE_BAD_HEADER);
}
+ /* Check for an non-binary file */
+
+ if (!AcIsFileBinary (File))
+ {
+ fprintf (stderr,
+ " %s: File does not appear to contain a valid AML table\n",
+ Filename);
+ return (AE_TYPE);
+ }
+
/* Read all tables within the file */
while (ACPI_SUCCESS (Status))
{
/* Get one entire ACPI table */
- Status = AcpiAcGetOneTableFromFile (
+ Status = AcGetOneTableFromFile (
Filename, File, GetOnlyAmlTables, &Table);
+
if (Status == AE_CTRL_TERMINATE)
{
Status = AE_OK;
@@ -135,13 +152,20 @@ AcpiAcGetAllTablesFromFile (
}
else if (Status == AE_TYPE)
{
- continue;
+ return (AE_OK);
}
else if (ACPI_FAILURE (Status))
{
return (Status);
}
+ /* Print table header for iASL/disassembler only */
+
+#ifdef ACPI_ASL_COMPILER
+
+ AcpiTbPrintTableHeader (0, Table);
+#endif
+
/* Allocate and link a table descriptor */
TableDesc = AcpiOsAllocate (sizeof (ACPI_NEW_TABLE_DESC));
@@ -186,7 +210,7 @@ AcpiAcGetAllTablesFromFile (
/*******************************************************************************
*
- * FUNCTION: AcpiAcGetOneTableFromFile
+ * FUNCTION: AcGetOneTableFromFile
*
* PARAMETERS: Filename - File where table is located
* File - Open FILE pointer to Filename
@@ -204,7 +228,7 @@ AcpiAcGetAllTablesFromFile (
******************************************************************************/
static ACPI_STATUS
-AcpiAcGetOneTableFromFile (
+AcGetOneTableFromFile (
char *Filename,
FILE *File,
UINT8 GetOnlyAmlTables,
@@ -214,21 +238,28 @@ AcpiAcGetOneTableFromFile (
ACPI_TABLE_HEADER TableHeader;
ACPI_TABLE_HEADER *Table;
INT32 Count;
- long Position;
+ long TableOffset;
*ReturnTable = NULL;
+ /* Get the table header to examine signature and length */
- /* Get just the table header to get signature and length */
-
- Position = ftell (File);
+ TableOffset = ftell (File);
Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File);
if (Count != sizeof (ACPI_TABLE_HEADER))
{
return (AE_CTRL_TERMINATE);
}
+ /* Validate the table signature/header (limited ASCII chars) */
+
+ Status = AcValidateTableHeader (File, TableOffset);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
if (GetOnlyAmlTables)
{
/* Table must be an AML table (DSDT/SSDT) or FADT */
@@ -237,7 +268,7 @@ AcpiAcGetOneTableFromFile (
!AcpiUtIsAmlTable (&TableHeader))
{
fprintf (stderr,
- " %s: [%4.4s] is not an AML table - ignoring\n",
+ " %s: Table [%4.4s] is not an AML table - ignoring\n",
Filename, TableHeader.Signature);
return (AE_TYPE);
@@ -252,9 +283,9 @@ AcpiAcGetOneTableFromFile (
return (AE_NO_MEMORY);
}
- /* Now read the entire table */
+ /* Read the entire ACPI table, including header */
- fseek (File, Position, SEEK_SET);
+ fseek (File, TableOffset, SEEK_SET);
Count = fread (Table, 1, TableHeader.Length, File);
if (Count != (INT32) TableHeader.Length)
@@ -268,18 +299,13 @@ AcpiAcGetOneTableFromFile (
Status = AcpiTbVerifyChecksum (Table, TableHeader.Length);
if (ACPI_FAILURE (Status))
{
- Status = AcpiAcCheckTextModeCorruption (Table);
+ Status = AcCheckTextModeCorruption (Table);
if (ACPI_FAILURE (Status))
{
goto ErrorExit;
}
}
- fprintf (stderr,
- "Loading ACPI table [%4.4s] from file %12s - Length 0x%06X (%u)\n",
- TableHeader.Signature, Filename,
- TableHeader.Length, TableHeader.Length);
-
*ReturnTable = Table;
return (AE_OK);
@@ -292,7 +318,159 @@ ErrorExit:
/*******************************************************************************
*
- * FUNCTION: AcpiAcCheckTextModeCorruption
+ * FUNCTION: AcIsFileBinary
+ *
+ * PARAMETERS: File - Open input file
+ *
+ * RETURN: TRUE if file appears to be binary
+ *
+ * DESCRIPTION: Scan a file for any non-ASCII bytes.
+ *
+ * Note: Maintains current file position.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcIsFileBinary (
+ FILE *File)
+{
+ UINT8 Byte;
+ BOOLEAN IsBinary = FALSE;
+ long FileOffset;
+
+
+ /* Scan entire file for any non-ASCII bytes */
+
+ FileOffset = ftell (File);
+ while (fread (&Byte, 1, 1, File) == 1)
+ {
+ if (!isprint (Byte) && !isspace (Byte))
+ {
+ IsBinary = TRUE;
+ goto Exit;
+ }
+ }
+
+Exit:
+ fseek (File, FileOffset, SEEK_SET);
+ return (IsBinary);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcValidateTableHeader
+ *
+ * PARAMETERS: File - Open input file
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Determine if a file seems to contain one or more binary ACPI
+ * tables, via the
+ * following checks on what would be the table header:
+ * 1) File must be at least as long as an ACPI_TABLE_HEADER
+ * 2) There must be enough room in the file to hold entire table
+ * 3) Signature, OemId, OemTableId, AslCompilerId must be ASCII
+ *
+ * Note: There can be multiple definition blocks per file, so we cannot
+ * expect/compare the file size to be equal to the table length. 12/2015.
+ *
+ * Note: Maintains current file position.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcValidateTableHeader (
+ FILE *File,
+ long TableOffset)
+{
+ ACPI_TABLE_HEADER TableHeader;
+ size_t Actual;
+ long OriginalOffset;
+ UINT32 FileSize;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE ("AcValidateTableHeader");
+
+
+ /* Read a potential table header */
+
+ OriginalOffset = ftell (File);
+ fseek (File, TableOffset, SEEK_SET);
+
+ Actual = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), File);
+ fseek (File, OriginalOffset, SEEK_SET);
+
+ if (Actual < sizeof (ACPI_TABLE_HEADER))
+ {
+ return (AE_ERROR);
+ }
+
+ /* Validate the signature (limited ASCII chars) */
+
+ if (!AcpiIsValidSignature (TableHeader.Signature))
+ {
+ fprintf (stderr, "Invalid table signature: 0x%8.8X\n",
+ *ACPI_CAST_PTR (UINT32, TableHeader.Signature));
+ return (AE_BAD_SIGNATURE);
+ }
+
+ /* Validate table length against bytes remaining in the file */
+
+ FileSize = CmGetFileSize (File);
+ if (TableHeader.Length > (UINT32) (FileSize - TableOffset))
+ {
+ fprintf (stderr, "Table [%4.4s] is too long for file - "
+ "needs: 0x%.2X, remaining in file: 0x%.2X\n",
+ TableHeader.Signature, TableHeader.Length,
+ (UINT32) (FileSize - TableOffset));
+ return (AE_BAD_HEADER);
+ }
+
+ /*
+ * These fields must be ASCII: OemId, OemTableId, AslCompilerId.
+ * We allow a NULL terminator in OemId and OemTableId.
+ */
+ for (i = 0; i < ACPI_NAME_SIZE; i++)
+ {
+ if (!ACPI_IS_ASCII ((UINT8) TableHeader.AslCompilerId[i]))
+ {
+ goto BadCharacters;
+ }
+ }
+
+ for (i = 0; (i < ACPI_OEM_ID_SIZE) && (TableHeader.OemId[i]); i++)
+ {
+ if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemId[i]))
+ {
+ goto BadCharacters;
+ }
+ }
+
+ for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (TableHeader.OemTableId[i]); i++)
+ {
+ if (!ACPI_IS_ASCII ((UINT8) TableHeader.OemTableId[i]))
+ {
+ goto BadCharacters;
+ }
+ }
+
+ return (AE_OK);
+
+
+BadCharacters:
+
+ ACPI_WARNING ((AE_INFO,
+ "Table header for [%4.4s] has invalid ASCII character(s)",
+ TableHeader.Signature));
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcCheckTextModeCorruption
*
* PARAMETERS: Table - Table buffer starting with table header
*
@@ -305,7 +483,7 @@ ErrorExit:
******************************************************************************/
static ACPI_STATUS
-AcpiAcCheckTextModeCorruption (
+AcCheckTextModeCorruption (
ACPI_TABLE_HEADER *Table)
{
UINT32 i;
diff --git a/source/common/adisasm.c b/source/common/adisasm.c
index 33500d6df4d6..4011dea73b2f 100644
--- a/source/common/adisasm.c
+++ b/source/common/adisasm.c
@@ -192,10 +192,12 @@ AdAmlDisassemble (
{
/* Get the list of all AML tables in the file */
- Status = AcpiAcGetAllTablesFromFile (Filename,
+ Status = AcGetAllTablesFromFile (Filename,
ACPI_GET_ALL_TABLES, &ListHead);
if (ACPI_FAILURE (Status))
{
+ AcpiOsPrintf ("Could not get ACPI tables from %s, %s\n",
+ Filename, AcpiFormatException (Status));
return (Status);
}
@@ -281,13 +283,12 @@ AdAmlDisassemble (
Cleanup:
-// check!
-#if 0
- if (Table && !AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
+ if (Table &&
+ !AcpiGbl_ForceAmlDisassembly &&
+ !AcpiUtIsAmlTable (Table))
{
ACPI_FREE (Table);
}
-#endif
if (File)
{
@@ -592,7 +593,7 @@ AdDoExternalFileList (
AcpiOsPrintf ("External object resolution file %16s\n",
ExternalFilename);
- Status = AcpiAcGetAllTablesFromFile (
+ Status = AcGetAllTablesFromFile (
ExternalFilename, ACPI_GET_ONLY_AML_TABLES, &ExternalListHead);
if (ACPI_FAILURE (Status))
{
diff --git a/source/common/getopt.c b/source/common/getopt.c
index e5b72174c031..64c1fef6e58a 100644
--- a/source/common/getopt.c
+++ b/source/common/getopt.c
@@ -47,6 +47,7 @@
* Option strings:
* "f" - Option has no arguments
* "f:" - Option requires an argument
+ * "f+" - Option has an optional argument
* "f^" - Option has optional single-char sub-options
* "f|" - Option has required single-char sub-options
*/