void FlWriteFile ( UINT32 FileId, void *Buffer, UINT32 Length) { UINT32 Actual; /* Write and check for error */ Actual = fwrite ((char *) Buffer, 1, Length, Gbl_Files[FileId].Handle); if (Actual != Length) { FlFileError (FileId, ASL_MSG_WRITE); AslAbort (); } if ((FileId == ASL_FILE_PREPROCESSOR) && Gbl_PreprocessorOutputFlag) { /* Duplicate the output to the user preprocessor (.i) file */ Actual = fwrite ((char *) Buffer, 1, Length, Gbl_Files[ASL_FILE_PREPROCESSOR_USER].Handle); if (Actual != Length) { FlFileError (FileId, ASL_MSG_WRITE); AslAbort (); } } }
void AslCoreSubsystemError ( ACPI_PARSE_OBJECT *Op, ACPI_STATUS Status, char *ExtraMessage, BOOLEAN Abort) { sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage); if (Op) { AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, Op->Asl.LogicalByteOffset, Op->Asl.Column, Op->Asl.Filename, MsgBuffer); } else { AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0, 0, 0, 0, NULL, MsgBuffer); } if (Abort) { AslAbort (); } }
static ACPI_STATUS LsAmlListingWalk ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { UINT8 FileByte; UINT32 i; UINT32 FileId = (UINT32) ACPI_TO_INTEGER (Context); LsWriteNodeToListing (Op, FileId); if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DATA) { /* Buffer is a resource template, don't dump the data all at once */ return (AE_OK); } /* Write the hex bytes to the listing file(s) (if requested) */ for (i = 0; i < Op->Asl.FinalAmlLength; i++) { if (ACPI_FAILURE (FlReadFile (ASL_FILE_AML_OUTPUT, &FileByte, 1))) { FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ); AslAbort (); } LsWriteListingHexBytes (&FileByte, 1, FileId); } return (AE_OK); }
ACPI_STATUS FlReadFile ( UINT32 FileId, void *Buffer, UINT32 Length) { UINT32 Actual; /* Read and check for error */ Actual = fread (Buffer, 1, Length, Gbl_Files[FileId].Handle); if (Actual < Length) { if (feof (Gbl_Files[FileId].Handle)) { /* End-of-file, just return error */ return (AE_ERROR); } FlFileError (FileId, ASL_MSG_READ); AslAbort (); } return (AE_OK); }
void FlPrintFile ( UINT32 FileId, char *Format, ...) { INT32 Actual; va_list Args; va_start (Args, Format); Actual = vfprintf (Gbl_Files[FileId].Handle, Format, Args); va_end (Args); if (Actual == -1) { FlFileError (FileId, ASL_MSG_WRITE); AslAbort (); } if ((FileId == ASL_FILE_PREPROCESSOR) && Gbl_PreprocessorOutputFlag) { /* * Duplicate the output to the user preprocessor (.i) file, * except: no #line directives. */ if (!strncmp (Format, "#line", 5)) { return; } va_start (Args, Format); Actual = vfprintf (Gbl_Files[ASL_FILE_PREPROCESSOR_USER].Handle, Format, Args); va_end (Args); if (Actual == -1) { FlFileError (FileId, ASL_MSG_WRITE); AslAbort (); } } }
void UtExpandLineBuffers ( void) { UINT32 NewSize; /* Attempt to double the size of all line buffers */ NewSize = Gbl_LineBufferSize * 2; if (Gbl_CurrentLineBuffer) { DbgPrint (ASL_DEBUG_OUTPUT, "Increasing line buffer size from %u to %u\n", Gbl_LineBufferSize, NewSize); } Gbl_CurrentLineBuffer = realloc (Gbl_CurrentLineBuffer, NewSize); Gbl_LineBufPtr = Gbl_CurrentLineBuffer; if (!Gbl_CurrentLineBuffer) { goto ErrorExit; } Gbl_MainTokenBuffer = realloc (Gbl_MainTokenBuffer, NewSize); if (!Gbl_MainTokenBuffer) { goto ErrorExit; } Gbl_MacroTokenBuffer = realloc (Gbl_MacroTokenBuffer, NewSize); if (!Gbl_MacroTokenBuffer) { goto ErrorExit; } Gbl_ExpressionTokenBuffer = realloc (Gbl_ExpressionTokenBuffer, NewSize); if (!Gbl_ExpressionTokenBuffer) { goto ErrorExit; } Gbl_LineBufferSize = NewSize; return; /* On error above, simply issue error messages and abort, cannot continue */ ErrorExit: printf ("Could not increase line buffer size from %u to %u\n", Gbl_LineBufferSize, Gbl_LineBufferSize * 2); AslError (ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, NULL, NULL); AslAbort (); }
UINT32 FlGetFileSize ( UINT32 FileId) { UINT32 FileSize; FileSize = CmGetFileSize (Gbl_Files[FileId].Handle); if (FileSize == ACPI_UINT32_MAX) { AslAbort(); } return (FileSize); }
void FlSeekFile ( UINT32 FileId, long Offset) { int Error; Error = fseek (Gbl_Files[FileId].Handle, Offset, SEEK_SET); if (Error) { FlFileError (FileId, ASL_MSG_SEEK); AslAbort (); } }
UINT32 FlGetFileSize ( UINT32 FileId) { long FileSize; FileSize = UtGetFileSize (Gbl_Files[FileId].Handle); if (FileSize == -1) { AslAbort(); } return ((UINT32) FileSize); }
static UINT32 HxReadAmlOutputFile ( UINT8 *Buffer) { UINT32 Actual; Actual = fread (Buffer, 1, HEX_TABLE_LINE_SIZE, Gbl_Files[ASL_FILE_AML_OUTPUT].Handle); if (ferror (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle)) { FlFileError (ASL_FILE_AML_OUTPUT, ASL_MSG_READ); AslAbort (); } return (Actual); }
void FlWriteFile ( UINT32 FileId, void *Buffer, UINT32 Length) { UINT32 Actual; /* Write and check for error */ Actual = fwrite ((char *) Buffer, 1, Length, Gbl_Files[FileId].Handle); if (Actual != Length) { FlFileError (FileId, ASL_MSG_WRITE); AslAbort (); } }
void FlOpenFile ( UINT32 FileId, char *Filename, char *Mode) { FILE *File; File = fopen (Filename, Mode); if (!File) { FlFileError (FileId, ASL_MSG_OPEN); AslAbort (); } Gbl_Files[FileId].Filename = Filename; Gbl_Files[FileId].Handle = File; }
DT_FIELD * DtScanFile ( FILE *Handle) { ACPI_STATUS Status; UINT32 Offset; ACPI_FUNCTION_NAME (DtScanFile); /* Get the file size */ Gbl_InputByteCount = CmGetFileSize (Handle); if (Gbl_InputByteCount == ACPI_UINT32_MAX) { AslAbort (); } Gbl_CurrentLineNumber = 0; Gbl_CurrentLineOffset = 0; Gbl_NextLineOffset = 0; /* Scan line-by-line */ while ((Offset = DtGetNextLine (Handle, 0)) != ASL_EOF) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s", Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer)); Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset); if (Status == AE_NOT_FOUND) { break; } } /* Dump the parse tree if debug enabled */ DtDumpFieldList (Gbl_FieldList); return (Gbl_FieldList); }
void DtOutputBinary ( DT_SUBTABLE *RootTable) { if (!RootTable) { return; } /* Walk the entire parse tree, emitting the binary data */ DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL); Gbl_TableLength = CmGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle); if (Gbl_TableLength == ACPI_UINT32_MAX) { AslAbort (); } }
void FlPrintFile ( UINT32 FileId, char *Format, ...) { INT32 Actual; va_list Args; va_start (Args, Format); Actual = vfprintf (Gbl_Files[FileId].Handle, Format, Args); va_end (Args); if (Actual == -1) { FlFileError (FileId, ASL_MSG_WRITE); AslAbort (); } }
void FlCloseFile ( UINT32 FileId) { int Error; if (!Gbl_Files[FileId].Handle) { return; } Error = fclose (Gbl_Files[FileId].Handle); if (Error) { FlFileError (FileId, ASL_MSG_CLOSE); AslAbort (); } Gbl_Files[FileId].Handle = NULL; return; }
void FlCloseFile ( UINT32 FileId) { int Error; if (!Gbl_Files[FileId].Handle) { return; } Error = fclose (Gbl_Files[FileId].Handle); if (Error) { FlFileError (FileId, ASL_MSG_CLOSE); AslAbort (); } /* Do not clear/free the filename string */ Gbl_Files[FileId].Handle = NULL; return; }
void AcpiDmGetExternalsFromFile ( void) { FILE *ExternalRefFile; char *Token; char *MethodName; UINT32 ArgCount; UINT32 ImportCount = 0; if (!Gbl_ExternalRefFilename) { return; } /* Open the file */ ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r"); if (!ExternalRefFile) { fprintf (stderr, "Could not open external reference file \"%s\"\n", Gbl_ExternalRefFilename); AslAbort (); return; } /* Each line defines a method */ while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile)) { Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */ if (!Token) { continue; } if (strcmp (Token, "External")) { continue; } MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */ if (!MethodName) { continue; } Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */ if (!Token) { continue; } if (strcmp (Token, "MethodObj")) { continue; } Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */ if (!Token) { continue; } /* Convert arg count string to an integer */ errno = 0; ArgCount = strtoul (Token, NULL, 0); if (errno) { fprintf (stderr, "Invalid argument count (%s)\n", Token); continue; } if (ArgCount > 7) { fprintf (stderr, "Invalid argument count (%u)\n", ArgCount); continue; } /* Add this external to the global list */ AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n", Gbl_ExternalRefFilename, ArgCount, MethodName); AcpiDmAddPathToExternalList (MethodName, ACPI_TYPE_METHOD, ArgCount, (ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_FILE)); ImportCount++; } if (!ImportCount) { fprintf (stderr, "Did not find any external methods in reference file \"%s\"\n", Gbl_ExternalRefFilename); } else { /* Add the external(s) to the namespace */ AcpiDmAddExternalsToNamespace (); AcpiOsPrintf ("%s: Imported %u external method definitions\n", Gbl_ExternalRefFilename, ImportCount); } fclose (ExternalRefFile); }
ACPI_STATUS AnOperandTypecheckWalkEnd ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { const ACPI_OPCODE_INFO *OpInfo; UINT32 RuntimeArgTypes; UINT32 RuntimeArgTypes2; UINT32 RequiredBtypes; UINT32 ThisNodeBtype; UINT32 CommonBtypes; UINT32 OpcodeClass; ACPI_PARSE_OBJECT *ArgOp; UINT32 ArgType; switch (Op->Asl.AmlOpcode) { case AML_RAW_DATA_BYTE: case AML_RAW_DATA_WORD: case AML_RAW_DATA_DWORD: case AML_RAW_DATA_QWORD: case AML_RAW_DATA_BUFFER: case AML_RAW_DATA_CHAIN: case AML_PACKAGE_LENGTH: case AML_UNASSIGNED_OPCODE: case AML_DEFAULT_ARG_OP: /* Ignore the internal (compiler-only) AML opcodes */ return (AE_OK); default: break; } OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); if (!OpInfo) { return (AE_OK); } ArgOp = Op->Asl.Child; OpcodeClass = OpInfo->Class; RuntimeArgTypes = OpInfo->RuntimeArgs; #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE /* * Update 11/2008: In practice, we can't perform this check. A simple * analysis is not sufficient. Also, it can cause errors when compiling * disassembled code because of the way Switch operators are implemented * (a While(One) loop with a named temp variable created within.) */ /* * If we are creating a named object, check if we are within a while loop * by checking if the parent is a WHILE op. This is a simple analysis, but * probably sufficient for many cases. * * Allow Scope(), Buffer(), and Package(). */ if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) { if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) { AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); } } #endif /* * Special case for control opcodes IF/RETURN/WHILE since they * have no runtime arg list (at this time) */ switch (Op->Asl.AmlOpcode) { case AML_IF_OP: case AML_WHILE_OP: case AML_RETURN_OP: if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) { /* Check for an internal method */ if (AnIsInternalMethod (ArgOp)) { return (AE_OK); } /* The lone arg is a method call, check it */ RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); if (Op->Asl.AmlOpcode == AML_RETURN_OP) { RequiredBtypes = 0xFFFFFFFF; } ThisNodeBtype = AnGetBtype (ArgOp); if (ThisNodeBtype == ACPI_UINT32_MAX) { return (AE_OK); } AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype); } return (AE_OK); case AML_EXTERNAL_OP: /* * Not really a "runtime" opcode since it used by disassembler only. * The parser will find any issues with the operands. */ return (AE_OK); default: break; } /* Ignore the non-executable opcodes */ if (RuntimeArgTypes == ARGI_INVALID_OPCODE) { return (AE_OK); } /* * Special handling for certain opcodes. */ switch (Op->Asl.AmlOpcode) { /* BankField has one TermArg */ case AML_BANK_FIELD_OP: OpcodeClass = AML_CLASS_EXECUTE; ArgOp = ArgOp->Asl.Next; ArgOp = ArgOp->Asl.Next; break; /* Operation Region has 2 TermArgs */ case AML_REGION_OP: OpcodeClass = AML_CLASS_EXECUTE; ArgOp = ArgOp->Asl.Next; ArgOp = ArgOp->Asl.Next; break; /* DataTableRegion has 3 TermArgs */ case AML_DATA_REGION_OP: OpcodeClass = AML_CLASS_EXECUTE; ArgOp = ArgOp->Asl.Next; break; /* Buffers/Packages have a length that is a TermArg */ case AML_BUFFER_OP: case AML_PACKAGE_OP: case AML_VARIABLE_PACKAGE_OP: /* If length is a constant, we are done */ if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) || (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA)) { return (AE_OK); } break; /* Store can write any object to the Debug object */ case AML_STORE_OP: /* * If this is a Store() to the Debug object, we don't need * to perform any further validation -- because a Store of * any object to Debug is permitted and supported. */ if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP) { return (AE_OK); } break; default: break; } switch (OpcodeClass) { case AML_CLASS_EXECUTE: case AML_CLASS_CREATE: case AML_CLASS_CONTROL: case AML_CLASS_RETURN_VALUE: /* Reverse the runtime argument list */ RuntimeArgTypes2 = 0; while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) { RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; RuntimeArgTypes2 |= ArgType; INCREMENT_ARG_LIST (RuntimeArgTypes); } /* Typecheck each argument */ while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) { /* Get the required type(s) for the argument */ RequiredBtypes = AnMapArgTypeToBtype (ArgType); if (!ArgOp) { AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "Null ArgOp in argument loop"); AslAbort (); } /* Get the actual type of the argument */ ThisNodeBtype = AnGetBtype (ArgOp); if (ThisNodeBtype == ACPI_UINT32_MAX) { goto NextArgument; } /* Examine the arg based on the required type of the arg */ switch (ArgType) { case ARGI_TARGETREF: if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) { /* ZERO is the placeholder for "don't store result" */ ThisNodeBtype = RequiredBtypes; break; } /* Fallthrough */ case ARGI_STORE_TARGET: if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) { /* * This is the case where an original reference to a resource * descriptor field has been replaced by an (Integer) offset. * These named fields are supported at compile-time only; * the names are not passed to the interpreter (via the AML). */ if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) { AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL); } else { AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL); } } break; #ifdef __FUTURE_IMPLEMENTATION /* * Possible future typechecking support */ case ARGI_REFERENCE: /* References */ case ARGI_INTEGER_REF: case ARGI_OBJECT_REF: case ARGI_DEVICE_REF: switch (ArgOp->Asl.ParseOpcode) { case PARSEOP_LOCAL0: case PARSEOP_LOCAL1: case PARSEOP_LOCAL2: case PARSEOP_LOCAL3: case PARSEOP_LOCAL4: case PARSEOP_LOCAL5: case PARSEOP_LOCAL6: case PARSEOP_LOCAL7: /* TBD: implement analysis of current value (type) of the local */ /* For now, just treat any local as a typematch */ /*ThisNodeBtype = RequiredBtypes;*/ break; case PARSEOP_ARG0: case PARSEOP_ARG1: case PARSEOP_ARG2: case PARSEOP_ARG3: case PARSEOP_ARG4: case PARSEOP_ARG5: case PARSEOP_ARG6: /* Hard to analyze argument types, so we won't */ /* for now. Just treat any arg as a typematch */ /* ThisNodeBtype = RequiredBtypes; */ break; case PARSEOP_DEBUG: case PARSEOP_REFOF: case PARSEOP_INDEX: default: break; } break; #endif case ARGI_INTEGER: default: break; } /* Check for a type mismatch (required versus actual) */ CommonBtypes = ThisNodeBtype & RequiredBtypes; if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) { if (AnIsInternalMethod (ArgOp)) { return (AE_OK); } /* Check a method call for a valid return value */ AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype); } /* * Now check if the actual type(s) match at least one * bit to the required type */ else if (!CommonBtypes) { /* No match -- this is a type mismatch error */ AnFormatBtype (StringBuffer, ThisNodeBtype); AnFormatBtype (StringBuffer2, RequiredBtypes); sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", StringBuffer, OpInfo->Name, StringBuffer2); AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); } NextArgument: ArgOp = ArgOp->Asl.Next; INCREMENT_ARG_LIST (RuntimeArgTypes2); } break; default: break; } return (AE_OK); }